'''
Created on 14-Oct-2024
@author: bthakur
'''

import random
import inspect
import traceback


from xv.km.util import latex_fraction

        
from ..helper import BaseHelper
from xv.km.managers import BaseManager
from xv.km.kelements import KProblemTemplate

from xv.km.util import KmTemplateUtil



# _algebra_manager
# AlgebraManager
        
        
class AlgebraManager(BaseManager):
    '''
    AlgebraManager



    Examples
    --------
    ke = AlgebraManager()
    ke 
    
    ke.printProblemTypes()
    ke.helpProblemType(0)
    
    ke.getRandomProblem()
    ke.getRandomProblem(problem_type = 0)


    ke.printAnswer()
    ke.printSolution()
    

    doc_style: xv_doc
    ''' 

    
    
    def __new__(cls, *args, **kwargs):
        instance = super(AlgebraManager, cls).__new__(cls, *args, **kwargs)
        for base_class in AlgebraManager.__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_algebric_expression_manager',
            '_problem_binomial_manager',
            '_problem_complex_number_manager',
            '_problem_func_manager',
            '_problem_func_transform_manager',
            '_problem_gamma_func_manager',
            '_problem_law_of_proportion_manager',
            '_problem_linear_equation_manager',
            '_problem_linear_equations_advanced_manager',
            '_problem_laplace_transform_manager',
            '_problem_multinomial_manager',
            '_problem_matrix_manager',
            '_problem_multi_variable_manager',
            '_problem_polynomial_manager',
            '_problem_set_theory_manager',
            '_problem_single_variable_manager',
            '_problem_single_variate_first_order',
            '_problem_rational_number_line_manager',
            '_problem_rational_number_manager',            
            
            ])
        pass




    def _problem_algebric_expression_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from AlgebricExpressionManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "AlgebricExpressionManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import AlgebricExpressionManager
        kwargs['manager_class'] = AlgebricExpressionManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_binomial_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from BinomialManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "BinomialManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import BinomialManager
        kwargs['manager_class'] = BinomialManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_complex_number_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from ComplexNumberManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "ComplexNumberManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import ComplexNumberManager
        kwargs['manager_class'] = ComplexNumberManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_func_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from FuncManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "FuncManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import FuncManager
        kwargs['manager_class'] = FuncManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_func_transform_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from FuncTransformManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "FuncTransformManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import FuncTransformManager
        kwargs['manager_class'] = FuncTransformManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_gamma_func_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from GammaFuncManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "GammaFuncManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import GammaFuncManager
        kwargs['manager_class'] = GammaFuncManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_law_of_proportion_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from LawOfProportionManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "LawOfProportionManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import LawOfProportionManager
        kwargs['manager_class'] = LawOfProportionManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_linear_equation_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from LinearEquationManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "LinearEquationManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import LinearEquationManager
        kwargs['manager_class'] = LinearEquationManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_linear_equations_advanced_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from LinearEquationsAdvancedManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "LinearEquationsAdvancedManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import LinearEquationsAdvancedManager
        kwargs['manager_class'] = LinearEquationsAdvancedManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_laplace_transform_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from LaplaceTransformManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "LaplaceTransformManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import LaplaceTransformManager
        kwargs['manager_class'] = LaplaceTransformManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_multinomial_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from MultinomialManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "MultinomialManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import MultinomialManager
        kwargs['manager_class'] = MultinomialManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_matrix_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from MatrixManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "MatrixManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import MatrixManager
        kwargs['manager_class'] = MatrixManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_multi_variable_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from MultiVariableManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "MultiVariableManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import MultiVariableManager
        kwargs['manager_class'] = MultiVariableManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_polynomial_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from PolynomialManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "PolynomialManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import PolynomialManager
        kwargs['manager_class'] = PolynomialManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_set_theory_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from SetTheoryManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "SetTheoryManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import SetTheoryManager
        kwargs['manager_class'] = SetTheoryManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_single_variable_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from SingleVariableManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "SingleVariableManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import SingleVariableManager
        kwargs['manager_class'] = SingleVariableManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_single_variate_first_order(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from SingleVariateFirstOrder
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "SingleVariateFirstOrder", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import SingleVariateFirstOrder
        kwargs['manager_class'] = SingleVariateFirstOrder
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_rational_number_line_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from RationalNumberLineManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "RationalNumberLineManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import RationalNumberLineManager
        kwargs['manager_class'] = RationalNumberLineManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass




    def _problem_rational_number_manager(self, *args, **kwargs):
        """
        @generate_notebook: Default True

        doc_style: xv_doc
        """

        sInfo = f"""Processing {self.__class__.__name__}.{inspect.stack()[0][3]}: 
        creating notebook and getting problem from RationalNumberManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"algebra"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.algebra", 
                                                   "RationalNumberManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

        #get a problem        
        from xv.math.algebra import RationalNumberManager
        kwargs['manager_class'] = RationalNumberManager
        kwargs['problem_type'] = None
        kwargs['generate_notebook'] = False
        problemTemplate = self._get_problem_from_a_manager(*args, **kwargs)
        return problemTemplate

        pass

