# -*- coding: utf-8 -*-
#    This file is part of twms.

# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms specified in COPYING.

try:
    from PIL import Image, ImageDraw, ImageColor, ImageFont
except ImportError:
    import Image, ImageDraw, ImageColor, ImageFont

import urllib
import os, sys
import array

import projections
import config
from gpxparse import GPXParser
import math


HAVE_CAIRO = True
try:
    import cairo
    import pango
    import pangocairo
except ImportError:
    HAVE_CAIRO = False


def wkt(wkt, img, bbox, srs, color, blend=0.5):
    """
    Simple WKT renderer
    """
    wkt = wkt.replace("((", "(")
    for obj in wkt.split("),"):

        canvas = img.copy()
        name, coords = obj.split("(")
        coords = coords.replace(")", "")
        text = ""
        if name == "TEXT":
            text, coords = coords.split(",", 1)
        coords = coords.split(",")
        coords = [[float(t) for t in x.split(" ")] for x in coords]
        canvas = render_vector(name, canvas, bbox, coords, srs, color, text=text)
        img = Image.blend(img, canvas, blend)
    return img


def gpx(track, img, bbox, srs, color, blend=0.5):
    """
    Simple GPX renderer
    """
    for i in track.tracks.keys():
        coords = track.getTrack(i)
        canvas = img.copy()
        canvas = render_vector("LINESTRING", canvas, bbox, coords, srs, color)
        img = Image.blend(img, canvas, blend)
    return img


def render_vector(
    geometry,
    img,
    bbox,
    coords,
    srs,
    color=None,
    renderer=None,
    linestring_width=None,
    text=None,
    cairo_font=None,
    pil_font=None,
):
    """
    Renders a vector geometry on image.
    """
    if not color:
        color = config.geometry_color[geometry]
    if not renderer:
        renderer = config.default_vector_renderer
    if not linestring_width:
        if "linestring_width" in dir(config):
            linestring_width = config.linestring_width
        else:
            linestring_width = 3
    if not cairo_font:
        if "cairo_font" in dir(config):
            cairo_font = config.cairo_font
    if not pil_font:
        if "pil_font" in dir(config):
            pil_font = config.pil_font
    bbox = projections.from4326(bbox, srs)
    lo1, la1, lo2, la2 = bbox
    coords = projections.from4326(coords, srs)
    W, H = img.size
    prevcoord = False
    coords = [
        (
            (coord[0] - lo1) * (W - 1) / abs(lo2 - lo1),
            (la2 - coord[1]) * (H - 1) / (la2 - la1),
        )
        for coord in coords
    ]

    if renderer == "cairo" and HAVE_CAIRO:
        "rendering as cairo"
        imgd = img.tostring()
        a = array.array("B", imgd)
        surface = cairo.ImageSurface.create_for_data(
            a, cairo.FORMAT_ARGB32, W, H, W * 4
        )
        cr = cairo.Context(surface)
        cr.move_to(*coords[0])
        color = ImageColor.getrgb(color)
        cr.set_source_rgba(color[2] / 255.0, color[1] / 255.0, color[0] / 255.0, 1)
        if geometry == "LINESTRING" or geometry == "POLYGON":
            for k in coords:
                cr.line_to(*k)
        if geometry == "LINESTRING":
            if linestring_width is not None:
                cr.set_line_width(linestring_width)
            cr.stroke()
        elif geometry == "POLYGON":
            cr.fill()
        elif geometry == "POINT":
            cr.arc(coords[0][0], coords[0][1], 6, 0, 2 * math.pi)
            cr.fill()
        elif geometry == "TEXT" and text and cairo_font:
            pcr = pangocairo.CairoContext(cr)
            pcr.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
            layout = pcr.create_layout()
            font = pango.FontDescription(cairo_font)
            layout.set_font_description(font)
            layout.set_text(text)
            pcr.update_layout(layout)
            pcr.show_layout(layout)

        img = Image.frombuffer("RGBA", (W, H), surface.get_data(), "raw", "RGBA", 0, 1)

    else:
        "falling back to PIL"
        coord = [
            (int(coord[0]), int(coord[1])) for coord in coords
        ]  # PIL dislikes subpixels
        draw = ImageDraw.Draw(img)
        if geometry == "LINESTRING":
            draw.line(coords, fill=color, width=linestring_width)
        elif geometry == "POINT":
            draw.ellipse(
                (
                    coords[0][0] - 3,
                    coords[0][1] - 3,
                    coords[0][0] + 3,
                    coords[0][1] + 3,
                ),
                fill=color,
                outline=color,
            )
        elif geometry == "POLYGON":
            draw.polygon(coords, fill=color, outline=color)
        elif geometry == "TEXT" and text and pil_font:
            font = ImageFont.truetype(pil_font[0], pil_font[1])
            draw.text(coords[0], text, color, font=font)
    return img
