"""
Makernote (proprietary) tag definitions for Canon.

http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html
"""

from typing import Callable, Dict, Tuple

from exifread.tags import SubIfdTagDict


def add_one(value):
    return value + 1


def subtract_one(value):
    return value - 1


def convert_temp(value):
    return "%d C" % (value - 128)


TAGS: SubIfdTagDict = {
    0x0003: ("FlashInfo", None),
    0x0006: ("ImageType", None),
    0x0007: ("FirmwareVersion", None),
    0x0008: ("ImageNumber", None),
    0x0009: ("OwnerName", None),
    0x000C: ("SerialNumber", None),
    0x000E: ("FileLength", None),
    0x0010: (
        "ModelID",
        {
            0x412: "EOS M50 / Kiss M",
            0x801: "PowerShot SX740 HS",
            0x804: "PowerShot G5 X Mark II",
            0x805: "PowerShot SX70 HS",
            0x808: "PowerShot G7 X Mark III",
            0x811: "EOS M6 Mark II",
            0x812: "EOS M200",
            0x1010000: "PowerShot A30",
            0x1040000: "PowerShot S300 / Digital IXUS 300 / IXY Digital 300",
            0x1060000: "PowerShot A20",
            0x1080000: "PowerShot A10",
            0x1090000: "PowerShot S110 / Digital IXUS v / IXY Digital 200",
            0x1100000: "PowerShot G2",
            0x1110000: "PowerShot S40",
            0x1120000: "PowerShot S30",
            0x1130000: "PowerShot A40",
            0x1140000: "EOS D30",
            0x1150000: "PowerShot A100",
            0x1160000: "PowerShot S200 / Digital IXUS v2 / IXY Digital 200a",
            0x1170000: "PowerShot A200",
            0x1180000: "PowerShot S330 / Digital IXUS 330 / IXY Digital 300a",
            0x1190000: "PowerShot G3",
            0x1210000: "PowerShot S45",
            0x1230000: "PowerShot SD100 / Digital IXUS II / IXY Digital 30",
            0x1240000: "PowerShot S230 / Digital IXUS v3 / IXY Digital 320",
            0x1250000: "PowerShot A70",
            0x1260000: "PowerShot A60",
            0x1270000: "PowerShot S400 / Digital IXUS 400 / IXY Digital 400",
            0x1290000: "PowerShot G5",
            0x1300000: "PowerShot A300",
            0x1310000: "PowerShot S50",
            0x1340000: "PowerShot A80",
            0x1350000: "PowerShot SD10 / Digital IXUS i / IXY Digital L",
            0x1360000: "PowerShot S1 IS",
            0x1370000: "PowerShot Pro1",
            0x1380000: "PowerShot S70",
            0x1390000: "PowerShot S60",
            0x1400000: "PowerShot G6",
            0x1410000: "PowerShot S500 / Digital IXUS 500 / IXY Digital 500",
            0x1420000: "PowerShot A75",
            0x1440000: "PowerShot SD110 / Digital IXUS IIs / IXY Digital 30a",
            0x1450000: "PowerShot A400",
            0x1470000: "PowerShot A310",
            0x1490000: "PowerShot A85",
            0x1520000: "PowerShot S410 / Digital IXUS 430 / IXY Digital 450",
            0x1530000: "PowerShot A95",
            0x1540000: "PowerShot SD300 / Digital IXUS 40 / IXY Digital 50",
            0x1550000: "PowerShot SD200 / Digital IXUS 30 / IXY Digital 40",
            0x1560000: "PowerShot A520",
            0x1570000: "PowerShot A510",
            0x1590000: "PowerShot SD20 / Digital IXUS i5 / IXY Digital L2",
            0x1640000: "PowerShot S2 IS",
            0x1650000: "PowerShot SD430 / Digital IXUS Wireless / IXY Digital Wireless",
            0x1660000: "PowerShot SD500 / Digital IXUS 700 / IXY Digital 600",
            0x1668000: "EOS D60",
            0x1700000: "PowerShot SD30 / Digital IXUS i Zoom / IXY Digital L3",
            0x1740000: "PowerShot A430",
            0x1750000: "PowerShot A410",
            0x1760000: "PowerShot S80",
            0x1780000: "PowerShot A620",
            0x1790000: "PowerShot A610",
            0x1800000: "PowerShot SD630 / Digital IXUS 65 / IXY Digital 80",
            0x1810000: "PowerShot SD450 / Digital IXUS 55 / IXY Digital 60",
            0x1820000: "PowerShot TX1",
            0x1870000: "PowerShot SD400 / Digital IXUS 50 / IXY Digital 55",
            0x1880000: "PowerShot A420",
            0x1890000: "PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000",
            0x1900000: "PowerShot SD550 / Digital IXUS 750 / IXY Digital 700",
            0x1920000: "PowerShot A700",
            0x1940000: "PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS",
            0x1950000: "PowerShot S3 IS",
            0x1960000: "PowerShot A540",
            0x1970000: "PowerShot SD600 / Digital IXUS 60 / IXY Digital 70",
            0x1980000: "PowerShot G7",
            0x1990000: "PowerShot A530",
            0x2000000: "PowerShot SD800 IS / Digital IXUS 850 IS / IXY Digital 900 IS",
            0x2010000: "PowerShot SD40 / Digital IXUS i7 / IXY Digital L4",
            0x2020000: "PowerShot A710 IS",
            0x2030000: "PowerShot A640",
            0x2040000: "PowerShot A630",
            0x2090000: "PowerShot S5 IS",
            0x2100000: "PowerShot A460",
            0x2120000: "PowerShot SD850 IS / Digital IXUS 950 IS / IXY Digital 810 IS",
            0x2130000: "PowerShot A570 IS",
            0x2140000: "PowerShot A560",
            0x2150000: "PowerShot SD750 / Digital IXUS 75 / IXY Digital 90",
            0x2160000: "PowerShot SD1000 / Digital IXUS 70 / IXY Digital 10",
            0x2180000: "PowerShot A550",
            0x2190000: "PowerShot A450",
            0x2230000: "PowerShot G9",
            0x2240000: "PowerShot A650 IS",
            0x2260000: "PowerShot A720 IS",
            0x2290000: "PowerShot SX100 IS",
            0x2300000: "PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS",
            0x2310000: "PowerShot SD870 IS / Digital IXUS 860 IS / IXY Digital 910 IS",
            0x2320000: "PowerShot SD890 IS / Digital IXUS 970 IS / IXY Digital 820 IS",
            0x2360000: "PowerShot SD790 IS / Digital IXUS 90 IS / IXY Digital 95 IS",
            0x2370000: "PowerShot SD770 IS / Digital IXUS 85 IS / IXY Digital 25 IS",
            0x2380000: "PowerShot A590 IS",
            0x2390000: "PowerShot A580",
            0x2420000: "PowerShot A470",
            0x2430000: "PowerShot SD1100 IS / Digital IXUS 80 IS / IXY Digital 20 IS",
            0x2460000: "PowerShot SX1 IS",
            0x2470000: "PowerShot SX10 IS",
            0x2480000: "PowerShot A1000 IS",
            0x2490000: "PowerShot G10",
            0x2510000: "PowerShot A2000 IS",
            0x2520000: "PowerShot SX110 IS",
            0x2530000: "PowerShot SD990 IS / Digital IXUS 980 IS / IXY Digital 3000 IS",
            0x2540000: "PowerShot SD880 IS / Digital IXUS 870 IS / IXY Digital 920 IS",
            0x2550000: "PowerShot E1",
            0x2560000: "PowerShot D10",
            0x2570000: "PowerShot SD960 IS / Digital IXUS 110 IS / IXY Digital 510 IS",
            0x2580000: "PowerShot A2100 IS",
            0x2590000: "PowerShot A480",
            0x2600000: "PowerShot SX200 IS",
            0x2610000: "PowerShot SD970 IS / Digital IXUS 990 IS / IXY Digital 830 IS",
            0x2620000: "PowerShot SD780 IS / Digital IXUS 100 IS / IXY Digital 210 IS",
            0x2630000: "PowerShot A1100 IS",
            0x2640000: "PowerShot SD1200 IS / Digital IXUS 95 IS / IXY Digital 110 IS",
            0x2700000: "PowerShot G11",
            0x2710000: "PowerShot SX120 IS",
            0x2720000: "PowerShot S90",
            0x2750000: "PowerShot SX20 IS",
            0x2760000: "PowerShot SD980 IS / Digital IXUS 200 IS / IXY Digital 930 IS",
            0x2770000: "PowerShot SD940 IS / Digital IXUS 120 IS / IXY Digital 220 IS",
            0x2800000: "PowerShot A495",
            0x2810000: "PowerShot A490",
            0x2820000: "PowerShot A3100/A3150 IS",
            0x2830000: "PowerShot A3000 IS",
            0x2840000: "PowerShot SD1400 IS / IXUS 130 / IXY 400F",
            0x2850000: "PowerShot SD1300 IS / IXUS 105 / IXY 200F",
            0x2860000: "PowerShot SD3500 IS / IXUS 210 / IXY 10S",
            0x2870000: "PowerShot SX210 IS",
            0x2880000: "PowerShot SD4000 IS / IXUS 300 HS / IXY 30S",
            0x2890000: "PowerShot SD4500 IS / IXUS 1000 HS / IXY 50S",
            0x2920000: "PowerShot G12",
            0x2930000: "PowerShot SX30 IS",
            0x2940000: "PowerShot SX130 IS",
            0x2950000: "PowerShot S95",
            0x2980000: "PowerShot A3300 IS",
            0x2990000: "PowerShot A3200 IS",
            0x3000000: "PowerShot ELPH 500 HS / IXUS 310 HS / IXY 31S",
            0x3010000: "PowerShot Pro90 IS",
            0x3010001: "PowerShot A800",
            0x3020000: "PowerShot ELPH 100 HS / IXUS 115 HS / IXY 210F",
            0x3030000: "PowerShot SX230 HS",
            0x3040000: "PowerShot ELPH 300 HS / IXUS 220 HS / IXY 410F",
            0x3050000: "PowerShot A2200",
            0x3060000: "PowerShot A1200",
            0x3070000: "PowerShot SX220 HS",
            0x3080000: "PowerShot G1 X",
            0x3090000: "PowerShot SX150 IS",
            0x3100000: "PowerShot ELPH 510 HS / IXUS 1100 HS / IXY 51S",
            0x3110000: "PowerShot S100 (new)",
            0x3120000: "PowerShot ELPH 310 HS / IXUS 230 HS / IXY 600F",
            0x3130000: "PowerShot SX40 HS",
            0x3140000: "IXY 32S",
            0x3160000: "PowerShot A1300",
            0x3170000: "PowerShot A810",
            0x3180000: "PowerShot ELPH 320 HS / IXUS 240 HS / IXY 420F",
            0x3190000: "PowerShot ELPH 110 HS / IXUS 125 HS / IXY 220F",
            0x3200000: "PowerShot D20",
            0x3210000: "PowerShot A4000 IS",
            0x3220000: "PowerShot SX260 HS",
            0x3230000: "PowerShot SX240 HS",
            0x3240000: "PowerShot ELPH 530 HS / IXUS 510 HS / IXY 1",
            0x3250000: "PowerShot ELPH 520 HS / IXUS 500 HS / IXY 3",
            0x3260000: "PowerShot A3400 IS",
            0x3270000: "PowerShot A2400 IS",
            0x3280000: "PowerShot A2300",
            0x3320000: "PowerShot S100V",
            0x3330000: "PowerShot G15",
            0x3340000: "PowerShot SX50 HS",
            0x3350000: "PowerShot SX160 IS",
            0x3360000: "PowerShot S110 (new)",
            0x3370000: "PowerShot SX500 IS",
            0x3380000: "PowerShot N",
            0x3390000: "IXUS 245 HS / IXY 430F",
            0x3400000: "PowerShot SX280 HS",
            0x3410000: "PowerShot SX270 HS",
            0x3420000: "PowerShot A3500 IS",
            0x3430000: "PowerShot A2600",
            0x3440000: "PowerShot SX275 HS",
            0x3450000: "PowerShot A1400",
            0x3460000: "PowerShot ELPH 130 IS / IXUS 140 / IXY 110F",
            0x3470000: "PowerShot ELPH 115/120 IS / IXUS 132/135 / IXY 90F/100F",
            0x3490000: "PowerShot ELPH 330 HS / IXUS 255 HS / IXY 610F",
            0x3510000: "PowerShot A2500",
            0x3540000: "PowerShot G16",
            0x3550000: "PowerShot S120",
            0x3560000: "PowerShot SX170 IS",
            0x3580000: "PowerShot SX510 HS",
            0x3590000: "PowerShot S200 (new)",
            0x3600000: "IXY 620F",
            0x3610000: "PowerShot N100",
            0x3640000: "PowerShot G1 X Mark II",
            0x3650000: "PowerShot D30",
            0x3660000: "PowerShot SX700 HS",
            0x3670000: "PowerShot SX600 HS",
            0x3680000: "PowerShot ELPH 140 IS / IXUS 150 / IXY 130",
            0x3690000: "PowerShot ELPH 135 / IXUS 145 / IXY 120",
            0x3700000: "PowerShot ELPH 340 HS / IXUS 265 HS / IXY 630",
            0x3710000: "PowerShot ELPH 150 IS / IXUS 155 / IXY 140",
            0x3740000: "EOS M3",
            0x3750000: "PowerShot SX60 HS",
            0x3760000: "PowerShot SX520 HS",
            0x3770000: "PowerShot SX400 IS",
            0x3780000: "PowerShot G7 X",
            0x3790000: "PowerShot N2",
            0x3800000: "PowerShot SX530 HS",
            0x3820000: "PowerShot SX710 HS",
            0x3830000: "PowerShot SX610 HS",
            0x3840000: "EOS M10",
            0x3850000: "PowerShot G3 X",
            0x3860000: "PowerShot ELPH 165 HS / IXUS 165 / IXY 160",
            0x3870000: "PowerShot ELPH 160 / IXUS 160",
            0x3880000: "PowerShot ELPH 350 HS / IXUS 275 HS / IXY 640",
            0x3890000: "PowerShot ELPH 170 IS / IXUS 170",
            0x3910000: "PowerShot SX410 IS",
            0x3930000: "PowerShot G9 X",
            0x3940000: "EOS M5",
            0x3950000: "PowerShot G5 X",
            0x3970000: "PowerShot G7 X Mark II",
            0x3980000: "EOS M100",
            0x3990000: "PowerShot ELPH 360 HS / IXUS 285 HS / IXY 650",
            0x4010000: "PowerShot SX540 HS",
            0x4020000: "PowerShot SX420 IS",
            0x4030000: "PowerShot ELPH 190 IS / IXUS 180 / IXY 190",
            0x4040000: "PowerShot G1",
            0x4040001: "PowerShot ELPH 180 IS / IXUS 175 / IXY 180",
            0x4050000: "PowerShot SX720 HS",
            0x4060000: "PowerShot SX620 HS",
            0x4070000: "EOS M6",
            0x4100000: "PowerShot G9 X Mark II",
            0x4150000: "PowerShot ELPH 185 / IXUS 185 / IXY 200",
            0x4160000: "PowerShot SX430 IS",
            0x4170000: "PowerShot SX730 HS",
            0x4180000: "PowerShot G1 X Mark III",
            0x6040000: "PowerShot S100 / Digital IXUS / IXY Digital",
            0x4007D673: "DC19/DC21/DC22",
            0x4007D674: "XH A1",
            0x4007D675: "HV10",
            0x4007D676: "MD130/MD140/MD150/MD160/ZR850",
            0x4007D777: "DC50",
            0x4007D778: "HV20",
            0x4007D779: "DC211",
            0x4007D77A: "HG10",
            0x4007D77B: "HR10",
            0x4007D77D: "MD255/ZR950",
            0x4007D81C: "HF11",
            0x4007D878: "HV30",
            0x4007D87C: "XH A1S",
            0x4007D87E: "DC301/DC310/DC311/DC320/DC330",
            0x4007D87F: "FS100",
            0x4007D880: "HF10",
            0x4007D882: "HG20/HG21",
            0x4007D925: "HF21",
            0x4007D926: "HF S11",
            0x4007D978: "HV40",
            0x4007D987: "DC410/DC411/DC420",
            0x4007D988: "FS19/FS20/FS21/FS22/FS200",
            0x4007D989: "HF20/HF200",
            0x4007D98A: "HF S10/S100",
            0x4007DA8E: "HF R10/R16/R17/R18/R100/R106",
            0x4007DA8F: "HF M30/M31/M36/M300/M306",
            0x4007DA90: "HF S20/S21/S200",
            0x4007DA92: "FS31/FS36/FS37/FS300/FS305/FS306/FS307",
            0x4007DCA0: "EOS C300",
            0x4007DDA9: "HF G25",
            0x4007DFB4: "XC10",
            0x4007E1C3: "EOS C200",
            0x80000001: "EOS-1D",
            0x80000167: "EOS-1DS",
            0x80000168: "EOS 10D",
            0x80000169: "EOS-1D Mark III",
            0x80000170: "EOS Digital Rebel / 300D / Kiss Digital",
            0x80000174: "EOS-1D Mark II",
            0x80000175: "EOS 20D",
            0x80000176: "EOS Digital Rebel XSi / 450D / Kiss X2",
            0x80000188: "EOS-1Ds Mark II",
            0x80000189: "EOS Digital Rebel XT / 350D / Kiss Digital N",
            0x80000190: "EOS 40D",
            0x80000213: "EOS 5D",
            0x80000215: "EOS-1Ds Mark III",
            0x80000218: "EOS 5D Mark II",
            0x80000219: "WFT-E1",
            0x80000232: "EOS-1D Mark II N",
            0x80000234: "EOS 30D",
            0x80000236: "EOS Digital Rebel XTi / 400D / Kiss Digital X",
            0x80000241: "WFT-E2",
            0x80000246: "WFT-E3",
            0x80000250: "EOS 7D",
            0x80000252: "EOS Rebel T1i / 500D / Kiss X3",
            0x80000254: "EOS Rebel XS / 1000D / Kiss F",
            0x80000261: "EOS 50D",
            0x80000269: "EOS-1D X",
            0x80000270: "EOS Rebel T2i / 550D / Kiss X4",
            0x80000271: "WFT-E4",
            0x80000273: "WFT-E5",
            0x80000281: "EOS-1D Mark IV",
            0x80000285: "EOS 5D Mark III",
            0x80000286: "EOS Rebel T3i / 600D / Kiss X5",
            0x80000287: "EOS 60D",
            0x80000288: "EOS Rebel T3 / 1100D / Kiss X50",
            0x80000289: "EOS 7D Mark II",
            0x80000297: "WFT-E2 II",
            0x80000298: "WFT-E4 II",
            0x80000301: "EOS Rebel T4i / 650D / Kiss X6i",
            0x80000302: "EOS 6D",
            0x80000324: "EOS-1D C",
            0x80000325: "EOS 70D",
            0x80000326: "EOS Rebel T5i / 700D / Kiss X7i",
            0x80000327: "EOS Rebel T5 / 1200D / Kiss X70 / Hi",
            0x80000328: "EOS-1D X Mark II",
            0x80000331: "EOS M",
            0x80000346: "EOS Rebel SL1 / 100D / Kiss X7",
            0x80000347: "EOS Rebel T6s / 760D / 8000D",
            0x80000349: "EOS 5D Mark IV",
            0x80000350: "EOS 80D",
            0x80000355: "EOS M2",
            0x80000382: "EOS 5DS",
            0x80000393: "EOS Rebel T6i / 750D / Kiss X8i",
            0x80000401: "EOS 5DS R",
            0x80000404: "EOS Rebel T6 / 1300D / Kiss X80",
            0x80000405: "EOS Rebel T7i / 800D / Kiss X9i",
            0x80000406: "EOS 6D Mark II",
            0x80000408: "EOS 77D / 9000D",
            0x80000417: "EOS Rebel SL2 / 200D / Kiss X9",
            0x80000421: "EOS R5",
            0x80000422: "EOS Rebel T100 / 4000D / 3000D",
            0x80000424: "EOS R",
            0x80000428: "EOS-1D X Mark III",
            0x80000432: "EOS Rebel T7 / 2000D / 1500D / Kiss X90",
            0x80000433: "EOS RP",
            0x80000435: "EOS Rebel T8i / 850D / X10i",
            0x80000436: "EOS SL3 / 250D / Kiss X10",
            0x80000437: "EOS 90D",
            0x80000450: "EOS R3",
            0x80000453: "EOS R6",
            0x80000464: "EOS R7",
            0x80000465: "EOS R10",
            0x80000467: "PowerShot ZOOM",
            0x80000468: "EOS M50 Mark II / Kiss M2",
            0x80000480: "EOS R50",
            0x80000481: "EOS R6 Mark II",
            0x80000487: "EOS R8",
            0x80000491: "PowerShot V10",
            0x80000495: "EOS R1",
            0x80000496: "R5 Mark II",
            0x80000498: "EOS R100",
            0x80000520: "EOS D2000C",
            0x80000560: "EOS D6000C",
        },
    ),
    0x0013: ("ThumbnailImageValidArea", None),
    0x0015: ("SerialNumberFormat", {0x90000000: "Format 1", 0xA0000000: "Format 2"}),
    0x001A: ("SuperMacro", {0: "Off", 1: "On (1)", 2: "On (2)"}),
    0x001C: (
        "DateStampMode",
        {
            0: "Off",
            1: "Date",
            2: "Date & Time",
        },
    ),
    0x001E: ("FirmwareRevision", None),
    0x0028: ("ImageUniqueID", None),
    0x0095: ("LensModel", None),
    0x0096: ("InternalSerialNumber ", None),
    0x0097: ("DustRemovalData ", None),
    0x0098: ("CropInfo ", None),
    0x009A: ("AspectInfo", None),
    0x00B4: ("ColorSpace", {1: "sRGB", 2: "Adobe RGB"}),
}

# this is in element offset, name, optional value dictionary format
# 0x0001
_CAMERA_SETTINGS: SubIfdTagDict = {
    1: ("Macromode", {1: "Macro", 2: "Normal"}),
    2: ("SelfTimer", None),
    3: (
        "Quality",
        {
            -1: "n/a",
            1: "Economy",
            2: "Normal",
            3: "Fine",
            4: "RAW",
            5: "Superfine",
            7: "CRAW",
        },
    ),
    4: (
        "FlashMode",
        {
            -1: "n/a",
            0: "Flash Not Fired",
            1: "Auto",
            2: "On",
            3: "Red-Eye Reduction",
            4: "Slow Synchro",
            5: "Auto + Red-Eye Reduction",
            6: "On + Red-Eye Reduction",
            16: "external flash",
        },
    ),
    5: (
        "ContinuousDriveMode",
        {
            0: "Single Or Timer",
            1: "Continuous",
            2: "Movie",
        },
    ),
    7: (
        "FocusMode",
        {
            0: "One-Shot",
            1: "AI Servo",
            2: "AI Focus",
            3: "MF",
            4: "Single",
            5: "Continuous",
            6: "MF",
        },
    ),
    9: (
        "RecordMode",
        {
            1: "JPEG",
            2: "CRW+THM",
            3: "AVI+THM",
            4: "TIF",
            5: "TIF+JPEG",
            6: "CR2",
            7: "CR2+JPEG",
            9: "MOV",
            10: "MP4",
            11: "CRM",
        },
    ),
    10: (
        "ImageSize",
        {
            -1: "n/a",
            0: "Large",
            1: "Medium",
            2: "Small",
            8: "Postcard",
            9: "Widescreen",
        },
    ),
    11: (
        "EasyShootingMode",
        {
            0: "Full Auto",
            1: "Manual",
            2: "Landscape",
            3: "Fast Shutter",
            4: "Slow Shutter",
            5: "Night",
            6: "B&W",
            7: "Sepia",
            8: "Portrait",
            9: "Sports",
            10: "Macro/Close-Up",
            11: "Pan Focus",
            51: "High Dynamic Range",
        },
    ),
    12: ("DigitalZoom", {0: "None", 1: "2x", 2: "4x", 3: "Other"}),
    13: ("Contrast", {0xFFFF: "Low", 0: "Normal", 1: "High"}),
    14: ("Saturation", {0xFFFF: "Low", 0: "Normal", 1: "High"}),
    15: ("Sharpness", {0xFFFF: "Low", 0: "Normal", 1: "High"}),
    16: (
        "ISO",
        {
            0: "See ISOSpeedRatings Tag",
            15: "Auto",
            16: "50",
            17: "100",
            18: "200",
            19: "400",
        },
    ),
    17: (
        "MeteringMode",
        {
            0: "Default",
            1: "Spot",
            2: "Average",
            3: "Evaluative",
            4: "Partial",
            5: "Center-weighted",
        },
    ),
    18: (
        "FocusType",
        {0: "Manual", 1: "Auto", 3: "Close-Up (Macro)", 8: "Locked (Pan Mode)"},
    ),
    19: (
        "AFPointSelected",
        {
            0x3000: "None (MF)",
            0x3001: "Auto-Selected",
            0x3002: "Right",
            0x3003: "Center",
            0x3004: "Left",
        },
    ),
    20: (
        "ExposureMode",
        {
            0: "Easy Shooting",
            1: "Program",
            2: "Tv-priority",
            3: "Av-priority",
            4: "Manual",
            5: "A-DEP",
        },
    ),
    22: (
        "LensType",
        {
            -1: "n/a",
            1: "Canon EF 50mm f/1.8",
            3: "Canon EF 135mm f/2.8 Soft",
            5: "Canon EF 35-70mm f/3.5-4.5",
            7: "Canon EF 100-300mm f/5.6L",
            11: "Canon EF 35mm f/2",
            13: "Canon EF 15mm f/2.8 Fisheye",
            14: "Canon EF 50-200mm f/3.5-4.5L",
            15: "Canon EF 50-200mm f/3.5-4.5",
            16: "Canon EF 35-135mm f/3.5-4.5",
            17: "Canon EF 35-70mm f/3.5-4.5A",
            18: "Canon EF 28-70mm f/3.5-4.5",
            20: "Canon EF 100-200mm f/4.5A",
            21: "Canon EF 80-200mm f/2.8L",
            23: "Canon EF 35-105mm f/3.5-4.5",
            24: "Canon EF 35-80mm f/4-5.6 Power Zoom",
            25: "Canon EF 35-80mm f/4-5.6 Power Zoom",
            27: "Canon EF 35-80mm f/4-5.6",
            29: "Canon EF 50mm f/1.8 II",
            30: "Canon EF 35-105mm f/4.5-5.6",
            35: "Canon EF 35-80mm f/4-5.6",
            36: "Canon EF 38-76mm f/4.5-5.6",
            38: "Canon EF 80-200mm f/4.5-5.6 II",
            39: "Canon EF 75-300mm f/4-5.6",
            40: "Canon EF 28-80mm f/3.5-5.6",
            41: "Canon EF 28-90mm f/4-5.6",
            43: "Canon EF 28-105mm f/4-5.6",
            44: "Canon EF 90-300mm f/4.5-5.6",
            45: "Canon EF-S 18-55mm f/3.5-5.6 [II]",
            46: "Canon EF 28-90mm f/4-5.6",
            48: "Canon EF-S 18-55mm f/3.5-5.6 IS",
            49: "Canon EF-S 55-250mm f/4-5.6 IS",
            50: "Canon EF-S 18-200mm f/3.5-5.6 IS",
            51: "Canon EF-S 18-135mm f/3.5-5.6 IS",
            52: "Canon EF-S 18-55mm f/3.5-5.6 IS II",
            53: "Canon EF-S 18-55mm f/3.5-5.6 III",
            54: "Canon EF-S 55-250mm f/4-5.6 IS II",
            63: "Irix 30mm F1.4 Dragonfly",
            80: "Canon TS-E 50mm f/2.8L Macro",
            81: "Canon TS-E 90mm f/2.8L Macro",
            82: "Canon TS-E 135mm f/4L Macro",
            94: "Canon TS-E 17mm f/4L",
            95: "Canon TS-E 24mm f/3.5L II",
            106: "Rokinon SP / Samyang XP 35mm f/1.2",
            124: "Canon MP-E 65mm f/2.8 1-5x Macro Photo",
            125: "Canon TS-E 24mm f/3.5L",
            126: "Canon TS-E 45mm f/2.8",
            129: "Canon EF 300mm f/2.8L USM",
            130: "Canon EF 50mm f/1.0L USM",
            132: "Canon EF 1200mm f/5.6L USM",
            134: "Canon EF 600mm f/4L IS USM",
            135: "Canon EF 200mm f/1.8L USM",
            138: "Canon EF 28-80mm f/2.8-4L",
            139: "Canon EF 400mm f/2.8L USM",
            140: "Canon EF 500mm f/4.5L USM",
            141: "Canon EF 500mm f/4.5L USM",
            142: "Canon EF 300mm f/2.8L IS USM",
            144: "Canon EF 35-135mm f/4-5.6 USM",
            145: "Canon EF 100-300mm f/4.5-5.6 USM",
            146: "Canon EF 70-210mm f/3.5-4.5 USM",
            147: "Canon EF 35-135mm f/4-5.6 USM",
            148: "Canon EF 28-80mm f/3.5-5.6 USM",
            149: "Canon EF 100mm f/2 USM",
            151: "Canon EF 200mm f/2.8L USM",
            162: "Canon EF 200mm f/2.8L USM",
            163: "Canon EF 300mm f/4L",
            164: "Canon EF 400mm f/5.6L",
            165: "Canon EF 70-200mm f/2.8L USM",
            166: "Canon EF 70-200mm f/2.8L USM + 1.4x",
            167: "Canon EF 70-200mm f/2.8L USM + 2x",
            171: "Canon EF 300mm f/4L USM",
            175: "Canon EF 400mm f/2.8L USM",
            176: "Canon EF 24-85mm f/3.5-4.5 USM",
            177: "Canon EF 300mm f/4L IS USM",
            178: "Canon EF 28-135mm f/3.5-5.6 IS",
            179: "Canon EF 24mm f/1.4L USM",
            184: "Canon EF 400mm f/2.8L USM + 2x",
            185: "Canon EF 600mm f/4L IS USM",
            186: "Canon EF 70-200mm f/4L USM",
            187: "Canon EF 70-200mm f/4L USM + 1.4x",
            188: "Canon EF 70-200mm f/4L USM + 2x",
            189: "Canon EF 70-200mm f/4L USM + 2.8x",
            190: "Canon EF 100mm f/2.8 Macro USM",
            193: "Canon EF 35-80mm f/4-5.6 USM",
            194: "Canon EF 80-200mm f/4.5-5.6 USM",
            195: "Canon EF 35-105mm f/4.5-5.6 USM",
            196: "Canon EF 75-300mm f/4-5.6 USM",
            199: "Canon EF 28-80mm f/3.5-5.6 USM",
            200: "Canon EF 75-300mm f/4-5.6 USM",
            201: "Canon EF 28-80mm f/3.5-5.6 USM",
            202: "Canon EF 28-80mm f/3.5-5.6 USM IV",
            208: "Canon EF 22-55mm f/4-5.6 USM",
            209: "Canon EF 55-200mm f/4.5-5.6",
            210: "Canon EF 28-90mm f/4-5.6 USM",
            211: "Canon EF 28-200mm f/3.5-5.6 USM",
            212: "Canon EF 28-105mm f/4-5.6 USM",
            214: "Canon EF-S 18-55mm f/3.5-5.6 USM",
            215: "Canon EF 55-200mm f/4.5-5.6 II USM",
            217: "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD",
            220: "Yongnuo YN 50mm f/1.8",
            224: "Canon EF 70-200mm f/2.8L IS USM",
            225: "Canon EF 70-200mm f/2.8L IS USM + 1.4x",
            226: "Canon EF 70-200mm f/2.8L IS USM + 2x",
            227: "Canon EF 70-200mm f/2.8L IS USM + 2.8x",
            228: "Canon EF 28-105mm f/3.5-4.5 USM",
            229: "Canon EF 16-35mm f/2.8L USM",
            230: "Canon EF 24-70mm f/2.8L USM",
            232: "Canon EF 70-300mm f/4.5-5.6 DO IS USM",
            233: "Canon EF 28-300mm f/3.5-5.6L IS USM",
            235: "Canon EF-S 10-22mm f/3.5-4.5 USM",
            236: "Canon EF-S 60mm f/2.8 Macro USM",
            237: "Canon EF 24-105mm f/4L IS USM",
            238: "Canon EF 70-300mm f/4-5.6 IS USM",
            241: "Canon EF 50mm f/1.2L USM",
            242: "Canon EF 70-200mm f/4L IS USM",
            243: "Canon EF 70-200mm f/4L IS USM + 1.4x",
            244: "Canon EF 70-200mm f/4L IS USM + 2x",
            245: "Canon EF 70-200mm f/4L IS USM + 2.8x",
            246: "Canon EF 16-35mm f/2.8L II USM",
            247: "Canon EF 14mm f/2.8L II USM",
            249: "Canon EF 800mm f/5.6L IS USM",
            488: "Canon EF-S 15-85mm f/3.5-5.6 IS USM",
            489: "Canon EF 70-300mm f/4-5.6L IS USM",
            490: "Canon EF 8-15mm f/4L Fisheye USM",
            492: "Canon EF 400mm f/2.8L IS II USM",
            494: "Canon EF 600mm f/4L IS II USM",
            496: "Canon EF 200-400mm f/4L IS USM",
            499: "Canon EF 200-400mm f/4L IS USM + 1.4x",
            503: "Canon EF 24mm f/2.8 IS USM",
            504: "Canon EF 24-70mm f/4L IS USM",
            505: "Canon EF 35mm f/2 IS USM",
            506: "Canon EF 400mm f/4 DO IS II USM",
            507: "Canon EF 16-35mm f/4L IS USM",
            751: "Canon EF 16-35mm f/2.8L III USM",
            752: "Canon EF 24-105mm f/4L IS II USM",
            753: "Canon EF 85mm f/1.4L IS USM",
            754: "Canon EF 70-200mm f/4L IS II USM",
            757: "Canon EF 400mm f/2.8L IS III USM",
            758: "Canon EF 600mm f/4L IS III USM",
            1136: "Sigma 24-70mm f/2.8 DG OS HSM | A",
            4142: "Canon EF-S 18-135mm f/3.5-5.6 IS STM",
            4144: "Canon EF 40mm f/2.8 STM",
            4145: "Canon EF-M 22mm f/2 STM",
            4146: "Canon EF-S 18-55mm f/3.5-5.6 IS STM",
            4147: "Canon EF-M 11-22mm f/4-5.6 IS STM",
            4148: "Canon EF-S 55-250mm f/4-5.6 IS STM",
            4149: "Canon EF-M 55-200mm f/4.5-6.3 IS STM",
            4150: "Canon EF-S 10-18mm f/4.5-5.6 IS STM",
            4152: "Canon EF 24-105mm f/3.5-5.6 IS STM",
            4153: "Canon EF-M 15-45mm f/3.5-6.3 IS STM",
            4154: "Canon EF-S 24mm f/2.8 STM",
            4155: "Canon EF-M 28mm f/3.5 Macro IS STM",
            4156: "Canon EF 50mm f/1.8 STM",
            4157: "Canon EF-M 18-150mm f/3.5-6.3 IS STM",
            4158: "Canon EF-S 18-55mm f/4-5.6 IS STM",
            4159: "Canon EF-M 32mm f/1.4 STM",
            4160: "Canon EF-S 35mm f/2.8 Macro IS STM",
            36910: "Canon EF 70-300mm f/4-5.6 IS II USM",
            36912: "Canon EF-S 18-135mm f/3.5-5.6 IS USM",
            61491: "Canon CN-E 14mm T3.1 L F",
            61492: "Canon CN-E 24mm T1.5 L F",
            61494: "Canon CN-E 85mm T1.3 L F",
            61495: "Canon CN-E 135mm T2.2 L F",
            61496: "Canon CN-E 35mm T1.5 L F",
            65535: "n/a",
        },
    ),
    23: ("LongFocalLengthOfLensInFocalUnits", None),
    24: ("ShortFocalLengthOfLensInFocalUnits", None),
    25: ("FocalUnitsPerMM", None),
    26: ("MaxAperture", None),
    27: ("MinAperture", None),
    28: (
        "FlashActivity",
        {
            0: "Did Not Fire",
            1: "Fired",
        },
    ),
    29: (
        "FlashDetails",
        {
            0: "Manual",
            1: "TTL",
            2: "A-TTL",
            3: "E-TTL",
            4: "FP Sync Enabled",
            7: '2nd("Rear")-Curtain Sync Used',
            11: "FP Sync Used",
            13: "Internal Flash",
            14: "External E-TTL",
        },
    ),
    32: ("FocusMode", {0: "Single", 1: "Continuous", 8: "Manual"}),
    33: (
        "AESetting",
        {
            0: "Normal AE",
            1: "Exposure Compensation",
            2: "AE Lock",
            3: "AE Lock + Exposure Comp.",
            4: "No AE",
        },
    ),
    34: (
        "ImageStabilization",
        {
            0: "Off",
            1: "On",
            2: "Shoot Only",
            3: "Panning",
            4: "Dynamic",
            256: "Off",
            257: "On",
            258: "Shoot Only",
            259: "Panning",
            260: "Dynamic",
        },
    ),
    39: ("SpotMeteringMode", {0: "Center", 1: "AF Point"}),
    41: (
        "ManualFlashOutput",
        {
            0x0: "n/a",
            0x500: "Full",
            0x502: "Medium",
            0x504: "Low",
            0x7FFF: "n/a",
        },
    ),
}

# 0x0002
_FOCAL_LENGTH: SubIfdTagDict = {
    1: (
        "FocalType",
        {
            1: "Fixed",
            2: "Zoom",
        },
    ),
    2: ("FocalLength", None),
}

# 0x0004
_SHOT_INFO: SubIfdTagDict = {
    1: ("AutoISO", None),
    2: ("BaseISO", None),
    3: ("MeasuredEV", None),
    4: ("TargetAperture", None),
    5: ("TargetExposureTime", None),
    6: ("ExposureCompensation", None),
    7: (
        "WhiteBalance",
        {
            0: "Auto",
            1: "Daylight",
            2: "Cloudy",
            3: "Tungsten",
            4: "Fluorescent",
            5: "Flash",
            6: "Custom",
            7: "Black & White",
            8: "Shade",
        },
    ),
    8: (
        "SlowShutter",
        {
            -1: "n/a",
            0: "Off",
            1: "Night Scene",
            2: "On",
            3: "None",
        },
    ),
    9: ("SequenceNumber", None),
    10: ("OpticalZoomCode", None),
    12: ("CameraTemperature", convert_temp),
    13: ("FlashGuideNumber", None),
    14: ("AFPointUsed", None),
    15: (
        "FlashBias",
        {
            0xFFC0: "-2 EV",
            0xFFCC: "-1.67 EV",
            0xFFD0: "-1.50 EV",
            0xFFD4: "-1.33 EV",
            0xFFE0: "-1 EV",
            0xFFEC: "-0.67 EV",
            0xFFF0: "-0.50 EV",
            0xFFF4: "-0.33 EV",
            0x0000: "0 EV",
            0x000C: "0.33 EV",
            0x0010: "0.50 EV",
            0x0014: "0.67 EV",
            0x0020: "1 EV",
            0x002C: "1.33 EV",
            0x0030: "1.50 EV",
            0x0034: "1.67 EV",
            0x0040: "2 EV",
        },
    ),
    16: (
        "AutoExposureBracketing",
        {
            -1: "On",
            0: "Off",
            1: "On (shot 1)",
            2: "On (shot 2)",
            3: "On (shot 3)",
        },
    ),
    18: (
        "ControlMode",
        {
            0: "n/a",
            1: "Camera Local Control",
            3: "Computer Remote Control",
        },
    ),
    19: ("SubjectDistance", None),
}

# 0x0012
_AF_INFO: SubIfdTagDict = {
    0: ("NumAFPoints", None),
    1: ("ValidAFPoints", None),
    2: ("CanonImageWidth", None),
    3: ("CanonImageHeight", None),
    4: ("AFImageWidth", None),
    5: ("AFImageHeight", None),
    6: ("AFAreaWidth", None),
    7: ("AFAreaHeight", None),
    8: ("AFAreaXPositions", None),
    9: ("AFAreaYPositions", None),
    10: ("AFPointsInFocus", None),
    11: ("PrimaryAFPoint ", None),
    12: ("PrimaryAFPoint ", None),
}

# 0x0026
_AF_INFO_2: SubIfdTagDict = {
    2: (
        "AFAreaMode",
        {
            0: "Off (Manual Focus)",
            2: "Single-point AF",
            4: "Multi-point AF or AI AF",
            5: "Face Detect AF",
            6: "Face + Tracking",
            7: "Zone AF",
            8: "AF Point Expansion",
            9: "Spot AF",
            11: "Flexizone Multi",
            13: "Flexizone Single",
        },
    ),
    3: ("NumAFPoints", None),
    4: ("ValidAFPoints", None),
    5: ("CanonImageWidth", None),
}

# 0x0093
_FILE_INFO: SubIfdTagDict = {
    1: ("FileNumber", None),
    3: (
        "BracketMode",
        {
            0: "Off",
            1: "AEB",
            2: "FEB",
            3: "ISO",
            4: "WB",
        },
    ),
    4: ("BracketValue", None),
    5: ("BracketShotNumber", None),
    6: (
        "RawJpgQuality",
        {
            0xFFFF: "n/a",
            1: "Economy",
            2: "Normal",
            3: "Fine",
            4: "RAW",
            5: "Superfine",
            130: "Normal Movie",
        },
    ),
    7: (
        "RawJpgSize",
        {
            0: "Large",
            1: "Medium",
            2: "Small",
            5: "Medium 1",
            6: "Medium 2",
            7: "Medium 3",
            8: "Postcard",
            9: "Widescreen",
            10: "Medium Widescreen",
            14: "Small 1",
            15: "Small 2",
            16: "Small 3",
            128: "640x480 Movie",
            129: "Medium Movie",
            130: "Small Movie",
            137: "1280x720 Movie",
            142: "1920x1080 Movie",
        },
    ),
    8: (
        "LongExposureNoiseReduction2",
        {
            0: "Off",
            1: "On (1D)",
            2: "On",
            3: "Auto",
        },
    ),
    9: (
        "WBBracketMode",
        {
            0: "Off",
            1: "On (shift AB)",
            2: "On (shift GM)",
        },
    ),
    12: ("WBBracketValueAB", None),
    13: ("WBBracketValueGM", None),
    14: (
        "FilterEffect",
        {
            0: "None",
            1: "Yellow",
            2: "Orange",
            3: "Red",
            4: "Green",
        },
    ),
    15: (
        "ToningEffect",
        {
            0: "None",
            1: "Sepia",
            2: "Blue",
            3: "Purple",
            4: "Green",
        },
    ),
    16: ("MacroMagnification", None),
    19: ("LiveViewShooting", {0: "Off", 1: "On"}),
    25: ("FlashExposureLock", {0: "Off", 1: "On"}),
}


# CameraInfo data structures have variable sized members. Each entry here is:
# byte offset: (item name, data item type, decoding map).
# Note that the data item type is fed directly to struct.unpack at the
# specified offset.
CAMERA_INFO_TAG_NAME = "MakerNote Tag 0x000D"

CanonCameraInfo = Tuple[str, str, Callable]
CanonCameraInfoMap = Dict[int, CanonCameraInfo]

CAMERA_INFO_5D: CanonCameraInfoMap = {
    23: ("CameraTemperature", "<B", convert_temp),
    204: ("DirectoryIndex", "<L", subtract_one),
    208: ("FileIndex", "<H", add_one),
}

CAMERA_INFO_5DMKII: CanonCameraInfoMap = {
    25: ("CameraTemperature", "<B", convert_temp),
    443: ("FileIndex", "<L", add_one),
    455: ("DirectoryIndex", "<L", subtract_one),
}

CAMERA_INFO_5DMKIII: CanonCameraInfoMap = {
    27: ("CameraTemperature", "<B", convert_temp),
    652: ("FileIndex", "<L", add_one),
    656: ("FileIndex2", "<L", add_one),
    664: ("DirectoryIndex", "<L", subtract_one),
    668: ("DirectoryIndex2", "<L", subtract_one),
}

CAMERA_INFO_600D: CanonCameraInfoMap = {
    25: ("CameraTemperature", "<B", convert_temp),
    475: ("FileIndex", "<L", add_one),
    487: ("DirectoryIndex", "<L", subtract_one),
}

# A map of regular expressions on 'Image Model' to the CameraInfo spec
CAMERA_INFO_MODEL_MAP: Dict[str, CanonCameraInfoMap] = {
    r"EOS 5D$": CAMERA_INFO_5D,
    r"EOS 5D Mark II$": CAMERA_INFO_5DMKII,
    r"EOS 5D Mark III$": CAMERA_INFO_5DMKIII,
    r"\b(600D|REBEL T3i|Kiss X5)\b": CAMERA_INFO_600D,
}

OFFSET_TAGS: Dict[int, SubIfdTagDict] = {
    0x0001: _CAMERA_SETTINGS,
    0x0002: _FOCAL_LENGTH,
    0x0004: _SHOT_INFO,
    0x0012: _AF_INFO,
    0x0026: _AF_INFO_2,
    0x0093: _FILE_INFO,
}
