"""
SysParams.py --

This file implements the Dynamic mode window.

Date of creation: 2010-15-11

Copyright
Julian David Colorado, jd.colorado@upm.es
Universidad Politecnica de Madrid

See the file "license.terms" for information on usage and redistribution of this file, and for a
DISCLAIMER OF ALL WARRANTIES.
"""

import wx
import os, sys
from numpy import *
from systems import dcmotor
from interface.dynparamscroll import *
from interface.paramvaluestree import *

class SysParamsWindow( wx.Panel ):
	""" Window where the systems parameters are displayed."""
	def __init__(self, parent, id,pyshell):
		wx.Panel.__init__(self, parent, id )
		self.pyshell=pyshell

		#SysParamsWindow vertical sizer.
		self.Sizer = wx.BoxSizer( wx.VERTICAL )
		self.Sizer2 = wx.BoxSizer( wx.HORIZONTAL )

		#SysParamsWindow title.
		font = wx.Font(10, wx.ROMAN, wx.NORMAL, wx.BOLD)
		if(os.name=='nt'):
			self.Title = wx.StaticText( self, -1, "Parameters                                          ", (0,0), style=wx.TE_LEFT )
		else:
			self.Title = wx.StaticText( self, -1, "Parameters                            ", (0,0), style=wx.TE_LEFT )
		self.Title.SetFont( font )

		#Gauge
		self.gauge = wx.Gauge(self, -1, 50, size=(80, 15))

		#SysParamsWindow scrolled panel.
		self.Scroll = DynParamScroll( self, -1, wx.Point(0, 0), wx.Size(180, 100))

		#Load toolbar
		self.ToolBar=SimulationToolBar( self,-1, self.Scroll,self.gauge,self.pyshell )
		self.ToolBar.Realize()
		#panel = wx.Panel(self, -1)
		self.Sizer2.Add(self.Title, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 4)
		self.Sizer2.Add(self.gauge, 0,wx.CENTER )


		self.Sizer.Add(self.Sizer2, 0, wx.LEFT )
		self.Sizer.Add(self.ToolBar, 0, wx.EXPAND |wx.LEFT )
		self.Sizer.Add(self.Scroll, 1, wx.EXPAND | wx.TOP )
		self.SetSizer(self.Sizer)


class SimulationToolBar(wx.ToolBar):
	"""Toolbar for ecuation interprete load, and c++ compilation"""
	def __init__(self, parent,id, Scroll,gauge,pyshell ):
		self.pyshell=pyshell
		self.Scroll = Scroll
		self.gauge=gauge
		#Toolbar

		wx.ToolBar.__init__(self, parent,-1,size=(12,36), style=wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT | wx.TB_TEXT)

		self.SetToolBitmapSize((24,24))

		new=self.AddSimpleTool(wx.ID_ANY, wx.Image('interface/images/stock_new.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'New Simulation', '')
		load=self.AddSimpleTool(wx.ID_ANY, wx.Image('interface/images/open.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Open simulation', '')
		save=self.AddSimpleTool(wx.ID_ANY, wx.Image('interface/images/save32.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Save Simulation', '')
		self.AddSeparator()

		default=self.AddSimpleTool(wx.ID_ANY, wx.Image('interface/images/default.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Default Simulation', '')
		self.AddSeparator()

		refresh=self.AddSimpleTool(wx.ID_ANY, wx.Image('interface/images/refresh.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Refresh Simulation', '')
		self.AddSeparator()

		#Binding functions of ToolBar
		self.Bind(wx.EVT_TOOL, self.OnNew, new )
		self.Bind(wx.EVT_TOOL, self.OnLoad, load )
		self.Bind(wx.EVT_TOOL, self.OnSave, save )
		self.Bind(wx.EVT_TOOL, self.OnDefault, default )
		self.Bind(wx.EVT_TOOL, self.OnRefresh, refresh )

	#Functions binded to toolbar
	def OnNew(self, event):
		"""cleans tree"""
		self.system.odesolver=''
		#self.system.dynmodel
		self.system.motor=''
		self.system.ctrlnum=0
		self.system.control1=''
		self.system.control2=''
		self.system.range=0.0
		self.system.swinguporder=0.0
		self.system.ctrlorder=0.0
		self.system.dynmodelorder=4
		self.system.initime=0.0
		self.system.finaltime=0.0
		self.system.integstep=0.0
		self.system.ctrlstep=0.0
		self.system.grav=9.81
		self.Scroll.ParamValuesTree.UpdateTreeCtrlInfo( self.system )

	def OnLoad(self, event):
		"""Load simulation"""
		"""Loads a new sub-tree depending on option selected by the user"""
		dir = os.getcwd()
		dir = os.path.join(dir, 'simulations/'+self.systemtype)

		dlg = wx.FileDialog(self, "Choose a simulation", dir, "", "*.sim", wx.OPEN)

		if dlg.ShowModal() == wx.ID_OK:
			try:
				path=dlg.GetPath()
				file=os.path.basename(path)
				(file, ext) = os.path.splitext(file)

			except IOError, error:
				error_dlg = wx.MessageDialog(self, 'Error opening file\n' + str(error))
				error_dlg.ShowModal()
		f=open(path,'r+')
		lines=f.readlines()
		self.ReadFile(lines)
		f.close()
		dlg.Destroy()
		self.Scroll.ParamValuesTree.UpdateTreeCtrlInfo( self.system )

	def ReadFile(self,lines):
		"""Read Simulation From File"""
		line=2
		self.system.odesolver=lines[line].split(': ')[1].split('\n')[0]
		line+=1
		self.system.dynmodel=lines[line].split(': ')[1].split('\n')[0]
		line+=1
		self.system.motor=lines[line].split(': ')[1].split('\n')[0]
		line+=1
		self.system.ctrlnum=float(lines[line].split(': ')[1].split('\n')[0])
		line+=1

		#Depending on number of controllers
		if(self.system.ctrlnum>0):
			self.system.control1=lines[line].split(': ')[1].split('\n')[0]
			line+=1
			self.system.ctrlorder=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.ctrlstep=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
		if(self.system.ctrlnum==2):
			self.system.range=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.control2=lines[line].split(': ')[1].split('\n')[0]
			line+=1
			self.system.swinguporder=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1

		self.system.dynmodelorder=float(lines[line].split(': ')[1].split('\n')[0])
		line+=1
		self.system.initime=float(lines[line].split(': ')[1].split('\n')[0])
		line+=1
		self.system.finaltime=float(lines[line].split(': ')[1].split('\n')[0])
		line+=1
		self.system.integstep=float(lines[line].split(': ')[1].split('\n')[0])
		line+=1
		self.system.grav=float(lines[line].split(': ')[1].split('\n')[0])
		line+=4

		#Depending on system
		if(self.systemtype=="bat"):
			self.system.M=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.m=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.K=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.p=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.PendLength=float(lines[line].split(': ')[1].split('\n')[0])

		elif(self.systemtype=="batwing"):
			self.system.m=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.Pend2Ine=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.Pend2fric=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.Pend1Length=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.Pend2Length=float(lines[line].split(': ')[1].split('\n')[0])

		line+=2

		if (self.system.motor=="motor1"):
			self.system.dcmotor.Ka=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.dcmotor.Ta=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
		elif (self.system.motor=="motor2" or self.system.motor=="motor3"):
			self.system.dcmotor.R=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.dcmotor.r=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.dcmotor.Km=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1
			self.system.dcmotor.Kg=float(lines[line].split(': ')[1].split('\n')[0])
			line+=1

		#self.statusbar.SetStatusText('Loading simulation')

	def OnSave(self, event):
		"""Save simulation"""
		dir = os.getcwd()
		dir = os.path.join(dir, 'simulations/'+self.systemtype)

		dlg = wx.FileDialog(self, "Save simulation", dir, "", "*.sim", wx.SAVE)

		if dlg.ShowModal() == wx.ID_OK:
			try:
				path=dlg.GetPath()
				file=os.path.basename(path)
				(file, ext) = os.path.splitext(file)

			except IOError, error:
				error_dlg = wx.MessageDialog(self, 'Error saving file\n' + str(error))
				error_dlg.ShowModal()

		f=open(path,'wb+')

		#Filling dynamic simulation parameters
		self.file_data=["SIMULATION FILE FOR: "				+self.system.systemtype+"\n\n"]
		self.file_data.append('Odesolver: '					+self.system.odesolver)
		self.file_data.append('\nDynmodel: '				+self.system.dynmodel)
		self.file_data.append('\nMotor: '					+self.system.motor)

		self.file_data.append('\n#Controllers: '			+str(self.system.ctrlnum))

		if(self.system.ctrlnum>0):
			self.file_data.append('\nController: '			+self.system.control1)
			self.file_data.append('\nControler order: '		+str(self.system.ctrlorder))
			self.file_data.append('\nControl step time: '	+str(self.system.ctrlstep))

		if(self.system.ctrlnum==2):
			self.file_data.append('\nRange: '				+str(self.system.range))
			self.file_data.append('\nSwing Up: '			+self.system.control2)
			self.file_data.append('\nSwing Up order: '		+str(self.system.swinguporder))

		self.file_data.append('\ndynmodel order: '			+str(self.system.dynmodelorder))
		self.file_data.append('\nTini: '					+str(self.system.initime))
		self.file_data.append('\nTfinal: '					+str(self.system.finaltime))
		self.file_data.append('\nIntegrator step time: '	+str(self.system.integstep))

		self.file_data.append('\nGrav: '					+str(self.system.grav))
		#Dynamic Params.
		self.file_data.append('\n\nDYN PARAMS:\n')
		if(self.systemtype=="bat"):
			#self.file_data.append('\nBody Mass: '			+str(self.system.Mb))
			self.file_data.append('\nHumerus Mass: '			+str(self.system.M))
			self.file_data.append('\nRadius Mass: '		+str(self.system.m))
			self.file_data.append('\nHumerus Lenght: '		+str(self.system.K))
			self.file_data.append('\nRadius Lenght: '	+str(self.system.p))
			self.file_data.append('\nLift Coeff: '		+str(self.system.PendLength))

		elif(self.systemtype=="batwing"):
			self.file_data.append('\nMass: '				+str(self.system.m))
			self.file_data.append('\nInertia: '				+str(self.system.Pend2Ine))
			self.file_data.append('\nFriction: '			+str(self.system.Pend2fric))
			self.file_data.append('\nPend. 1 Length: '		+str(self.system.Pend1Length))
			self.file_data.append('\nPend. 2 Length: '		+str(self.system.Pend2Length))


		self.file_data.append('\n\nDC MOTORS:\n')
		if (self.system.motor=="motor1"):
			self.file_data.append('\nKa: '				+str(self.system.dcmotor.Ka))
			self.file_data.append('\nTa: '				+str(self.system.dcmotor.Ta))
		elif (self.system.motor=="motor2" or self.system.motor=="motor3"):
			self.file_data.append('\nRsma: '				+str(self.system.dcmotor.R))
			self.file_data.append('\nrsma: '				+str(self.system.dcmotor.r))
			self.file_data.append('\nLsma: '				+str(self.system.dcmotor.Km))
			self.file_data.append('\nhsma: '				+str(self.system.dcmotor.Kg))


		f.writelines(self.file_data)
		f.close()
		print self.system.dcmotor.R
		dlg.Destroy()

		#self.statusbar.SetStatusText('Saving simulation')

	def OnDefault(self, event):
		"""Load default simulation"""
		#self.statusbar.SetStatusText('Loading default simulation')
		path = os.getcwd()
		path = os.path.join(path, 'simulations/'+self.systemtype+'/default.sim')
		f=open(path,'r+')
		lines=f.readlines()
		self.ReadFile(lines)
		f.close()
		self.Scroll.ParamValuesTree.UpdateTreeCtrlInfo( self.system )

	def OnRefresh(self,event):
		"""Load simulation"""
		#self.statusbar.SetStatusText('Refreshing base system with new simulation')

		self.system.make_compile(self.gauge,self.pyshell)

	def GetSystemValues( self, system ):
		"""Gets the loaded system values in order to manipulate them"""
		self.system = system
		self.systemtype = system.type
		self.simtime = self.system.finaltime

