'''
Created on 20-Jan-2022

@author: bthakur
'''

import inspect
import traceback
import random
import numpy as np
import sympy as sp

from sympy import (latex, Symbol, symbols,
                    Rational,
                    sin, cos, tan,
                    asin, acos, atan,
                    sinh, cosh, tanh,
                    log, exp, sqrt,
                   diff, factor, 
                   Function, Eq,
                   Add, 
                   simplify, solve, factorial,
                   Sum, binomial, pi
                   )


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 xv.plotter.core import Plotter2D, Plotter3D

from xv.util import UtilClass, toIntOrFloat
from xv.km.kelements import KTransformer


# _volume_helper
# VolumeHelper

class VolumeHelper(UtilClass):
    _MAIN_OPACITY = 0.6
    _SUB_OPACITY = 0.1
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        pass

    def get_problem_calc_volume_of_mixed_objects(self, index = None, **kwargs):
        sInfo = f"""Info: {self.__class__.__name__}.{inspect.stack()[0][3]}
        """
        self._log(sInfo)
        
        if index is None:
            indexes = list(range(1, 3))
            identifier = f"{self.__class__.__name__}{id(self)}.{inspect.stack()[0][3]}"
            index = self.get_no_repeat_random_choice(identifier, indexes)
        
        if index == 1:
            return self._calc_volume_of_mixed_objects_type_one(**kwargs)
        
        if index == 2:
            return self._calc_volume_regular_octagons(**kwargs)
        
        return self._calc_volume_regular_octagons(**kwargs)
        pass

    def _calc_volume_of_mixed_objects_type_one(self, **kwargs):
        sInfo = f"""Info: {self.__class__.__name__}.{inspect.stack()[0][3]}
        """
        self._log(sInfo)

        k_transformer = KTransformer()
        image_s = "see image::/images/math/volume_area_manager_volume_of_mixed_objects.png"
        image_s = k_transformer.get_img_str(image_s.strip(), verbose = True)
        
        prob_s = f"""
        Derive the volume of the object
        <br/>
        {image_s}
        <br/>
        """
        
        soln_stmts = []
        
        r = Symbol('r')
        h_cylinder = Symbol("h_{{cylinder}}")
        h_cone = Symbol("h_{{cone}}")
        
        v_val_symb = Symbol(f"""
          {latex(Rational(1, 2))} \\cdot {latex(Rational(4, 3))} {latex(sp.pi)} {latex(r ** 3)}
          + {latex(sp.pi)} {latex(r ** 2)} {latex(h_cylinder)}
          + {latex(Rational(1, 3))} {latex(sp.pi)} {latex(r ** 2)} {latex(h_cone)}        
        """.replace("\n", " "))
        
        
        soln_stmt = f"""
        Volume of the object 
        
        $\\displaystyle 
        \\begin {{aligned}}
        
        & = \\text{{ volume of semi-sphere }}
          + \\text{{ volume of cylinder }}
          + \\text{{ volume of cone }}
        \\\\ \\\\
        
        & = {latex(v_val_symb)}
        \\\\ \\\\
        
        \\end {{aligned}}
        $
        
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_s = "\n\n".join(soln_stmts)
        
        answer_s = f"""
        $\\displaystyle 
        {latex(v_val_symb)}
        $
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        
        return result
        pass

    
    def _calc_volume_regular_octagons(self, **kwargs):
        sInfo = f"""Info: {self.__class__.__name__}.{inspect.stack()[0][3]}
        """
        self._log(sInfo)

        k_transformer = KTransformer()
        image_s = "see image::/images/math/volume_area_manager__calc_volume_regular_octagons.png"
        image_s = k_transformer.get_img_str(image_s.strip(), verbose = True)
        
        image_soln_s = "see image::/images/math/volume_area_manager__calc_volume_regular_octagons_soln.png"
        image_soln_s = k_transformer.get_img_str(image_soln_s.strip(), verbose = True)
        
        prob_s = f"""
        Corners are sliced off a unit cube so that the six faces each become regular octagons. 
        What is the total volume of the removed tetrahedra? 
        """
        
        soln_stmts = []
        
        r = Symbol('r')
        x = Symbol('x')
        y = Symbol('y')
        z = Symbol('z')
        
        eq = Eq(2 * r * sp.sqrt(2) + r, 1)
        r_val = sp.solve(eq, r)[0]
        
        soln_stmt = f"""
        {image_s}
        <br/>
        
        The side of the unit cube is $1
        $ and let us assume that the side of the regular octagons is ${latex(r)}$. 
        
        The projection of r shown in the image above on the side of cube is $
        {latex(r)} = {latex(x * sp.sqrt(2))} 
        $
        """
        soln_stmts.append(soln_stmt.strip())

        
        
        soln_stmt = f"""
        {image_soln_s}
        
        Therefore, 
        $\\displaystyle 
        \\begin {{aligned}}
        
        & {latex(x)} 
        + {latex(r)} 
        + {latex(x)} 
        = 1
        \\\\ \\\\
        
        \\implies
        {latex(x)} \\left(
            2 + {latex(sp.sqrt(2))}
        \\right)
        = 1
        \\\\ \\\\
        
        \\implies
        {latex(x)} 
        = \\frac{{ 1 }} {{ 2 + {latex(sp.sqrt(2))} }} 
        \\\\ \\\\
        
        \\implies
        {latex(x)} 
        = \\frac{{ 2 - {latex(sp.sqrt(2))}  }} {{ 2 }} 
        \\\\ \\\\
        
        \\end {{aligned}}
        $
        """
        soln_stmts.append(soln_stmt.strip())
        

        x_val = (2 - sp.sqrt(2)) / 2
        x_val_symb = Symbol(f""" \\left( \\frac{{ 2 - {latex(sp.sqrt(2))}  }} {{ 2 }} \\right) """)
        
        V_val = Rational(8, 6) * x_val ** 3
        V_val = V_val.simplify()
        
        soln_stmt = f"""
        Volume of all corners 
        $\\displaystyle 
        \\begin {{aligned}}
        
        & = 8 \\text{{ (volume of each corner) }}
        \\\\ \\\\
        
        & = 8 \\cdot {latex(Rational(1, 6))} 
        \\cdot {latex(x)} 
        \\cdot {latex(y)} 
        \\cdot {latex(z)} 
        \\\\ \\\\
        
        & = 8 \\cdot {latex(Rational(1, 6))} 
        \\cdot {latex(x ** 3)} 
        \\\\ \\\\
        
        & = 8 \\cdot {latex(Rational(1, 6))} 
        \\cdot {latex(x_val_symb ** 3)} 
        \\\\ \\\\
        
        & = {latex(V_val)}
        
        \\end {{aligned}}
        $
        """
        soln_stmts.append(soln_stmt.strip())
        
        
        soln_s = "\n\n".join(soln_stmts)
        
        answer_s = f"""
        $\\displaystyle 
        {latex(V_val)}
        $
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        
        return result
        pass

    
    pass
#class VolumeHelper:
