import math


def prepare_ozi(mbbox, mwidth, mheight, name, transform):
    """Create georeferencing file for OziExplorer"""
    def deg(value, is_lon):
        degrees = math.floor(abs(value))
        minutes = (abs(value) - degrees) * 60
        return '{:4d},{:3.5F},{}'.format(
            int(round(degrees)), minutes,
            ('W' if is_lon else 'S') if value < 0 else ('E' if is_lon else 'N'))

    ozipoint = ('Point{:02d},xy,     ,     ,in, deg,    ,        ,N,    ,        ,E' +
                ', grid,   ,           ,           ,N')
    bbox = transform.backward(mbbox)
    points = "\n".join([ozipoint.format(n) for n in range(3, 31)])
    header = '''OziExplorer Map Data File Version 2.2
Nik4
{name}
1 ,Map Code,
WGS 84,WGS 84,   0.0000,   0.0000,WGS 84
Reserved 1
Reserved 2
Magnetic Variation,,,E
Map Projection,Mercator,PolyCal,No,AutoCalOnly,No,BSBUseWPX,No
Point01,xy,    0,    0,in, deg,{top},{left}, grid,   ,           ,           ,N
Point02,xy, {width:4d}, {height:4d},in, deg,{bottom},{right}, grid,   ,           ,           ,N
{points}
Projection Setup,,,,,,,,,,
Map Feature = MF ; Map Comment = MC     These follow if they exist
Track File = TF      These follow if they exist
Moving Map Parameters = MM?    These follow if they exist
MM0,Yes
MMPNUM,4
MMPXY,1,0,0
'''.format(name=name,
           top=deg(bbox.maxy, False),
           left=deg(bbox.minx, True),
           width=mwidth - 1,
           height=mheight - 1,
           bottom=deg(bbox.miny, False),
           right=deg(bbox.maxx, True),
           points=points)
    return ''.join([
        header,
        "MMPXY,2,{},0\n".format(mwidth),
        "MMPXY,3,{},{}\n".format(mwidth, mheight),
        "MMPXY,4,0,{}\n".format(mheight),
        'MMPLL,1,{:4.6f},{:4.6f}\n'.format(bbox.minx, bbox.maxy),
        'MMPLL,2,{:4.6f},{:4.6f}\n'.format(bbox.maxx, bbox.maxy),
        'MMPLL,3,{:4.6f},{:4.6f}\n'.format(bbox.maxx, bbox.miny),
        'MMPLL,4,{:4.6f},{:4.6f}\n'.format(bbox.minx, bbox.miny),
        "MM1B,{}\n".format((mbbox.maxx - mbbox.minx) / mwidth * math.cos(
            math.radians(bbox.center().y))),
        "MOP,Map Open Position,0,0\n",
        "IWH,Map Image Width/Height,{},{}\n".format(mwidth, mheight),
    ])