/*
 https://perso.isima.fr/~mafortias/enigma/index.html
 utiliser la configuration par défaut
 Attention, les fils de connection de la table de liaison des lettres n'est pas géré (plugboard)
 pour faciliter le déchiffrage en ligne
 supprimer les caractères AB de la configuration du plugboard
 * 
 */
#include "Enigma.h"

Enigma::Enigma() {
}

// Destructeur

Enigma::~Enigma() {
   
}

void Enigma::init() {
 strcpy(rotorHautIn, "EKMFLGDQVZNTOWYHXUSPAIBRCJ");
 strcpy(rotorHautOut, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");

 strcpy(rotorMilieuIn, "AJDKSIRUXBLHWTMCQGZNPYFVOE");
 strcpy(rotorMilieuOut, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 
 strcpy(rotorBasIn, "BDFHJLCPRTXVZNYEIWGAKMUSQO");
 strcpy(rotorBasOut, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 
 strcpy(reflector, "EJMZALYXVBWFCRQUONTSPIKHGD");
 ptrbuf=0;

}

char Enigma::encode(char car) {
    int curIndex;
    char carRot;
    char carChiffre;
    //gestion de la rotation des 3 disques
    carRot = rotate(rotorHautIn);
    rotate(rotorHautOut);
    if (carRot == 'X') {
        rotate(rotorMilieuIn);
        rotate(rotorMilieuOut);
    }
    else{
        if (rotorMilieuIn[0]=='S'){
            rotate(rotorMilieuIn);
            rotate(rotorMilieuOut);
            rotate(rotorBasIn);
            rotate(rotorBasOut);
        }
    }
    //recherche du caractère crypté sur 3 disques
    curIndex = getCharRotor(rotorHautIn, rotorHautOut, car - 'A');
    curIndex = getCharRotor(rotorMilieuIn, rotorMilieuOut, curIndex);
    curIndex = getCharRotor(rotorBasIn, rotorBasOut, curIndex);
    curIndex = getReflector(reflector, curIndex);
    curIndex = getCharRotor(rotorBasOut, rotorBasIn, curIndex);
    curIndex = getCharRotor(rotorMilieuOut, rotorMilieuIn, curIndex);
    curIndex = getCharRotor(rotorHautOut, rotorHautIn, curIndex);
    carChiffre=(char) ('A' + curIndex);
    buffer[ptrbuf++]=carChiffre;
    if (ptrbuf==BUFFER_SIZE-2){
        ptrbuf=0;
    }
    buffer[ptrbuf]=0;
    return carChiffre;
}

char * Enigma::getChiffre(){
    return buffer;
}

//decallage de la chaine de caractère
//retourne le caractère decallé en fin de fin de chaine
char Enigma::rotate(char *rot) {
    char temp = rot[0];
    for (int i = 1; i < 26; i++) {
        rot[i - 1] = rot[i];
    }
    rot[25] = temp;
    return temp;
}

//retourne l'index du caractère sortant en fonction des chaine in et out et de l'index du caractère entrant
//l'opération se fait sur un disque
int Enigma::getCharRotor(char *rotIn, char* rotOut, int indexCar){
    int index;
    int i;
    char nextCar;    
    nextCar=rotIn[indexCar];            
    for (i = 0; i < 26; i++) {
        if (rotOut[i] == nextCar) {
            index=i;
        }
    }    
 return index;
}

//la suite de caractère du réflécteur est toujours la meme
//pas de recherche le nouvel index est immédiat
int Enigma::getReflector(char *refl, int indexCar) {
    char car=refl[indexCar];
    return car-'A';
}
