from __future__ import print_function
import sys,struct,glob,array,numpy
import makeHistogram as mH

def timeTrigNet(inputParam, TimeList):
    """
    Time table make from TrigNET T0
    """

    if isinstance(inputParam,int):
	filename=mH.getFilePath(inputParam,'TrigNET')
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        filelist=glob.glob(inputParam)
        filename=filelist[0]

    if len(filename)>0:
	firstPID = -1 # local
	PID = 0 # local
	PIDb = -1 # local
	#nT0 = 0

	#--------------------------
	f = open(filename, "rb")
	while 1:
	    a=f.read(8)
	    if len(a)==0:
		break
	#--------------------------
            b=mH.decode_VNR_TrigNET(a)

            if b[1]==-999:
                continue

            if b[0]=='0x5b':

                PID = long(b[3])
                if firstPID == -1:
                    firstPID = PID
		    PIDb = PID - 1

	    else:
		if b[0]=='0x5c':
		    clk=str2clk(a[1:8])
		    T0=clk[0]+clk[1]+clk[2]
		    PIDb += 1
		    while ( PID > PIDb):
			T0b += 0.04
			TimeList.append(T0b)
			PIDb += 1
			#nT0 += 1
		    TimeList.append(T0)
		    #nT0 += 1
		    T0b = T0

	#--------------------------
	f.close()
	#--------------------------
    return TimeList


def c2l(c):
	return long(ord(c))

def str2clk(d):
	if 7==len(d):
	    sec=long((c2l(d[0])<<22)+(c2l(d[1])<<14)+(c2l(d[2])<<6)+(c2l(d[3])>>2))
	    subsec=float(((c2l(d[3])&3)<<13)+(c2l(d[4])<<5)+(c2l(d[5])>>3))/32768.
	    submsec=float(((c2l(d[5])&0x7)<<8)+c2l(d[6]))/40000000.
	    return sec,subsec,submsec

def getEventDataArrayTime(inputParam,detector="MWPC",pixels=(256,256),dio=-1, nT0start=0, nT0end=-1, initial_bin=10000.0, final_bin=38100.0):
    """
    Modified in 1703 ver. (s.kasai)
    used array.array to conserve memory
    """
    if nT0end == -1:
        nT0end = 2 ** 32  # nT0 end set to very large number

    print("dio in getEventDataArray", dio)

    dioSortingList=[]
    if dio != -1:
        dioSortingList = mH.processTrigNet(inputParam, dioSortingList, dio)

    T0Count = []
    T0Count = mH.createT0Count(dio, dioSortingList, T0Count)

    TimeList=[]
    TimeList = timeTrigNet(inputParam, TimeList)

    if isinstance(inputParam,int):
        filelist=mH.getFilePathNew(inputParam,detector)
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        filelist=glob.glob(inputParam)
    
    PX=pixels[0]
    PY=pixels[1]
    if dio == -1 or dio == 0:

        data=[[[array.array('I') for i in xrange(PX)] for j in xrange(PY)]]
    else:
        data=[[[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('I') for i in xrange(PX)] for j in xrange(PY)]]

    indexDIO=0
    t0indexorigin=-1
    iDIO = 0 # flag
    nDIO = 0 # count bet. each periods
    fDIO = 0 # flag for increasing an index
    nT0 = 0 # for dio=-1

    #nT0Range = 0L # for T0 range

    #func_name = "".join(['decode_',XXX,'_',detector])
    #func = globals()[func_name]

    #nT0_in_range = False # Flag if nT0 is in parameters set by option
    for filename in filelist:
        with open(filename, "rb") as f:
	    i1=0
	    i2=0

	    while 1:
		a=f.read(8)
		if len(a)==0:
		    break
		#b = func(a)
		b = mH.decode_VNR_MWPC(a)
		if b[1]==-999:
                    #AS Start 20160125 4 byte back for many bad data reduction.
                    f.seek(-4,1)
                    #AS End
                    continue

                if b[0]=='0xb7':
		    # check time  by s.k
		    #decode = struct.unpack('8B', a)
		    #t0count = (decode[7]<<23) | (decode[6]<<15) | (decode[5]<<7) | ((decode[4]&0xFE)>>1)
		    t0count = b[2]
		    if t0indexorigin < 0:
			t0indexorigin = t0count
		    neutime = TimeList[ t0count - t0indexorigin] - TimeList[0]
		    if ( neutime >= float( nT0end)):
			break
		    # nT0 range check (1610 AS)
		    # nT0Range+=1L
		    # if nT0Range > nT0end:
		    #    break
		    # elif nT0Range >= nT0start:
		    #    nT0_in_range = True
		    # nT0 range check end
		    if dio == -1:
			if neutime > float(nT0start):
			    nT0+=1
		    else:
			if len(dioSortingList)==0:
			    break

			if fDIO==1:
			    indexDIO+=1
			    nDIO = 0
			    fDIO = 0
			    if indexDIO >= len(dioSortingList):
				break

			PID = long(b[2])
                        #print '################### ', indexDIO, len(dioSortingList)
                        if dioSortingList[indexDIO][1]>PID:
                        #print 'before PID ', PID
                            iDIO = 0
                            nDIO = 0

                        elif dioSortingList[indexDIO][1]+dioSortingList[indexDIO][3]>=PID:
                            iDIO = 1
                            #print '*** ', PID, dioSortingList[indexDIO]

                        if dioSortingList[indexDIO][1]+dioSortingList[indexDIO][3]==PID:
                            fDIO = 1

		#elif b[0] == '0xb5' and nT0_in_range: # nT0 flag check added (1610 AS)
		elif b[0] == '0xb5':
                    if b[1]>=initial_bin and b[1]<=final_bin and b[2]<PX and b[3]<PY:
			t0time = TimeList[ t0count - t0indexorigin] - TimeList[0]
			neutime = t0time + float(b[1]) / 1000000.0
			neui = int( neutime)

			if ( neui >= nT0start):
			    if dio == -1:
				data[0][b[3]][b[2]].append(neui)
			    elif dio == 0:
				if iDIO == 1:
				    nDIO+=1
				    data[0][b[3]][b[2]].append(neui)
			    else:
				if iDIO == 1:
				    nDIO+=1
				    data[dioSortingList[indexDIO][0]][b[3]][b[2]].append(neui)


    if dio == -1:
	T0Count.append(nT0)

    datalist=[]

    if dio == -1 or dio == 0:
        dl = []
        dl=[[numpy.array(data[0][j][i]) for i in xrange(PX)] for j in xrange(PY)]
        datalist.append(dl)
    else:
        for k in [0,1,2,3]:
            dl = []
            dl=[[numpy.array(data[k][j][i]) for i in xrange(PX)] for j in xrange(PY)]
            datalist.append(dl)

    print(T0Count)
    return datalist, T0Count, neutime

################
def getEventDataArrayMulti(inputParam,detector="MWPC",pixels=(256,256),dio=-1, nT0start=0, nT0end=-1, nT0step=-1, initial_bin=10000.0, final_bin=38100.0):
    """
    Made in 1703 ver. (by s.kasai)
    used array.array to conserve memory
    """
    if nT0end == -1:
        nT0end = 2 ** 32  # nT0 end set to very large number

    print("dio in getEventDataArray", dio)

    dioSortingList=[]
    if dio != -1:
        dioSortingList = mH.processTrigNet(inputParam, dioSortingList, dio)

    TimeList=[]
    TimeList = timeTrigNet(inputParam, TimeList)

    if isinstance(inputParam,int):
        filelist=mH.getFilePathNew(inputParam,detector)
    elif isinstance(inputParam,str) or isinstance(inputParam,unicode):
        filelist=glob.glob(inputParam)
    
    PX=pixels[0]
    PY=pixels[1]
    if dio == -1 or dio == 0:

        data=[[[array.array('I') for i in xrange(PX)] for j in xrange(PY)]]
    else:
        data=[[[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
              [[array.array('I') for i in xrange(PX)] for j in xrange(PY)]]

    indexDIO=0
    t0indexorigin=-1
    t0count = 0

    iDIO = 0 # flag
    # nDIO = 0 # count bet. each periods
    nextHisto = False # go next histogram
    fDIO = 0 # flag for increasing an index


    nT0 = 0 # for dio=-1
    nT0l = [0, 0, 0, 0] # for dio=0, or above
    T0Count = []
    datalist=[]

    #func_name = "".join(['decode_',XXX,'_',detector])
    #func = globals()[func_name]

    for filename in filelist:
        with open(filename, "rb") as f:

	    while 1:
		a=f.read(8)
		if len(a)==0:
		    break
		#b = func(a)
		b = mH.decode_VNR_MWPC(a)
		if b[1]==-999:
                    #AS Start 20160125 4 byte back for many bad data reduction.
                    f.seek(-4,1)
                    #AS End
                    continue

                if b[0]=='0xb7':
		    t0count = b[2]
		    if t0indexorigin < 0:
			t0indexorigin = t0count
		    neutime = TimeList[ t0count - t0indexorigin] - TimeList[0]
		    if ( neutime >= float( nT0end)):
			break
		    if ( nextHisto == True and nT0step > 0):
			nT0start += nT0step
			if dio == -1:
			    T0Count.append(nT0)
			    nT0 = 0
			else:
			    if dio == 0:
				T0Count.append( sum(nT0l))
			    else:
				T0Count.append( nT0l)
			    nT0l = [0,0,0,0]

			if dio == -1 or dio == 0:
			    dl = []
			    dl=[[numpy.array(data[0][j][i]) for i in xrange(PX)] for j in xrange(PY)]
			    datalist.append(dl)
			    data=[[[array.array('I') for i in xrange(PX)] for j in xrange(PY)]]
			else:
			    for k in [0,1,2,3]:
				dl = []
				dl=[[numpy.array(data[k][j][i]) for i in xrange(PX)] for j in xrange(PY)]
				datalist.append([dl])
			    data=[[[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
				  [[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
				  [[array.array('I') for i in xrange(PX)] for j in xrange(PY)],
				  [[array.array('I') for i in xrange(PX)] for j in xrange(PY)]]
			nextHisto = False

		    if dio == -1:
			if neutime > float(nT0start):
			    nT0+=1
		    else:
			if len(dioSortingList)==0:
			    break

			if fDIO==1:
			    indexDIO+=1
			    fDIO = 0
			    if indexDIO >= len(dioSortingList):
				break

			PID = long(b[2])
			if dioSortingList[indexDIO][1]>PID:
			    iDIO = 0

			elif dioSortingList[indexDIO][1]+dioSortingList[indexDIO][3]>=PID:
			    iDIO = 1
			    T0Count[dioSortingList[indexDIO][0]] += 1

			if dioSortingList[indexDIO][1]+dioSortingList[indexDIO][3]==PID:
			    fDIO = 1

		elif b[0] == '0xb5' and t0indexorigin >= 0:
		    t0time = TimeList[ t0count - t0indexorigin] - TimeList[0]
		    if ( nT0step > 0 and (t0time + 0.04) >= float( nT0start+nT0step)):
			nextHisto = True
		    if b[1]>=initial_bin and b[1]<=final_bin and b[2]<PX and b[3]<PY:
			neutime = t0time + float(b[1]) / 1000000.0

			if ( neutime >= float(nT0start)):
			    if dio == -1:
				data[0][b[3]][b[2]].append(b[1])
			    elif dio == 0:
				if iDIO == 1:
				    #nDIO+=1
				    data[0][b[3]][b[2]].append(b[1])
			    else:
				if iDIO == 1:
				    #nDIO+=1
				    data[dioSortingList[indexDIO][0]][b[3]][b[2]].append(b[1])

    if dio == -1:
	if ( nT0 > 0):
	    T0Count.append(nT0)
	    dl = []
	    dl=[[numpy.array(data[0][j][i]) for i in xrange(PX)] for j in xrange(PY)]
	    datalist.append(dl)
    else:
	if ( sum(nT0l) > 0):
	    if ( dio == 0):
		T0Count.append( sum(nT0l))
		dl = []
		dl=[[numpy.array(data[0][j][i]) for i in xrange(PX)] for j in xrange(PY)]
		datalist.append(dl)
	    else:
		T0Count.append( nT0l)
		for k in [0,1,2,3]:
		    dl = []
		    dl=[[numpy.array(data[k][j][i]) for i in xrange(PX)] for j in xrange(PY)]
		    datalist.append([dl])

    print(T0Count)
    return datalist, T0Count
