#include <stdio.h>
#include <stdlib.h>
#include "../Src/PickObject.c"
#include "../Src/getnames.c"
#include "../Src/getdata.c"
#include "../Src/score.c"

/*  External data, described in extern.i  */
short           MaxAtt, MaxClass, MaxDiscrVal = 2;
ItemNo          MaxItem;
Description     *Item;
DiscrValue      *MaxAttVal;
char            *SpecialStatus;
String          *ClassName, *AttName, **AttValName, FileName = "DF";

/* Lift Globals */
float BaseLift;
int BestClassCount;
float BestSupport = 0.3;

/* a^2/(a+b) Globals */
int best, rest;
int **aCounts, **bCounts;

float (*score)(void*);

int power( int b, int e )
{
  int c = b, i;
  for ( i = 0; i < e-1; i++ )
    b *= c;

  if ( e == 0 ) return 1;
  return b;
}

char *getLine( FILE *r )
{
  int size=500, cnt=0;
  char *line = (char*)malloc( sizeof(char) * size ), c = fgetc(r);
  while ( c != '\n' )
  {
    line[cnt++]=c;
    c = fgetc(r);
  }

  line = (char*)realloc( line, sizeof(char) * (cnt+1) );
  line[cnt] = '\0';
  return line;
}

PickObject *getPO( FILE *r )
{
  PickObject *toRet = NULL, *temp1, *temp2;
  float vals[3]; vals[2] = 0;
  char *att, *attVal, *line;
  line = getLine( r );

  if ( strcmp( line, "END" ) == 0 ) return NULL;

  while ( strcmp( line, "END" ) != 0 )
  {
    att = strtok( line, ":" );
    vals[0] = Which( att, AttName, 0, MaxAtt+1 );
    attVal = strtok( NULL, "," );
    do
    {
      vals[1] = Which( attVal, AttValName[(int)vals[0]], 1, MaxAttVal[(int)vals[0]] );
      temp1 = setupPickObject( vals );
      temp2 = toRet;
      toRet = combinePickObject( temp2, temp1 );
      attVal = strtok( NULL, "," );
    } while ( attVal != NULL );
    line = getLine( r );
  }
  return toRet;
}

PickObject *createNULLPickObject()
{
  PickObject *toRet;
  float vals[3] = { 0, 0, 0 };
  toRet = setupPickObject( vals );
  toRet->mScore = 0.0;
  return toRet;
}

void printRule( PickObject *po )
{
  int a, v;
  printf( "%s = [ %s", AttName[po->mPicked[0].mAttr], AttValName[po->mPicked[0].mAttr][po->mPicked[0].mAttrVal[0]] );
  for ( v = 1; v < po->mPicked[0].mSize; v++ )
    printf( " OR %s", AttValName[po->mPicked[0].mAttr][po->mPicked[0].mAttrVal[v]] );
  printf( " ]\n" );

  for ( a = 1; a < po->mSize; a++ )
  {
    printf( "AND %s = [ %s", AttName[po->mPicked[a].mAttr], AttValName[po->mPicked[a].mAttr][po->mPicked[a].mAttrVal[0]] );
    for ( v = 1; v < po->mPicked[a].mSize; v++ )
      printf( " OR %s", AttValName[po->mPicked[a].mAttr][po->mPicked[a].mAttrVal[v]] );
    printf( " ]\n" );
  }
}

/**
 * This program will take in a data file and a file with Which's and Tar3's rule from that data file.
 * It will then write to a file, which's score, tar3's score, the difference, the number of times which had no rule
 * and the number of times tar3 had no rule.
 * argv[1] The input data file.
 * argv[2] The which rule file.
 * argv[3] The tar3 rule file.
 * argv[4] The output file.
 * argv[5] The scoring method.
 * arfv[6] The current file number.
 **/
int main( int argc, char *argv[] )
{
  FILE *ruleFile, *outFile;
  PickObject *whichPO, *tar3PO;
  int noWhich = 0, noTar = 0;
  
  // Read in the data file.
  FileName = argv[1];
  GetNames();
  GetData(".data");
  
  // Determine the scoring method.
  switch( argv[5][0] )
  {
    case 'l':
      calcBaseLift();
      score = scoreLift; 
      break;
    case 'p': 
      calcBaseProbSupt();
      score = scoreProbSupt; 
      break;
    //case 'i': score = scoreInfoGain; break;
  }

  ruleFile = fopen( argv[2], "r" );
  printf( "\nWhich\n" );
  whichPO = getPO( ruleFile );
  if ( whichPO == NULL ) { whichPO = createNULLPickObject(); noWhich = 1; }
  else whichPO->mScore = score( whichPO );
  printRule( whichPO );
  printf( "%f\n", whichPO->mScore );
  scoreTmp( whichPO );
  fclose( ruleFile );
  
  ruleFile = fopen( argv[3], "r" );
  printf( "\n\nTar3\n" );
  tar3PO = getPO( ruleFile );
  if ( tar3PO == NULL ) { tar3PO = createNULLPickObject(); noTar = 1; }
  else tar3PO->mScore = score( tar3PO );
  printRule( tar3PO );
  printf( "%f\n", tar3PO->mScore );
  scoreTmp( tar3PO );
  fclose( ruleFile );



  outFile = fopen( argv[4], "a" );
  fprintf( outFile, "%s %f %f %f %d %d %d %d\n", argv[6], whichPO->mScore, tar3PO->mScore, 
	   whichPO->mScore - tar3PO->mScore, noWhich, noTar, whichPO->mSize, tar3PO->mSize );
  printf( "%s %f %f %f %d %d %d %d\n", argv[6], whichPO->mScore, tar3PO->mScore, 
	  whichPO->mScore - tar3PO->mScore, noWhich, noTar, whichPO->mSize, tar3PO->mSize );
  fclose( outFile );
  
  return 0;
}
