'''
Created on 16-Apr-2021

@author: rishi_priyansh

'''
from sympy import symbols, Eq, solve, Symbol, latex, sqrt, UnevaluatedExpr
from xv.km.ui import SvgHelper  
import matplotlib.pyplot as plt

import random
import inspect
import traceback

from ..helper import BaseHelper

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


# QuantumAtomicModelManager
# _quantum_atomic_model_manager

class QuantumAtomicModelManager(BaseManager):
    '''
    QuantumAtomicModelManager
    Example:
        ke = QuantumAtomicModelManager()
        ke.getRandomProblem()
        ke.getRandomProblem(problem_type = 0)
        ...
        
        ke.printProblem()
        ke.printAnswer()
        ke.printSolution()
        
        ke.printProblemTypes()
        
    '''    
    _OPR_TYPE_COUNT = 10
    
    def __new__(cls, *args, **kwargs):
        instance = super(QuantumAtomicModelManager, cls).__new__(cls, *args, **kwargs)
        for base_class in QuantumAtomicModelManager.__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_basic_concepts_overview',
            '_problem_bohr_radius',
            '_problem_lowest_mechanical_energy_of_electron',
            '_problem_derive_probability_of_ground_state_schrodinger_wavefunction',
            '_problem_derive_maximum_of_radial_probability_function',
            '_problem_derive_expected_value_of_radial_probability_function',
            '_problem_expected_value_potential_energy_of_ground_state_schrodinger_wavefunction',
            '_problem_derive_probability_of_momentum_space_ground_state_schrodinger_wavefunction',
            '_problem_derive_expected_value_of_radial_momentum_probability_function',
            '_problem_derive_expected_value_of_radial_momentum_probability_function_squared',
            '_problem_expected_value_kinetic_energy_of_ground_state_schrodinger_wavefunction',
            '_problem_expected_value_total_energy_of_ground_state_schrodinger_wavefunction',

            ])
        pass
    
    def _problem_basic_concepts_overview(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_basic_concepts_overview(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_bohr_radius(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_bohr_radius(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_lowest_mechanical_energy_of_electron(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_lowest_mechanical_energy_of_electron(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_derive_probability_of_ground_state_schrodinger_wavefunction(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_derive_probability_of_ground_state_schrodinger_wavefunction(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_derive_maximum_of_radial_probability_function(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_derive_maximum_of_radial_probability_function(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_derive_expected_value_of_radial_probability_function(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_derive_expected_value_of_radial_probability_function(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_expected_value_potential_energy_of_ground_state_schrodinger_wavefunction(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_expected_value_potential_energy_of_ground_state_schrodinger_wavefunction(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_derive_probability_of_momentum_space_ground_state_schrodinger_wavefunction(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_derive_probability_of_momentum_space_ground_state_schrodinger_wavefunction(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_derive_expected_value_of_radial_momentum_probability_function(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_derive_expected_value_of_radial_momentum_probability_function(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_derive_expected_value_of_radial_momentum_probability_function_squared(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_derive_expected_value_of_radial_momentum_probability_function_squared(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_expected_value_kinetic_energy_of_ground_state_schrodinger_wavefunction(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_expected_value_kinetic_energy_of_ground_state_schrodinger_wavefunction(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    def _problem_expected_value_total_energy_of_ground_state_schrodinger_wavefunction(self, *args, **kwargs):
        """
        """

        qam_helper = self.base_helper.get_quantum_atomic_model_helper()

        result = qam_helper.get_problem_expected_value_total_energy_of_ground_state_schrodinger_wavefunction(**kwargs)

        problemTemplate = KProblemTemplate()
        problemTemplate.problem_type = kwargs.get('problem_type')

        prob_s = f"""
        {result['prob_s'].strip()}
        """
        problemTemplate.add_problem(prob_s.strip(), 'text/html')

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

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

        return problemTemplate
        pass

    
    