#include	<stdio.h>
#ifdef AMIGA
#include	<exec/types.h>
#include        <string.h>
#endif
#include	"struct.h"
#include	"error.h"
#include	"port.h"
#include	"parse.h"
#include	"memory.h"

/* =======================================================
 * Public Data Declarations
 */

/* =======================================================
 * Private Function Prototypes
 */

/* =======================================================
 * Public Function Definitions
 */

/*
 * Parse command line arguments and load the specified files
 */
int PORT_load ( Account *a, char *argv[], int argc )
{
  int	setup_file = 0, price_file = 0, trans_file = 0,
        command_file = 0, instruction = 0;
  int c = 1;				/* skip command name */
  int error = NOERROR;
  while ( c < argc ) {
    if ( !strcmp (argv[c], "-s") ) setup_file = ++c;
    if ( !strcmp (argv[c], "-p") ) price_file = ++c;
    if ( !strcmp (argv[c], "-t") ) trans_file = ++c;
    if ( !strcmp (argv[c], "-c") ) command_file = ++c;
    if ( !strcmp (argv[c], "-i") ) instruction = ++c;
    if ( !strcmp (argv[c], "-h") ) printf(
	  "%s -s setup_file -p price_file -p transaction_file "
	  "[-c command_file] [-i instruction] [-h]\n",argv[0]);
    c++;
  }

  /*
   * Open each info file and read data in
   */
  if ( setup_file && PORT_setup ( a, argv[setup_file] ) )
    fprintf(stderr,"couldn't open setup file\n");
  if ( price_file && PORT_price ( a, argv[price_file] ) )
    fprintf(stderr,"couldn't open price file\n");
  if ( trans_file && PORT_trans ( a, argv[trans_file] ) )
    fprintf(stderr,"couldn't open transaction file\n");
  if ( command_file && (error = PORT_command ( a, argv[command_file] ) ) ) {
    if (error != EXIT)
    fprintf(stderr,"couldn't open command file\n");
  }
  if ( instruction )  error = PARSE_execute( a, argv[instruction]);

  return error;
}

/*
 * Read in the number of funds, their names and aliases
 */
int PORT_setup( Account *a, char *file )
{
  FILE *fp;
  char buf[MAXLINE];
  int eof = 0;
  int f = 0;

  if (!(fp = fopen ( file, "r" ))) return FILEOPEN;
  else {
    if (a->fund_no) PORT_unload(a, P_SETUP);	/* Clear the old stuff */
    /*
     * count the number of lines in the file
     */
    while ( !eof ) {
      if (!fgets( buf, MAXLINE, fp )) eof = 1;
      else f++;
    }
    rewind( fp );
    a->fund_no = f;
	a->fund = ( Fund * ) MEM_malloc( a->fund_no * sizeof( Fund ));
	if (!a->fund) return MEMORY;
    eof = f = 0;
    while (!eof ) {
      if (!fgets( buf, MAXLINE, fp )) eof = 1;
      else sscanf(buf, "%s %s %d %c",
	    a->fund[f].name, a->fund[f].alias,
	    &(a->fund[f].color), &(a->fund[f].type) );
      f++;
    }
    fclose ( fp );
  }

#ifdef DEBUG
  printf("%d\n", a->fund_no );
  for ( f = 0; f < a->fund_no; f++ )
    printf("%s %s %d\n", a->fund[f].name, a->fund[f].alias, a->fund[f].color);
#endif

  return NOERROR;
}

/*
 * Read in the number of prices, and the prices themselves
 */
int PORT_price( Account *a, char *file )
{
  FILE * fp;
  char buf[MAXLINE];
  int eof = 0;
  int n = 0;
  int f = 0;

  if (!(fp = fopen ( file, "r" ))) return FILEOPEN;
  else {
    if (a->price_no) PORT_unload(a, P_PRICE);	/* Clear the old stuff */
    /*
     * count the number of lines in the file
     */
    while ( !eof ) {
      if (!fgets( buf, MAXLINE, fp )) eof = 1;
      else n++;
    }
    rewind( fp );
    a->price_no = n;
	a->price_dates = ( Date * ) MEM_malloc ( a->price_no * sizeof( int ));
	if (!a->price_dates) return MEMORY;
    a->price = ( Price * )
	    MEM_malloc (a->fund_no*a->price_no*sizeof(float));
	if (!a->price) return MEMORY;
    n = 0;
    eof = 0;
    while ( !eof ) {
      if (!fgets( buf, MAXLINE, fp )) eof = 1;
      else {
        int i = 0;
        /*
         * Parse the current line
         */
        sscanf(buf,"%d",  &(a->price_dates[n]) );	/* Read date */
        f = 0;
        while ( buf[i] && f < a->fund_no ) {	/* While not end of line */
          while ( buf[i] != ' ' ) i++;		/* Find next element */
          /*sscanf( &(buf[++i]),"%f", &(a->price[n][f++]) );*/
          sscanf( &(buf[++i]),"%f", &( a->price[n*a->fund_no + f++]) );
        }
      	n++;
      }
    }
    fclose ( fp );
  }

#ifdef DEBUG
  printf("%d\n", a->price_no );
  for ( n = 0; n < a->price_no; n++ ) {
    printf("%6d ", a->price_dates[n]);
    for ( f = 0; f < a->fund_no; f++ )
      printf("%5.2f ", a->price[n*a->fund_no + f]);
    printf("\n");
  }
#endif

  return NOERROR;
}

/*
 * Read in the transactions
 */
int PORT_trans( Account *a, char *file )
{
  FILE * fp;
  char buf[MAXLINE];
  int eof = 0;
  int n = 0;

  if (!(fp = fopen ( file, "r" ))) return FILEOPEN;
  else {
    if (a->trans_no) PORT_unload(a, P_TRANS);		/* Clear the old stuff */
	/*
	 * Count the number of lines
	 */
    while (!eof ) {
      if (!fgets( buf, MAXLINE, fp )) eof = 1;
      else n++;
    }
    a->trans_no = n;
    n = 0;
    rewind( fp );
    eof = 0;
    a->trans = ( Transaction * )
	   MEM_malloc ( a->trans_no * sizeof( Transaction ) );
	if (!a->trans) return MEMORY;
    while (!eof ) {
      if (!fgets( buf, MAXLINE, fp )) eof = 1;
      else {
        /*
         * Parse the current line
         */
        sscanf(buf, "%d %s %s %f",&(a->trans[n].date),a->trans[n].alias,a->trans[n].type, &(a->trans[n].amount));
	n++;
      }
    }
    fclose ( fp );
  }

#ifdef DEBUG
  printf("%d\n", a->trans_no );
  for ( n = 0; n < a->trans_no; n++ ) printf("%d %s %s %7.2f\n",
    a->trans[n].date, a->trans[n].alias, a->trans[n].type, a->trans[n].amount );
#endif

  return NOERROR;
}

/*
 * Read in the commands
 */
int PORT_command( Account *a, char *file )
{
  FILE * fp;
  char buf[MAXLINE];
  BOOL eof = FALSE;
  if (!(fp = fopen ( file, "r" ))) return FILEOPEN;
  else {
    while (!eof ) {
      if (!fgets( buf, MAXLINE, fp )) eof = TRUE;
      else eof = PARSE_execute( a, buf );
    }
    fclose ( fp );
  }
  if (eof == EXIT ) return EXIT;
  return NOERROR;
}

/*
 * Free the portfolio structure
 */
static	port_fund_no = 0;	/* If fund is cleared before price need to know*/
int PORT_unload( Account *a, int t )
{
  if ( t & P_SETUP && a->fund ) {
     MEM_free( a->fund, a->fund_no * sizeof ( Fund ));
	 port_fund_no = a->fund_no;
	 a->fund_no = 0;
  }

  if ( t & P_PRICE && a->price ) {
     MEM_free( a->price_dates, a->price_no * sizeof ( int ));
	 if ( a->fund_no ) port_fund_no = a->fund_no;
     MEM_free( a->price, port_fund_no * a->price_no * sizeof ( float ));
	 a->price_no = 0;
	 port_fund_no = 0;
  }

  if ( t & P_TRANS && a->trans ) {
     MEM_free( a->trans, a->trans_no * sizeof ( Transaction ));
	 a->trans_no = 0;
  }
  return NOERROR;
}

/* =======================================================
 * Private Function Definitions
 */

