"""
Enhanced Meta File
"""
from construct import *


record_type = Enum(ULInt32("record_type"),
    ABORTPATH = 68,
    ANGLEARC = 41,
    ARC = 45,
    ARCTO = 55,
    BEGINPATH = 59,
    BITBLT = 76,
    CHORD = 46,
    CLOSEFIGURE = 61,
    CREATEBRUSHINDIRECT = 39,
    CREATEDIBPATTERNBRUSHPT = 94,
    CREATEMONOBRUSH = 93,
    CREATEPALETTE = 49,
    CREATEPEN = 38,
    DELETEOBJECT = 40,
    ELLIPSE = 42,
    ENDPATH = 60,
    EOF = 14,
    EXCLUDECLIPRECT = 29,
    EXTCREATEFONTINDIRECTW = 82,
    EXTCREATEPEN = 95,
    EXTFLOODFILL = 53,
    EXTSELECTCLIPRGN = 75,
    EXTTEXTOUTA = 83,
    EXTTEXTOUTW = 84,
    FILLPATH = 62,
    FILLRGN = 71,
    FLATTENPATH = 65,
    FRAMERGN = 72,
    GDICOMMENT = 70,
    HEADER = 1,
    INTERSECTCLIPRECT = 30,
    INVERTRGN = 73,
    LINETO = 54,
    MASKBLT = 78,
    MODIFYWORLDTRANSFORM = 36,
    MOVETOEX = 27,
    OFFSETCLIPRGN = 26,
    PAINTRGN = 74,
    PIE = 47,
    PLGBLT = 79,
    POLYBEZIER = 2,
    POLYBEZIER16 = 85,
    POLYBEZIERTO = 5,
    POLYBEZIERTO16 = 88,
    POLYDRAW = 56,
    POLYDRAW16 = 92,
    POLYGON = 3,
    POLYGON16 = 86,
    POLYLINE = 4,
    POLYLINE16 = 87,
    POLYLINETO = 6,
    POLYLINETO16 = 89,
    POLYPOLYGON = 8,
    POLYPOLYGON16 = 91,
    POLYPOLYLINE = 7,
    POLYPOLYLINE16 = 90,
    POLYTEXTOUTA = 96,
    POLYTEXTOUTW = 97,
    REALIZEPALETTE = 52,
    RECTANGLE = 43,
    RESIZEPALETTE = 51,
    RESTOREDC = 34,
    ROUNDRECT = 44,
    SAVEDC = 33,
    SCALEVIEWPORTEXTEX = 31,
    SCALEWINDOWEXTEX = 32,
    SELECTCLIPPATH = 67,
    SELECTOBJECT = 37,
    SELECTPALETTE = 48,
    SETARCDIRECTION = 57,
    SETBKCOLOR = 25,
    SETBKMODE = 18,
    SETBRUSHORGEX = 13,
    SETCOLORADJUSTMENT = 23,
    SETDIBITSTODEVICE = 80,
    SETMAPMODE = 17,
    SETMAPPERFLAGS = 16,
    SETMETARGN = 28,
    SETMITERLIMIT = 58,
    SETPALETTEENTRIES = 50,
    SETPIXELV = 15,
    SETPOLYFILLMODE = 19,
    SETROP2 = 20,
    SETSTRETCHBLTMODE = 21,
    SETTEXTALIGN = 22,
    SETTEXTCOLOR = 24,
    SETVIEWPORTEXTEX = 11,
    SETVIEWPORTORGEX = 12,
    SETWINDOWEXTEX = 9,
    SETWINDOWORGEX = 10,
    SETWORLDTRANSFORM = 35,
    STRETCHBLT = 77,
    STRETCHDIBITS = 81,
    STROKEANDFILLPATH = 63,
    STROKEPATH = 64,
    WIDENPATH = 66,
    _default_ = Pass,
)

generic_record = Struct("records",
    record_type,
    ULInt32("record_size"),      # Size of the record in bytes 
    Union("params",              # Parameters
        Field("raw", lambda ctx: ctx._.record_size - 8),
        Array(lambda ctx: (ctx._.record_size - 8) // 4, ULInt32("params"))
    ),
)

header_record = Struct("header_record",
    Const(record_type, "HEADER"),
    ULInt32("record_size"),              # Size of the record in bytes 
    SLInt32("bounds_left"),              # Left inclusive bounds 
    SLInt32("bounds_right"),             # Right inclusive bounds 
    SLInt32("bounds_top"),               # Top inclusive bounds 
    SLInt32("bounds_bottom"),            # Bottom inclusive bounds 
    SLInt32("frame_left"),               # Left side of inclusive picture frame 
    SLInt32("frame_right"),              # Right side of inclusive picture frame 
    SLInt32("frame_top"),                # Top side of inclusive picture frame 
    SLInt32("frame_bottom"),             # Bottom side of inclusive picture frame 
    Const(ULInt32("signature"), 0x464D4520),
    ULInt32("version"),                  # Version of the metafile 
    ULInt32("size"),                     # Size of the metafile in bytes 
    ULInt32("num_of_records"),           # Number of records in the metafile 
    ULInt16("num_of_handles"),           # Number of handles in the handle table 
    Padding(2),
    ULInt32("description_size"),         # Size of description string in WORDs 
    ULInt32("description_offset"),       # Offset of description string in metafile 
    ULInt32("num_of_palette_entries"),   # Number of color palette entries 
    SLInt32("device_width_pixels"),      # Width of reference device in pixels 
    SLInt32("device_height_pixels"),     # Height of reference device in pixels 
    SLInt32("device_width_mm"),          # Width of reference device in millimeters
    SLInt32("device_height_mm"),         # Height of reference device in millimeters
    
    # description string
    Pointer(lambda ctx: ctx.description_offset,
        StringAdapter(
            Array(lambda ctx: ctx.description_size,
                Field("description", 2)
            )
        )
    ),
    
    # padding up to end of record
    Padding(lambda ctx: ctx.record_size - 88),
)

emf_file = Struct("emf_file",
    header_record,
    Array(lambda ctx: ctx.header_record.num_of_records - 1, 
        generic_record
    ),
)


if __name__ == "__main__":
    obj = emf_file.parse_stream(open("../../../tests/emf1.emf", "rb"))
    print (obj)


































