//! Latin encoding tables for PDF text extraction.
//!
//! Port of pdfminer.six `pdfminer/latin_enc.py`.
//! Based on PDF Reference Manual 1.6, pp.925 "D.1 Latin Character Set and Encodings"

/// An encoding row containing glyph name and its positions in various encodings.
/// Format: (name, std, mac, win, pdf)
/// - name: Adobe glyph name
/// - std: StandardEncoding position
/// - mac: MacRomanEncoding position
/// - win: WinAnsiEncoding position
/// - pdf: PDFDocEncoding position
pub type EncodingRow = (&'static str, Option<u8>, Option<u8>, Option<u8>, Option<u8>);

/// Latin encoding table mapping glyph names to byte positions.
/// Each tuple contains: (glyph_name, standard, mac, win, pdf)
pub const ENCODING: &[EncodingRow] = &[
    // (name, std, mac, win, pdf)
    ("A", Some(65), Some(65), Some(65), Some(65)),
    ("AE", Some(225), Some(174), Some(198), Some(198)),
    ("Aacute", None, Some(231), Some(193), Some(193)),
    ("Acircumflex", None, Some(229), Some(194), Some(194)),
    ("Adieresis", None, Some(128), Some(196), Some(196)),
    ("Agrave", None, Some(203), Some(192), Some(192)),
    ("Aring", None, Some(129), Some(197), Some(197)),
    ("Atilde", None, Some(204), Some(195), Some(195)),
    ("B", Some(66), Some(66), Some(66), Some(66)),
    ("C", Some(67), Some(67), Some(67), Some(67)),
    ("Ccedilla", None, Some(130), Some(199), Some(199)),
    ("D", Some(68), Some(68), Some(68), Some(68)),
    ("E", Some(69), Some(69), Some(69), Some(69)),
    ("Eacute", None, Some(131), Some(201), Some(201)),
    ("Ecircumflex", None, Some(230), Some(202), Some(202)),
    ("Edieresis", None, Some(232), Some(203), Some(203)),
    ("Egrave", None, Some(233), Some(200), Some(200)),
    ("Eth", None, None, Some(208), Some(208)),
    ("Euro", None, None, Some(128), Some(160)),
    ("F", Some(70), Some(70), Some(70), Some(70)),
    ("G", Some(71), Some(71), Some(71), Some(71)),
    ("H", Some(72), Some(72), Some(72), Some(72)),
    ("I", Some(73), Some(73), Some(73), Some(73)),
    ("Iacute", None, Some(234), Some(205), Some(205)),
    ("Icircumflex", None, Some(235), Some(206), Some(206)),
    ("Idieresis", None, Some(236), Some(207), Some(207)),
    ("Igrave", None, Some(237), Some(204), Some(204)),
    ("J", Some(74), Some(74), Some(74), Some(74)),
    ("K", Some(75), Some(75), Some(75), Some(75)),
    ("L", Some(76), Some(76), Some(76), Some(76)),
    ("Lslash", Some(232), None, None, Some(149)),
    ("M", Some(77), Some(77), Some(77), Some(77)),
    ("N", Some(78), Some(78), Some(78), Some(78)),
    ("Ntilde", None, Some(132), Some(209), Some(209)),
    ("O", Some(79), Some(79), Some(79), Some(79)),
    ("OE", Some(234), Some(206), Some(140), Some(150)),
    ("Oacute", None, Some(238), Some(211), Some(211)),
    ("Ocircumflex", None, Some(239), Some(212), Some(212)),
    ("Odieresis", None, Some(133), Some(214), Some(214)),
    ("Ograve", None, Some(241), Some(210), Some(210)),
    ("Oslash", Some(233), Some(175), Some(216), Some(216)),
    ("Otilde", None, Some(205), Some(213), Some(213)),
    ("P", Some(80), Some(80), Some(80), Some(80)),
    ("Q", Some(81), Some(81), Some(81), Some(81)),
    ("R", Some(82), Some(82), Some(82), Some(82)),
    ("S", Some(83), Some(83), Some(83), Some(83)),
    ("Scaron", None, None, Some(138), Some(151)),
    ("T", Some(84), Some(84), Some(84), Some(84)),
    ("Thorn", None, None, Some(222), Some(222)),
    ("U", Some(85), Some(85), Some(85), Some(85)),
    ("Uacute", None, Some(242), Some(218), Some(218)),
    ("Ucircumflex", None, Some(243), Some(219), Some(219)),
    ("Udieresis", None, Some(134), Some(220), Some(220)),
    ("Ugrave", None, Some(244), Some(217), Some(217)),
    ("V", Some(86), Some(86), Some(86), Some(86)),
    ("W", Some(87), Some(87), Some(87), Some(87)),
    ("X", Some(88), Some(88), Some(88), Some(88)),
    ("Y", Some(89), Some(89), Some(89), Some(89)),
    ("Yacute", None, None, Some(221), Some(221)),
    ("Ydieresis", None, Some(217), Some(159), Some(152)),
    ("Z", Some(90), Some(90), Some(90), Some(90)),
    ("Zcaron", None, None, Some(142), Some(153)),
    ("a", Some(97), Some(97), Some(97), Some(97)),
    ("aacute", None, Some(135), Some(225), Some(225)),
    ("acircumflex", None, Some(137), Some(226), Some(226)),
    ("acute", Some(194), Some(171), Some(180), Some(180)),
    ("adieresis", None, Some(138), Some(228), Some(228)),
    ("ae", Some(241), Some(190), Some(230), Some(230)),
    ("agrave", None, Some(136), Some(224), Some(224)),
    ("ampersand", Some(38), Some(38), Some(38), Some(38)),
    ("aring", None, Some(140), Some(229), Some(229)),
    ("asciicircum", Some(94), Some(94), Some(94), Some(94)),
    ("asciitilde", Some(126), Some(126), Some(126), Some(126)),
    ("asterisk", Some(42), Some(42), Some(42), Some(42)),
    ("at", Some(64), Some(64), Some(64), Some(64)),
    ("atilde", None, Some(139), Some(227), Some(227)),
    ("b", Some(98), Some(98), Some(98), Some(98)),
    ("backslash", Some(92), Some(92), Some(92), Some(92)),
    ("bar", Some(124), Some(124), Some(124), Some(124)),
    ("braceleft", Some(123), Some(123), Some(123), Some(123)),
    ("braceright", Some(125), Some(125), Some(125), Some(125)),
    ("bracketleft", Some(91), Some(91), Some(91), Some(91)),
    ("bracketright", Some(93), Some(93), Some(93), Some(93)),
    ("breve", Some(198), Some(249), None, Some(24)),
    ("brokenbar", None, None, Some(166), Some(166)),
    ("bullet", Some(183), Some(165), Some(149), Some(128)),
    ("c", Some(99), Some(99), Some(99), Some(99)),
    ("caron", Some(207), Some(255), None, Some(25)),
    ("ccedilla", None, Some(141), Some(231), Some(231)),
    ("cedilla", Some(203), Some(252), Some(184), Some(184)),
    ("cent", Some(162), Some(162), Some(162), Some(162)),
    ("circumflex", Some(195), Some(246), Some(136), Some(26)),
    ("colon", Some(58), Some(58), Some(58), Some(58)),
    ("comma", Some(44), Some(44), Some(44), Some(44)),
    ("copyright", None, Some(169), Some(169), Some(169)),
    ("currency", Some(168), Some(219), Some(164), Some(164)),
    ("d", Some(100), Some(100), Some(100), Some(100)),
    ("dagger", Some(178), Some(160), Some(134), Some(129)),
    ("daggerdbl", Some(179), Some(224), Some(135), Some(130)),
    ("degree", None, Some(161), Some(176), Some(176)),
    ("dieresis", Some(200), Some(172), Some(168), Some(168)),
    ("divide", None, Some(214), Some(247), Some(247)),
    ("dollar", Some(36), Some(36), Some(36), Some(36)),
    ("dotaccent", Some(199), Some(250), None, Some(27)),
    ("dotlessi", Some(245), Some(245), None, Some(154)),
    ("e", Some(101), Some(101), Some(101), Some(101)),
    ("eacute", None, Some(142), Some(233), Some(233)),
    ("ecircumflex", None, Some(144), Some(234), Some(234)),
    ("edieresis", None, Some(145), Some(235), Some(235)),
    ("egrave", None, Some(143), Some(232), Some(232)),
    ("eight", Some(56), Some(56), Some(56), Some(56)),
    ("ellipsis", Some(188), Some(201), Some(133), Some(131)),
    ("emdash", Some(208), Some(209), Some(151), Some(132)),
    ("endash", Some(177), Some(208), Some(150), Some(133)),
    ("equal", Some(61), Some(61), Some(61), Some(61)),
    ("eth", None, None, Some(240), Some(240)),
    ("exclam", Some(33), Some(33), Some(33), Some(33)),
    ("exclamdown", Some(161), Some(193), Some(161), Some(161)),
    ("f", Some(102), Some(102), Some(102), Some(102)),
    ("fi", Some(174), Some(222), None, Some(147)),
    ("five", Some(53), Some(53), Some(53), Some(53)),
    ("fl", Some(175), Some(223), None, Some(148)),
    ("florin", Some(166), Some(196), Some(131), Some(134)),
    ("four", Some(52), Some(52), Some(52), Some(52)),
    ("fraction", Some(164), Some(218), None, Some(135)),
    ("g", Some(103), Some(103), Some(103), Some(103)),
    ("germandbls", Some(251), Some(167), Some(223), Some(223)),
    ("grave", Some(193), Some(96), Some(96), Some(96)),
    ("greater", Some(62), Some(62), Some(62), Some(62)),
    ("guillemotleft", Some(171), Some(199), Some(171), Some(171)),
    ("guillemotright", Some(187), Some(200), Some(187), Some(187)),
    ("guilsinglleft", Some(172), Some(220), Some(139), Some(136)),
    ("guilsinglright", Some(173), Some(221), Some(155), Some(137)),
    ("h", Some(104), Some(104), Some(104), Some(104)),
    ("hungarumlaut", Some(205), Some(253), None, Some(28)),
    ("hyphen", Some(45), Some(45), Some(45), Some(45)),
    ("i", Some(105), Some(105), Some(105), Some(105)),
    ("iacute", None, Some(146), Some(237), Some(237)),
    ("icircumflex", None, Some(148), Some(238), Some(238)),
    ("idieresis", None, Some(149), Some(239), Some(239)),
    ("igrave", None, Some(147), Some(236), Some(236)),
    ("j", Some(106), Some(106), Some(106), Some(106)),
    ("k", Some(107), Some(107), Some(107), Some(107)),
    ("l", Some(108), Some(108), Some(108), Some(108)),
    ("less", Some(60), Some(60), Some(60), Some(60)),
    ("logicalnot", None, Some(194), Some(172), Some(172)),
    ("lslash", Some(248), None, None, Some(155)),
    ("m", Some(109), Some(109), Some(109), Some(109)),
    ("macron", Some(197), Some(248), Some(175), Some(175)),
    ("minus", None, None, None, Some(138)),
    ("mu", None, Some(181), Some(181), Some(181)),
    ("multiply", None, None, Some(215), Some(215)),
    ("n", Some(110), Some(110), Some(110), Some(110)),
    ("nbspace", None, Some(202), Some(160), None),
    ("nine", Some(57), Some(57), Some(57), Some(57)),
    ("ntilde", None, Some(150), Some(241), Some(241)),
    ("numbersign", Some(35), Some(35), Some(35), Some(35)),
    ("o", Some(111), Some(111), Some(111), Some(111)),
    ("oacute", None, Some(151), Some(243), Some(243)),
    ("ocircumflex", None, Some(153), Some(244), Some(244)),
    ("odieresis", None, Some(154), Some(246), Some(246)),
    ("oe", Some(250), Some(207), Some(156), Some(156)),
    ("ogonek", Some(206), Some(254), None, Some(29)),
    ("ograve", None, Some(152), Some(242), Some(242)),
    ("one", Some(49), Some(49), Some(49), Some(49)),
    ("onehalf", None, None, Some(189), Some(189)),
    ("onequarter", None, None, Some(188), Some(188)),
    ("onesuperior", None, None, Some(185), Some(185)),
    ("ordfeminine", Some(227), Some(187), Some(170), Some(170)),
    ("ordmasculine", Some(235), Some(188), Some(186), Some(186)),
    ("oslash", Some(249), Some(191), Some(248), Some(248)),
    ("otilde", None, Some(155), Some(245), Some(245)),
    ("p", Some(112), Some(112), Some(112), Some(112)),
    ("paragraph", Some(182), Some(166), Some(182), Some(182)),
    ("parenleft", Some(40), Some(40), Some(40), Some(40)),
    ("parenright", Some(41), Some(41), Some(41), Some(41)),
    ("percent", Some(37), Some(37), Some(37), Some(37)),
    ("period", Some(46), Some(46), Some(46), Some(46)),
    ("periodcentered", Some(180), Some(225), Some(183), Some(183)),
    ("perthousand", Some(189), Some(228), Some(137), Some(139)),
    ("plus", Some(43), Some(43), Some(43), Some(43)),
    ("plusminus", None, Some(177), Some(177), Some(177)),
    ("q", Some(113), Some(113), Some(113), Some(113)),
    ("question", Some(63), Some(63), Some(63), Some(63)),
    ("questiondown", Some(191), Some(192), Some(191), Some(191)),
    ("quotedbl", Some(34), Some(34), Some(34), Some(34)),
    ("quotedblbase", Some(185), Some(227), Some(132), Some(140)),
    ("quotedblleft", Some(170), Some(210), Some(147), Some(141)),
    ("quotedblright", Some(186), Some(211), Some(148), Some(142)),
    ("quoteleft", Some(96), Some(212), Some(145), Some(143)),
    ("quoteright", Some(39), Some(213), Some(146), Some(144)),
    ("quotesinglbase", Some(184), Some(226), Some(130), Some(145)),
    ("quotesingle", Some(169), Some(39), Some(39), Some(39)),
    ("r", Some(114), Some(114), Some(114), Some(114)),
    ("registered", None, Some(168), Some(174), Some(174)),
    ("ring", Some(202), Some(251), None, Some(30)),
    ("s", Some(115), Some(115), Some(115), Some(115)),
    ("scaron", None, None, Some(154), Some(157)),
    ("section", Some(167), Some(164), Some(167), Some(167)),
    ("semicolon", Some(59), Some(59), Some(59), Some(59)),
    ("seven", Some(55), Some(55), Some(55), Some(55)),
    ("six", Some(54), Some(54), Some(54), Some(54)),
    ("slash", Some(47), Some(47), Some(47), Some(47)),
    ("space", Some(32), Some(32), Some(32), Some(32)),
    // Note: Python source has duplicate "space" entries for nbspace mappings
    // ("space", None, Some(202), Some(160), None),
    // ("space", None, Some(202), Some(173), None),
    ("sterling", Some(163), Some(163), Some(163), Some(163)),
    ("t", Some(116), Some(116), Some(116), Some(116)),
    ("thorn", None, None, Some(254), Some(254)),
    ("three", Some(51), Some(51), Some(51), Some(51)),
    ("threequarters", None, None, Some(190), Some(190)),
    ("threesuperior", None, None, Some(179), Some(179)),
    ("tilde", Some(196), Some(247), Some(152), Some(31)),
    ("trademark", None, Some(170), Some(153), Some(146)),
    ("two", Some(50), Some(50), Some(50), Some(50)),
    ("twosuperior", None, None, Some(178), Some(178)),
    ("u", Some(117), Some(117), Some(117), Some(117)),
    ("uacute", None, Some(156), Some(250), Some(250)),
    ("ucircumflex", None, Some(158), Some(251), Some(251)),
    ("udieresis", None, Some(159), Some(252), Some(252)),
    ("ugrave", None, Some(157), Some(249), Some(249)),
    ("underscore", Some(95), Some(95), Some(95), Some(95)),
    ("v", Some(118), Some(118), Some(118), Some(118)),
    ("w", Some(119), Some(119), Some(119), Some(119)),
    ("x", Some(120), Some(120), Some(120), Some(120)),
    ("y", Some(121), Some(121), Some(121), Some(121)),
    ("yacute", None, None, Some(253), Some(253)),
    ("ydieresis", None, Some(216), Some(255), Some(255)),
    ("yen", Some(165), Some(180), Some(165), Some(165)),
    ("z", Some(122), Some(122), Some(122), Some(122)),
    ("zcaron", None, None, Some(158), Some(158)),
    ("zero", Some(48), Some(48), Some(48), Some(48)),
];

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_encoding_length() {
        // 230 entries (excluding duplicate space entries from Python source)
        assert_eq!(ENCODING.len(), 230);
    }

    #[test]
    fn test_basic_ascii() {
        // Find 'A' entry
        let a_entry = ENCODING.iter().find(|(name, _, _, _, _)| *name == "A");
        assert!(a_entry.is_some());
        let (name, std, mac, win, pdf) = a_entry.unwrap();
        assert_eq!(*name, "A");
        assert_eq!(*std, Some(65));
        assert_eq!(*mac, Some(65));
        assert_eq!(*win, Some(65));
        assert_eq!(*pdf, Some(65));
    }

    #[test]
    fn test_special_chars() {
        // Euro sign has different positions in different encodings
        let euro = ENCODING.iter().find(|(name, _, _, _, _)| *name == "Euro");
        assert!(euro.is_some());
        let (_, std, mac, win, pdf) = euro.unwrap();
        assert_eq!(*std, None);
        assert_eq!(*mac, None);
        assert_eq!(*win, Some(128));
        assert_eq!(*pdf, Some(160));
    }

    #[test]
    fn test_ligatures() {
        // fi ligature
        let fi = ENCODING.iter().find(|(name, _, _, _, _)| *name == "fi");
        assert!(fi.is_some());
        let (_, std, mac, win, pdf) = fi.unwrap();
        assert_eq!(*std, Some(174));
        assert_eq!(*mac, Some(222));
        assert_eq!(*win, None);
        assert_eq!(*pdf, Some(147));
    }
}
