import os

from django.http import HttpResponse
from django.shortcuts import render

import troggle.settings as settings
from troggle.core.models.caves import Cave, Entrance
from troggle.core.views.caves import caveKey

# from pathlib import Path

# from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned


""" Generates the prospecting guide document.

Also produces the overlay of points on top of a prospecting_image map - to be deleted.
Not working with recent PIL aka Pillow image package - removed.
"""

AREANAMES = [
    # ('',     'Location unclear'),
    ("1a", "1a – Plateau: around Top Camp"),
    ("1b", "1b – Western plateau near 182"),
    ("1c", "1c – Eastern plateau near 204 walk-in path"),
    ("1d", "1d – Further plateau around 76"),
    ("2a", "2a – Southern Schwarzmooskogel near 201 path and the Nipple"),
    ("2b", "2b – Eishöhle area"),
    ("2b or 4 (unclear)", "2b or 4 (unclear)"),
    ("2c", "2c – Kaninchenhöhle area"),
    ("2d", "2d – Steinbrückenhöhle area"),
    ("3", "3 – Bräuning Alm"),
    ("4", "4 – Kratzer valley"),
    ("5", "5 – Schwarzmoos-Wildensee"),
    ("6", "6 – Far plateau"),
    ("1626 or 6 (borderline)", "1626 or 6 (borderline)"),
    ("7", "7 – Egglgrube"),
    ("8a", "8a – Loser south face"),
    ("8b", "8b – Loser below Dimmelwand"),
    ("8c", "8c – Augst See"),
    ("8d", "8d – Loser-Hochganger ridge"),
    ("9", "9 – Gschwandt Alm"),
    ("10", "10 – Altaussee"),
    ("11", "11 – Augstbach"),
]


def prospecting(request):
    """This produces the multipage 'prospecting guide' document,
    intended to be printed and carried into the field - in 1999.

    All the formatting and selection cleverness is in the template file.

    This produces a vast number of bad 404 URLs as many URLs in the cave_data
    XML files refer to other caves, assuming that they are in the same directory
    as the prospecting guide. But since the introduction of the 1623/ level, this is
    not true. e.g. 163 refers to 162 as href="../162.htm" which is valid in the cave
    description page but not when navigating from the prospecting guide page.

    Since this vast number of broken links is getting in the way of finding real errors, the guide
    has been disabled.
    """
    message = (
        "This prospecting guide text report contains many broken URLs because of a major redesign\n"
        + " to put caves into 1623/ and 1624/ folders in 2017. It was mostly useless because recent QM info was not in it anyway.\n\n"
        + 'It is disabled in the python code in "prospecting(request):" in troggle/core/views/prospect.py'
    )
    return render(request, "errors/disabled.html", {"message": message})

    areas = []
    caves = Cave.objects.all()

    for c in caves:
        if c.subarea in AREANAMES:
            areas.append((AREANAMES[c.subarea], subarea, c))
    return render(request, "prospecting.html", {"areas": areas})


# Parameters for big map and zoomed subarea maps:
# big map first (zoom factor ignored)

# These are the values for the url /prospecting/[mapcode].png

maps = {
    # id	left		top			right		bottom		zoom
    # 		G&K			G&K			G&K			G&K			factor
    "all": [33810.4, 85436.5, 38192.0, 81048.2, 0.35, "All"],
    "40": [36275.6, 82392.5, 36780.3, 81800.0, 3.0, "Eishöhle"],
    "76": [35440.0, 83220.0, 36090.0, 82670.0, 1.3, "Eislufthöhle"],
    "204": [36354.1, 84154.5, 37047.4, 83300, 3.0, "Steinbrückenhöhle"],
    "tc": [35230.0, 82690.0, 36110.0, 82100.0, 3.0, "Near Top Camp"],
    "grieß": [36000.0, 86300.0, 38320.0, 84400.0, 4.0, "Grießkogel Area"],
}

for n in list(maps.keys()):
    L, T, R, B, S, name = maps[n]
    W = (R - L) / 2
    H = (T - B) / 2
    for i in range(2):
        for j in range(2):
            maps["%s%i%i" % (n, i, j)] = [L + i * W, T - j * H, L + (i + 1) * W, T - (j + 1) * H, S, name]
# Keys in the order in which we want the maps output
mapcodes = ["all", "grieß", "40", "76", "204", "tc"]
# Field codes
L = 0
T = 1
R = 2
B = 3
ZOOM = 4
DESC = 5
SIZE = 5

areacolours = {
    "1a": "#00ffff",
    "1b": "#ff00ff",
    "1c": "#ffff00",
    "1d": "#ffffff",
    "2a": "#ff0000",
    "2b": "#00ff00",
    "2c": "#008800",
    "2d": "#ff9900",
    "3": "#880000",
    "4": "#0000ff",
    "6": "#000000",  # doubles for surface fixed pts, and anything else
    "7": "#808080",
}

for FONT in [
    "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
    "/usr/X11R6/lib/X11/fonts/truetype/arial.ttf",
    "/mnt/c/windows/fonts/arial.ttf",
    "C:\WINNT\Fonts\ARIAL.TTF",
]:
    if os.path.isfile(FONT):
        break
TEXTSIZE = 16
CIRCLESIZE = 8
LINEWIDTH = 2
# myFont = ImageFont.truetype(FONT, TEXTSIZE) # disabled as not importing PIL
# print(f' - myFont {myFont} {FONT} {TEXTSIZE}')


def mungecoord(x, y, mapcode, img):
    # Top of Zinken is 73 1201 = dataset 34542 81967
    # Top of Hinter is 1073 562 = dataset 36670 83317
    # image is 1417 by 2201
    # FACTOR1 = 1000.0 / (36670.0-34542.0)
    # FACTOR2 = (1201.0-562.0) / (83317 - 81967)
    # FACTOR = (FACTOR1 + FACTOR2)/2
    # The factors aren't the same as the scanned map's at a slight angle. I
    # can't be bothered to fix this.  Since we zero on the Hinter it makes
    # very little difference for caves in the areas round 76 or 204.
    # xoffset = (x - 36670)*FACTOR
    # yoffset = (y - 83317)*FACTOR
    # return (1073 + xoffset, 562 - yoffset)

    m = maps[mapcode]
    factorX, factorY = img.size[0] / (m[R] - m[L]), img.size[1] / (m[T] - m[B])
    return ((x - m[L]) * factorX, (m[T] - y) * factorY)


COL_TYPES = {True: "red", False: "#dddddd", "Reference": "#dddddd"}


def prospecting_image(request, name):
    """This draws map outlines on an existing map image.
    But getting the entrances plotted is broken by later changes elsewhere in the system since this code was written.

    SurvexStations are in x=latitude, y=longitude - these are what appear in essentials.gpx
    Entrances are in northing, easting

    which is why we can't simply plot all the Entrances...

    We should replace all this with something that exports an overlay for Google Maps and OpenStreetView
    """

    mainImage = Image.open(os.path.join(settings.EXPOFILES, "location_maps", "pguidemap.jpg"))
    # if settings.PUBLIC_SITE and not request.user.is_authenticated:
    # mainImage = Image.new("RGB", mainImage.size, '#ffffff')
    m = maps[name]
    imgmaps = []
    if name == "all":
        img = mainImage
    else:
        M = maps["all"]
        W, H = mainImage.size
        l = int((m[L] - M[L]) / (M[R] - M[L]) * W)
        t = int((m[T] - M[T]) / (M[B] - M[T]) * H)
        r = int((m[R] - M[L]) / (M[R] - M[L]) * W)
        b = int((m[B] - M[T]) / (M[B] - M[T]) * H)
        img = mainImage.crop((l, t, r, b))
        w = int(round(m[ZOOM] * (m[R] - m[L]) / (M[R] - M[L]) * W))
        h = int(round(m[ZOOM] * (m[B] - m[T]) / (M[B] - M[T]) * H))
        img = img.resize((w, h), Image.BICUBIC)
    draw = ImageDraw.Draw(img)
    # draw.setfont(myFont)
    if name == "all":
        for maparea in list(maps.keys()):
            if maparea == "all":
                continue
            localm = maps[maparea]
            l, t = mungecoord(localm[L], localm[T], "all", img)
            r, b = mungecoord(localm[R], localm[B], "all", img)
            text = maparea + " map"
            textlen = draw.textsize(text)[0] + 3
            draw.rectangle([l, t, l + textlen, t + TEXTSIZE + 2], fill="#ffffff")
            draw.text((l + 2, t + 1), text, fill="#000000", font=myFont)
            imgmaps.append([l, t, l + textlen, t + SIZE + 2, "submap" + maparea, maparea + " subarea map"])
            draw.line([l, t, r, t], fill="#777777", width=LINEWIDTH)
            draw.line([l, b, r, b], fill="#777777", width=LINEWIDTH)
            draw.line([l, t, l, b], fill="#777777", width=LINEWIDTH)
            draw.line([r, t, r, b], fill="#777777", width=LINEWIDTH)
            draw.line([l, t, l + textlen, t], fill="#777777", width=LINEWIDTH)
            draw.line([l, t + TEXTSIZE + 2, l + textlen, t + TEXTSIZE + 2], fill="#777777", width=LINEWIDTH)
            draw.line([l, t, l, t + TEXTSIZE + 2], fill="#777777", width=LINEWIDTH)
            draw.line([l + textlen, t, l + textlen, t + TEXTSIZE + 2], fill="#777777", width=LINEWIDTH)
    # imgmaps[maparea] = []

    # Draw scale bar
    m100 = int(100 / (m[R] - m[L]) * img.size[0])
    draw.line([10, TEXTSIZE * 3, 10, TEXTSIZE * 2], fill="#000000", width=LINEWIDTH)
    draw.line([10, TEXTSIZE * 2, 10 + m100, TEXTSIZE * 2], fill="#000000", width=LINEWIDTH)
    draw.line([10 + m100, TEXTSIZE * 3, 10 + m100, TEXTSIZE * 2], fill="#000000", width=LINEWIDTH)
    label = "100m"
    draw.text([10 + (m100 - draw.textsize(label)[0]) / 2, TEXTSIZE / 2], label, fill="#000000", font=myFont)

    # Draw the circles for known points
    # Northing, Easting, Diameter - but N&E are swapped re database
    for (N, E, D, num) in [
        (35975.37, 83018.21, 100, "177"),  # Calculated from bearings
        (35350.00, 81630.00, 50, "71"),  # From Auer map
        (36025.00, 82475.00, 50, "146"),  # From mystery map
        (35600.00, 82050.00, 50, "35"),  # From Auer map
        (35650.00, 82025.00, 50, "44"),  # From Auer map
        (36200.00, 82925.00, 50, "178"),  # Calculated from bearings
        (35232.64, 82910.37, 25, "181"),  # Calculated from bearings
        (35323.60, 81357.83, 50, "74"),  # From Auer map
    ]:
        (N, E, D) = list(map(float, (N, E, D)))
        maparea = Cave.objects.get(kataster_number=num).areacode
        lo = mungecoord(N - D, E + D, name, img)
        hi = mungecoord(N + D, E - D, name, img)
        lpos = mungecoord(N - D, E, name, img)
        draw.ellipse([lo, hi], outline="#000000")
        draw.ellipse([lo[0] + 1, lo[1] + 1, hi[0] - 1, hi[1] - 1], outline=areacolours[maparea])
        draw.ellipse([lo[0] + 2, lo[1] + 2, hi[0] - 2, hi[1] - 2], outline=areacolours[maparea])
        draw.rectangle(
            [lpos[0], lpos[1] - TEXTSIZE / 2, lpos[0] + draw.textsize(name)[0], lpos[1] + TEXTSIZE / 2], fill="#ffffff"
        )
        draw.text((lpos[0], lpos[1] - TEXTSIZE / 2), num, fill="#000000")
        # print(f' CIRCLES - {num} {(N,E,D)}')

    # ml = MapLocations()
    # for p in ml.points():
    # surveypoint, number,  point_type, label = p
    # print(f'{surveypoint}, {number},  {point_type}, {label}')
    # plot(surveypoint, number,  True, label, name, draw, img)
    # print(f'{name},\n{draw},\n{img}')

    ents = Entrance.objects.all()  # only has entrances and fixed points in it these days,
    # but there are only 11 Entrances with northing, easting and a useable tag!
    D = 50
    for e in ents:
        try:
            E, N = e.easting, e.northing
            if e.tag_station:
                st = e.tag_station
            elif e.other_station:
                st = e.other_station
            else:
                # print(f' No tag    - {e.name}   ')
                continue
            if not e.northing:
                continue
            lo = mungecoord(N - D, E + D, st, img)
            hi = mungecoord(N + D, E - D, st, img)
            lpos = mungecoord(N - D, E, st, img)

            draw.ellipse([lo, hi], outline="#000000")
            draw.ellipse([lo[0] + 1, lo[1] + 1, hi[0] - 1, hi[1] - 1], outline="#ffffff")
            draw.ellipse([lo[0] + 2, lo[1] + 2, hi[0] - 2, hi[1] - 2], outline="#ffffff")
            draw.rectangle(
                [lpos[0], lpos[1] - TEXTSIZE / 2, lpos[0] + draw.textsize(st)[0], lpos[1] + TEXTSIZE / 2],
                fill="#ffffff",
            )
            draw.text((lpos[0], lpos[1] - TEXTSIZE / 2), num, fill="#000000")

            # draw.ellipse([(x-CIRCLESIZE,y-CIRCLESIZE),(x+CIRCLESIZE,y+CIRCLESIZE)], fill="red", outline="blue")
            # draw.rectangle([(x+CIRCLESIZE, y-TEXTSIZE/2), (x+CIRCLESIZE*2+draw.textsize(shortnumber)[0], y+TEXTSIZE/2)], fill="#ffffff")
            # draw.text((x+CIRCLESIZE * 1.5,y-TEXTSIZE/2), shortnumber, fill="#000000")
            # print(f' SUCCESS - {st} {(E, N)}   ')
        except:
            # print(f' FAIL    - {st}  {(E, N)} ')
            pass

    response = HttpResponse(content_type="image/png")
    del draw
    img.save(response, "PNG")
    return response


# def plot(surveypoint, number,  point_type, label, mapcode, draw, img):
# try:
# ss = SurvexStation.objects.lookup(surveypoint)
# E, N = ss.x, ss.y
# shortnumber = number.replace("—","")
# (x,y) = list(map(int, mungecoord(E, N, mapcode, img)))
# imgmaps[maparea].append( [x-4, y-SIZE/2, x+4+draw.textsize(shortnumber)[0], y+SIZE/2, shortnumber, label] )
# draw.rectangle([(x+CIRCLESIZE, y-TEXTSIZE/2), (x+CIRCLESIZE*2+draw.textsize(shortnumber)[0], y+TEXTSIZE/2)], fill="#ffffff")
# draw.text((x+CIRCLESIZE * 1.5,y-TEXTSIZE/2), shortnumber, fill="#000000")
# draw.ellipse([(x-CIRCLESIZE,y-CIRCLESIZE),(x+CIRCLESIZE,y+CIRCLESIZE)], fill=COL_TYPES[point_type], outline="#000000")
# print(f' SUCCESS - YES {surveypoint}, {number},  {point_type}, {label}')
# except:
# print(f'         - NO  {surveypoint}, {number},  {point_type}, {label}')
# pass