#! /usr/bin/env python3

import numpy as np
from math import pi, tan, sqrt, sin, cos
import inkex
from Path import Path
from Pattern import Pattern

class Hypar(Pattern):
    def __init__(self):
        Pattern.__init__(self)  # Must be called in order to parse common options
        self.add_argument("-p", "--pattern",  default="template1", help="Origami pattern")
        self.add_argument("--radius", type=float, default=10.0, help="Radius of tower (mm)")
        self.add_argument("--sides", type=int, default=4, help="Number of polygon sides")
        self.add_argument("--rings", type=int, default=7, help="Number of rings")
        self.add_argument("--simplify_center", type=inkex.Boolean, default=0, help="Simplify center")

    def generate_path_tree(self):
        """ Specialized path generation for your origami pattern
        """
        # retrieve saved parameters
        unit_factor = self.calc_unit_factor()
        vertex_radius = self.options.vertex_radius * unit_factor
        pattern = self.options.pattern
        radius = self.options.radius * unit_factor
        sides = self.options.sides
        rings = self.options.rings
        simplify_center = self.options.simplify_center
        sin_ = sin(pi / float(sides))
        a = radius*sin_  # half of length of polygon side
        H = radius*sqrt(1 - sin_**2)

        polygon = Path.generate_polygon(sides, radius, 'e')

        # # OLD diagonals generation with universal creases
        # diagonals = []
        # for i in range(sides):
        #     diagonals.append(Path([(0, 0), polygon.points[i]], 'u'))
        # points = [(x, y) for x, y in polygon.points]
        # diagonals = diagonals + [Path.generate_separated_paths(points, 'm')]

        # # modify center if needed
        # if simplify_center:
        #     for i in range(sides):
        #         if i % 2 == 0:
        #             p2 = diagonals[i].points[1]
        #             diagonals[i].points[0] = (1. / (rings + 1) * p2[0], 1. / (rings + 1) * p2[1])

        # separate generic closed ring to create edges
        self.edge_points = polygon.points

        # vertex and diagonal lines creation
        vertex_line = []
        diagonal_line = []
        for i in range(1, rings + 2):
            y1 = a * (float(i - 1) / (rings + 1.))
            x1 = H * float(i - 1) / (rings + 1.)
            y2 = a * (float(i) / (rings + 1.))
            x2 = H * float(i) / (rings + 1.)
            vertex_line.append((Path((x2, y2), style='p', radius=vertex_radius)))
            diagonal_line.append((Path([(x1, y1), (x2, y2)], style='m' if i % 2 else 'v')))

        # rotation of vertices and diagonals for completing the drawing
        diagonals = []
        vertices = [Path((0, 0), style='p', radius=vertex_radius)]
        for i in range(sides):
            vertices = vertices+Path.list_rotate(vertex_line, i * 2 * pi / float(sides))
            diagonals = diagonals+[Path.list_rotate(diagonal_line, i * 2 * pi / float(sides))]

        # modify center if needed
        if simplify_center:
            for i in range(sides):
                if i % 2 == 0:
                    del diagonals[i][0]

        # inkex.debug(len(diagonals))
        # inkex.debug(len(diagonals[0]))
        # diagonals = diagonals + diagonal

        # scale generic closed ring to create inner rings
        inner_rings = []
        for i in range(rings + 1):
            inner_rings.append(polygon * (float(i)/(rings+1)))
            inner_rings[i].style = 'v' if i % 2 else 'm'

        # create points for zig zag pattern
        zig_zags = []
        if pattern != "classic":
            zig_zag = []
            for i in range(1, rings + 1):
                y_out = a * ((i + 1.) / (rings + 1.))
                y_in = a * (float(i) / (rings + 1.))
                x_out = H * (i + 1.) / (rings + 1.)
                x_in = H * float(i) / (rings + 1.)

                if pattern == "alternate_asymmetric" and i % 2:
                    zig_zag.append(Path([(x_in, -y_in), (x_out, +y_out)], style='u'))
                else:
                    zig_zag.append(Path([(x_in, +y_in), (x_out, -y_out)], style='u'))

            # reflect zig zag pattern to create all sides
            zig_zags.append(zig_zag)
            for i in range(sides - 1):
                points = diagonals[i][0].points
                zig_zags.append(Path.list_reflect(zig_zags[i], points[0], points[1]))

        self.translate = (radius, radius)
        self.path_tree = [diagonals, zig_zags, inner_rings, vertices]

# Main function, creates an instance of the Class and calls inkex.affect() to draw the origami on inkscape
if __name__ == '__main__':
    Hypar().run()