# HC_SCORE.py : Les methodes de scores

import math
import string
#=========================================
def initIC( fic_IC ):
    1
#=========================================
def initPlain( fic_plain ):
    global lePlain
    f = open(fic_plain,"r")
    leTexte = f.readlines()
    texteConcat = ""
    f.close()
    for i in range(len(leTexte)):
        ch = leTexte[i]
        ch = ch.upper()
        for j in range(len(ch)):
            if not is_maj(ch[j]):
                continue
            texteConcat = texteConcat + ch[j]
    lePlain = texteConcat

#===========Unigram=======================
def initUni( fic_uni ):
    global lesUni
    for i in range(26):
        lesUni.append( 0. )
    f_uni = open( "STATS/" + fic_uni + ".uni", "r")
    while 1:
        ch = f_uni.readline()
        if ch == "":break
        ch = ch.strip()
        (uni,fre) = ch.split(',')
        i = (string.ascii_uppercase).index(uni)
        lesUni[i]= float(fre)
    print

#===========Bigrammes=====================
def initBig( fic_big ):
    global lesBig
    for i in range(26*26):
            lesBig.append( 1. )

    f_big = open( "STATS/" + fic_big + ".big" , "r" )
    while 1:
            ch = f_big.readline()
            if ch == "": break
            ch = ch.strip()
            (big,fre) = ch.split(',')
            i1 = (string.ascii_uppercase).index(big[0])
            i2 = (string.ascii_uppercase).index(big[1])
            lesBig[ i1*26 + i2 ] = math.log(int(fre))
            #print("%c %c %2d %2d %10.5f"%(big[0],big[1],i1,i2,lesBig[i1*26+i2]))

#===============================================
def initTri( fic_tri ):
    global lesTri
    for i in range(26*26*26):
            lesTri.append( 1. )

    f_tri = open( "STATS/" + fic_tri + ".tri" ,"r")
    while 1:
        ch = f_tri.readline()
        if ch == "": break
        ch = ch.strip()
        (tri,fre) = ch.split(',')
        i1 = (string.ascii_uppercase).index(tri[0])
        i2 = (string.ascii_uppercase).index(tri[1])
        i3 = (string.ascii_uppercase).index(tri[2])
        lesTri[ i1*26*26 + i2*26 + i3 ] = math.log(int(fre))

#===============================================
def initQua( fic_qua ):
        global lesQua
        f_qua = open( "STATS/" + fic_qua + ".qua","r")
        while 1:
                ch = f_qua.readline()
                if ch == "": break
                ch = ch.strip()
                (qua,fre) = ch.split(',')
                lesQua[qua]=math.log(int(fre))

#================================================
def is_maj(car):
    if (string.ascii_uppercase).find(car) == -1:
        return 0
    else:
        return 1

# ===================================
def score_IC(texte):
        f = []
        for i in range(26):
                f.append(0)
        N = len(texte)
        for i in range(N):
                indice = (string.ascii_uppercase).index(texte[i])
                f[indice] = f[indice] + 1
        total = 0
        for i in range(26):
                if ( f[i] > 1):
                        total = total + f[i]*(f[i]-1)
        return total / float(N * (N-1))

#=====================================
def score_plain(texte):
    global lePlain
    total = 0
    N = len(texte)
    for i in range(N):
        if texte[i] == lePlain[i]:
            total = total + 1
    return total / float(N)

#=====================================
def score_ADE(texte):
    global lePlain
    N = len(texte)
    maxds = N * 26
    for i in range(N):
        x = abs(ord(texte[i]) - ord(lePlain[i])) 
        if x > 13:
            x -= 13
        maxds = maxds - x 
    return maxds / float(N * 26)

#=====================================
def score_ADE2(texte):
    global lePlain
    N = len(texte)
    maxds = N * 26
    for i in range(N):
        x = abs(ord(texte[i]) - ord(lePlain[i]))
        if x > 13:
            x = abs( x - 26 )
        maxds -= x
    return maxds / float(N * 26 )

#=====================================
def score_uni(texte):
    global lesUni
    total = 0
    for i in range( len(texte) ):
        lettre = texte[i]
        idx = string.ascii_uppercase.index( lettre )
        total += lesUni[ idx ]
    return total

#=====================================
def score_big(texte):
    global lesBig
    total = 0
    for i in range( len(texte) - 1 ):
            lettre = texte[i]
            idx1 = string.ascii_uppercase.index( lettre )
    
            lettre = texte[i+1]
            idx2 = string.ascii_uppercase.index( lettre )

            total += lesBig[ idx1*26 + idx2 ]
            #print("%c %c %2d %2d %10.2f" % (texte[i],texte[i+1],idx1,idx2,    lesBig[ idx1*26+idx2 ]))
    return total

#=======================================
def score_tri(texte):
        global lesTri
        total = 0
        for i in range( len(texte) - 2 ):
                lettre = texte[i]
                idx1 = string.ascii_uppercase.index( lettre )

                lettre = texte[i+1]
                idx2 = string.ascii_uppercase.index( lettre )

                lettre = texte[i+2]
                idx3 = string.ascii_uppercase.index( lettre )

                total += lesTri[ idx1*26*26 + idx2*26 + idx3 ]
        return total

#=======================================
def score_qua(texte):
        global lesQua
        total = 0
        for i in range( len(texte) - 3 ):
                qua = texte[i] + texte[i+1] + texte[i+2] + texte[i+3]
                #if lesQua.has_key(qua):
                if qua in lesQua:
                        total += lesQua[qua]
        return total

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
lesUni = []
lesBig = []
lesTri = []
lesQua = {}

score_init = { 'IC':initIC, 'PLN':initPlain, 'UNI':initUni, 'BIG':initBig, 
               'TRI':initTri, 'QUA':initQua, 'ADE':initPlain, 'ADE2':initPlain
}
score = { 'IC':score_IC, 'PLN':score_plain, 'UNI':score_uni, 'BIG':score_big, 
          'TRI':score_tri, 'QUA':score_qua, 'ADE':score_ADE, 'ADE2':score_ADE2
}

