'''
Created on 10-May-2021

@author: bthakur

'''
import traceback
import inspect
import sympy
from sympy import (symbols, latex, sympify, Eq
                   )
class LatexEquation:
    @classmethod
    def from_eq(cls, eq, var_names = {}, **kwargs):
        return LatexEquation(latex(eq.lhs), latex(eq.rhs), 
                             eq = eq, 
                             var_names = var_names,
                             **kwargs)
        pass
    
    def __init__(self, lhs, rhs, eq = None, var_names = {}, **kwargs):
        '''
        Mandatory parameters:
        :lhs # latex expression of lhs of LatexEquation
        :rhs # latex expression of rhs of LatexEquation
        
        Default parameters:
        :eq = None  # if None, Eq(lhs, rhs)
        :verbose = False
        :to_latex = False # lhs and rhs should be converted to latex or not
        :desc = {} #it must be a dict describing various members/symbols of this object 
        :var_names = {} #it must be a dict describing various symbols
        '''
        self.verbose = kwargs.get('verbose', False)
        to_latex = kwargs.get('to_latex', False)
        if not to_latex:
            self.lhs = f"{lhs}"
            self.rhs = f"{rhs}"
            

        else:
            self.lhs = latex(lhs)
            self.rhs = latex(rhs)
            

        
        self.eq = self._init_eq(eq)
        
        self.desc = kwargs.get('desc', {})
        self.var_names = var_names
        pass
    
    def _init_eq(self, eq):
        try:
            if not eq is None:
                if not isinstance(eq, Eq):
                    raise Exception(f"Invalid type {type(eq)}")
                return eq
                
            lhs = sympify(self.lhs, evaluate = False)    
            rhs = sympify(self.rhs, evaluate = False)    
            return Eq(lhs, rhs)
            pass
        except Exception as e:
            sError = f"""{inspect.stack()[0][3]} Error: {e}
            eq: {eq}
            lhs: {self.lhs}
            rhs: {self.rhs}
            """
            if self.verbose:
                print(sError)
                print(traceback.format_exc())
        
        return None
        pass
    
    def _repr_html_(self):
        #print("_repr_html_")
        
        s = f"""${self.lhs}$ = ${self.rhs}$"""
        return s
        pass

    def _repr_latex_(self):
        #print("_repr_latex_")
        
        s = f"""${self.lhs}$ = ${self.rhs}$"""
        return s
        pass

    def __str__(self):
        #print("__str__")
        
        s = f"""{self.lhs} = {self.rhs}"""
        return s
        pass

    pass

#class LatexEquation:
    
class LatexEquation_WORK_IN_PROGRESS(Eq):
    @classmethod
    def from_eq(cls, eq):
        return LatexEquation(latex(eq.lhs), latex(eq.rhs), eq)
        pass
    def __new__(cls, lhs, rhs, eq = None, **kwargs):
        options = kwargs.copy()
        if 'verbose' in kwargs.keys():
            del options['verbose']
        
        if not eq is None:
            instance = super(Eq, cls).__new__(cls, eq.lhs, rhs = eq.rhs, **options)
        else:
            lhs = sympify(lhs, evaluate = False)    
            rhs = sympify(rhs, evaluate = False)    
            instance = super(Eq, cls).__new__(cls, lhs, rhs = rhs, **options)
        return instance
 
    def __init__(self, lhs, rhs, eq = None, **kwargs):
        self.verbose = kwargs.get('verbose', False)
        pass  

    def _repr_html_(self):
        s = f"""${self.lhs} = {self.rhs}$"""
        return s
        pass

    def _repr_latex_(self):
        s = f"""${self.lhs} = {self.rhs}$"""
        return s
        pass

    def __str__(self):
        s = f"""${self.lhs} = {self.rhs}$"""
        return s
        pass

    pass

    
