/**
 *  Routines for initial processing of ciphertext.
 *
 *  Author: Ramkumar Natarajan (nrk@cs.purdue.edu)
 **/

#include "quip.h"
#include "printfuncs.h"

LOCAL void initCipherText(CipherText *ctptr) {
    int i;
    ctptr->ociphertxt   = NULL;
    ctptr->ciphertxt    = NULL;
    ctptr->cipherwords  = NULL;
    ctptr->ncipherwords = 0;
    ctptr->longest      = NULL;
    for ( i = 0; i < ALPHA_SZ_; ++i ) {
        CipherChar *cipherchar  = ctptr->ciphermap + i;
        cipherchar->plainmap    = ALEPH_NONE;
        cipherchar->isPresent   = FALSE;
    }
}

LOCAL int processWord(CipherWord *wptr, CipherText *ctptr) {
    int  i;
    char *word = wptr->word;

    for ( i = 0; i < wptr->len; ++i ) {
        CipherChar *cipherchar;
        
        if ( !isalpha((int) word[i]) ) {
            if ( wptr->nonalphapos >= 0 )
                assert(wptr->nonalphapos < 0);
            wptr->nonalphapos = i;
            continue;
        }

        cipherchar = ctptr->ciphermap + CHAR_TO_INDEX(word[i]);
        if ( !cipherchar->isPresent ) {
            cipherchar->isPresent    = TRUE;
            cipherchar->plainmap     = ALEPH_ALL;
        }
    }
    return 0;
}

int processInput(char *ociphertxt, CipherText *ctptr) {
    int   txtlen;
    int   nwords;
    int   longlen = 0;
    int   i;
    char *cptr;

    initCipherText(ctptr);
    
    txtlen = strlen(ociphertxt);
    ctptr->ociphertxt = my_malloc(sizeof *ctptr->ociphertxt * txtlen + 1);
    strcpy(ctptr->ociphertxt, ociphertxt);

    ctptr->ciphertxt  = my_malloc(sizeof *ctptr->ciphertxt * txtlen + 1);
    cptr = ctptr->ciphertxt;
    while ( *ociphertxt && (*cptr++ = tolower((int)*ociphertxt++)) );
    *cptr = 0;

    ctptr->cipherwords  = my_malloc(sizeof *ctptr->cipherwords * EXP_NUMWORDS_);
    ctptr->ncipherwords = EXP_NUMWORDS_;
    nwords              = 0;
    cptr                = ctptr->ciphertxt;
    while ( *cptr ) {
        CipherWord *cipherword;
        
        if ( nwords == ctptr->ncipherwords ) {
            ctptr->cipherwords   = my_realloc(ctptr->cipherwords, 
                                              sizeof *ctptr->cipherwords * (ctptr->ncipherwords + EXP_NUMWORDS_));
            ctptr->ncipherwords += EXP_NUMWORDS_;
        }
        cipherword = ctptr->cipherwords[nwords] = my_malloc(sizeof *ctptr->cipherwords[nwords]);
        cipherword->word = cptr;
        while ( *cptr && (isalpha((int) *cptr) || *cptr == '-' || *cptr == '\'') )
            ++cptr;
        cipherword->len         = cptr - cipherword->word;
        cipherword->nonalphapos = -1;
        if ( cipherword->len == 0 ) {
            while ( *cptr && !(isalpha((int) *cptr) || *cptr == '-' || *cptr == '\'') )
                ++cptr;
            continue;
        }
        
        assert( cipherword->len < MAX_WORDLEN_ );
        
        cipherword->possiblewords = NULL;
        cipherword->npossibles    = 0;
        cipherword->isIgnored     = FALSE;
        cipherword->curmatch      = 0;
        for ( i = 0; i < ALPHA_SZ_; ++i ) {
            cipherword->map[i] = ALEPH_ALL;
        }

    
        if ( cipherword->len > longlen ) {
            ctptr->longest = cipherword;
            longlen        = cipherword->len;
        }
        if ( *cptr ) *cptr++ = 0;
        while ( *cptr && !isalpha((int) *cptr) )
            ++cptr;
        ++nwords;
    }
    ctptr->ncipherwords = nwords;

    for ( i = 0; i < ctptr->ncipherwords; ++i ) {
        processWord(ctptr->cipherwords[i], ctptr);
    }

    return 0;
}
