#Basic funcionality of the parser : To parse the SBD file
# -*- coding: iso-8859-15 -*-
import array
import binascii
class SBD: 
	def __init__(self, data_packet):
		self.hex_string=data_packet # 03e5694be69d24a44c0b
		self.hex_data = self.hex_string.decode("hex") #convert in to Hex
		self.array=array.array('c',self.hex_data) #put all hex into an array('c','\x03\xe5iK\xe6\x9d$\xa4L\x0b')
		self.message_header_byte=binascii.hexlify(self.array[0])
		self.DecimalHeader=int(self.message_header_byte,16)
		self.header=self.DecimalHeader#self.data_bytes[0]				#header tells what all data fields are present
		self.header_encoding_scheme={0:'GPS_Data', 1:'Date_Time', 2:'Supply Voltage', 3:'ADC Channel 0', \
			4:'ADC Channel 1', 5:'GPIO Data', 6:'Accelerometer Data', 7:'Gyroscope Data'}
		self.data_encoding_scheme={0:41, 1:28, 2:9, 3:12, 4:12, 5:2, 6:44, 7:48}
		self.field_encoding_scheme={0:[20,21], 1:[8,9,5,6], 2:[9], 3:[12], 4:[12], 5:[1,1], \
			6:[12,12,12,8], 7:[16,16,16]}
		self.field_data={0:['Latitude', 'Longitude'], 1:['Year','Day','Hour','Minute'], 2:['Supply Voltage'],\
			3:['ADC Channel 2'], 4:['ADC Channel 3'], 5:['GPIO 0','GPIO 1'], 6:['Acc X', 'Acc Y', 'Acc Z', 'Temperature'],\
			7:['Gyro X', 'Gyro Y', 'Gyro Z'] }
		self.field_functions={0:[lambda x:(x*0.00018)-90, lambda x:(x*.00018)-180], 1:[lambda x:(2000+x), 
			lambda x:x,lambda x:x,lambda x:x] , 2:[lambda x: x*0.038672], 3:[lambda x: x*0.000805664], \
			4:[lambda x: x*0.000805664], 5:[lambda x:x,lambda x:x], 6:[lambda x:x,lambda x:x,lambda x:x,lambda x:x],\
			7:[lambda x:x,lambda x:x,lambda x:x] }
		self.bitstring=''
		
		self.data_bitstrings={}   
		self.field_bitstrings={}
		self.field_ints={}
		self.final_results={0:[None, None], 1:[None,None,None,None], 2:[None],
			3:[None], 4:[None], 5:[None,None],6:[None,None,None,None],7:[None,None,None]}
		self.final_list=[]
		self.binary_array= ''             #bin(ch)[2:].rjust(8,'0')[::-1]
		for ch in self.array:
			self.binary_array+=bin(int(binascii.hexlify(ch),16))[2:].rjust(8,'0')[::-1]
			
		print(self.binary_array)
	def get_header_encoding(self):
		return(dict.values(self.header_encoding_scheme))

	def get_packet_contents(self):
		packet_contents=[]
		for i in range (0, 8):
			if (self.header & 1<<i) == 1<<i:
				packet_contents.append(self.header_encoding_scheme[i])
		return packet_contents

	def get_packet_size(self):
		size=0
		for i in range (0, 8):
			if (self.header & 1<<i) == 1<<i:
				size+=self.data_encoding_scheme[i]
		return size

	def get_bitstring(self):
		return self.binary_array

	def get_field_vals(self):
		return self.field_data

	def get_header(self):
		return self.header

	def parse_data(self):
		bitsread=8
		for i in range (0, 8): #0-7
			if (self.header & 1<<i) == 1<<i:
				field_list=[]
				field_int_list=[]
				for j in range(0,len(self.field_encoding_scheme[i])): # e.g. scheme 0 : [20,21] len:2
					bitstoread = self.field_encoding_scheme[i][j]
					
					field_str=self.binary_array[bitsread:bitsread+bitstoread]

					bitsread += bitstoread
				 	field_list.append(field_str[::-1])
					
				 	field_int_list.append(int(field_list[-1],2))#reverse order e.g. 11110000 to 00001111 then convert to decimal

				self.field_ints[i]=field_int_list
				
		return self.field_ints
		#print(bitsread)      
#self.field_encoding_scheme={0:[20,21], 1:[8,9,5,6], 2:[9], 3:[12], 4:[12], 5:[1,1],6:[12,12,12,8], 7:[16,16,16]}
	def display_parsed_data(self):
		self.parse_data()
		Path= "/home/admin.warriertech/warriertech/SBD Project/Data.txt"
		f1=open(Path,'a')
		for i in range(0,8):
			if (self.header & 1<<i) == 1<<i:
				f1.write("!--------------" + str(self.header_encoding_scheme[i]) + "--------------!")
				for j in range(0,len(self.field_encoding_scheme[i])):
					result = self.field_functions[i][j](self.field_ints[i][j])
					self.final_list.append(result)
					f1.write(self.field_data[i][j] +":" + str(result))
					self.final_results[i][j]=result
				
		return self.final_results