#!/usr/bin/python

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


from vLabtool import interface
from vLabtool.widgets.nodeList import Ui_Form as nodeWidget
from vLabtool.templates.template_wireless_demo 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)

		self.I.NRF.start_token_manager()
		print self.I.readLog()	
		self.plot = self.Exp.add2DPlot()
		self.plot.setLabel('bottom', 'Datapoints -->>')
		self.plot.setYRange(-35000,35000)
		self.curves=[]
		self.nodeWidgets=[]
		self.nodeList=[]
		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(200,self.updateLogWindow)
		self.delayedTask(0,self.logs.setMaximumWidth,1900)
		self.deviceMenus=[]
		menu = self.PermanentMenu()
		self.curveMenu = QtGui.QMenu('Active Traces')
		menu.addMenu(self.curveMenu)
		self.paramMenus.insertWidget(0,menu)
		self.deviceMenus.append(menu)

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

	def addPlot(self,addr,param):
		newNode = self.I.newRadioLink(address=addr)
		self.nodeList.append(newNode)
		print 'made link',addr,param
		#newNode.write_register(self.I.NRF.RF_SETUP,0x0E)
		#self.I.NRF.write_register(self.I.NRF.RF_SETUP,0x0E) #Change to 2MBPS
		cls=False
		if(param==0x68):
			cls=MPU6050.MPU6050(newNode)
			numplots=7;
		elif(param==0x1E):
			cls=HMC5883L.HMC5883L(newNode)
			numplots=3
		elif(param==0x5A):
			cls=MLX90614.MLX90614(newNode)
			numplots=1
		elif(param==0x77):
			cls=BMP180.BMP180(newNode)
			numplots=3
		elif(param==0x39):
			cls=TSL2561.TSL2561(newNode)
			numplots=3
		elif(param==0x40):
			cls=SHT21.SHT21(newNode)
			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:%s[%d]'%(hex(addr),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:%s[%d]'%(hex(addr),label[:10],a),cols[a]) for a in range(numplots)]
				for a in range(len(curves)):
					self.Exp.plotLegend.addItem(curves[a],'%s:%s[%d]'%(hex(addr),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:%s[%d]'%(hex(addr),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,addr)

	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 nodeHandler(QtGui.QFrame,nodeWidget):
		def __init__(self,addr,I2Cs,evaluator):
			super(Handler.nodeHandler, self).__init__()
			self.setupUi(self)
			#self.cmd = getattr(self.I,cmd)
			#self.cmdname=cmd
			self.label.setText(hex(addr))
			self.addr=addr
			self.cmd = evaluator
			for i in I2Cs:
				self.items.addItem(hex(i))

		def clicked(self):
			val = self.items.currentText()
			self.cmd(self.addr,int(val,0))
			

	def updateLogWindow(self):
		x=self.I.readLog()
		if len(x):print 'Log:',x
		lst = self.I.NRF.get_nodelist()
		T='''
		<style type="text/css" scoped>
		table.GeneratedTable {width:100%;background-color:#FFFFFF;border-collapse:collapse;
		border-width:1px;border-color:#336600;	border-style:solid;	color:#009900;	}
		table.GeneratedTable td, table.GeneratedTable th {
		border-width:1px;border-color:#336600;border-style:solid;padding:3px;}
		table.GeneratedTable thead {background-color:#CCFF99;}
		</style>

		<table class="GeneratedTable"><thead>
		<tr><th>Node Address</th><th>Sensors detected</th>	</tr>
		</thead><tbody>
		'''
		for a in lst:
			T+='<tr><td>'
			T+=hex(a)
			T+='</td><td>'
			for b in lst[a]:
				T+='''<span title="%s">'''%(sensorHints.get(b,'No clue'))+hex(b)+'. </span>'
			T+='</td></tr>'
		
		
		T+='''
		</tbody></table>
		'''
		self.logs.setHtml(T)

	def reloadNodelist(self):
		lst = self.I.NRF.get_nodelist()
		x=self.I.readLog()
		if len(x):print x
		for a in self.nodeWidgets:
			a.setParent(None)
		self.nodeWidgets=[]
		for a in lst:
			new = self.I.newRadioLink(address=a)
			print new.I2C_scan()
			newNode=self.nodeHandler(a,lst[a],self.addPlot)
			self.nodeArea.insertWidget(0,newNode)
			self.nodeWidgets.append(newNode)

	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.I.NRF.start_token_manager()
			self.refreshTimer.start()
		else: 
			self.I.NRF.stop_token_manager()
			self.refreshTimer.stop()

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