# -*- coding: utf-8 -*-
import sys,os,time
reload(sys)
sys.setdefaultencoding('utf-8')
import struct,binascii
from utils.serialboard_manager import *

#用于数据链路层的数据格式化
class TransferData():
    def __init__(self):
        print ""

Command_Excute_Counter = 0
Status_Transfer_Send = 0x01
Status_Transfer_Return_Wait = 0x02
Status_Transfer_Return_Timeout = 0x03
Status_Transfer_CmdCRC_Error = 0x0F
Transfer_Status = Status_Transfer_Send

Status_Command_Return_Pass = 0x0A
Status_Command_Return_Fail = 0x0E
Status_Init = 0x00
Command_Status = Status_Init

Packet_Head_Offset = 0
Packet_Len_Offset = 1
Packet_uCommand_Offset = 2
Packet_CRC_Len = 2
Packet_CRC1_Back_Offset = -2
Packet_CRC2_Back_Offset = -1
Packet_Min_Len = 5

Return_Cmd_Head = 0xAB
Try_Count_Max = 3

Command_Send_End_Time = 0
Command_Read_End_Time = 0

class TCLFactoryTransfer():
    CRC_TABLE = [0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7, \
                0x8108,0x9129,0xA14A,0xB16B,0xC18C,0xD1AD,0xE1CE,0xF1EF]
    Buffer_Len = 128
    def __init__(self):
        self.serialManager = TCLSerial()

    def CRCCalculate(self, bytearr, arrLen):
        #print "Calculate command CRC,arrlen=",arrLen
        uwCRC = 0xFFFF
        ucTemp = 0x00

        index = 0
        while(index < arrLen):
            #print "calculate byte:0x%x"%bytearr[index]
            ucTemp = (uwCRC>>0x0C)& 0xFF
            #print "calculate ucTemp:0x%x" % ucTemp
            uwCRC <<= 4
            uwCRC ^= TCLFactoryTransfer.CRC_TABLE[ucTemp ^((bytearr[index])>>0x04)]
            uwCRC &= 0xFFFF
            #print "calculate uwCRC:0x%x" % (uwCRC & 0xFFFF)
            ucTemp = (uwCRC >> 0x0C) & 0xFF
            #print "calculate ucTemp:0x%x" % ucTemp
            uwCRC <<= 4
            uwCRC ^= TCLFactoryTransfer.CRC_TABLE[ucTemp^(bytearr[index]&0x0F)]
            uwCRC &= 0xFFFF
            index += 1
        return uwCRC

    def appendCRC(self, bytearr):
        # print "[TCLFactoryTransfer:sendCommandToTV], command bytes:", binascii.hexlify(bytearr)
        crc = self.CRCCalculate(bytearr, bytearr.__len__() - Packet_CRC_Len)
        # print "[TCLFactoryTransfer:sendCommandToTV],bytearr crc:0x%x" % (crc & 0xFFFF)
        crc1_index = bytearr.__len__() - 2
        crc2_index = bytearr.__len__() - 1
        bytearr[crc1_index] = crc >> 8
        bytearr[crc2_index] = crc & 0x00FF

    #返回结果True:代表指令发送成功,包含CRC校验成功。False:代表指令发送失败,包含CRC校验失败
    def sendCommandToTV(self, bytearr):
        global Transfer_Status, Command_Excute_Counter,Command_Send_End_Time,Command_Read_End_Time
        Command_Excute_Counter += 1
        #print "[TCLFactoryTransfer:sendCommandToTV], transfer send counter=", Command_Excute_Counter
        Transfer_Status = Status_Transfer_Return_Wait
        self.appendCRC(bytearr)
        #print "[TCLFactoryTransfer:sendCommandToTV], command bytes with CRC:", binascii.hexlify(bytearr)
        self.serialManager.sendCommand(bytearr)
        Command_Send_End_Time = time.time()
        while (Transfer_Status == Status_Transfer_Return_Wait):
            pass

        #print "[TCLFactoryTransfer:sendCommandToTV],command result=0x%x"%Transfer_Status
        if (Transfer_Status == Status_Command_Return_Pass) or (Transfer_Status == Status_Command_Return_Fail):
            Transfer_Status = Status_Transfer_Send
            Command_Excute_Counter = 0
            return True
        else:
            if (Command_Excute_Counter == Try_Count_Max):
                Transfer_Status = Status_Transfer_Send
                Command_Excute_Counter = 0
                return False
            else:
                return self.sendCommandToTV(bytearr)

    def checkReturnCmdCRC(self, bytearr):
        global Transfer_Status,Command_Status
        Command_Status = Status_Init
        #print "[TCLFactoryTransfer:checkCmdCRC],bytearr:", binascii.hexlify(bytearr)
        if (bytearr.__len__() < Packet_Min_Len):
            return
        #print "[TCLFactoryTransfer:checkCmdCRC],bytearr Head=%x"%bytearr[0]
        if (bytearr[Packet_Head_Offset] == Return_Cmd_Head):
            cmd_len = bytearr[Packet_Len_Offset]
            crc = self.CRCCalculate(bytearr, cmd_len - Packet_CRC_Len)
            #print "[TCLFactoryTransfer:checkCmdCRC],bytearr crc:0x%x" % (crc & 0xFFFF)
            crc1 = crc >> 8
            crc2 = crc & 0x00FF
            if (cmd_len >= Packet_Min_Len) \
                    and (crc1 == bytearr[cmd_len + Packet_CRC1_Back_Offset]) \
                    and (crc2 == bytearr[cmd_len + Packet_CRC2_Back_Offset]):
                Transfer_Status = Command_Status = bytearr[Packet_uCommand_Offset]

    def readResultLine(self):
        global Command_Read_End_Time, Transfer_Status
        line = self.serialManager.readData(TCLFactoryTransfer.Buffer_Len)
        self.checkReturnCmdCRC(line)
        Command_Read_End_Time = time.time()
        if ((Command_Read_End_Time - Command_Send_End_Time) > 0.5) and (Transfer_Status == Status_Transfer_Return_Wait):
            print "Transfer read timeout!!!"
            Transfer_Status = Status_Transfer_Return_Timeout
        return Command_Status, line