'''
Created on 16-Apr-2021

@author: rishi_priyansh
'''
from sympy import symbols, Eq, solve, Symbol, latex, sqrt, UnevaluatedExpr
from xv.km.ui import SvgHelper  
import matplotlib.pyplot as plt

import random
import inspect
import traceback

from ..helper import BaseHelper

from xv.km.managers import BaseManager
from xv.km.kelements import KProblemTemplate
from xv.util import list_to_str
        
# _diff_eq_manager
# DiffEqManager   
class DiffEqManager(BaseManager):
    '''
    DiffEqManager
    Example:
        ke = DiffEqManager()
        ke.getRandomProblem()
        ke.getRandomProblem(problem_type = 0)
        ...
        
        ke.printProblem()
        ke.printAnswer()
        ke.printSolution()
        
        ke.printProblemTypes()
        
    '''    
    _OPR_TYPE_COUNT = 10
    
    def __new__(cls, *args, **kwargs):
        instance = super(DiffEqManager, cls).__new__(cls, *args, **kwargs)
        for base_class in DiffEqManager.__bases__:
            base_class.__init__(instance, *args, **kwargs)
        return instance
    
    def __init__(self, *args, **kwargs):
        self.base_helper = BaseHelper(**kwargs)
        pass

    def _init_problem_types(self, *args, **kwargs):
        self._append_problem_types([
            '_problem_second_degree_diff_eq',
            '_problem_generat_x_t_equation',
            '_problem_heat_equation',
            '_problem_wave_equation',
            '_problem_laplace_equation',
            
            ])
        pass

    def _problem_second_degree_diff_eq(self, *args, **kwargs):
        de_helper = self.base_helper.get_diff_eq_helper()

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        
        problem_s = r"""
        Deduce a expression for $f^{\prime \prime}(x)$?
        """
        problemTemplate.add_problem(problem_s.strip(), "text/html")
        
        soln_s = r"""
        $$
        f^{\prime \prime}(x)=\lim _{h \rightarrow 0} \frac{f^{\prime}(x+h)-f^{\prime}(x)}{h}=\lim _{h \rightarrow 0} \frac{f^{\prime}(x)-f^{\prime}(x-h)}{h} .
        $$
        We use the second limit. Approximate $f^{\prime}(x)$ and $f^{\prime}(x-h)$ using
        $$
        f^{\prime}(x)=\lim _{h \rightarrow 0} \frac{f(x+h)-f(x)}{h}
        $$
        and
        $$
        f^{\prime}(x-h)=\lim _{h \rightarrow 0} \frac{f(x)-f(x-h)}{h} .
        $$
        Substitute the approximations into Eq. (3) to get
        
        $$
        \begin{aligned}
        f^{\prime \prime}(x) & \approx \frac{\frac{f(x+h)-f(x)}{h}-\frac{f(x)-f(x-h)}{h}}{h}=\frac{f(x+h)-2 f(x)+f(x-h)}{h^{2}} \\
        &=\frac{2}{h^{2}}\left\{\frac{1}{2}[f(x+h)+f(x-h)]-f(x)\right\} .
        \end{aligned}
        $$        
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = r"""
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/plane')
        return problemTemplate
    
    
    def _problem_generat_x_t_equation(self, *args, **kwargs):
        de_helper = self.base_helper.get_diff_eq_helper()

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        
        problem_s = r"""
        $$
        A \frac{\partial^{2} u(t, x)}{\partial t^{2}}+B \frac{\partial^{2} u(t, x)}{\partial x \partial t}+C \frac{\partial^{2} u(t, x)}{\partial x^{2}}=0
        $$
        """
        problemTemplate.add_problem(problem_s.strip(), "text/html")
        
        soln_s = """
        $$
        A \frac{\partial^{2} u(t, x)}{\partial t^{2}}+B \frac{\partial^{2} u(t, x)}{\partial x \partial t}+C \frac{\partial^{2} u(t, x)}{\partial x^{2}}=0
        $$
        because by a linear transformation of variables, any equation of the form o can be transformed into one of the three equations. We show at the end of the that the transformation is exactly the same as transforming an equation of
        $$
        A x^{2}+B x y+C y^{2}=0
        $$
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/plane')
        return problemTemplate
    
    def _problem_heat_equation(self, *args, **kwargs):
        de_helper = self.base_helper.get_diff_eq_helper()

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        
        problem_s = r"""
        The heat equation
        $$
        \frac{\partial u(t, \widehat{x})}{\partial t}=\kappa \Delta u(t, \widehat{x})
        $$
        """
        problemTemplate.add_problem(problem_s.strip(), "text/html")
        
        soln_s = f"""
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        

        soln_s = f"""
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/plane')
        return problemTemplate
    
    def _problem_wave_equation(self, *args, **kwargs):
        de_helper = self.base_helper.get_diff_eq_helper()

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        
        problem_s = r"""
        Wave equation
        $$
        \frac{\partial^{2} u(t, \widehat{x})}{\partial t^{2}}=\alpha^{2} \Delta u(t, \widehat{x})
        $$
        """
        problemTemplate.add_problem(problem_s.strip(), "text/html")
        
        soln_s = f"""
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        

        soln_s = f"""
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/plane')
        return problemTemplate
    
    def _problem_laplace_equation(self, *args, **kwargs):
        de_helper = self.base_helper.get_diff_eq_helper()

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        
        problem_s = r"""
        Laplace's equation
        $$
        \Delta u(x, y)=0 .
        $$
        """
        problemTemplate.add_problem(problem_s.strip(), "text/html")
        
        soln_s = f"""
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        

        soln_s = f"""
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/plane')
        return problemTemplate
    

    pass

