# Path: mgz/enums.py
# def DifficultyEnum(ctx):
#     """Difficulty Enumeration."""
#     return Enum(
#         ctx,
#         hardest=0,
#         hard=1,
#         moderate=2,
#         standard=3,
#         easiest=4,
#         extreme=5,
#         unknown=6
#     )
# 
# def PlayerTypeEnum(ctx):
#     """Player Type Enumeration."""
#     return Enum(
#         ctx,
#         absent=0,
#         closed=1,
#         human=2,
#         eliminated=3,
#         computer=4,
#         cyborg=5,
#         spectator=6
#     )
# 
# def AgeEnum(ctx):
#     """Age Enumeration."""
#     return Enum(
#         ctx,
#         what=-2,
#         unset=-1,
#         dark=0,
#         feudal=1,
#         castle=2,
#         imperial=3,
#         postimperial=4,
#         dmpostimperial=6,
#         default='unknown'
#     )
# 
# Path: mgz/util.py
# class Find(Construct):
#     """Find bytes, and read past them."""
# 
#     __slots__ = ["find", "max_length"]
# 
#     def __init__(self, find, max_length):
#         """Initiallize."""
#         Construct.__init__(self)
#         if not isinstance(find, list):
#             find = [find]
#         self.find = find
#         self.max_length = max_length
# 
#     def _parse(self, stream, context, path):
#         """Parse stream to find a given byte string."""
#         start = stream.tell()
#         read_bytes = ""
#         if self.max_length:
#             read_bytes = stream.read(self.max_length)
#         else:
#             read_bytes = stream.read()
#         candidates = []
#         for f in self.find:
#             match = re.search(f, read_bytes)
#             if not match:
#                 continue
#             candidates.append(match.end())
#         if not candidates:
#             raise RuntimeError('could not find bytes: {}'.format(f))
#         choice = min(candidates)
#         stream.seek(start + choice)
#         return choice
# 
# class Version(Enum):
#     """Version enumeration.
# 
#     Using consts from https://github.com/goto-bus-stop/recanalyst/blob/master/src/Model/Version.php
#     for consistency.
#     """
#     AOK = 1
#     AOC = 4
#     AOC10 = 5
#     AOC10C = 8
#     USERPATCH12 = 12
#     USERPATCH13 = 13
#     USERPATCH14 = 11
#     USERPATCH15 = 20
#     DE = 21
#     USERPATCH14RC2 = 22
#     MCP = 30
#     HD = 19
# 
# def find_save_version(ctx):
#     """Find save version."""
#     if 'save_version' not in ctx:
#         return find_save_version(ctx._)
#     return ctx.save_version
# 
# def find_version(ctx):
#     """Find version."""
#     if 'version' not in ctx:
#         return find_version(ctx._)
#     return ctx.version


from construct import (Array, Float32l, Int16ul, Int32sl, Int32ul, Padding,
                       PascalString, Peek, String, Struct, Bytes, If, IfThenElse)
from mgz.enums import DifficultyEnum, PlayerTypeEnum, AgeEnum
from mgz.util import Find, Version, find_save_version, find_version
    "instructions"/Bytes(lambda ctx: ctx.instructions_length),
    "hints"/PascalString(lengthfield="hints_length"/Int16ul),
    "victory"/PascalString(lengthfield="victory_length"/Int16ul),
    "defeat"/PascalString(lengthfield="defeat_length"/Int16ul),
    "history"/PascalString(lengthfield="history_length"/Int16ul),
    "scouts"/If(lambda ctx: ctx._._.version != Version.AOK, PascalString(lengthfield="scouts_length"/Int16ul)),
    "pg_cin"/PascalString(lengthfield="pg_cin_length"/Int16ul),
    "vict_cin"/PascalString(lengthfield="vict_cin_length"/Int16ul),
    "loss_cin"/PascalString(lengthfield="loss_cin_length"/Int16ul),
    "background"/PascalString(lengthfield="background_length"/Int16ul),
    "bitmap_included"/Int32ul,
    "bitmap_x"/Int32ul,
    "bitmap_y"/Int32ul,
    Padding(2),
    # bitmap here if it is included
    Padding(64), # 16 nulls
)

# Scenario player definitions.
scenario_players = "players"/Struct(
    Array(16, "ai_names"/PascalString(lengthfield="ai_name_length"/Int16ul)),
    Array(16, "ai"/Struct(Padding(8), "file"/PascalString(lengthfield="ai_file_length"/Int32ul))),
    Padding(4),
    Array(16, "resources"/Struct(
        "gold"/Int32ul,
        "wood"/Int32ul,
        "food"/Int32ul,
        "stone"/Int32ul,
        "unk0"/Int32ul,
        "unk1"/Int32ul,

# Path: mgz/enums.py
# def DifficultyEnum(ctx):
#     """Difficulty Enumeration."""
#     return Enum(
#         ctx,
#         hardest=0,
#         hard=1,
#         moderate=2,
#         standard=3,
#         easiest=4,
#         extreme=5,
#         unknown=6
#     )
# 
# def PlayerTypeEnum(ctx):
#     """Player Type Enumeration."""
#     return Enum(
#         ctx,
#         absent=0,
#         closed=1,
#         human=2,
#         eliminated=3,
#         computer=4,
#         cyborg=5,
#         spectator=6
#     )
# 
# def AgeEnum(ctx):
#     """Age Enumeration."""
#     return Enum(
#         ctx,
#         what=-2,
#         unset=-1,
#         dark=0,
#         feudal=1,
#         castle=2,
#         imperial=3,
#         postimperial=4,
#         dmpostimperial=6,
#         default='unknown'
#     )
# 
# Path: mgz/util.py
# class Find(Construct):
#     """Find bytes, and read past them."""
# 
#     __slots__ = ["find", "max_length"]
# 
#     def __init__(self, find, max_length):
#         """Initiallize."""
#         Construct.__init__(self)
#         if not isinstance(find, list):
#             find = [find]
#         self.find = find
#         self.max_length = max_length
# 
#     def _parse(self, stream, context, path):
#         """Parse stream to find a given byte string."""
#         start = stream.tell()
#         read_bytes = ""
#         if self.max_length:
#             read_bytes = stream.read(self.max_length)
#         else:
#             read_bytes = stream.read()
#         candidates = []
#         for f in self.find:
#             match = re.search(f, read_bytes)
#             if not match:
#                 continue
#             candidates.append(match.end())
#         if not candidates:
#             raise RuntimeError('could not find bytes: {}'.format(f))
#         choice = min(candidates)
#         stream.seek(start + choice)
#         return choice
# 
# class Version(Enum):
#     """Version enumeration.
# 
#     Using consts from https://github.com/goto-bus-stop/recanalyst/blob/master/src/Model/Version.php
#     for consistency.
#     """
#     AOK = 1
#     AOC = 4
#     AOC10 = 5
#     AOC10C = 8
#     USERPATCH12 = 12
#     USERPATCH13 = 13
#     USERPATCH14 = 11
#     USERPATCH15 = 20
#     DE = 21
#     USERPATCH14RC2 = 22
#     MCP = 30
#     HD = 19
# 
# def find_save_version(ctx):
#     """Find save version."""
#     if 'save_version' not in ctx:
#         return find_save_version(ctx._)
#     return ctx.save_version
# 
# def find_version(ctx):
#     """Find version."""
#     if 'version' not in ctx:
#         return find_version(ctx._)
#     return ctx.version


# Path: mgz/header/scenario.py
from construct import (Array, Float32l, Int16ul, Int32sl, Int32ul, Padding,
                       PascalString, Peek, String, Struct, Bytes, If, IfThenElse)
from mgz.enums import DifficultyEnum, PlayerTypeEnum, AgeEnum
from mgz.util import Find, Version, find_save_version, find_version

    "instructions"/Bytes(lambda ctx: ctx.instructions_length),
    "hints"/PascalString(lengthfield="hints_length"/Int16ul),
    "victory"/PascalString(lengthfield="victory_length"/Int16ul),
    "defeat"/PascalString(lengthfield="defeat_length"/Int16ul),
    "history"/PascalString(lengthfield="history_length"/Int16ul),
    "scouts"/If(lambda ctx: ctx._._.version != Version.AOK, PascalString(lengthfield="scouts_length"/Int16ul)),
    "pg_cin"/PascalString(lengthfield="pg_cin_length"/Int16ul),
    "vict_cin"/PascalString(lengthfield="vict_cin_length"/Int16ul),
    "loss_cin"/PascalString(lengthfield="loss_cin_length"/Int16ul),
    "background"/PascalString(lengthfield="background_length"/Int16ul),
    "bitmap_included"/Int32ul,
    "bitmap_x"/Int32ul,
    "bitmap_y"/Int32ul,
    Padding(2),
    # bitmap here if it is included
    Padding(64), # 16 nulls
)

# Scenario player definitions.
scenario_players = "players"/Struct(
    Array(16, "ai_names"/PascalString(lengthfield="ai_name_length"/Int16ul)),
    Array(16, "ai"/Struct(Padding(8), "file"/PascalString(lengthfield="ai_file_length"/Int32ul))),
    Padding(4),
    Array(16, "resources"/Struct(
        "gold"/Int32ul,
        "wood"/Int32ul,
        "food"/Int32ul,
        "stone"/Int32ul,
        "unk0"/Int32ul,
        "unk1"/Int32ul,

        If(lambda ctx: ctx._._._.version in (Version.DE, Version.HD),