	/*
		STAT 251, WI'02, Project 1


 	Compile: %> c++ -g -o Proj1_1_Codon_code1 Proj1_1_Codon_code1.c -lm
			cc -g -o Proj1_1_Codon_code1 Proj1_1_Codon_code1.c -lm
	Execute by: %> Proj1_1_Codon_code1 > results.text

	*/

#include <stdio.h>
#include <unistd.h>
#include <math.h>

#define MaxNumberPositions 4
#define NumberOfBases 4

	//int **output;
	typedef int* IntPnt;
	IntPnt* output;
	int currentPositionValue[MaxNumberPositions];

int numberTs(int k)
{  int i, numTs=0;
	for (i = 1; i <= MaxNumberPositions; i++)
	{   if (output[k][i-1] == 3)   numTs++;     }
    return numTs;
}

bool tripletTAA(int k)
{   bool TAA=false;
    int i;
	for (i = 3; i <= MaxNumberPositions; i++)
	{   if (output[k][i-3]==3 && output[k][i-2]==0 && output[k][i-1]==0)
   		TAA = true;
         }
    return TAA;
}

bool G_position2_3(int k)
{   bool G_pos2_3=false;
	if (output[k][1]==2 || output[k][2]==2)
   		G_pos2_3 = true;
    return G_pos2_3;
}

bool checkStopCondition(int k, int i)
{	bool stopReading = false;

	if (i>=3 && numberTs(k)>=3)		// at least 3 T's occur
	  return true;
	if (i>=3 && tripletTAA(k)==true)	// Triplet TAA , stopping codon
		return true;
	if (i==3 && G_position2_3(k)==true)	// G occurs on position 2 or 3.
		return true;
	return stopReading;		// If none of these stopping
					// criteria is satisfied return false
}


void main ( int argc, char * argv[] )
{
	int k, i, j, correction=0;
	int TotalNumberStrings;
	int numTbases=0;
	int numerator, denominator;

	TotalNumberStrings = (int)(pow( (double)(NumberOfBases),
				(double)(MaxNumberPositions) )) ;

	/***
	if((output = (int **) malloc(TotalNumberStrings*sizeof(int *)))==NULL)
        { printf("(Proj1_1_Codon_code) Error in Mem_alloc 'output'. \n"); 
	   exit(0);
	 }
	****/
	
	for (k=0; k < MaxNumberPositions; k++)
	{     currentPositionValue[k] = 1;  }

	output = new IntPnt[TotalNumberStrings];

        for (k = 0; k < TotalNumberStrings; k++)
        {   /***
	    if((output[k]=(int *) malloc(MaxNumberPositions*sizeof(int)))==NULL)
            { printf("(Proj1_1_Codon_code)Error in Mem_alloc output[%d].\n",k+1);
		exit(0);
	     }
	    ****/
	    output[k]=new int[MaxNumberPositions];
	 }


	 for (k = 0; k < TotalNumberStrings; k++)
         {	// Fill in the output strings and print them out ...
	     for (i=1; i <= MaxNumberPositions; i++)
	     { 	  numerator = k;
		  denominator = (int)(pow( (double)(NumberOfBases),
				(double)(MaxNumberPositions-i) )) ;

		  for (j=1; j<i; j++)
		  {  numerator -= output[k][j-1] * 
				(int)(pow( (double)(NumberOfBases),
				(double)(MaxNumberPositions-j) )) ;
		   }

		   output[k][i-1] = numerator/denominator;
	      }
	  }

	for (k = 0; k < TotalNumberStrings; k++)
        {    // Print out the output strings and print them out ...
	     fprintf(stdout, "Output[%d]=", k+1);
	     numTbases=0;

	     for (i=1; i <= MaxNumberPositions; i++)
	     {   //   fprintf(stdout, "%d", output[k][i-1]);
		  if (output[k][i-1]==3) numTbases++;

		  if (checkStopCondition(k, i)==false)
		  {
		 	if(output[k][i-1]==0)
		 		fprintf(stdout, "A");
		 	else if(output[k][i-1]==1)
		 		fprintf(stdout, "C");
		 	else if(output[k][i-1]==2)
		 		fprintf(stdout, "G");
		 	else if(output[k][i-1]==3)
		 		fprintf(stdout, "T");
		 	else fprintf(stdout, "-----");
		  }
		  else {  fprintf(stdout, "---STOPPED---");
			  break;
		   }
	      }
	     
	     fprintf(stdout, "\t P(Output) = %f", pow(0.25, (double)(i-1)) ); 
	     if (numTbases>0)  
		fprintf(stdout, "\t !!!! T !!!!");
	     fprintf(stdout, "\n");
	 }

	printf("D-O-N-E!\n");

}	/* END: main() */


