# -*- coding: utf-8 -*-
# https://github.com/urschrei/hexcover
"""
util.py
Created by Stephan Hügel on 2019-06-28
This file is part of hexcover.
Copyright (c) 2019 Stephan Hügel
Blue Oak Model License Version 1.0.0
Purpose
This license gives everyone as much permission to work with this
software as possible, while protecting contributors from liability.
Acceptance
In order to receive this license, you must agree to its rules. The
rules of this license are both obligations under that agreement and conditions
to your license. You must not do anything with this software that triggers a
rule that you cannot or will not follow.
Copyright
Each contributor licenses you to do everything with this software that
would otherwise infringe that contributor’s copyright in it.
Notices
You must ensure that everyone who gets a copy of any part of this
software from you, with or without changes, also gets the text of this license
or a link to https://blueoakcouncil.org/license/1.0.0.
Excuse
If anyone notifies you in writing that you have not complied with
Notices, you can keep your license by taking all practical steps to comply
within 30 days after the notice. If you do not do so, your license ends
immediately.
Patent
Each contributor licenses you to do everything with this software that
would otherwise infringe any patent claims they can license or become able to
license.
Reliability
No contributor can revoke this license.
No Liability
As far as the law allows, this software comes as is, without any
warranty or condition, and no contributor will be liable to anyone for any
damages related to this software or this license, under any kind of legal claim.
"""

__author__ = u"Stephan Hügel <shugel@tcd.ie>"
__version__ = "0.4.0"

from shapely.geometry import Polygon
from shapely.affinity import translate
import math
from collections import namedtuple


Hexagons = namedtuple(
    "Hexagons",
    ["centre", "top", "topright", "bottomright", "bottom", "bottomleft", "topleft"],
)


def _flat_hex_coords(centre, size, i):
    """ Return the point coordinate of a flat-topped regular hexagon.
    points are returned in counter-clockwise order as i increases
    the first coordinate (i=0) will be:
    centre.x + size, centre.y
    """
    angle_deg = 60 * i
    angle_rad = math.pi / 180 * angle_deg
    return (
        centre.x + size * math.cos(angle_rad),
        centre.y + size * math.sin(angle_rad),
    )


def _flat_hex_polygon(centre, size):
    """ Return a flat-topped regular hexagonal Polygon, given a centroid Point and side length """
    return Polygon([_flat_hex_coords(centre, size, i) for i in range(6)])


def hexagon_coverage(centre, size):
    """ Tile an area having a Shapely Point centroid _centre_ with regular flat-topped
    hexagonal polygons having side-length _size_.
    The returned namedtuple has seven entries:
    0 is the central polygon, 1 - 6 are surrounding polygons, beginning directly
    above 0, progressing clockwise.
    """
    cp = _flat_hex_polygon(centre, size)
    width = 2 * size
    height = math.sqrt(3) * size
    horizontal_distance = width * 0.75
    vertical_distance = height * 0.5
    # second hex is directly above central_polygon, progresses clockwise
    return Hexagons(
        cp,
        translate(cp, 0, vertical_distance * 2),
        translate(cp, horizontal_distance, vertical_distance),
        translate(cp, horizontal_distance, -vertical_distance),
        translate(cp, 0, vertical_distance * -2),
        translate(cp, -horizontal_distance, vertical_distance),
        translate(cp, -horizontal_distance, -vertical_distance),
    )
