/* Index access routines */ 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "utils.h"
#include "tyc_ep.h"
#include "itycep.h" 

int load_idx_tyc_ep (char* ifile,idx_tyc_ep* index) 
{
/* Routine to load an index from a file. The structure for the index must
 * already exist as must the file of course
 */
   idx_tyc_ep idx;
   FILE *fp;
   int i;

   if ( (fp=fopen(ifile,"r"))==NULL)
   {
	fprintf(stderr,"load_idx_tyc_ep unable to open %s \n",ifile);
	return (-1);
   }
   if (index == NULL) 
   {
      fprintf (stderr,"load_idx_tyc_ep NULL pointer for index\n");
      return (-1);
   }
   /*printf("Loading index idx_tyc_ep from %s.. ",ifile);*/
   for (i=0;i<idx_tyc_ep_entries;i++)
   {
	if ( (getnext_idx_tyc_ep (fp,&index[i])) != 0)
   	{
	   fprintf(stderr,"load_idx_tyc_ep problem with entry %d \n",i);
	   break;
	}
   /*     if  ( (i % 5000) == 0) printf("#");*/
   }
   if ( i < idx_tyc_ep_entries) 
   {
	fprintf(stderr,"Premature end of index file \n");
   	return -1;
   }
   /* printf(" done \n"); */
   return 0;
} /* End of load_idx_tyc_ep*/

int getnext_idx_tyc_ep (FILE* fp, idx_tyc_ep* entry)
{
   char buffer[idx_tyc_ep_REC_LEN + 2];
   if (fgets((char *)&buffer,idx_tyc_ep_REC_LEN+1,fp))
   { 
	char delimiter[3]="|\r\0";
	char *token=strtok((char *)&buffer,(char *)&delimiter); 
	read_tyc_id(token,&entry->tycep_idx1);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->tycep_idx2);
   return 0;
   }
   else
        return -1;
} /* End of getnext_idx_tyc_ep */

long find_idx_tyc_ep (tyc_id* key)
{
   static int init=0;
   static idx_tyc_ep index[idx_tyc_ep_entries];
   int mid,lpos,rpos,found;
   if (init == 0)
   {
        if (load_idx_tyc_ep("tyc_ep.idx",(idx_tyc_ep*)&index) !=0)
             return -1;
        init=1;
   }

   /*  Binary search */ 
   rpos = idx_tyc_ep_entries; 
   lpos = 0;
   if (rpos > idx_tyc_ep_entries) rpos = idx_tyc_ep_entries;
   found = 0;
   while (!found && !(lpos==mid && rpos==mid || lpos > rpos))
   {
	mid =  (rpos + lpos) /2;
        found = index[mid].tycep_idx1.tyc1.value == key->tyc1.value;
     	if (key->tyc1.value > index[mid].tycep_idx1.tyc1.value )
	   lpos = mid+1;
	else
	   if (key->tyc1.value < index[mid].tycep_idx1.tyc1.value)
	      rpos = mid;
	/*printf (" %d,%d Betweeen %d,%d and %d,%d Key = %d\n",mid,index[mid].tycep_idx1.tyc1.value,lpos,index[lpos].tycep_idx1.tyc1.value,rpos,index[rpos].tycep_idx1.tyc1.value,key->tyc1.value);*/
   }
   if (found)
    {
	int remember=mid;
	/*may be gone beyond the entry we want so search back*/
	while ( key->tyc1.value == index[mid].tycep_idx1.tyc1.value &&  
		key->tyc2.value < index[mid].tycep_idx1.tyc2.value && 
		mid >= 0)
	   mid--;
	if ( key->tyc2.value == index[mid].tycep_idx1.tyc2.value )
	{
	   while ( key->tyc3.value < index[mid].tycep_idx1.tyc3.value && mid >=0) 
	      mid--;
	   if (key->tyc3.value == index[mid].tycep_idx1.tyc3.value) 
		return index[mid].tycep_idx2.value;
	}
	/*need to serach forward since it was not back there */
	mid=remember+1;
	while ( key->tyc2.value > index[mid].tycep_idx1.tyc2.value && 
		key->tyc1.value == index[mid].tycep_idx1.tyc1.value &&
		mid <= idx_tyc_ep_entries) 
	   mid++;
	if ( key->tyc2.value == index[mid].tycep_idx1.tyc2.value )
	{
	   while ( key->tyc3.value > index[mid].tycep_idx1.tyc3.value && mid <= idx_tyc_ep_entries) 
	      mid++;
	   if (key->tyc3.value == index[mid].tycep_idx1.tyc3.value) 
		return index[mid].tycep_idx2.value;
	}
	return -1;
   }
   else
   {
      return -1;
   }
   
} /* End of find_idx_tyc_ep */


