from django.shortcuts import render

# Create your views here.

import json
from django.shortcuts import render
from django.views import View


from django.http import HttpResponseRedirect
import plots.packing_algo as poly
from bokeh.embed import file_html
from bokeh.models import BoxZoomTool
from django.views.generic import TemplateView
import matplotlib
from django.http import JsonResponse

from django.http import HttpResponse
import pdb;pdb.set_trace
import matplotlib.pyplot as plt
import mpld3

import math
from plots import plot_helpers
from bokeh.plotting import figure, output_file, show
from bokeh.resources import CDN
from bokeh.models.widgets import Panel, Tabs
from bokeh.layouts import layout
from bokeh.models.widgets import Tabs, Panel
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import Figure
from bokeh.models import ColumnDataSource, CustomJS, Slider
from bokeh.embed import components
from bokeh.embed import json_item
from bokeh.events import ButtonClick
import numpy as np
from bokeh.models import PolyDrawTool, PolyEditTool
from bokeh.models.callbacks import CustomJS
from bokeh.embed import json_item
import json
import pandas


def index(request):

    convex_polygons = poly.create_multiple_convex_polygons(10,9)
    cc = poly.ConvexContainer(convex_polygons)
    plot_steps = cc.plot_steps(render=False)
    plot_steps_html = file_html(plot_steps, CDN, "my plot2")

    return render(request, 'plots/packed_polygons.html', context={"plot_steps":plot_steps_html})

                                                        # 'high_classes': plot_high_class_list,})
            #                                            'hc_container': hc_container})

class PackingRectContainer(View):
    def get(self, request, *args, **kwargs):
        coordinates =[]
        if PolygonEditView.polygons==[]:
            plot_steps_html = "No Polygon"
        else:
            end = poly.pack_polygons(PolygonEditView.polygons)
            plot_steps = end.plot_steps(render=False)
            plot_steps_html = file_html(plot_steps, CDN, "my plot23")
            #PackingPolygons.context["packed_polygons"]=plot_steps_html
            coordinates = end.polygon_shells
        return render(request, 'plots/packed_polygons.html', context={"plot_steps": plot_steps_html,
                                                                      "coordinates":coordinates})


class PackingRotatedRectContainer(View):
    def get(self, request, *args, **kwargs):
        coordinates = []
        if PolygonEditView.polygons==[]:
            plot_steps_html = "No Polygon"
        else:
            cc = poly.ConvexContainer(PolygonEditView.polygons,steps=90)
            plot_steps = cc.plot_steps(render=False)
            plot_steps_html = file_html(plot_steps, CDN, "my plot23")
            # PackingPolygons.context["packed_polygons"]=plot_steps_html
            coordinates = cc.polygon_shells
        return render(request, 'plots/packed_polygons.html', context={"plot_steps": plot_steps_html,
                                                                      "coordinates":coordinates})

class PackingConvexContainer(View):
    coordinates = []
    def post(self, request, *args, **kwargs):
        if PolygonEditView.polygons==[]:
            plot_steps_html = "No Polygon"
        else:
            angle = int(request.POST["angle"])
            cc = poly.ConvexContainer(PolygonEditView.polygons, steps=angle)
            plot_steps = cc.plot_steps(render=False)
            plot_steps_html = file_html(plot_steps, CDN, "my plot23")
            coordinates = cc.polygon_shells
        return render(request, 'plots/packed_polygons.html', context={"plot_steps": plot_steps_html,
                                                                      "coordinates":coordinates})


class ClearPolygons(View):
    def get(self, request):
        PolygonEditView.colum_data_x.clear()
        PolygonEditView.colum_data_y.clear()
        PolygonEditView.context["drawn_polygons"] = "No Polygons"
        PolygonEditView.context["polygons_single_plot"] = "No Polygons"
        PolygonEditView.polygons = []
        PolygonEditView.plot_max_x = 100
        PolygonEditView.plot_min_x = 0
        PolygonEditView.plot_max_y = 100
        PolygonEditView.plot_min_y = 0
        return HttpResponseRedirect('/index/')


class CreateConvexPolygons(View):
    def post(self, request, *args, **kwargs):
        max_vertices_count = int(request.POST["vertices"])
        polygon_count = int(request.POST["polygon_count"])
        polygons = poly.create_multiple_convex_polygons(polygon_count,max_vertices_count)

        all_x_values = [PolygonEditView.plot_max_x, PolygonEditView.plot_min_x]
        all_y_values = [PolygonEditView.plot_min_y,PolygonEditView.plot_max_y]
        for polygon in polygons:
            all_x_values = all_x_values + polygon.x_values
            all_y_values = all_y_values + polygon.y_values
            PolygonEditView.colum_data_x.append(polygon.x_values)
            PolygonEditView.colum_data_y.append(polygon.y_values)
        PolygonEditView.plot_max_x = max(all_x_values)
        PolygonEditView.plot_min_x = min(all_x_values)
        PolygonEditView.plot_max_y = max(all_y_values)
        PolygonEditView.plot_min_y = min(all_y_values)

        return HttpResponseRedirect('/index/')


class CSVPolygons(View):

    def get(self, request):
        PolygonEditView.csv_polygons = []
        PolygonEditView.polygons = PolygonEditView.drawn_polygons
        PolygonEditView.context["csv_polygons"] = "Cleared"

        if len(PolygonEditView.polygons) != 0:
            polygons_single_plot = poly.plot_polygons_in_single_plot(PolygonEditView.drawn_polygons, plot_height=850, plot_width=2000,
                                                                     render=False)
            polygons_single_plot_html = file_html(polygons_single_plot, CDN, "single plot")
        else:
            polygons_single_plot_html = "No Polygons"
        PolygonEditView.context["polygons_single_plot"] = polygons_single_plot_html
        return HttpResponseRedirect('/index/')

    def post(self, request, *args, **kwargs):
        df = pandas.read_csv('plots/polygon.txt',sep="#")
        csv_polygons = df["Polygon"]
        all_x_values = [PolygonEditView.plot_max_x, PolygonEditView.plot_min_x]
        all_y_values = [PolygonEditView.plot_min_y,PolygonEditView.plot_max_y]
        for polygon_str in csv_polygons:
            polygon = eval(polygon_str)
            x_tuples, y_tuples = (zip(*polygon))
            x_values= list(x_tuples)
            y_values = list(y_tuples)
            all_x_values = all_x_values +x_values
            all_y_values = all_y_values + y_values
            PolygonEditView.colum_data_x.append(x_values)
            PolygonEditView.colum_data_y.append(y_values)
        PolygonEditView.plot_max_x = max(all_x_values)
        PolygonEditView.plot_min_x = min(all_x_values)
        PolygonEditView.plot_max_y = max(all_y_values)
        PolygonEditView.plot_min_y = min(all_y_values)

        return HttpResponseRedirect('/index/')






class PolygonEditView(View):
    context = {}
    polygons = []
    drawn_polygons = []

    #all_polygons=[]
    plot_min_x = 0
    plot_max_x = 100
    plot_min_y = 0
    plot_max_y = 100
    colum_data_x =[] # wil be a list of lists
    colum_data_y =[]
    def get(self, request, *args, **kwargs):
        TOOLTIPS = [("index", "$index"), ("(x,y)", "($x{1.1}, $y{1.1})"), ]
        source = ColumnDataSource(data=dict(x=PolygonEditView.colum_data_x,
                                            y=PolygonEditView.colum_data_y),
                                  name='my-data-source')

        p = figure(x_range=(PolygonEditView.plot_min_x, PolygonEditView.plot_max_x), y_range=(PolygonEditView.plot_min_y, PolygonEditView.plot_max_y), width=1000, height=1000,
                   title='Poly Edit Tool', tooltips=TOOLTIPS)
        #p.aspect_ratio = 1
        p1 = p.patches("x", "y", fill_alpha=0.4, source=source, fill_color="red")

        c1 = p.circle([], [], size=10, color='red', )

        draw_tool = PolyDrawTool(renderers=[p1])
        edit_tool = PolyEditTool(renderers=[p1], vertex_renderer=c1)

        p.add_tools(draw_tool, edit_tool)
        p.toolbar.active_drag = draw_tool
        response = file_html(p, CDN, "my plot")
        PolygonEditView.context["response"] = response


        return render(request, 'plots/index.html', PolygonEditView.context)

    def post(self, request, *args, **kwargs):

        x_y_values_dict_str = request.POST["drawn_polygons"]
        dict_poly = json.loads(x_y_values_dict_str)
        PolygonEditView.colum_data_x.clear()
        PolygonEditView.colum_data_y.clear()
        for poly_x in dict_poly["x"]:
            PolygonEditView.colum_data_x.append(poly_x)
        for poly_y in dict_poly["y"]:
            PolygonEditView.colum_data_y.append(poly_y)
        polygon_list=[]
        polygons_x_y_tuple = list(zip(dict_poly["x"], dict_poly["y"]))
        for x,y in  polygons_x_y_tuple:
            polygon_list.append(list(zip(x,y)))
        print(polygon_list)
        drawn_polygons=[]
        polygon_max_x_list=[]
        polygon_min_x_list = []
        polygon_min_y_list = []
        polygon_max_y_list=[]
        for polygon in polygon_list:
            try:
                polygon2 = poly.ConvexPolygon(polygon)
                polygon_max_x_list.append(polygon2.max_x)
                polygon_min_x_list.append(polygon2.min_x)
                polygon_max_y_list.append(polygon2.max_y)
                polygon_min_y_list.append(polygon2.min_y)
                drawn_polygons.append(polygon2)
            except:
                print(polygon, " has to less convex Points")

        PolygonEditView.drawn_polygons = drawn_polygons
        PolygonEditView.polygons = drawn_polygons
        if len(drawn_polygons) > 0:
            PolygonEditView.plot_max_y = max(polygon_max_y_list)
            PolygonEditView.plot_min_y = min(polygon_min_y_list)
            PolygonEditView.plot_max_x = max(polygon_max_x_list)
            PolygonEditView.plot_min_x = min(polygon_min_x_list)

        plot_drawn = poly.polygons_to_tab_plot(drawn_polygons, ncols=4, tab_poly_count=8)
        polygons_drawn_plot_html = file_html(plot_drawn, CDN, "my plot")
        PolygonEditView.context["drawn_polygons"] = polygons_drawn_plot_html
        polygons_single_plot = poly.plot_polygons_in_single_plot(drawn_polygons, plot_height=850, plot_width=2000,
                                                                 render=False)
        polygons_single_plot_html = file_html(polygons_single_plot, CDN, "single plot")
        PolygonEditView.context["polygons_single_plot"] = polygons_single_plot_html

        return HttpResponseRedirect('/index/')