'''
Created on 2-June-2024

@author: b thakur

'''
import inspect
import traceback

import numpy as np
import sympy as sp

from sympy import (Symbol, symbols, latex, 
                   Derivative, Integral,
                   
                   )

from sympy.vector import (CoordSys3D, BaseVector, BaseScalar,
                          VectorAdd, VectorMul,
                          )


import random

from xv.util import (UtilClass, get_arrow_symbols, get_arrow_symbol, )
# _point_mass_helper
# PointMassHelper

class PointMassHelper(UtilClass):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self._coord_sys_3d = CoordSys3D('N')

        pass


    def get_problem_point_mass_with_position_vector(self):

        from ..core import NewtonianParticle
        
        particle = NewtonianParticle(verbose = self.verbose)
        
        r = particle.r
        r_vec = particle.get_r_vec()
        m = particle.m
        
        m_label = particle.m_label
        r_label = particle.r_label
        v_label = particle.v_label
        a_label = particle.a_label
        E_label = particle.E_label
        V_label = particle.V_label
        F_label = particle.F_label
        W_label = particle.W_label
        
        prob_s = f"""
        The ${latex(r_label)}$ of a point ${latex(m_label)} {latex(m)}$ with is given by 
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$.
        Find the expressions for $
        {latex(v_label)}, \\;
        {latex(a_label)}, \\; 
        {latex(E_label)}, \\; 
        {latex(F_label)}, \\; 
        {latex(V_label)}, \\; 
        {latex(W_label)}, \\; 
        $
        """
        
        soln_stmts = []

        
        soln_stmt = f"""
        We have ${latex(r_label)}$
        
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_v_from_r()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        
        
        soln_stmt = f"""
        {particle.get_stmt_a_from_v()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_E_from_a()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""
        {particle.get_stmt_F_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""        
        {particle.get_stmt_V_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_stmt = f"""
        {particle.get_stmt_W_from_V()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_s = "\n\n".join(soln_stmts)
        
        answer_s = f"""
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$
        
        $\\displaystyle {latex(particle.v)} = {particle.get_v_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.a)} = {particle.get_a_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.E)} = {particle.get_E_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.F)} = {latex(particle.get_F_ueval_symb())}$
        
        $\\displaystyle {latex(particle.V)} = {latex(particle.get_V_ueval_symb())}$
        
        $\\displaystyle {latex(particle.W)} = {latex(particle.get_W_ueval_symb())}$
        
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
        pass

    def get_problem_point_mass_with_velocity_vector(self):

        from ..core import NewtonianParticle
        
        particle = NewtonianParticle(verbose = self.verbose)
        
        v = particle.v
        v_vec = particle.get_v_vec()
        m = particle.m
        
        m_label = particle.m_label
        r_label = particle.r_label
        v_label = particle.v_label
        a_label = particle.a_label
        E_label = particle.E_label
        V_label = particle.V_label
        F_label = particle.F_label
        W_label = particle.W_label
        
        prob_s = f"""
        The ${latex(v_label)}$ of a point ${latex(m_label)} {latex(m)}$ with is given by 
        $\\displaystyle {latex(particle.v)} = {particle.get_v_vec().get_latex()}$
        
        Find the expressions for $
        {latex(r_label)}, \\;
        {latex(a_label)}, \\; 
        {latex(E_label)}, \\; 
        {latex(F_label)}, \\; 
        {latex(V_label)}, \\; 
        {latex(W_label)}, \\; 
        $
        """
        
        soln_stmts = []

        
        soln_stmt = f"""
        We have ${latex(v_label)}$
        
        $\\displaystyle {latex(v)} = {v_vec.get_latex()}$
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_r_from_v()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        
        
        soln_stmt = f"""
        {particle.get_stmt_a_from_v()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_E_from_a()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""
        {particle.get_stmt_F_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""        
        {particle.get_stmt_V_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_stmt = f"""
        {particle.get_stmt_W_from_V()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_s = "\n\n".join(soln_stmts)
        
        answer_s = f"""
        $\\displaystyle {latex(v)} = {v_vec.get_latex()}$
        
        $\\displaystyle {latex(particle.r)} = {particle.get_r_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.a)} = {particle.get_a_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.E)} = {particle.get_E_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.F)} = {latex(particle.get_F_ueval_symb())}$
        
        $\\displaystyle {latex(particle.V)} = {latex(particle.get_V_ueval_symb())}$
        
        $\\displaystyle {latex(particle.W)} = {latex(particle.get_W_ueval_symb())}$
        
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
        pass

    def get_problem_point_mass_with_acceleration_vector(self):

        from ..core import NewtonianParticle
        
        particle = NewtonianParticle(verbose = self.verbose)
        
        a = particle.a
        a_vec = particle.get_a_vec()
        m = particle.m
        
        m_label = particle.m_label
        r_label = particle.r_label
        v_label = particle.v_label
        a_label = particle.a_label
        E_label = particle.E_label
        V_label = particle.V_label
        F_label = particle.F_label
        W_label = particle.W_label
        
        prob_s = f"""
        The ${latex(a_label)}$ of a point ${latex(m_label)} {latex(m)}$ with is given by 
        $\\displaystyle {latex(particle.a)} = {particle.get_a_vec().get_latex()}$
        
        Find the expressions for $
        {latex(r_label)}, \\;
        {latex(v_label)}, \\; 
        {latex(E_label)}, \\; 
        {latex(F_label)}, \\; 
        {latex(V_label)}, \\; 
        {latex(W_label)}, \\; 
        $
        """
        
        soln_stmts = []

        
        soln_stmt = f"""
        We have ${latex(a_label)}$
        
        $\\displaystyle {latex(a)} = {a_vec.get_latex()}$
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_v_from_a()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_r_from_v()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_E_from_a()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""
        {particle.get_stmt_F_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""        
        {particle.get_stmt_V_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_stmt = f"""
        {particle.get_stmt_W_from_V()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_s = "\n\n".join(soln_stmts)
        
        answer_s = f"""
        $\\displaystyle {latex(a)} = {a_vec.get_latex()}$
        
        $\\displaystyle {latex(particle.v)} = {particle.get_v_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.r)} = {particle.get_r_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.E)} = {particle.get_E_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.F)} = {latex(particle.get_F_ueval_symb())}$
        
        $\\displaystyle {latex(particle.V)} = {latex(particle.get_V_ueval_symb())}$
        
        $\\displaystyle {latex(particle.W)} = {latex(particle.get_W_ueval_symb())}$
        
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
        pass

    def get_problem_gravitation_on_point_mass_WRONG_IMPLEMENTATION(self):

        from ..core import NewtonianParticle
        
        terms = [random.randint(-9, 9),
                 random.randint(-9, 9),
                 random.randint(-9, 9),
                ]
        particle = NewtonianParticle(verbose = self.verbose)
        
        r_vec = particle.get_vector(*terms)
        particle.init_values(r_vec = r_vec)
        
        r = particle.r
        #r_vec = particle.get_r_vec()
        m = particle.m
        
        m_label = particle.m_label
        r_label = particle.r_label
        v_label = particle.v_label
        a_label = particle.a_label
        E_label = particle.E_label
        V_label = particle.V_label
        F_label = particle.F_label
        W_label = particle.W_label
        
        prob_s = f"""
        The ${latex(r_label)}$ of a point ${latex(m_label)} {latex(m)}$ with is given by 
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$.
        Find the expressions for $
        {latex(v_label)}, \\;
        {latex(a_label)}, \\; 
        {latex(E_label)}, \\; 
        {latex(F_label)}, \\; 
        {latex(V_label)}, \\; 
        {latex(W_label)}, \\; 
        $
        """
        
        soln_stmts = []

        
        soln_stmt = f"""
        We have ${latex(r_label)}$
        
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_v_from_r()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        
        
        soln_stmt = f"""
        {particle.get_stmt_a_from_v()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_E_from_a()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""
        {particle.get_stmt_F_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""        
        {particle.get_stmt_V_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_stmt = f"""
        {particle.get_stmt_W_from_V()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_s = "\n\n".join(soln_stmts)
        
        answer_s = f"""
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$
        
        $\\displaystyle {latex(particle.v)} = {particle.get_v_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.a)} = {particle.get_a_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.E)} = {particle.get_E_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.F)} = {latex(particle.get_F_ueval_symb())}$
        
        $\\displaystyle {latex(particle.V)} = {latex(particle.get_V_ueval_symb())}$
        
        $\\displaystyle {latex(particle.W)} = {latex(particle.get_W_ueval_symb())}$
        
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
        pass

    def get_problem_gravitation_on_point_mass(self):

        from ..core import NewtonianParticle
        
        terms = [random.randint(-9, 9),
                 random.randint(-9, 9),
                 random.randint(-9, 9),
                ]
        particle = NewtonianParticle(auto_init = False, verbose = self.verbose)
        
        
        r = particle.r
        m = particle.m
        
        G = Symbol('G', real = True)
        M = Symbol('M', real = True)
        E_vec = (G * M / abs(r) ** 3) * r
        
        particle.init_values(E_vec = E_vec)
        r_vec = particle.get_r_vec()
        
        
        m_label = particle.m_label
        r_label = particle.r_label
        v_label = particle.v_label
        a_label = particle.a_label
        E_label = particle.E_label
        V_label = particle.V_label
        F_label = particle.F_label
        W_label = particle.W_label
        
        prob_s = f"""
        The ${latex(r_label)}$ of a point ${latex(m_label)} {latex(m)}$ with is given by 
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$.
        Find the expressions for $
        {latex(v_label)}, \\;
        {latex(a_label)}, \\; 
        {latex(E_label)}, \\; 
        {latex(F_label)}, \\; 
        {latex(V_label)}, \\; 
        {latex(W_label)}, \\; 
        $
        """
        
        soln_stmts = []

        
        soln_stmt = f"""
        We have ${latex(r_label)}$
        
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_v_from_r()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        
        
        soln_stmt = f"""
        {particle.get_stmt_a_from_v()}
        """
        soln_stmts.append(soln_stmt.strip())
        
        soln_stmt = f"""
        {particle.get_stmt_E_from_a()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""
        {particle.get_stmt_F_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())


        soln_stmt = f"""        
        {particle.get_stmt_V_from_E()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_stmt = f"""
        {particle.get_stmt_W_from_V()}
        """
        soln_stmts.append(soln_stmt.strip())

        soln_s = "\n\n".join(soln_stmts)
        
        answer_s = f"""
        $\\displaystyle {latex(r)} = {r_vec.get_latex()}$
        
        $\\displaystyle {latex(particle.v)} = {particle.get_v_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.a)} = {particle.get_a_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.E)} = {particle.get_E_vec().get_latex()}$
        
        $\\displaystyle {latex(particle.F)} = {latex(particle.get_F_ueval_symb())}$
        
        $\\displaystyle {latex(particle.V)} = {latex(particle.get_V_ueval_symb())}$
        
        $\\displaystyle {latex(particle.W)} = {latex(particle.get_W_ueval_symb())}$
        
        """
        
        result = {
            'prob_s': prob_s.strip(),
            'soln_s': soln_s.strip(),
            'answer_s': answer_s.strip(),
            }
        
        return result
        pass

    pass
#class PointMassHelper:
    