'''
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



# _calculus_manager
# CalculusManager
        
        
class CalculusManager(BaseManager):
    '''
    CalculusManager



    Examples
    --------
    ke = CalculusManager()
    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(CalculusManager, cls).__new__(cls, *args, **kwargs)
        for base_class in CalculusManager.__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_differentiation_manager',
            '_problem_integration_manager',
            '_problem_differential_equation_manager',
            
            
            '_problem_selected_problems_in_calculus',
            '_problem_short_overview_of_limit',
            '_problem_short_overview_of_continuity',
            '_problem_short_overview_of_differential_calculus',
            '_problem_short_overview_of_integral_calculus',
            
            ])
        pass


    def _problem_differentiation_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 DifferentiationManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"calculus"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.calculus", 
                                                   "DifferentiationManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

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

        pass




    def _problem_integration_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 IntegrationManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"calculus"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.calculus", 
                                                   "IntegrationManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

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

        pass



    def _problem_differential_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 DifferentialEquationManager
        """
        self._log(sInfo.strip())
        
        
        #create notebook
        generate_notebook = kwargs.get('generate_notebook', True)
        
        if generate_notebook:
            saveToFolder = f"calculus"
            KmTemplateUtil.CREATE_MANAGER_NOTEBOOK("xv.math.calculus", 
                                                   "DifferentialEquationManager", 
                                                   saveToFolder = saveToFolder,
                                                   overwrite = False, 
                                                   verbose = self.verbose)

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

        pass




    def _problem_selected_problems_in_calculus(self, *args, **kwargs):
        """
        
        """
        
        folder_path = "question_bank/math/calculus"
        search_file_paths = [
                "selected_problems_in_calculus.txt"
            ]
        
        
        file_paths = self.get_q_bank_factory().search_question_bank_files(folder_path, search_file_paths)
        return self.get_q_bank_factory().PROBLEM_TEMPLATE_Q_BANK_RANDOM_QUESTION(file_paths, *args, **kwargs)




    def _problem_short_overview_of_limit(self, *args, **kwargs):
        folder_path = "comprehension/math/calculus"
        search = 'short_overview_of_limit.txt'
        
        search_in_content = kwargs.get("search", None)
        file_paths = self.get_comp_factory().search_comprehension_files(folder_path,
                                                                        search_in_name = search,
                                                                        search_in_content = search_in_content)

        
        file_path = random.choice(file_paths)
        kwargs['count'] = 1
        return self.get_comp_factory().PROBLEM_TEMPLATE_COMP_RANDOM_QUESTIONS(file_path, *args, **kwargs)



    def _problem_short_overview_of_continuity(self, *args, **kwargs):
        folder_path = "comprehension/math/calculus"
        search = 'short_overview_of_continuity.txt'
        
        search_in_content = kwargs.get("search", None)
        file_paths = self.get_comp_factory().search_comprehension_files(folder_path,
                                                                        search_in_name = search,
                                                                        search_in_content = search_in_content)

        
        file_path = random.choice(file_paths)
        kwargs['count'] = 1
        return self.get_comp_factory().PROBLEM_TEMPLATE_COMP_RANDOM_QUESTIONS(file_path, *args, **kwargs)





    def _problem_short_overview_of_differential_calculus(self, *args, **kwargs):
        folder_path = "comprehension/math/calculus"
        search = 'short_overview_of_differential_calculus.txt'
        
        search_in_content = kwargs.get("search", None)
        file_paths = self.get_comp_factory().search_comprehension_files(folder_path,
                                                                        search_in_name = search,
                                                                        search_in_content = search_in_content)

        
        file_path = random.choice(file_paths)
        kwargs['count'] = 1
        return self.get_comp_factory().PROBLEM_TEMPLATE_COMP_RANDOM_QUESTIONS(file_path, *args, **kwargs)





    def _problem_short_overview_of_integral_calculus(self, *args, **kwargs):
        folder_path = "comprehension/math/calculus"
        search = 'short_overview_of_integral_calculus.txt'
        
        search_in_content = kwargs.get("search", None)
        file_paths = self.get_comp_factory().search_comprehension_files(folder_path,
                                                                        search_in_name = search,
                                                                        search_in_content = search_in_content)

        
        file_path = random.choice(file_paths)
        kwargs['count'] = 1
        return self.get_comp_factory().PROBLEM_TEMPLATE_COMP_RANDOM_QUESTIONS(file_path, *args, **kwargs)




