# EAeDIP128-6 Python Driver
#
# Created: March 2015
#      by: Manolo Broseta at ALBA Computing Division
#

import smbus
import time, sys, select, math

from image_res import *

I2C_ADDRESS = 0x94

# Fixed I2C bus numbers given by the I2C-tool using the NUC board
NUC_I2C_BUS_0 = 8
NUC_I2C_BUS_1 = 9

DC1_BYTE = 0x11
DC2_BYTE = 0x12

ACK_VALUE = 0x06
NACK_VALUE = 0x15

DATA_LEN = 32

# Conversion to the I2C_ADDRESS to be used used by the I2C-tools
# Only the 7 MSB shifted 1 bit to the right
I2C_ADDRESS = I2C_ADDRESS >> 1

DEBUG = False

class PanelDriver():	
	def __init__(self, parent=None):
		self.bus = smbus.SMBus(NUC_I2C_BUS_0)		
	
	def SendData(self,arg):
			try:
				cmds_list = arg.replace(","," ").split(" ")
			except:
				cmds_list = arg

			lst = []
			for cmd in cmds_list:
				if "^" in cmd:
					if cmd[1] in ['L','M','J']:
						lst.append(ord(cmd[1])-64)
				else:
					if cmd.isdigit():
						lst.append(int(cmd))
					else:
						for ch in cmd:
							if ord(ch) == 0x23:
								lst.append(0x1B)
							else:
								lst.append(ord(ch))
		#				if '#Z' not in cmd:
		#					lst.append(0x0A)

			send_list = []
			send_list.append(DC1_BYTE)
			bcc = DC1_BYTE

			# Fisrt value to be sent is te len of the protocol
			send_list.append(len(lst))
			
			# build the list to send
			for it in lst:
				bcc = bcc + it
				send_list.append(it)
			
			bcc = bcc + len(lst)
			
			# Add the checksum as last element
			bcc = bcc & 0xff
			send_list.append(bcc)
			
			if DEBUG:
				print "I2C_WRITE_DATA= ",
				for el in send_list:
					print hex(el)+",",
				print
			
			self.bus.write_block_data(I2C_ADDRESS, 0, send_list)
			ret_value = self.bus.read_byte(I2C_ADDRESS)
			
			return(ret_value)

	def SetProtocol(self, size=32,timeout=0):
		send_list = [DC2_BYTE, 3, 0x44, size, timeout]
		
		# build the list to send
		bcc = 0
		for it in send_list:
			bcc = bcc + it
		
		# Add the checksum as last element
		bcc = bcc & 0xff
		send_list.append(bcc)

		self.bus.write_block_data(I2C_ADDRESS, 0, send_list)
		ret_value = self.bus.read_byte(I2C_ADDRESS)
		
		return(ret_value)

	def GetProtocol(self):
		# Start Request for content of send buffer 
		send_list = [DC2_BYTE, 0x01, 0x50]
		bcc = 0
		for it in send_list:
			bcc = bcc + it
		bcc = bcc & 0xff
		send_list.append(bcc)

		self.bus.write_block_data(I2C_ADDRESS, 0, send_list)
		
		ret_value = []	
		if self.bus.read_byte(I2C_ADDRESS) == ACK_VALUE:
			ret_value = self.bus.read_i2c_block_data(I2C_ADDRESS,0)
			
		return ret_value

	def GetData(self):
		# Start Request for content of send buffer 
		send_list = [DC2_BYTE, 0x01, 0x53]
		bcc = 0
		for it in send_list:
			bcc = bcc + it
		bcc = bcc & 0xff
		send_list.append(bcc)

		self.bus.write_block_data(I2C_ADDRESS, 0, send_list)
		
		ret_value = []	
		if self.bus.read_byte(I2C_ADDRESS) == ACK_VALUE:
			ret_value = self.bus.read_i2c_block_data(I2C_ADDRESS,0)
		
		return ret_value
	
	def ClearScreen(self):
		r_d = self.SendData("^L")
		r_d = self.SendData("#DL")
		r_d = self.SendData("#RL 0,0,128,64")
		return r_d
			
	def PanelSettings(self, bright= 100, illumination=True):
		if bright >100 : bright = 100
		self.SendData("#YH "+str(bright))	
		self.SendData("#YL "+str(int(illumination)))
		if DEBUG:
			print "Panel Brightness = %s Illumination = %s"%(str(bright),illumination)

	def DrawImage(self,pos_x=0,pos_y=0,image=[]):
		width = image[0]
		real_width = ((width/8)*8)+8
		if real_width>128:real_width = 128
		blocks = real_width/8
		height = image[1]
		init_pos_x = pos_x
		init_pos_y = pos_y

		#for a in range(0,len(image)-2,blocks):
		for a in range(len(image)-2):
			y = ((a * 8) / real_width)
			x = ((a * 8 ) - (y * real_width)) 
			
			y += init_pos_y
			x += init_pos_x
			
			if x>120 or y>63: pass
		
			#dato = image[(a+2):(a+2+blocks)]
			#dato_inv = [int("{:08b}".format(a)[::-1],2) for a in dato]
			#temp = "#UL  "+str(x)+","+str(y)+","+str(blocks*8)+",1"
			#for a in dato_inv:
			#	temp += ","+str(a)
			dato = image[a+2]
			dato_inv = int("{:08b}".format(dato)[::-1],2)
			temp = "#UL  "+str(x)+","+str(y)+",8,1,"+str(dato_inv)
			self.SendData(temp)
			if DEBUG:
				print temp
