#include <stdlib.h>
#include <string.h>
#include "minfo.h"
#include "ga.h"

int eval_gene(char *curGene, struct gastuff * theGA)
{
    int curChar;
    int score;

    // need to convert to a path then evaluate path,
    convert_to_path(curGene, theGA);

    // storing in best if needed
    score = checkPath(theGA->matrixRef, theGA->workpath, theGA->plen, 0);
    // printf ("Score = %d\n", score);
    if (score > theGA->bestscore)
    {
	theGA->bestscore = score;
	strcpy(theGA->bestpath, theGA->workpath);
	// printf ("New Winner !!!\n");
    }
}

void convert_to_path(char * curGene, struct gastuff * theGA)
{
    static char thedirs[] = "ESWN";
    static int dircount[4];
    int curpchar = 0;
    register int plen = 0;
    int dirindex = 0;
    register int curChar;
    int numToAdd;

    dircount[0] = 0; dircount[1] = 0; dircount[2] = 0; dircount[3] = 0;

    for (curChar = 0; curChar < theGA->genesize; curChar += 3)
    {
	if (curGene[curChar] == '1')
	{
	    dirindex = curGene[curChar+1] == '1';
	    dirindex += curGene[curChar+2] == '1' ? 2 : 0;
	    theGA->workpath[curpchar] = thedirs[dirindex];
	    dircount[dirindex]++;
	    curpchar++;
	    plen ++;
	}
	else
	    break;
    }
    numToAdd = dircount[2] - dircount[0] + 1;
    for (;numToAdd > 0 ;numToAdd--)
    {
	theGA->workpath[curpchar++] = 'E';
	plen ++;
    }
    numToAdd = dircount[3] - dircount[1] + 1;
    for (;numToAdd > 0 ;numToAdd--)
    {
	theGA->workpath[curpchar++] = 'S';
	plen ++;
    }

    theGA->workpath[curpchar] = '\0';
    theGA->plen = plen;
    // puts(theGA->workpath);
    // printf ("plen = %d\n", plen);
}

void fill_pop(char *pop[NUM_GENES], struct gastuff * theGA)
{
    int curGene, curChar;

    for (curGene = 0; curGene < NUM_GENES; curGene++)
    {
	for (curChar = 0; curChar < theGA->genesize; curChar++)
	    pop[curGene][curChar] = (drand48() < 0.5) ? '0' : '1';
	eval_gene(pop[curGene], theGA);
    }
    
}

void init_ga(struct minfo * theMatrix, struct gastuff * theGA)
{
    int curGene;
    theGA->genesize = theMatrix->rows * theMatrix->cols * 3;

    theGA -> bestscore = -999999;
    theGA -> matrixRef = theMatrix;

    for (curGene = 0; curGene < NUM_GENES; curGene++)
    {
	theGA->pop1[curGene] = (char *) malloc (sizeof(char) * theGA->genesize);
	theGA->pop2[curGene] = (char *) malloc (sizeof(char) * theGA->genesize);
    }
    if (drand48() < 0.5)
	strcpy (theGA->bestpath, "SE");
    else
	strcpy (theGA->bestpath, "ES");
    fill_pop(theGA->pop1, theGA);
    fill_pop(theGA->pop2, theGA);
}
