# -*- coding: utf-8 -*-
"""
Written by Daniel M. Aukes
Email: danaukes<at>gmail.com
Please see LICENSE for full license.
"""

import sympy
import pynamics
from pynamics.name_generator import NameGenerator

class Variable(sympy.Symbol,NameGenerator):
    def __new__(self,name=None):
        
        name = name or self.generate_name()
        
        obj = sympy.Symbol.__new__(self,name)
        return obj

class Constant(sympy.Symbol,NameGenerator):
    def __new__(self,value=None,name=None,system = None):

        name = name or self.generate_name()

        system = system or pynamics.get_system()

        obj = sympy.Symbol.__new__(self,name)
#        obj.value = value
        system.add_constant(obj)
        if value is not None:
            system.add_constant_value(obj,value)
        return obj

class Differentiable(sympy.Symbol,NameGenerator):
    def __new__(cls,name=None,system = None,limit = 3,ii=0,ini = None):

        system = system or pynamics.get_system()

        name = name or cls.generate_name()

        
        output = []
        differentiables = []
        
        

        for kk,jj in enumerate(range(ii,limit)):
            

            if kk==0:
                subname = name
                variable = sympy.Symbol.__new__(cls,subname)
            else:
                subname = name+'_'+'d'*kk
                # if jj==limit-1:
                    # variable = Variable(subname)
                # else:
                    # variable = sympy.Symbol.__new__(cls,subname)
                variable = sympy.Symbol.__new__(cls,subname)

            output.append(variable)
            # if jj!=limit-1:
            #     differentiables.append(variable)
            #     system.add_q(variable,jj)
            differentiables.append(variable)
            system.add_q(variable,jj)

        # for item in differentiables:
        #     system.set_derivative(item,None)

        for kk,(a,a_d) in enumerate(zip(output[:-1],output[1:])):
            system.set_derivative(a,a_d)

            if ini is not None:
                system.set_ini(a,ini[kk])
        
        if len(output)==1:
            return output[0]
        else:
            return output
        # return output


@@ -922,24 +922,41 @@
 0,ini = None
+,output_full=True
 ):%0A%0A        
@@ -1074,37 +1074,8 @@
  %5B%5D%0A
-        differentiables = %5B%5D%0A
     
@@ -1616,242 +1616,61 @@
     
-# if jj!=limit-1:%0A            #     differentiables.append(variable)%0A            #     system.add_q(variable,jj)%0A            differentiables.append(variable)%0A            system.add_q(variable,jj)%0A%0A        # for item in differentiables
+system.add_q(variable,jj)%0A%0A        for item in output
 :%0A  
@@ -1678,18 +1678,14 @@
     
- #
      
-sys
+i
 tem.
@@ -1703,17 +1703,23 @@
 ive(
-item,None
+sympy.Number(0)
 )%0A%0A 
@@ -1823,16 +1823,50 @@
 e(a,a_d)
+%0A            a.set_derivative(a_d)
 %0A%0A      
@@ -1934,32 +1934,60 @@
 i%5Bkk%5D)%0A        %0A
+        if output_full:%0A    
         if len(o
@@ -2001,32 +2001,36 @@
 =1:%0A            
+ 
+   
 return output%5B0%5D
@@ -2030,32 +2030,36 @@
 tput%5B0%5D%0A        
+    
 else:%0A          
@@ -2052,32 +2052,36 @@
 se:%0A            
+  
+  
 return output%0A  
@@ -2090,21 +2090,281 @@
     
-# return output%0A%0A
+else:%0A            return output%5B0%5D%0A        # return output%0A%0A    @property%0A    def _d(self):%0A        return self.get_derivative()%0A        %0A    def set_derivative(self,other):%0A        self._time_derivative=other%0A%0A    def get_derivative(self):%0A        return self._time_derivative

update to variable_types