#! /usr/bin/env python3

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


# Select name of class, inherits from Pattern
# TODO:
# 1) Implement __init__ method to get all custom options and then call Pattern's __init__
# 2) Implement generate_path_tree to define all of the desired strokes

class PleatCircular(Pattern):
    def __init__(self):
        Pattern.__init__(self)
        self.add_argument("-p", "--pattern", default="pleat_circular", help="Origami pattern")
        self.add_argument("--radius",  type=float, default=55.0, help="Radius of circle")
        self.add_argument("--ratio", type=float, default=0.4, help="Opening ratio")
        self.add_argument("--rings", type=int, default=15, help="Number of rings")
        self.add_argument("--simulation_mode", type=inkex.Boolean, default=True, help="Approximate circle and draw semicreases for simulation?")
        self.add_argument("--sides", type=int, default=20, help="Number of sides for polygon approximating half circle")

    def generate_path_tree(self):
        """ Specialized path generation for your origami pattern
        """
        # retrieve saved parameters
        unit_factor = self.calc_unit_factor()
        R = self.options.radius * unit_factor
        ratio = self.options.ratio
        r = R * ratio
        rings = self.options.rings
        dr = (1.-ratio)*R/rings
        self.translate = (R, R)

        if not self.options.simulation_mode:
            inner_circles = []
            for i in range(1, rings):
                inner_circles.append(Path((0, 0), radius=r + i*dr, style='m' if i % 2 else 'v'))

            edges = [Path((0, 0), radius=R, style='e'),
                     Path((0, 0), radius=r, style='e')]

            self.path_tree = [inner_circles, edges]

        # append semicreases for simulation
        else:
            sides = self.options.sides
            dtheta = pi / sides
            # create diagonals
            diagonals = []
            for i in range(sides):
                p1 = (0, 0)
                p2 = (R * cos((1 + i * 2) * dtheta), R * sin((1 + i * 2) * dtheta))
                diagonals.append(Path([p1, p2], 'u'))

            s = sin(dtheta)
            c = cos(dtheta)

            # Edge
            paths = [Path([(c * R, -s * R), (R, 0), (c * R, s * R)], style='e'),
                     Path([(c * r, -s * r), (r, 0), (c * r, s * r)], style='e')]

            # MV circles
            for i in range(1, rings):
                r_i = r + i * dr
                paths.append(Path([(c * r_i, -s * r_i), (r_i, 0), (c * r_i, s * r_i)],
                                          style='m' if i % 2 else 'v'))

            # Semicreases
            top = []
            bottom = []
            for i in range(rings + 1):
                r_i = r + i*dr
                top.append((r_i*(1 + (i % 2)*(c-1)), -(i % 2)*s*r_i))
                bottom.append((r_i*(1 + (i % 2)*(c-1)), (i % 2)*s*r_i))
            paths = paths + [Path([(r, 0), (R, 0)], 's'),                       # straight line 1
                             Path([(r*c, r*s), (R*c, R*s)], 's', invert=True),  # straight line 2
                             Path(top, 's'),                                    # top half of semicrease pattern
                             Path(bottom, 's')]                                # bottom half of semicrease pattern

            all_paths = [paths]
            for i in range(1, sides):
                all_paths.append(Path.list_rotate(all_paths[0], i*2*dtheta))

            self.path_tree = all_paths

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