'''
Created on 19-Apr-2024

@author: bthakur
'''
import random
import inspect
import traceback
import re

from sympy import (symbols, Symbol, limit, latex, Function,
                   Limit, oo, Derivative, simplify,
                   Eq,
                   Derivative, Integral,
                   exp, log, expand_log,
                   Mul, Add, Pow, UnevaluatedExpr,
                   Sum, binomial, factorial, Rational, 
                   UnevaluatedExpr as ueval
                   )

from sympy import (sin, cos, tan, cot, sec, csc,
                   asin, acos, atan, acot, asec, acsc,
                   sinh, cosh, tanh, coth, sech, csch,
                   asinh, acosh, atanh, acoth, asech, acsch,
                   )

import sympy as sp        

from xv.km.util import latex_fraction
from xv.util import UtilClass

# _std_integration_base_helper
# StdIntegrationBaseHelper


class StdIntegrationBaseHelper(UtilClass):
    '''
    '''    

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        
        self.x = Symbol('x')
        self.y = Symbol('y')
        
        self.f = Function('f')(self.x)
        self.F = Function('F')(self.x)
        
        self.f_prime = Function(f"{latex(self.f)}'")(self.x)
        self.F_prime = Function(f"{latex(self.F)}'")(self.x)
        
        self.df = Symbol(f"d{latex(self.f)}")
        self.dF = Symbol(f"d{latex(self.F)}")
        
        self.dx = Symbol(f"d{latex(self.x)}")
        
        self.n = Symbol('n', real = True)
        self.C = Symbol('C', real = True)

        self.a = Symbol('a', real = True, positive = True)
        self.b = Symbol('b', real = True, positive = True)
        
        self._kwargs = kwargs
        
        self._std_integration_by_reversal_helper = None
        self._std_integration_by_parts_helper = None
        self._std_integration_by_subs_helper = None
        
        pass

    
    def _get_linear_x_func(self, x = None):
        if x is None:
            x = self.x
        a = self.a
        b = self.b
        
        linear_x_funcs = [
            x,
            a * x,
            a * x + b,
            a * x - b,
            x / a - b,
            x / a,
            ]
        
        return random.choice(linear_x_funcs)
        pass


    def get_std_integration_by_reversal_helper(self):
        if self._std_integration_by_reversal_helper is None:
            self._init_std_integration_by_reversal_helper(**self._kwargs)
        return self._std_integration_by_reversal_helper
        pass

    def _init_std_integration_by_reversal_helper(self, **kwargs):  
        from ._std_integration_by_reversal_helper import StdIntegrationByReversalHelper
        self._std_integration_by_reversal_helper = StdIntegrationByReversalHelper(**kwargs) 
        pass
   
  


    def get_std_integration_by_parts_helper(self):
        if self._std_integration_by_parts_helper is None:
            self._init_std_integration_by_parts_helper(**self._kwargs)
        return self._std_integration_by_parts_helper
        pass

    def _init_std_integration_by_parts_helper(self, **kwargs):  
        from ._std_integration_by_parts_helper import StdIntegrationByPartsHelper
        self._std_integration_by_parts_helper = StdIntegrationByPartsHelper(**kwargs) 
        pass
   
  


    def get_std_integration_by_subs_helper(self):
        if self._std_integration_by_subs_helper is None:
            self._init_std_integration_by_subs_helper(**self._kwargs)
        return self._std_integration_by_subs_helper
        pass

    def _init_std_integration_by_subs_helper(self, **kwargs):  
        from ._std_integration_by_subs_helper import StdIntegrationBySubsHelper
        self._std_integration_by_subs_helper = StdIntegrationBySubsHelper(**kwargs) 
        pass
   
  

    
        
    pass
#class StdIntegrationBaseHelper:
