from __future__ import print_function
import Manyo as mm
import os

LineFeedCode="\r"
#----------------------------------------------------------------------------------------------------------------------------

def printCenterValue(ecX):

    xvalues=""
    NumOfX=ecX.size()-1
    for i in range(NumOfX):
        if abs((ecX[i]+ecX[i+1])*0.5)<1e-10:
            xvalues=xvalues+"0.00"+LineFeedCode
        else:
            xvalues=xvalues+str((ecX[i]+ecX[i+1])*0.5)+LineFeedCode

    return xvalues

#----------------------------------------------------------------------------------------------------------------------------

def printIntensityAndError(ec):
    values=""
    ecY=ec.PutY()
    ecE=ec.PutE()
    NumOfY=ecY.size()

    for i in range(NumOfY):
        if abs(ecY[i])<1e-10:
            values=values+"0.00"+" "
        else:
            values=values+str(ecY[i])+" "

        if abs(ecE[i])<1e-10:
            values=values+"0.00"+LineFeedCode
        else:
            values=values+str(ecE[i])+LineFeedCode
    return values

#----------------------------------------------------------------------------------------------------------------------------

def exportDaveFormat(eca,filepath):
    base_ec = 0
    output = ""
    NumOfY = eca.PutTableSize()
    NumOfX = eca.Put(base_ec).PutX().size()-1

    xvalue = eca.Put(base_ec).PutX()
    xvalueStr = printCenterValue(xvalue)

    qvalue=[]
    for i in range(NumOfY):
        ec=eca.Put(i)
        hh=ec.PutHeader()
        if hh.CheckKey("XRANGE"): #"XRANGE" header means Q-boundary(min,max)
            QR = hh.PutDoubleVector("XRANGE")
            if i == 0:
                qvalue.append(QR[0])
            else:
                pass
            qvalue.append(QR[1])
        else:
            if i == 0:
                qvalue.append(0.0)
            else:
                pass
            qvalue.append(i+1.0)

    qvalue=mm.ListToDoubleVector(qvalue)
    qvalueStr = printCenterValue(qvalue)

    output = "# Number of x-values"+LineFeedCode\
           +str(NumOfX)+LineFeedCode\
           +"# Number of y-values"+LineFeedCode\
           +str(NumOfY)+LineFeedCode\
           +"# xvalues:"+LineFeedCode\
           + xvalueStr\
           +"# yvalues:"+LineFeedCode\
           + qvalueStr

    for i in range(NumOfY):
        output = output +"Group: "+str(i)+LineFeedCode
        yevalue=printIntensityAndError(eca.Put(i))
        output = output + yevalue

    f = open(filepath, 'w')
    f.write(output)
    f.close()

#----------------------------------------------------------------------------------------------------------------------------

def importDaveFormat(filepath):
    NumOfX=""
    NumOfY=""
    xvalue=[]
    qvalue=[]
    yvalue=[]
    evalue=[]

    eca=mm.ElementContainerArray()

    fi = open(filepath, 'rU')
    line = [li for li in fi]

    for i in range(len(line)):
        if "Number of x-values" in line[i]: #search "Number of x-values" line
            NumOfX = line[i+1]
        if "Number of y-values" in line[i]: #search "Number of y-values" line
            NumOfY = line[i+1]

    for i in range(len(line)):
        if "xvalues" in line[i]:            #search "xvalues" line
            for j in range(int(NumOfX)):
                xvalue.append(float(line[i+j+1].rstrip("\n")))

        if "yvalues" in line[i]:            #search "yvalues" line
            for j in range(int(NumOfY)):
                qvalue.append(float(line[i+j+1].rstrip("\n")))

        for k in range(int(NumOfY)):             #search "Group" line
            if "Group: "+str(k) in line[i]:
                yvalue_element=[]
                evalue_element=[]
                for j in range(int(NumOfX)):
                    yvalue_element.append(float(line[i+j+1].split()[0]))
                    evalue_element.append(float(line[i+j+1].split()[1].rstrip("\n")))
                yvalue.append(yvalue_element)
                evalue.append(evalue_element)

    dx=-(xvalue[1]-xvalue[0])*0.5+xvalue[0] # dx is initial x-bin 
    ecX=[dx]
    for i in range(int(NumOfX)):
        ecX.append(xvalue[i]+(-ecX[i]+xvalue[i]))

    dq=-(qvalue[1]-qvalue[0])*0.5+qvalue[0] # dq is initial q-bin
    ecQ=[dq]
    for i in range(int(NumOfY)):
        ecQ.append(qvalue[i]+(-ecQ[i]+qvalue[i]))

    for i in range(int(NumOfY)):
        ec=mm.ElementContainer()
        ec.Add("x",ecX)
        ec.Add("y",yvalue[i])
        ec.Add("e",evalue[i])
        ec.SetKeys("x","y","e")
        hh= mm.HeaderBase()
        hh.Add("XRANGE",mm.ListToDoubleVector([ecQ[i],ecQ[i+1]]))
        ec.InputHeader(hh)
        eca.Add(ec)

    fi.close()

    return eca

#----------------------------------------------------------------------------------------------------------------------------

def importTextFormat(filepath):
    fi = open(filepath, 'r')
    line = [li.split() for li in fi]
    xvalue=[]
    yvalue=[]
    evalue=[]
    qvalue=[]
    xvalue_element=[]
    yvalue_element=[]
    evalue_element=[]
    data=[]
    tmpQ=None

    eca=mm.ElementContainerArray()

    for li in line:
        if tmpQ!=None:
            if tmpQ!=li[0]:
                xvalue.append(xvalue_element)
                yvalue.append(yvalue_element)
                evalue.append(evalue_element)
                qvalue.append(float(li[0]))
                xvalue_element=[]
                yvalue_element=[]
                evalue_element=[]

        xvalue_element.append(float(li[1]))
        yvalue_element.append(float(li[2]))
        evalue_element.append(float(li[3]))

        if li == line[-1]:
            xvalue.append(xvalue_element)
            yvalue.append(yvalue_element)
            evalue.append(evalue_element)
            qvalue.append(float(li[0]))
        tmpQ=li[0]

    dx=-(xvalue[0][1]-xvalue[0][0])*0.5+xvalue[0][0] # dx is initial x-bin 
    ecX=[dx]
    for i in range(len(xvalue[0])):
        ecX.append(xvalue[0][i]+(-ecX[i]+xvalue[0][i]))

    dq=-(qvalue[1]-qvalue[0])*0.5+qvalue[0] # dq is initial q-bin
    ecQ=[dq]
    for i in range(len(qvalue)):
        ecQ.append(qvalue[i]+(-ecQ[i]+qvalue[i]))

    for i in range(len(qvalue)):
        ec=mm.ElementContainer()
        ec.Add("x",ecX)
        ec.Add("y",yvalue[i])
        ec.Add("e",evalue[i])
        ec.SetKeys("x","y","e")
        hh= mm.HeaderBase()
        hh.Add("XRANGE",mm.ListToDoubleVector([ecQ[i],ecQ[i+1]]))
        ec.InputHeader(hh)
        eca.Add(ec)

    fi.close()

    return eca

#----------------------------------------------------------------------------------------------------------------------------
def exportTextFormat(eca,filepath):
    """
    @param eca           (ElementContainerArray)
    @param filepath      (str)
    @retval None
    """
    num_of_ec=eca.PutSize()

    flug = os.path.exists(filepath)
    if flug:
           os.rename(filepath,filepath+"_bk1" )
    f = open(filepath, "w")

    for i in range(num_of_ec):
        ec = eca.PutPointer(i)
        hh = ec.PutHeaderPointer()

        Q_vec = hh.PutDoubleVector("XRANGE")
        Q=(Q_vec[0]+Q_vec[1])/2

        EnergyBin_org=ec.PutX()
        EnergyBin_org_size=len(EnergyBin_org)
        EnergyBin =[]
        IntensityBin=ec.PutY()
        ErrorBin=ec.PutE()

        for j in range(EnergyBin_org_size-1):
            EnergyBin_center = (EnergyBin_org[j]+EnergyBin_org[j+1])/2
            if abs(EnergyBin_center)<0.000001:
                   EnergyBin = 0.0
            else:
                   EnergyBin = EnergyBin_center
            f.write(str(Q)+"\t"+str(EnergyBin)+"\t"+str(IntensityBin[j])+"\t"+str(ErrorBin[j])+"\n")
    f.close()
#----------------------------------------------------------------------------------------------------------------------------

def OutputECText(ec,filename):
    """
    @param ec      (ElementContainer)
    @param filename          (string)
    @retval None
    """
    flug = os.path.exists(filename)
    if flug:
           os.rename(filename,filename+"_bk1" )

    f = open(filename, "w")

    xbin = ec.PutX()
    ybin = ec.PutY()
    ebin = ec.PutE()
 
    for i in range(len(ybin)):
        f.write(str((xbin[i]+xbin[i+1])*0.5)+"\t"+str(ybin[i])+"\t"+str(ebin[i])+"\n")
    f.close()

    print("")
    print("output >> ",filename)
    
    return

#----------------------------------------------------------------------------------------------------------------------------

def ReadECA(filename):
    """
    @param filename  (string)
    @retval eca      (ElementContainerArray)
    """
    flug = os.path.exists(filename)
    if flug:
        mread = mm.ReadSerializationFileBinary(filename)
        eca = mm.ElementContainerArray()

        mread.Load( eca )

    else:
           print("")
           print("can not find data file")
           print("")
           return
    return eca

#----------------------------------------------------------------------------------------------------------------------------

def OutputECA(eca,filepath):
    """
    @param eca           (ElementContainerArray)
    @param filepath      (str)
    @retval None
    """
    flug = os.path.exists(filepath)
    if flug:
           os.rename(filepath,filepath+"_bk1" )
    Mout = mm.WriteSerializationFileBinary(filepath)
    Mout.Save( eca )
    del( Mout )

#exportDaveFormat(eca,"out.txt")
#eca=importDaveFormat("data.txt")
#ec=eca.Put(2)

#ec.Dump()
