#include "structure.h"
#include 


//this string class is for this project only. 

//for example, the print function is very strange.
struct string {
//member functions

   string() {str=NULL;}
   string(char *);
   void print(ostream&);
   int find(const char&);
   string& operator=(const string&);
   string& token(string& s, const char& c);
//data members
   char* str;
   int slen;
};

string::string(char *word)
{ str=new char[strlen(word)+1];
  strcpy(str, word);
  slen=strlen(word);
}

int string::find(const char& c)
{ for (int i=0; i< slen; i++)
    if (str[i]==c) return ++i; 
  return 0;
}

void string::print(ostream& strm)
{ if (! find('!')) strm << str;
  else { strm << "    ";
   for (int i=find('!'); i< slen; i++) 
     if ( str[i]== '!' )  break;
   if (i< slen) {
     strm <<"    ";
     for (int j=i+1; j< slen; j++) 
     strm << str[j]; }
   else
     for ( i=find('!'); i< slen; i++) 
       strm << str[i];
  }
}

string& string::operator=(const string& s)
{ if (this==&s) return (*this);
  delete [] str;
  str=new char[strlen(s.str)+1];
  strcpy(str, s.str);
  slen=s.slen;
  return (*this);
}         

string& string::token(string& s, const char& c)
{ if (s.find(c)) {
   delete [] str;
   str=new char[s.find(c)];
   for (int i=0; i< s.find(c)-1; i++)
     str[i]=s.str[i];
   str[i]='\0';
   slen=strlen(str);
  }
  return (*this);
}






//*************************** class2.h







#include "class1.h"

#include "queue.hc"

#include < ctype.h>



struct pageentry {

  pageentry(){}

  pageentry(int p, int t):page(p),type(t) {}

//data

  int page;

  int type;

};



struct indexentry {

  indexentry() {pagenumbers=NULL;}

  indexentry(string& ,pageentry&);

  int operator<(const indexentry& I) const

      { return strcmp(name.str, I.name.str)<0;}

  void print(ostream&) ;

//data

  string name;

  Queue< pageentry>*  pagenumbers;

};

 



indexentry::indexentry(string& word, pageentry& p)

{ name=word;

  pagenumbers=new Queue< pageentry>;

  pagenumbers->Enqueue(p);

}







void indexentry::print(ostream& strm)

{ name.print(strm);

  strm << "    ";

  if (pagenumbers !=NULL) {

    while ( ! pagenumbers->IsEmpty() ) {

      pageentry pe= pagenumbers->GetFront();

      pagenumbers->Dequeue();

      if (pe.type==0) strm << pe.page << ", ";

      if (pe.type==-1) {

        strm << pe.page <<"-";

        if ( pagenumbers->IsEmpty() ) {

          strm << "?, "; break;}

          pageentry r=pagenumbers->GetFront();

        if ( r.type==-2) {

        strm << r.page <<", ";

        pagenumbers->Dequeue();}

        else strm << "?, ";

      }

      if (pe.type==-2) {

      strm << "?-" << pe.page << ", ";}

    }

  }

  strm << endl;

} 





//************************** class3.h



#include "class2.h"



//function "readline" is to read a line from the infile, put the information

//into param string word and pageentry p

void readline(ifstream& infile, string& word, pageentry& p)

{ char gb[80];

  char wordbuffer[80];

  infile.getline(gb, 30, '{');

  infile.getline(wordbuffer, 80, '}');

  string B(wordbuffer);

  if (!B.find('|')) {

    word=B; p.type=0; }

  else { word.token(B, '|');

         if (B.find('('))

           p.type=-1;

         else

           p.type=-2;

  }

  infile.getline(gb,80,'{');

  infile >> p.page;

  infile.getline(gb, 80);

}



//function "updatetree" is to put information of string word and pageentry p

//into SearchTree T, where all the information is stored.

void updatetree(SearchTree< indexentry >& T, string& word, pageentry& p)

{ indexentry Temp(word,p);

  const indexentry& temp=T.Find(Temp);

  if (T.WasFound()) { 

    temp.pagenumbers->Enqueue(p); delete [] Temp.name.str;

  }

  else { 

         T.Insert(indexentry(word, p));

  }

}