#Copyright (c) 2006-2007 SunMedia technology (Chengdu) co. Ltd. 
#All right reserved
#Author:jin.hu
#date:2009/09/15
import os
import sys
import string
import codecs

CASystemID = {'ACGA':'0xFFFF','BCNV':'0xFFFF','BCRT':'0xFFFF','BISS':'0xFFFF','COCN':'0xFFFF',
'COCR':'0xFFFF','COMG':'0xFFFF','CONV':'0xFFFF','CONX':'0x0B00','CRYW':'0x0D00','CWVA':'0xFFFF',
'DMV_':'0xFFFF','DRMC':'0x4A70','IRCW':'0x0D00','IRDT':'0x0600','IRKF':'0xFFFF','IRMG':'0xFFFF',
'IRNV':'0xFFFF','IRVG':'0xFFFF','MCV_':'0xFFFF','MCVI':'0xFFFF','MDS_':'0xFFFF','MGCW':'0xFFFF',
'MGIV':'0xFFFF','MGRD':'0xFFFF','MGVC':'0xFFFF','MGVG':'0xFFFF','MGVI':'0xFFFF','NAGV':'0xFFFF',
'NTL2':'0x0C00','POVU':'0xFFFF','PVU+':'0xFFFF','RAS_':'0xFFFF','SKYC':'0xFFFF','TASC':'0x2200',
'TVCM':'0x1200','VC2+':'0xFFFF','VCIR':'0xFFFF','VCON':'0xFFFF','VGRD':'0xFFFF','VIC_':'0xFFFF',
'VICS':'0x0500','VIMG':'0xFFFF','VINA':'0xFFFF','VIVG':'0xFFFF','WGNR':'0xFFFF','____':'NULL'}

CAValue = {'0x0100':'COMG', '0x0600':'IRDT', '0x0E00':'POVU','0x2200':'TASC','0x0D00':'IRCW',
    '0x0900':'IRVG', '0x0C00':'NTL2', '0x4A70':'DRMC','0xFFFF':'ACGA',
    '0x0B00':'COCN', '0x0500':'VICS', '0x1200':'TVCM', 'NULL':'____'
}

class ParserSDXFile:
    def __init__(self, sdxFile):
        self.sdxFile = sdxFile
        self.fp = 0
        self.fileDataList = []
        self.satelliteData = []
        self.satFlag = []
        self.TPData = []
        self.TPFlag = []
        self.TPFlagDict = {}
        self.serviceRadionData = []
        self.serviceTVData = []
        self.serviceData = []
        self.sdxData = []

        self.tpIndex = 0
        self.serviceIndex = 0
        
        self.structElement = []
        self.platform = 0

    def opensdxFile(self, paltform):
        self.platform = paltform
        try:
            #self.fp1 = open('E:\\DBTool111\\s1\\new.h','w')
            self.fp = open(self.sdxFile, 'r')
            self.fp.seek(0)
            self.getFileData()
            self.formatSDXData()
        except IOError:
            openFileInfo = 'Can not open file or file not existed'
    def closeCFile(self):
        self.fp.close()
    def getFileData(self):
        fileData = self.fp.read()
        self.fileDataList = fileData.split('\r')
        self.closeCFile()
    
    def setElementName(self, structElement):
        self.structElement = structElement

    def formatSDXData(self):
        for sdxData in self.fileDataList:
            if len(sdxData) != 127:
                continue
            self.formatSatellite(sdxData)
            self.formatTPData(sdxData)
            self.formatServiceData(sdxData)

    def formatSatellite(self, sdxData):
        singleSatData = {}
        band = string.atoi(sdxData[33:36]+sdxData[36:39], 10)
        if band < 9500:
            satFlag = sdxData[10:28]+'C_BAND'
            singleSatData['22KHz'] = '0'
        else:
            satFlag = sdxData[10:28]+'KU_BAND'
            singleSatData['22KHz'] = '2'
        if satFlag not in self.satFlag:
            #singleSatData.append('0')#22KHz
            #singleSatData.append('0')#12V
            singleSatData['12V'] = '0'
            singleSatData['LNB Power'] = '1'
            #singleSatData.append('0')#USALS East/West
            if string.atoi(sdxData[51:55], 10)<= 1800:
                singleSatData['USALS East/West'] = '0'
            else:
                singleSatData['USALS East/West'] = '1'
            #singleSatData.append('0')#ucDiseqcType
            singleSatData['ucDiseqcType'] = '0'
            #singleSatData.append('0')#ucDiseqcPort
            singleSatData['ucDiseqcPort'] = '0'
            singleSatData['ucPosition'] = '0'
            #singleSatData.append(sdxData[10:28])#szNetName[16]
            singleSatData['szNetName'] = sdxData[10:28]
            if string.atoi(sdxData[51:55], 10)<=1800:
                #singleSatData.append(str(string.atoi(sdxData[51:55], 10)))#iLongitude
                singleSatData['iLongitude'] = str(string.atoi(sdxData[51:55], 10))
            else:
                #singleSatData.append(str(3600-string.atoi(sdxData[51:55], 10)))#iLongitude
                singleSatData['iLongitude'] = str(3600-string.atoi(sdxData[51:55], 10))
            if band < 9500:
                #singleSatData.append('5150')#LNBFreq Vertical
                #singleSatData.append('5750')#LNBFreq Horizontal
                singleSatData['LNB Low Freq'] = '5150'
                singleSatData['LNB High Freq'] = '0'
            else:
                #singleSatData.append('9750')#LNBFreq Vertical
                #singleSatData.append('10600')#LNBFreq Horizontal
                singleSatData['LNB Low Freq'] = '9750'
                singleSatData['LNB High Freq'] = '10600'
            if band < 9500:
                #singleSatData.append('0x01')#ucInused
                singleSatData['LNB Type'] = '0'
                singleSatData['ucInUsed'] = '1'
            else:
                #singleSatData.append('0x41')#ucInused
                singleSatData['LNB Type'] = '1'
                if self.platform == 1:
                    singleSatData['ucInUsed'] = '65'
                else:
                	singleSatData['ucInUsed'] = '17'
            #singleSatData.append(' ')#netreserved
            #singleSatData.append('0')#netreserved_future_use
            singleSatData['netreserved'] = '0'
            singleSatData['netreserved_future_use'] = '0'
            self.satFlag.append(satFlag)
            self.satelliteData.append(singleSatData)
    def formatTPData(self, sdxData):
        singleTPData = {}
        band = string.atoi(sdxData[33:36]+sdxData[36:39], 10)
        satFlag = 'KU_BAND'
        if band < 9500:
            satFlag = 'C_BAND'
        TPFlagItem = sdxData[10:28] + satFlag + sdxData[33:36]+sdxData[36:39]+sdxData[42:43]
        
        if self.TPFlagDict.has_key(sdxData[10:28]+satFlag):
            if TPFlagItem in self.TPFlagDict[sdxData[10:28]+satFlag]:
                return
        #singleTPData.append('NULL')#szTpName[16]
        singleTPData['szTpName'] = 'NULL'
        #singleTPData.append(sdxData[33:36]+sdxData[36:39])#usFreqM
        singleTPData['usFreqM'] = sdxData[33:36]+sdxData[36:39]
        #singleTPData.append(sdxData[69:74])#usSymRateK
        singleTPData['usSymRateK'] = sdxData[69:74]
        #singleTPData.append(str(self.satFlag.index(sdxData[10:28]+satFlag)))#usSatIndex
        singleTPData['usSatIndex'] = str(self.satFlag.index(sdxData[10:28]+satFlag))
        #singleTPData.append(str(self.tpIndex))#usTpIndex
        singleTPData['usTpIndex'] = str(self.tpIndex)
        #singleTPData.append(sdxData[42:43])#ucSkew
        singleTPData['ucSkew'] = sdxData[42:43]
        #singleTPData.append(sdxData[74:75])#ucVCRate
        singleTPData['ucVCRate'] = sdxData[74:75]
        #singleTPData.append('0')#ucFlag
        singleTPData['ucFlag'] = '0'
        #singleTPData.append('1')#ucInUsed
        singleTPData['ucInUsed'] = '1'
        #singleTPData.append('  ')#tpreserved[2]
        singleTPData['tpreserved'] = ''
        #singleTPData.append('0')#tpreserved_future_use
        singleTPData['tpreserved_future_use'] = '0'
        self.TPData.append(singleTPData)
        self.TPFlag.append(TPFlagItem)
        if self.TPFlagDict.has_key(sdxData[10:28]+satFlag):
            tpValueList = self.TPFlagDict[sdxData[10:28]+satFlag]
            tpValueList.append(TPFlagItem)
            self.TPFlagDict[sdxData[10:28]+satFlag] = tpValueList
        else:
            tpValueList = []
            tpValueList.append(TPFlagItem)
            self.TPFlagDict[sdxData[10:28]+satFlag] = tpValueList
        self.tpIndex += 1

    def formatServiceData(self, sdxData):
        satFlag = 'KU_BAND'
        band = string.atoi(sdxData[33:36]+sdxData[36:39], 10)
        if band < 9500:
            satFlag = 'C_BAND'
        singleServiceData = {}
        #singleServiceData.append('1')#ucInUsed
        singleServiceData['ucInUsed'] = '1'
        #singleServiceData.append(sdxData[43:51] + sdxData[115:127])#szProgName[40]
        singleServiceData['szProgName'] = sdxData[43:51] + sdxData[115:127]
        #singleServiceData.append(str(self.serviceIndex))
        singleServiceData['usProgNo'] = str(self.serviceIndex)
        #singleServiceData.append(str(self.TPFlag.index(sdxData[33:36]+sdxData[36:39]+sdxData[42:43])))#usTpIndex
        TPFlagItem = sdxData[10:28] + satFlag + sdxData[33:36]+sdxData[36:39]+sdxData[42:43]
        singleServiceData['usTpIndex'] = str(self.TPFlag.index(TPFlagItem))
        #singleServiceData.append(sdxData[87:92])#usServiceId
        singleServiceData['usServiceId'] = sdxData[87:92]
        #singleServiceData.append(sdxData[97:102])#usTsId
        singleServiceData['usTsId'] = sdxData[97:102]
        #singleServiceData.append(sdxData[92:97])#usOrigNetId
        singleServiceData['usOrigNetId'] = sdxData[92:97]
        #singleServiceData.append(sdxData[75:79])#stVideoPid
        caSystemValue = 'Unknown'
        if CASystemID.has_key(sdxData[111:115]):
            caSystemValue = CASystemID[sdxData[111:115]]
        if sdxData[75:79] == '____':
            singleServiceData['Video PID'] = '0000'
            singleServiceData['usDataPID'] = '0'
            singleServiceData['usECMPID'] = '0'
        else:
            singleServiceData['Video PID'] = sdxData[75:79]
            singleServiceData['usDataPID'] = sdxData[75:79]
            singleServiceData['usECMPID'] = '0'
        if caSystemValue == 'Unknown' or caSystemValue == 'NULL' or caSystemValue == '0xFFFF':
            singleServiceData['Video Data'] = '0x1FFF00000000'
        else:
            singleServiceData['Video Data'] = '0x000000000000'
        #singleServiceData.append(sdxData[79:83])#stAudioPid1
        if sdxData[79:83] == '____':
            singleServiceData['Audio PID 1'] = '0000'
            singleServiceData['Audio1 PID'] = '0'
            singleServiceData['Audio1 PID Track'] = '0'
            singleServiceData['Audio1 Data'] = '0'
        else:
            singleServiceData['Audio PID 1'] = sdxData[79:83]
            audioValue = int(sdxData[79:83])
            singleServiceData['Audio1 PID'] = str(audioValue<<51>>51)
            singleServiceData['Audio1 PID Track'] = '0'
            singleServiceData['Audio1 Data'] = str(audioValue>>48&0xffff)
        if caSystemValue == 'Unknown' or caSystemValue == 'NULL' or caSystemValue == '0xFFFF':
            singleServiceData['Audio1 Data'] = '0x1FFF00000000'
        else:
            singleServiceData['Audio1 Data'] = '0x000000000000'
        #singleServiceData.append('0x1FFF')#stAudioPid2
        singleServiceData['Audio2 PID'] = '0x1FFF'
        if caSystemValue == 'Unknown' or caSystemValue == 'NULL' or caSystemValue == '0xFFFF':
            singleServiceData['Audio2 Data'] = '0x1FFF00000000'
        else:
        	singleServiceData['Audio2 Data'] = '0x000000000000'
        #singleServiceData.append(sdxData[83:87])#usPcrPid
        singleServiceData['usPcrPid'] = sdxData[83:87]
        #singleServiceData.append(sdxData[28:29])#usServiceType
        if sdxData[111:115] == '____':
            singleServiceData['uiProgAttrib'] = '0x0000'
            singleServiceData['usServiceType'] = '0'
        else:
            singleServiceData['usServiceType'] = '1'
            singleServiceData['uiProgAttrib'] = '0x1000'
        if sdxData[28:29] == 'T':
            singleServiceData['ucTvRadioType'] = '1'
        elif sdxData[28:29] == 'R':
            singleServiceData['ucTvRadioType'] = '2'
        #singleServiceData.append('0')#usPMTPid
        singleServiceData['usPMTPid'] = '0'
        #singleServiceData.append(caSystemValue)#usCASystemID
        singleServiceData['usCASystemID'] = caSystemValue
        #singleServiceData.append('  ')#serreserved[2]
        singleServiceData['szServiceReserved'] = ''
        #singleServiceData.append('0')#serreserved_future_use
        singleServiceData['serreserved_future_use'] = ''
        if sdxData[28:29] == 'T':
            self.serviceData.append(singleServiceData)
            self.serviceTVData.append(singleServiceData)
        elif sdxData[28:29] == 'R':
            self.serviceData.append(singleServiceData)
            self.serviceRadionData.append(singleServiceData)
        #singleDataFlag = []
        #singleDataFlag.append(sdxData[43:51] + sdxData[115:127])
        #singleDataFlag.append(sdxData[10:28]+sdxData[36:39])
        #singleDataFlag.append(sdxData[36:39]+sdxData[42:43])
        #singleDataFlag.append(sdxData[28:29])
        self.serviceIndex += 1
    
    def sortData(self, sdxData):
        dataList = []
        for singleDataDict in sdxData:
            singleDataList = []
            for elementName in self.structElement:
                if elementName.find('[') != -1:
                    elementName = elementName[:elementName.find('[')]
                if singleDataDict.has_key(elementName):
                    singleDataList.append(singleDataDict[elementName])
                else:
                    singleDataList.append('0')
            dataList.append(singleDataList)
        return dataList
    def getSatData(self):
        return self.sortData(self.satelliteData)
        #return self.satelliteData
    def getTPData(self):
        return self.sortData(self.TPData)
        #return self.TPData
    def getServiceData(self):
        #self.fp1.write(str(self.serviceData))
        return self.sortData(self.serviceData)
        #return self.serviceTVData + self.serviceRadionData

class ExportSDX:
    def __init__(self, sdxFile):
        self.sdxFile = sdxFile
        self.sdxDataDict = {}
        self.fp = open(self.sdxFile, 'wb')
    
    def formatString(self, formatValue, formatBitWidth, addNumber = False):
        if len(formatValue) == formatBitWidth:
            formatValue = formatValue
        elif len(formatValue) > formatBitWidth:
            formatValue = formatValue[0:formatBitWidth]
        else:
            if addNumber == False:
                for i in range(formatBitWidth-len(formatValue)):
                    formatValue += ' '
            else:
                addString = ''
                for i in range(formatBitWidth-len(formatValue)):
                    addString += '0'
                formatValue = addString + formatValue
        return formatValue
      
    def setDictItem(self, key , value):
        if key.find('[') != -1:
            key = key[:key.find('[')]
        self.sdxDataDict[key] = value
    def resetValue(self):
        self.sdxDataDict = {}

    def writeSDXFile(self):
        sdxData = 'SATCODX103'
        if self.sdxDataDict.has_key('szNetName'):
            sdxData += self.formatString(self.sdxDataDict['szNetName'], 18)
        else:
            sdxData += '                  '
        if self.sdxDataDict.has_key('ucTvRadioType'):
            serviceType = self.formatString(self.sdxDataDict['ucTvRadioType'], 1)
            if serviceType != ' ':
                if serviceType == '1':
                    sdxData += 'T'
                else:
                    sdxData += 'R'
            else:
                sdxData += 'D'
        else:
            sdxData += 'D'
        sdxData += 'MPG2'
        if self.sdxDataDict.has_key('usFreqM'):
            sdxData += self.formatString(self.sdxDataDict['usFreqM'], 6, True)
        else:
            sdxData += '000000'
        sdxData += '000'
        if self.sdxDataDict.has_key('ucSkew'):
            sdxData += self.formatString(self.sdxDataDict['ucSkew'], 1)
        else:
            sdxData += '0'
        if self.sdxDataDict.has_key('szProgName'):
            sdxData += self.formatString(self.sdxDataDict['szProgName'][0:8], 8)
        else:
            sdxData += '        '
        if self.sdxDataDict.has_key('iLongitude'):
            if self.sdxDataDict['iLongitude'] == '':
                self.sdxDataDict['iLongitude'] = '0'
            base = 10
            if self.sdxDataDict['iLongitude'].find('0x') != -1:
                base = 16
            if self.sdxDataDict.has_key('USALS East/West'):
                if self.sdxDataDict['USALS East/West'] == '0':
                    positionData = str(int(self.sdxDataDict['iLongitude'], base))
                    sdxData += self.formatString(positionData, 4, True)
                else:
                    sdxData += str(3600-int(self.sdxDataDict['iLongitude'], base))
            else:
                sdxData += str(3600-int(self.sdxDataDict['iLongitude'], base))
        else:
            sdxData += '0000'
        sdxData += 'TEL02CKU'
        sdxData += '______'
        if self.sdxDataDict.has_key('usSymRateK'):
            sdxData += self.formatString(self.sdxDataDict['usSymRateK'], 5, True)
        else:
            sdxData += '00000'
        if self.sdxDataDict.has_key('ucVCRate'):
            sdxData += self.formatString(self.sdxDataDict['ucVCRate'], 1, True)
        else:
            sdxData += '0'
        if self.sdxDataDict.has_key('stVideoPid'):
            sdxData += self.formatString(self.sdxDataDict['stVideoPid'], 4, True)
        elif self.sdxDataDict.has_key('Video PID'):
            sdxData += self.formatString(self.sdxDataDict['Video PID'], 4, True)
        elif self.sdxDataDict.has_key('usDataPID'):
            sdxData += self.formatString(self.sdxDataDict['usDataPID'], 4, True)
        else:
            sdxData += '0000'
        if self.sdxDataDict.has_key('Audio PID 1'):
            sdxData += self.formatString(self.sdxDataDict['Audio PID 1'], 4, True)
        elif self.sdxDataDict.has_key('Audio1 PID'):
            sdxData += self.formatString(self.sdxDataDict['Audio1 PID'], 4, True)
        elif self.sdxDataDict.has_key('Audio PID 1_1'):
        	sdxData += self.formatString(self.sdxDataDict['Audio PID 1_1'], 4, True)
        else:
            sdxData += '0000'
            '''
            if self.sdxDataDict.has_key('Audio PID 1_1') and self.sdxDataDict.has_key('Audio PID 1_Track') and self.sdxDataDict.has_key('Audio PID 1_2'):
                base = 10
                if self.sdxDataDict['Audio PID 1_1'].find('0x') != -1:
                    base = 16
                try:
                    audioValue1 = int(self.sdxDataDict['Audio PID 1_1'], base)
                except Exception:
                    audioValue1 = 0
                #audioValue2 = int(self.sdxDataDict['Audio PID 1_Track'], base)<<13 
                #audioValue3 = int(self.sdxDataDict['Audio PID 1_2'], base)<<48
                #audioValue = str(audioValue1 | audioValue2 | audioValue3)
                sdxData += self.formatString(str(audioValue1), 4, True)
                '''
            
        if self.sdxDataDict.has_key('usPcrPid'):
            sdxData += self.formatString(self.sdxDataDict['usPcrPid'], 4, True)
        else:
            sdxData += '0000'
        if self.sdxDataDict.has_key('usServiceId'):
            sdxData += self.formatString(self.sdxDataDict['usServiceId'], 5, True)
        else:
            sdxData += '00000'
        if self.sdxDataDict.has_key('usOrigNetId'):
            sdxData += self.formatString(self.sdxDataDict['usOrigNetId'], 5, True)
        else:
            sdxData += '00000'
        if self.sdxDataDict.has_key('usTsId'):
            sdxData += self.formatString(self.sdxDataDict['usTsId'], 5, True)
        else:
            sdxData += '00000'
        sdxData += '____'
        sdxData += '_____'
        if self.sdxDataDict.has_key('usCASystemID'):
            if CAValue.has_key(self.sdxDataDict['usCASystemID']):
                sdxData += CAValue[self.sdxDataDict['usCASystemID']]
            else:
                sdxData += '____'
        else:
            sdxData += '____'
        if self.sdxDataDict.has_key('szProgName'):
            sdxData += self.formatString(self.sdxDataDict['szProgName'][8:20], 12)
        else:
            sdxData += '            '
        sdxData += '\r'
        self.fp.write(sdxData)


def testSDX ():
    c = ParserSDXFile('E:\\DBTool\\set-one.sdx')
    c.opensdxFile()
    print len(c.getServiceData())
    '''
    c.formatSatellite()
    c.formatTPData()
    c.formatServiceData()
    '''
    #for i in c.getServiceData():
        #print i

def exportSDX():
    c = ExportSDX('E:\\DBTool\\hujin.sdx')
    sdxData = {}
    c.writeSDXFile(sdxData)

if __name__ == '__main__':
    testSDX()