#!/usr/bin/python

from vLabtool.experiment import *
if __name__ == "__main__":
	Exp=Experiment(parent=None,showresult=False)


from vLabtool import interface
from vLabtool.widgets.clicking import Ui_Form as Ui_Clicking
from vLabtool.templates.template_sensors import Ui_Form
from vLabtool.SENSORS import HMC5883L,MPU6050,MLX90614,BMP180,TSL2561,SHT21
from vLabtool.sensorlist import sensors as sensorHints
import time

class Handler(QtGui.QFrame,ConvenienceClass,Ui_Form):
	def __init__(self,exp):
		super(Handler, self).__init__()
		self.Exp=exp
		self.setupUi(self)
		self.I = interface.Interface(2.0)

		print self.I.readLog()	
		self.plot = self.Exp.add2DPlot()
		self.plot.setLabel('bottom', 'Datapoints -->>')
		self.plot.setYRange(-35000,35000)
		self.curves=[]
		self.acquireList=[]
		self.POINTS=1000
		self.xdata=range(self.POINTS)
		self.fps=0;self.lastTime=time.time();self.updatepos=0
		self.active_device_counter=0
		self.right_axes=[]
		self.Exp.loopTask(2,self.updatePlots)
		self.updatepos=0
		self.refreshTimer = self.Exp.loopTask(500,self.reloadNodelist)
		self.deviceMenus=[]
		self.sensorWidgets=[]
		menu = self.PermanentMenu()
		self.curveMenu = QtGui.QMenu('Active Traces')
		menu.addMenu(self.curveMenu)
		self.paramMenus.insertWidget(0,menu)
		self.deviceMenus.append(menu)
		self.availableClasses=[0x68,0x1E,0x5A,0x77,0x39,0x40]

	class plotItem:
		def __init__(self,handle,ydata,curves):
			self.handle = handle
			self.ydata = ydata
			self.curves=curves

	def addPlot(self,param):
		cls=False
		if(param==0x68):
			cls=MPU6050.MPU6050(self.I.I2C)
			numplots=7;
		elif(param==0x1E):
			cls=HMC5883L.HMC5883L(self.I.I2C)
			numplots=3
		elif(param==0x5A):
			cls=MLX90614.MLX90614(self.I.I2C)
			numplots=1
		elif(param==0x77):
			cls=BMP180.BMP180(self.I.I2C)
			numplots=3
		elif(param==0x39):
			cls=TSL2561.TSL2561(self.I.I2C)
			numplots=3
		elif(param==0x40):
			cls=SHT21.SHT21(self.I.I2C)
			numplots=1


		if cls:
			if hasattr(cls,'name'):	label = cls.name
			else: label =''
			if not self.active_device_counter:
				if len(label):self.plot.setLabel('left', label)
				curves=[self.Exp.addCurve(self.plot ,'%s[%d]'%(label[:10],a),self.random_color()) for a in range(numplots)]
			else:
				cols=[self.random_color() for a in range(numplots)]
				if label:
					colStr = lambda col: hex(col[0])[2:]+hex(col[1])[2:]+hex(col[2])[2:]
					newplt = self.Exp.addAxis(self.plot,label=label,color='#'+colStr(cols[0].getRgb()))
				else: newplt = self.Exp.addAxis(self.plot)
				self.right_axes.append(newplt)
				curves=[self.Exp.addCurve(newplt ,'%s[%d]'%(label[:10],a),cols[a]) for a in range(numplots)]
				for a in range(len(curves)):
					self.Exp.plotLegend.addItem(curves[a],'%s[%d]'%(label[:10],a))
			
			for a in range(len(curves)):
				curves[a].checked=True
				Callback = functools.partial(self.setTraceVisibility,curves[a])		
				action=self.curveMenu.addAction('%s[%d]'%(label[:12],a)) 
				action.triggered[bool].connect(Callback)
				action.setCheckable(True);action.setChecked(True)
				#self.curves.append(a)
			self.acquireList.append(self.plotItem(cls,np.zeros((numplots,self.POINTS)), curves)) 
			self.active_device_counter+=1
			self.createMenu(cls,param)

	def setTraceVisibility(self,curve,status):
		curve.clear()
		curve.setEnabled(status)
		curve.checked=status

	class PermanentMenu(QtGui.QMenu):
		def hideEvent(self, event):
			self.show()
        
	def createMenu(self,cls,addr):
		menu = self.PermanentMenu()
		menu.setMinimumHeight(25)
		sub_menu = QtGui.QMenu('%s:%s'%(hex(addr),cls.name[:15]))
		for i in cls.params: 
			mini=sub_menu.addMenu(i) 
			for a in cls.params[i]:
				Callback = functools.partial(getattr(cls,i),a)		
				mini.addAction(str(a),Callback) 
		menu.addMenu(sub_menu)
		self.paramMenus.insertWidget(1,menu)
		self.deviceMenus.append(menu)
		self.deviceMenus.append(sub_menu)
	

	class senHandler(QtGui.QFrame,Ui_Clicking):
		def __init__(self,addr,evaluator):
			super(Handler.senHandler, self).__init__()
			self.setupUi(self)
			self.label.setText(hex(addr))
			self.addr=addr
			self.cmd = evaluator
			self.button.setText('GO!')

		def clicked(self):
			self.cmd(self.addr)

			


	def reloadNodelist(self):
		lst = self.I.I2C.scan()
		for a in self.sensorWidgets:
			a.setParent(None)
		self.sensorWidgets=[]
		for a in lst:
			if a in self.availableClasses:
				newSensor=self.senHandler(a,self.addPlot)
				self.nodeArea.insertWidget(0,newSensor)
				self.sensorWidgets.append(newSensor)

	def updatePlots(self):			
		for item in self.acquireList:
			need_data=False
			for a in item.curves:
				if a.checked:need_data=True
			if need_data:			
				vals=item.handle.getRaw()
				if not vals:continue
				for X in range(len(item.curves)):
					item.ydata[X][self.updatepos] = vals[X]
				if self.updatepos%20==0:
					for a in range(len(item.curves)):
						if item.curves[a].checked:item.curves[a].setData(self.xdata,item.ydata[a])
		#N2.readADC(10)
		if len(self.acquireList):
			self.updatepos+=1
			if self.updatepos>=self.POINTS:self.updatepos=0
		
			now = time.time()
			dt = now - self.lastTime
			self.lastTime = now
			if self.fps is None:
				self.fps = 1.0/dt
			else:
				s = np.clip(dt*3., 0, 1)
				self.fps = self.fps * (1-s) + (1.0/dt) * s
			self.plot.setTitle('%0.2f fps' % (self.fps) )

			
	def toggleListen(self,state):
		if state:
			self.refreshTimer.start()
		else: 
			self.refreshTimer.stop()

	def __exit__(self):
		print 'CYA'
		
if __name__ == "__main__":
	handler = Handler(Exp)
	Exp.addHandler(handler)
	Exp.run()
	handler.I.NRF.stop_token_manager()
	handler.I.restoreStandalone()
