'''
Created on 16-Apr-2021

@author: rishi_priyansh
'''
import os 
import numpy as np
import random
import inspect
import traceback

from xv.km.ui import SvgHelper         
from ..helper import BaseHelper

from xv.km.managers import BaseManager
from xv.km.kelements import KProblemTemplate
        
class FieldManager(BaseManager):
    '''
    Circle and its geometry
    Example:
        ke = FieldManager()
        ke
        
        ke.printProblemTypes()
        
        ke.getRandomProblem()
        ke.getRandomProblem(problem_type = 0)
        ke.getRandomProblem(problem_type = 1)
        ...
        
        ke.printProblem()
        ke.printAnswer()
        ke.printSolution()
        
        ke.printLength(2, 5, 3, -1)
        ke.printMovementLengths()        
        
        
    '''    
    def __new__(cls, *args, **kwargs):
        instance = super(FieldManager, cls).__new__(cls, *args, **kwargs)
        for base_class in FieldManager.__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_field_of_a_force',
         ])
        pass


    def _problem_field_of_a_force(self, *args, **kwargs):
        ffh = self.base_helper.get_force_field_helper()

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

        problem_s = f"""
        Find the field of a gravitational/electric/magnetic force.
        
        """
        problemTemplate.add_problem(problem_s.strip(), 'text/html')
        
        soln_s = r"""
        <h2>Work</h2>
        Work is dependent on the displacement as well as the force acting on an object. As a particle moves through a force field along a path C, the work done by the force is a line integral

        $$W=\int_{C} \vec{F} \cdot d \vec{r}$$
        
        $$\vec{F}=-\nabla \phi$$
        
        
        <h2>Gradient field in euclidean spaces</h2>

        A vector field $V$ defined on an open set $S$ is called a gradient field or a conservative field if there exists a real-valued function (a scalar field) $f$ on $S$ such that
        $$
        V=\nabla f=\left(\frac{\partial f}{\partial x_{1}}, \frac{\partial f}{\partial x_{2}}, \frac{\partial f}{\partial x_{3}}, \ldots, \frac{\partial f}{\partial x_{n}}\right)
        $$
        The associated flow is called the gradient flow, and is used in the method of gradient descent.
        The path integral along any closed curve $\gamma(\gamma(0)=\gamma(1))$ in a conservative field is zero:
        $$
        \oint_{\gamma} V(\mathbf{x}) \cdot \mathrm{d} \mathbf{x}=\oint_{\gamma} \nabla f(\mathbf{x}) \cdot \mathrm{d} \mathbf{x}=f(\gamma(1))-f(\gamma(0))
        $$
        
        
        <h2>Divergence</h2>
        
        The divergence of a vector field on Euclidean space is a function (or scalar field). In threedimensions, the divergence is defined by
        $$
        \operatorname{div} \mathbf{F}=\nabla \cdot \mathbf{F}=\frac{\partial F_{1}}{\partial x}+\frac{\partial F_{2}}{\partial y}+\frac{\partial F_{3}}{\partial z}
        $$
        with the obvious generalization to arbitrary dimensions. The divergence at a point represents the degree to which a small volume around the point is a source or a sink for the vector flow, a result which is made precise by the divergence theorem.
                
              
          
        <h2>Curl in three dimensions</h2>
                
        The curl is an operation which takes a vector field and produces another vector field. The curl is defined only in three dimensions, but some properties of the curl can be captured in higher dimensions with the exterior derivative. In three dimensions, it is defined by
        $$
        \operatorname{curl} \mathbf{F}=\nabla \times \mathbf{F}=\left(\frac{\partial F_{3}}{\partial y}-\frac{\partial F_{2}}{\partial z}\right) \mathbf{e}_{1}-\left(\frac{\partial F_{3}}{\partial x}-\frac{\partial F_{1}}{\partial z}\right) \mathbf{e}_{2}+\left(\frac{\partial F_{2}}{\partial x}-\frac{\partial F_{1}}{\partial y}\right) \mathbf{e}_{3}
        $$
        The curl measures the density of the angular momentum of the vector flow at a point, that is, the amount to which the flow circulates around a fixed axis. This intuitive description is made precise by Stokes' theorem.



        
        """
        problemTemplate.add_solution(soln_s.strip(), 'text/html',
                                     add_html_line_break = True)
        
        answer_s = f"""
        {soln_s}
        """
        problemTemplate.add_answer(answer_s.strip(), 'text/html')
        
        return problemTemplate

