#ifndef STAT_H
#define STAT_H

#include <String.h>
#include <fstream.h>
#include <math.h>
#include "text.hh"
#include "perm.hh"
#include "vign.hh"

//============================================================
// STAT - The class STAT represents monogram, bigram and trigram
//        statistical information.
//        Functions a provided to computed monogram and trigram
//        scores of a TEXT after decrypting it with a permutation 
//        (PERM) or a Vigenere key (VIGN).
//============================================================

class STAT
{
public:
    
    int stat1[32];
    int stat2[32][32];
    int stat3[32][32][32];

    STAT(char *filename, int penalty)
        {
            int i1,i2,i3,dummy;
            
            ifstream out(filename);

            for(i1=0; i1<27; i1++)
                out >> dummy >> stat1[i1];
            
            for(i1=0; i1<27; i1++)
                for(i2=0; i2<27; i2++)
                {
                    out >> dummy >> dummy >> stat2[i1][i2];
                    if( stat2[i1][i2] == 0 )
                            stat2[i1][i2] = penalty;
                }
            
            for(i1=0; i1<27; i1++)
                for(i2=0; i2<27; i2++)
                    for(i3=0; i3<27; i3++)
                    {
                        out >> dummy >> dummy >> dummy >> stat3[i1][i2][i3];
                        if( stat3[i1][i2][i3] == 0 )
                            stat3[i1][i2][i3] = penalty;
                    }
            
        }

    int EvalText1( TEXT *t)
        {
            int sum = 0;

            for( int i=0; i < t->length; i++ )
            {
                sum += stat1[ t->data[i] ];
            }

            return sum;
        }

    int EvalTextPerm1( TEXT *t, PERM *p)
        {
            int sum = 0;

            for( int i=0; i < t->Length(); i++ )
            {
                
                sum += stat1[ p->Translate(t->Char(i)) ];
            }

            return sum;
        }

    int EvalTextPerm2( TEXT *t, PERM *p)
        {
            int sum = 0;
            int i1,i2;

            i2 = p->Translate(t->Char(0));
            
            for( int i=1; i < t->Length(); i++ )
            {
                i1 = i2;
                i2 = p->Translate(t->Char(i));
                sum += stat2[i1][i2];
            }
            
            return sum;
        }

        int EvalTextPerm3( TEXT *t, PERM *p )
        {
            int sum = 0;
            int i1,i2,i3;

            i2 = p->Translate(t->Char(0));
            i3 = p->Translate(t->Char(1));
                        
            for( int i=2; i < t->Length(); i++ )
            {
                i1 = i2;
                i2 = i3;
                i3 = p->Translate(t->Char(i));
                if( stat3[i1][i2][i3]  )
                    sum += stat3[i1][i2][i3];
            }
            
            return sum;
        }

        int EvalTextVign3( TEXT *t, VIGN *v)
        {
            int sum = 0;
            int i1,i2,i3;

            i2 = v->Translate(t->Char(0),0);
            i3 = v->Translate(t->Char(1),1);
            
            for( int i=2; i < t->Length(); i++ )
            {
                i1 = i2;
                i2 = i3;
                i3 = v->Translate(t->Char(i),i);
                sum += stat3[i1][i2][i3];
            }
            
            return sum;
        }

    friend ostream& operator << (ostream& o, STAT& s)
        {
            int i1,i2,i3;
            
            for(i1=0; i1<27; i1++)
                o << i1 << "\t" << s.stat1[i1] << endl;
            
            for(i1=0; i1<27; i1++)
                for(i2=0; i2<7; i2++)
                    o << i1 << "\t" << i2 << "\t" << s.stat2[i1][i2] << endl;
    
            for(i1=0; i1<27; i1++)
                for(i2=0; i2<27; i2++)
                    for(i3=0; i3<27; i3++)
                        o << i1 << "\t" << i2 << "\t" << i3 << "\t" <<
                            s.stat3[i1][i2][i3] << endl;

            return o;
        }
        
};


#endif 

