'''
Created on 20-Jan-2022

@author: bthakur
'''

import inspect
import traceback
import random
import numpy as np

from sympy import simplify, Rational, latex

from xv.km.util import latex_fraction
from sympy.core.expr import UnevaluatedExpr

from xv.km.ui import SvgHelper
from xv.util.data import CacheUtil
import matplotlib.pyplot as plt

from ...util import MathUtil
from xv.util import toIntOrFloat, list_to_str
from xv.plotter import Plotter2D

# _geometrical_shape_helper
# GeometricalShapeHelper
class GeometricalShapeHelper:
    
    def __init__(self, **kwargs):
        self.verbose = kwargs.get('verbose', False)
        pass

    def plot_regular_polygon(self, side_counts, **kwargs):
        '''
        @side_counts = a list of count of sides for each polygon, like [5, 3, 8]
        @labelled = False
        @auto_rotate: False
        @label_side_count: False
        @draw_radii: False
        @use_cache = True
        '''
        kwargs['side_counts'] = side_counts
        
        result = self._get_cache_or_plot(
                                calling_method = inspect.stack()[0][3],
                                method_to_call = self._plot_regular_polygon,
                                **kwargs
                                )
        
        return result
        pass
    
    def get_regular_polygon_names(self):
        plotter = Plotter2D(verbose = self.verbose)
        names = plotter.get_regular_polygon_names()
        return names
    
    def get_regular_polygon_names_html(self):
        names = self.get_regular_polygon_names()
        names_html = [f"<tr><td>{k}</td><td>{v}</td></tr>"
                              for k,v in names.items()]
        
        names_html.insert(0, f"<tr><td><b>Sides</b></td><td><b>Name</b></td></tr>")
        names_html = "".join(names_html)
        names_html = f"<table>{names_html}</table>"
        return names_html
    
    
    def _plot_regular_polygon(self, **kwargs):
        try:
            side_counts = kwargs.get('side_counts', False)
            labelled = kwargs.get('labelled', False)
            label_side_count = kwargs.get('label_side_count', False)
            draw_radii = kwargs.get('draw_radii', False)
            
            plt.ioff()
     
            plotter = Plotter2D(verbose = self.verbose)
            
            names = plotter.get_regular_polygon_names()
            
            polygon_count = len(side_counts)
            
            names = {k:v for k, v in names.items() if k in side_counts}
            
            col_count = polygon_count
            row_count = 1
            fig = plt.figure(figsize=(9, polygon_count * col_count))
            gs = fig.add_gridspec(row_count, polygon_count)
            
            row_id = 0
            for col_id, side_count in enumerate(side_counts):
                polygon_name = names[side_count]
                ax = fig.add_subplot(gs[row_id, col_id])
                plotter.plot_regular_polygon(side_count, 
                                             auto_rotate = True, 
                                             label_side_count = label_side_count,
                                             draw_radii = draw_radii,
                                             ax = ax)
                ax.axis('off')
                
                if labelled:
                    ax.set_title(polygon_name, fontsize = 8)
                pass
                            
            svgHelper = SvgHelper()
            svg_str = svgHelper.plt_to_svg()
            
            result = {
                'svg_str': svg_str,
                }
            
            return result
        except Exception as e:
            sError = f"""{inspect.stack()[0][3]} Error: {e}:
            kwargs = {kwargs}
            """
            self._log(sError)
            self._log(traceback.format_exc())
            return None
        pass
    
    def _get_cache_or_plot(self,
                            calling_method = None,
                            method_to_call = None,
                            **kwargs
                           ):

        try:
            use_cache = kwargs.get('use_cache', True)
            verbose = self.verbose
    
            self.cacheUtil = CacheUtil(use_cache = use_cache, verbose = verbose)
            
            cache_file_path, exists_cached_file = self.cacheUtil.get_cached_path(
                    self.__class__, calling_method,
                    kwargs,
                    file_prefix = f"{self.__class__.__name__}_{calling_method}_",
                    )
            
            if use_cache and exists_cached_file:
                return self.cacheUtil.load_file(cache_file_path)
            
            svg_str = method_to_call(**kwargs)
            if svg_str is None:
                print(f"Error: svg_str is None")
                plt.clf()
                plt.close()
                return None
    
            
            if not svg_str:
                if self.verbose:
                    print(f"Error: svg_str could not be initialized")
            else:
                self.cacheUtil.save_file(svg_str, cache_file_path)
            
            plt.clf()
            plt.close()
            
            return svg_str
        except Exception as e:
            sError = f"""{inspect.stack()[0][3]} Error: {e}:
            calling_method = {calling_method}
            method_to_call = {method_to_call}
            kwargs = {kwargs}
            """
            self._log(sError)
            self._log(traceback.format_exc())
            return None
        pass
    
    pass
#class GeometricalShapeHelper:
