// *****************************************************
// *                                                   *
// *   wordcounter.C (MP5)                             *
// *                                                   *
// *   Implementation for a WordCounter class          *
// *                                                   *
// * Author: Mariusz Zaczek                            *  
// * Date:   March 9, 1999                             *
// * Class:  Tu 11am-1pm, Chad Peiper                  *
// *                                                   *
// *****************************************************

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "string.h"
#include "bstree.h"
#include "keypair.h"
#include "wordcounter.h"

// BSTree
//    - default constructor
//    - initializes Tree of KeyPairs to default values
WordCounter::WordCounter() : MyTree()
{
  // no additional code needed
}



// InsertWord 
//    - parameters : s1 - a String value
//    - Inserts the word as a KeyPair into the tree
void WordCounter::InsertWord(String s1)
{
  KeyPair<String,int> x(s1,1);
  int num;    

  // If KeyPair of String and a number 1 is in the tree
  //  then increase the info number by 1...this is done
  //  by removing the current KeyPair and adding a KeyPair
  //  with the info field increased.
  //  Otherwise, if the KeyPair is not found in the tree
  //  then insert it. 
  if (MyTree.Find(x))
  {
     num = (MyTree.Last()).GetInfo();
     num++;
     MyTree.Remove(x);
     KeyPair<String,int> y(s1,num); 
     MyTree.Insert(y);
  }
  else
  {
    MyTree.Insert(x);
  }

  return;
}
    


// PrintFullInfo
//    - Prints out all of the data of the tree in alphabetical
//      order - i.e. the Keys and associated Info
void WordCounter::PrintFullInfo()
{

  // Output to screen the KeyPairs in alphabetical order by
  // using the InOrder() function.
  MyTree.InOrder();

  return;
}



// PrintWordInfo
//    - parameters : s1 - a String value
//    - if the string _s1_ is in the tree then it prints out
//      the string and its associated info, otherwise it prints
//      out the string and a 0 (zero)
void WordCounter::PrintWordInfo(String s1)
{
 KeyPair<String,int> x(s1,1);

 
  // If KeyPair is not found in tree then output String and 0
  //  else output String (Key) and info (Info).
  if (!MyTree.Find(x))
  {
    cout << "Key: "
         << s1
         << "       Info: 0"
         << endl; 
  }
  else
  {
    cout << "Key: "  
         << (MyTree.Last()).GetKey()
         << "       Info: "
         << (MyTree.Last()).GetInfo()
         << endl;
  }

  return;
}



// ReadFromFile
//    - parameters : filename - a char* referring to an input file
//    - reads data from file and inserts into tree
void WordCounter::ReadFromFile(char *filename)
{
  // open ifstream
  ifstream textfile(filename);

  char *newString = new char[100];
  int num;
  
  // Test if _filename_ file exists...
  //   .. if NO then output error
  //   .. if YES then read from file the String
  //      and the integer Info and insert it into
  //      the current tree.
  if (!textfile)
    cout << "Error: File error!" << endl;
  else
  {
    while  (textfile >> newString >> num)
    {
 
      (String)newString;
      KeyPair<String,int> x(newString,num);      

      MyTree.Insert(x);
    }
  }

  // close ifstream
  textfile.close();

  return;
}



// WriteToFile
//    - parameters : filename - a char referring to an output file
//    - writes out data from tree (Key and Info) to the file
void WordCounter::WriteToFile(char *filename)
{
  // open ostream
  ofstream textfile(filename);

  // Make a copy of the original tree (MyTree)
  BSTree< KeyPair<String, int> > NewTree = MyTree;
  
  // While a minimum KeyPair exists then output this
  //   KeyPair's Key and Info data to the _filename_ file.
  //   Once no more KeyPairs exist in tree then stop.
  while(NewTree.Find_Min())
  {
    textfile << (NewTree.Last()).GetKey() 
             << " " 
             << (NewTree.Last()).GetInfo() 
             << endl;

    NewTree.Remove(NewTree.Last());
  }

  // close ostream
  textfile.close();

  return;
}

