'''
Created on 02-Mar-2021

@author: bthakur
'''
'''
Created on 07-Feb-2021

@author: bthakur
'''
import numpy as np
import random
import inspect
import traceback

from sympy import (simplify, sympify, log, latex, Symbol, symbols, 
                   UnevaluatedExpr as ueval)

from xv.km.util import latex_fraction
from xv.km.kelements import KPrintElement
        
from ..helper import BaseHelper
from xv.km.managers import BaseManager
from xv.km.kelements import KProblemTemplate

# _grade11_manager
# Grade11Manager
        
class Grade11Manager(BaseManager):
    '''
    LCM
    Example:
        ke = Grade11Manager()
        ke.getRandomProblem()
        ke.getRandomProblem(problem_type = 0)
        ke.getRandomProblem(problem_type = 1)
        ...
        ke.printProblem()
        ke.printAnswer()
        ke.printSolution()

        ke.printProblemTypes()
    '''    
    def __new__(cls, *args, **kwargs):
        instance = super(Grade11Manager, cls).__new__(cls, *args, **kwargs)
        for base_class in Grade11Manager.__bases__:
            base_class.__init__(instance, *args, **kwargs)
        return instance
    
    def __init__(self, *args, **kwargs):
        self.base_helper = BaseHelper(**kwargs)
        pass

    def _TEMPLATE_CUSTOM_QUESTIONS(self, keywords, **kwargs):
        
        from ..storeddata import Grade11StoredQuestions
        
        stored_questions = Grade11StoredQuestions(verbose = self.verbose)
        result = stored_questions.get_random_question(keywords)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')
        
        if result is None:
            prob_s = f"""
            Failed to get questions
            keywords = {keywords}
            """
            problemTemplate.add_problem(prob_s.strip(), 'text/html')
            return problemTemplate
            
        
        prob_s = f"""
        {result['prob_s']}
        """
        problemTemplate.add_problem(prob_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
        pass

    def _init_problem_types(self, *args, **kwargs):
        self._append_problem_types([
            '_problem_custom_questions_complex_number',
            '_problem_custom_questions_function_domain',
            '_problem_custom_questions_circle_equation',
            '_problem_custom_questions_set_natural_integer',
            '_problem_custom_questions_limit_derivative',
            '_problem_custom_questions_function_input',
            '_problem_custom_questions_formula_of_arithmetic_sequence',
            '_problem_custom_questions_graph_circle',
            '_problem_custom_questions_trignometric_values',
            '_problem_custom_questions_set_domain',
            '_problem_custom_questions_derivative',
            '_problem_custom_questions_set_relation',
            '_problem_custom_questions_mean_absolute_deviation',
            '_problem_custom_questions_limit',
            '_problem_custom_questions_combination',
            '_problem_custom_questions_step_differentiation',
            '_problem_custom_questions_explicit_formula',
            '_problem_custom_questions_complex_division',
            '_problem_custom_questions_word_problem',
            '_problem_custom_questions_line_equation_from_points',
            '_problem_custom_questions_foci_ellipse',
            '_problem_custom_questions_cartesian_product',
            '_problem_custom_questions_inequality',
            '_problem_custom_questions_slope_between_points',
            '_problem_custom_questions_limit_1',
            '_problem_custom_questions_ellipse_equation',

                    
         ]) 
        pass

    def _problem_custom_questions_complex_number(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'complex_number')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_function_domain(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'function_domain')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_circle_equation(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'circle_equation')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_set_natural_integer(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'set_natural_integer')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_limit_derivative(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'limit_derivative')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_function_input(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'function_input')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_formula_of_arithmetic_sequence(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'formula_of_arithmetic_sequence')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_graph_circle(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'graph_circle')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_trignometric_values(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'trignometric_values')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_set_domain(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'set_domain')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_derivative(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'derivative')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_set_relation(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'set_relation')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_mean_absolute_deviation(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'mean_absolute_deviation')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_limit(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'limit')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_combination(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'combination')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_step_differentiation(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'step_differentiation')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_explicit_formula(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'explicit_formula')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_complex_division(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'complex_division')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_word_problem(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'word_problem')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_line_equation_from_points(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'line_equation_from_points')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_foci_ellipse(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'foci_ellipse')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_cartesian_product(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'cartesian_product')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_inequality(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'inequality')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_slope_between_points(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'slope_between_points')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_limit_1(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'limit_1')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)

    def _problem_custom_questions_ellipse_equation(self, *args, **kwargs):
        keywords = kwargs.get('keywords', 'ellipse_equation')
        return self._TEMPLATE_CUSTOM_QUESTIONS(keywords, **kwargs)



