'''
Created on 16-Apr-2021

@author: bthakur

https://faculty.math.illinois.edu/~hildebr/347.summer19/nt1.pdf

'''
import os 
import numpy as np
import random
import inspect
import traceback




from xv.km.kelements import KPrintElement
from sympy import (Symbol, symbols, factor)
from sympy import Rational, latex
from xv.km.util import latex_color
        
from ..helper import BaseHelper
from xv.km.managers import BaseManager
from xv.km.kelements import KProblemTemplate
from xv.util import toIntOrFloat, format_integers

# _fast_calculation_manager
# FastCalculationManager
        
class FastCalculationManager(BaseManager):
    '''
    Fast calculations is arithmetic


    Minimum Grade: 3
    Maximum Grade: 12


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


    ke.printProblem()
    ke.printAnswer()
    ke.printSolution()


    doc_style: xv_doc
    ''' 


    def __new__(cls, *args, **kwargs):
        instance = super(FastCalculationManager, cls).__new__(cls, *args, **kwargs)
        for base_class in FastCalculationManager.__bases__:
            base_class.__init__(instance, *args, **kwargs)
        return instance

    def __init__(self, *args, **kwargs):
        self.base_helper = BaseHelper(**kwargs)
        pass
    

    def _TEMPLATE_FAST_CALCULATION(self, result, **kwargs):
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        problem_s = f"""
        {result['problem_s']}
        """
        problemTemplate.add_problem(problem_s.strip(), 'text/html')
        
        soln_s = f"""
        {result['soln_s']}
        """
        
        problemTemplate.add_solution(soln_s.strip(), 'text/html')
        
        answer_s = f"""
        {result['answer_s']}
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        
        return problemTemplate

    
    def _init_problem_types(self, *args, **kwargs):
        self._append_problem_types([
                '_problem_square_ending_with_5',
                '_problem_multipy_units_sum_10',
                '_problem_multiply_any_two_numbrs',
                '_problem_multipy_number_close_to_round_off',
                '_problem_multipy_both_numbers_close_to_round_off',
                '_problem_multipy_number_with_99',
                '_problem_multipy_number_close_to_100',
                '_problem_square_of_number',
                '_problem_square_root_of_number',
                '_problem_cubic_root_of_number',
                '_problem_divide_or_multiply',
                
             ])
        pass

    def _problem_square_ending_with_5(self, *args, **kwargs):
        """
        doc_style: xv_doc
        """
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_square_ending_with_5()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        pass

    

        
    def _problem_multipy_units_sum_10(self, *args, **kwargs):
        """
        doc_style: xv_doc
        """
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_multipy_units_sum_10()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        pass

    

    def _problem_multiply_any_two_numbrs(self, *args, **kwargs):
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_multiply_any_two_numbrs()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        

    def _problem_multipy_number_close_to_round_off(self, *args, **kwargs):
        """
        doc_style: xv_doc
        """
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_multipy_number_close_to_round_off()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        pass

    


    def _problem_multipy_both_numbers_close_to_round_off(self, *args, **kwargs):
        """
        doc_style: xv_doc
        """
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_multipy_both_numbers_close_to_round_off()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        pass

    

    def _problem_multipy_number_with_99(self, *args, **kwargs):
        """
        doc_style: xv_doc
        """
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_multipy_number_with_99()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        pass

    
    def _problem_multipy_number_close_to_100(self, *args, **kwargs):
        """
        doc_style: xv_doc
        """
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_multipy_number_close_to_100()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        pass

    def _problem_square_of_number(self, *args, **kwargs):
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_square_of_number()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        
        

    def _problem_square_root_of_number(self, *args, **kwargs):
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_square_root_of_number()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        
        
     
    def _problem_cubic_root_of_number(self, *args, **kwargs):
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_cubic_root_of_number()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        
        
    def _problem_divide_or_multiply(self, *args, **kwargs):
        fc_helper = self.base_helper.get_arithmetic_helper().get_fast_calculation_helper()
        result = fc_helper.get_problem_divide_or_multiply()
        
        return self._TEMPLATE_FAST_CALCULATION(result, **kwargs)
        
        

    def _sample(self, *args, **kwargs):
        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        problem_s = f"""
        """
        problemTemplate.add_problem(problem_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/html')
        
        return problemTemplate
        
        
