'''
Created on 12-Jul-2021

@author: bthakur
'''
import random
import inspect
import traceback

from sympy import (symbols, Symbol, pi, latex,
                   Rational)

from sympy.vector import express
import matplotlib.pyplot as plt
import numpy as np
from xv.util import UtilClass

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

    def plot_point(self, p1 = None, fig = None, ax = None):
        import matplotlib.pylab as plt
        import numpy as np

        if p1 is None:
            p1 = np.random.randint(-5, 5, size = 3)

        origin = np.array([0, 0, 0])
        fig = self._get_figure(fig, ax)
        ax = self._get_axis(fig, ax)
        
        ax.plot(*origin, color = 'blue', marker = 'o')
        ax.text(origin[0] + 0.25, origin[1] + 0.25, origin[2] + 0.25, s = 'origin', fontsize = 12)

        ax.plot(*p1, color = 'red', marker = 'o')
        ax.text(p1[0] + 0.25, p1[1] + 0.25, p1[2] + 0.25, s = str(p1), fontsize = 12)

        ax.set_xticks(np.arange(-5, 6))
        ax.set_yticks(np.arange(-5, 6))
        ax.set_zticks(np.arange(-5, 6))
        ax.set_xlim(-5, 5)
        ax.set_ylim(-5, 5)
        ax.set_zlim(-5, 5)
        plt.grid()
        return ax


    def plot_plane(self, n = [2, 5, -5], d = None, fig = None, ax = None, **kwargs):
        steps = 100
        xrange = kwargs.get('xrange', [-10, 10])
        x = np.linspace(*xrange, steps)

        yrange = kwargs.get('yrange', [-10, 10])
        y = np.linspace(*yrange, steps)

        X,Y = np.meshgrid(x,y)
        if d == None:
            p1 = kwargs.get('p1', [0, 0, 0])
            d = -(n[0]*p1[0] + n[1]*p1[1] + n[2]*p1[2])
        Z = -(n[0]*X + n[1]*Y + d)/n[2]
        origin = np.array([0, 0, 0])

        fig = self._get_figure(fig, ax)
        ax = self._get_axis(fig, ax)
        
        ax.plot(*origin, color = 'blue', marker = 'o')
        ax.text(origin[0] + 0.25, origin[1] + 0.25, origin[2] + 0.25, s = 'O', fontsize = 12)

        ax.plot_surface(X, Y, Z, color= 'lightgrey', alpha = 0.6)

        ax.set_aspect('equal')
        return ax
    
    def plot_line(self, p1 = [1, -2, -3], n = [2, 5, -5], fig = None, ax = None, **kwargs):
        steps = 100
        trange = kwargs.get('t_range', [-3, 3])
        t = np.linspace(*trange, steps)
        x = p1[0] + n[0]*t
        y = p1[1] + n[1]*t
        z = p1[2] + n[2]*t
        origin = np.array([0, 0, 0])

        fig = self._get_figure(fig, ax)
        ax = self._get_axis(fig, ax)
        
        ax.plot(*origin, color = 'red', marker = 'o')
        # ax.text(origin[0] + 0.25, origin[1] + 0.25, origin[2] + 0.25, s = 'O', fontsize = 12)

        ax.plot(x, y, z, color= 'red')

        ax.set_aspect('equal')
        return ax

    def _get_figure(self, fig, ax):
        if fig is None:
            if ax is None:
                fig = plt.figure(figsize = (6, 6))
            else:
                fig = ax.get_figure()
        return fig
            
    
    def _get_axis(self, fig, ax):
        if ax is None:
            ax = fig.add_subplot(projection='3d', box_aspect = (1, 1, 1))
        return ax
    pass
#class Vector3dHelper:
