/*  Copyright 1997-2000: 
      Fred Hutchinson Cancer Research Center, Seattle, WA, USA
	biassed_blocks_finder   Find compositionally biassed blocks       */

/*--------------------------------------------------------------------------
11/15/97 Moved home directory defs to homedir.h
 6/ 4/00 Updated for new find_biassed_blocks
11/15/03 Add to blimps programs
===========================================================================*/
/* blimps stuff */
#define EXTERN

#include <blocksprogs.h>

typedef struct {
    char *name;
    char *val;
} entry;

/* from util.c */
/*
char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *len);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);
*/
 
entry entries[10000];

#define MAX_BLOCKS 10
#define PROGRAM_DBGLVL 3
#define PROGRAM_SCORECUTOFF 0.50
#define PROGRAM_FRACTIONCUTOFF 0.25

#define TMP_SUBDIR   "../tmp"
#define BIN_SUBDIR   "./blimps-bin"

char Block_file[LARGE_BUFF_LENGTH];
char find_biassed_blocks[LARGE_BUFF_LENGTH] ;
char program_output[LARGE_BUFF_LENGTH] ;
char error_file[LARGE_BUFF_LENGTH];
char tmp_dir[LARGE_BUFF_LENGTH];
char buf[LARGE_BUFF_LENGTH];

int pid;

entry *BLOCK_Ptr = NULL;

void read_startup_info()
{
  int i;
  char *script, *ptr;

  script = getenv("SCRIPT_NAME");

  pid = getpid();

  sprintf(find_biassed_blocks, "%s/find_biassed_blocks", BIN_SUBDIR);
  sprintf(program_output, "%s/%d.biassed_blocks_out", TMP_SUBDIR, pid);

  sprintf(Block_file, "%s/%d.blk", TMP_SUBDIR, pid);

  sprintf(tmp_dir, "%s", TMP_SUBDIR);

}   /*  end of read_startup_info */


int parse()
{
/* parse the input */

  register int i,num_entries=0;
  char *entry_string;
  int cl;

  /* check that there is something to use. */
  entry_string = getenv("QUERY_STRING");

/*
  if (entry_string == NULL) 
     {
     printf("No query information to decode.\n");
     exit(1);
     }
*/

  /* parse the query string into individual entries */

  cl = atoi(getenv("CONTENT_LENGTH"));

  for(i=0;cl && (!feof(stdin));i++) 
     {
     num_entries=i;
     entries[i].val = fmakeword(stdin,'&', &cl);
     plustospace(entries[i].val);
     unescape_url(entries[i].val);
     entries[i].name = makeword(entries[i].val,'=');

     if (!strncmp(entries[i].name, "BLOCK", 5)) 
        {
	BLOCK_Ptr = &entries[i]; 
        }

    }


  return num_entries;
} /*  end of parse */


void clean_temp_files()
{
  sprintf(buf, "rm -f %s/%d*temp", TMP_SUBDIR, pid); 
  system(buf);
}


void write_block()
{
  FILE  *bfp, *efp ;
  Block *block ;
  int   blocks_num ;


  /* check that a block was specified */
  if (BLOCK_Ptr->val[0] == NULL) 
    {
      printf("<H1>Error</H1>\n");
      printf("You need to enter a block by writing or pasting a block in the window.<P>\n");
      exit(0);
    }
  

  /* open error_file so that error messages from read_a_block can be examined*/
  sprintf(error_file, "%s/%d.block_errors", TMP_SUBDIR, pid);
  set_error_file_name(error_file) ;     



  /* if block was pasted/written - */
  if (BLOCK_Ptr->val[0] != NULL)
    {
      
      /* open up the block file to write to */
      bfp = fopen(Block_file, "w");
      
      fprintf(bfp, "%s\n",BLOCK_Ptr->val);

/* add "//" to the file end. 
   This is done to over come the fact that read_a_block does not detect if the 
   end of block signal (//) is missing and the program crashes later. */
      fprintf(bfp, "//\n");

      /* close and reopen block file in a read mode */
      fclose(bfp);
      bfp = fopen(Block_file, "r");
      
      
      blocks_num = 0 ;
      
      /* read-in blocks to check their format and content */
      while ((block = read_a_block(bfp)) != NULL)
        {
	  blocks_num++ ;
	  
	  /* try and open error file to see if there were any errors */
	  if ((efp = fopen(error_file, "r")) != NULL) 
	    {
	      printf("<H1>Error</H1>\n");
	      printf("There seems to be an error in the format of block number %d:<br>", blocks_num);
	      
	      printf("<pre>\n");
	      while((buf[0]=getc(efp)) != EOF) putchar(buf[0]) ; 
	      printf("</pre>") ;
	      
	      fclose(efp) ;
	      
	      clean_temp_files() ;
	      
	      exit(1);
	    }
	  
        }
      
      if (blocks_num <= 0) 
	{
	  printf("<H1>Error</H1>\n");
	  printf("No blocks were read.\n");
	  clean_temp_files() ;
	  exit(1);
	}

      if (blocks_num > MAX_BLOCKS) 
	{
	  printf("<H1>Error</H1>\n");
	  printf("Sorry, you can not check more than %d blocks each time.\n", 
                 MAX_BLOCKS);
	  clean_temp_files() ;
	  exit(1);
	}
      
      
      fclose(bfp);
    } /* end if (Block_Ptr->val[0] != NULL) */
} 
  

/**********************************************************************/
/*
run find_biassed_blocks
*/
void run_program()
{

  sprintf(buf, "%s %s %f %f %d > %s 2>&1", 
          find_biassed_blocks, Block_file, 
          PROGRAM_SCORECUTOFF, PROGRAM_FRACTIONCUTOFF, PROGRAM_DBGLVL, 
          program_output);

  if (system(buf)) {
    printf("<H1>Program Error</H1>\n");
    printf("An error occured during the execution.\n");
    printf("Please try again at a later time.\n");
    printf("If it fails again contact the maintainer of these pages\n");
    printf("and describe what caused the problem with an example.<P>\n");

    clean_temp_files() ;

    exit(0);
  }

}  /*  end of run_program */

/**********************************************************************/

void display_output()
{

  FILE *outf;

  printf("<TITLE>Biassed Blocks Results</TITLE>\n");
  printf("<H1>Biassed Blocks Results</H1>\n");
  printf("<HR>\n") ;

  if ((outf = fopen(program_output, "r")) == NULL)
     {
     printf("Error opening program output file.\n") ;

     clean_temp_files() ;

     exit(1) ;
     }


  printf("<pre>\n");
  while (!feof(outf) && fgets(buf, LARGE_BUFF_LENGTH, outf) != NULL)
     printf(buf) ; 
  printf("</pre>\n"); 

  fclose(outf);

}

/**********************************************************************/

void main(int argc, char *argv[]) {

  printf("Content-type: text/html\n\n\n");


  if(strcmp(getenv("REQUEST_METHOD"),"POST")) {
    printf("This script should be referenced with a METHOD of POST.\n");
    printf("If you don't understand this, see this ");
    printf("<A HREF=\"http://www.ncsa.uiuc.edu/SDG/Software/Mosaic/Docs/fill-out-forms/overview.html\">forms overview</A>.%c",10);

    printf("<P>What could have happened is that you just reloaded this page rather than redoing the search.\n");

    printf("<P>If you use NETSCAPE it has a tendency to try to reload a page when you go back to it.  This may be why you have this error.\n");

    exit(1);
  }

  if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) {
    printf("This script can only be used to decode form results. \n");
    exit(1);
  }

  /*    Set file permissions to "rw-rw----"     */
  system("umask 006");

  read_startup_info();

  parse();

  write_block();
  
  run_program();

  display_output(); 

  clean_temp_files() ;

  exit(0) ;
}

