//
//
//  WordCount.cc
//
//      AUTHOR: Russell Lowke
//         T.F: Francis Crick
//  CSCIE-s111: Unit Five, Easy Supp - question 6 [worth 4pts],  7/16/2002
//
// Description: Opens a text file and counts the number of words in the file.
//				Punctuation characters are ignored
//
//       Usage: When prompted, key in name of file to analyze
//              key in 'none' to exit.
//
//      Method: main loop asks for a filename via getString(),
//              subsequently setting the pFileName property, and
//				calling readFile() and printData()
//
//              readFile()   - opens file [pFileName] and counts words
//              printData()  - prints the data collected by readFile()
//              
//   Functions: getString()  - reads a string from input
//

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cctype>


// constants
const int MWORDSZ = 13;							// largest word counted
const int MAXSTR  = 80;							// max char string size


//
//  Get a string [str] of length maxLength
//  
void getString(char * query, char * str, int maxLength)
{
	cout << query;								// ask query
	
	cin >> ws;									// remove all the white spaces
	cin.getline(str, maxLength);				// read characters until \n MAXSTR
}


//
//   Analyzer class
//   analyzes files, counting number of small, large, and medium words
//
class Analyzer
{
	private :
	
		char *  pFileName;						// name of file being read
		int		pWordCount[MWORDSZ + 1];		// count of words in file
		
      public:
       
		        Analyzer(char *filename); 		// constructor
		        ~Analyzer();					// destructor
       	int     readFile();						// open and read
		void    printData();					// display
};


//
//  constructor for Analyzer class
//
Analyzer :: Analyzer (char * fileName)
{
	pFileName = fileName;
	for (int i = 1; i <= MWORDSZ; i++) {
		pWordCount[i] = 0;
	}
}


//
//  destructor for Analyzer class
//  
Analyzer :: ~Analyzer()
{
}


//
//  read file [pFileName]
//  counting small, large and medium words and placing into
//  pSmallWords, pLargeWords and pMediumWords respectivly.
//
int Analyzer :: readFile()
{
	char c;
	int wordLength = 0;
	
	// ready file
	ifstream inStream (pFileName);			
	
	// ensure file exists
	if (inStream == NULL) {					// file not found
	
		cout << pFileName << " -- Input file not found!\n";
		return -1;								// readFile failed
		
	} else {									// file OK
	
		inStream.unsetf(ios::skipws);			// unset skip whitespace	
		
		do {
		
			inStream >> c;						// read file
			
			// new word if space or EOF
			if ( isspace(c) || inStream.eof() ) {
			
				// add word to data
				if (wordLength == 0) {
					; 							// skip 0 word length issues 
				} else {
					pWordCount[wordLength]++;	// inc wordcount array
				}
				wordLength = 0;					// reset wordLength
			} else if ( isalpha(c) ) {			
				wordLength++;					// count regular characters
				if (wordLength > MWORDSZ) {
					wordLength = MWORDSZ;		// cap the wordLength to MWORDSZ
				}
			}
		} while (! inStream.eof() );
		
		inStream.close();						// close pFileName
	}
	
	return 0;									// readFile worked
}

//
//  Print data for Analyzer 
//
void Analyzer :: printData()
{	
	int totalWords = 0;
	
	for (int i = 1; i <= MWORDSZ; i++ ) {
		totalWords += pWordCount[i];
	}
	
	cout << "Data for " << pFileName << endl;
	
	if (totalWords == 0) {						// empty file
		cout << "File is empty. " << endl;
		
	} else {
	
		cout << "total words: " << totalWords << endl;
		
		for (int i = 1; i <= MWORDSZ; i++ ) {
			cout << "Proportion of " << i;
			
			if (i == MWORDSZ) {
				cout << "- (or more) letter words: ";
			} else {
				cout << "-letter words: ";
			}

			cout << setw(8) << (pWordCount[i]  / (float) totalWords) * 100 << "%" 
			     << "  (" << pWordCount[i] << " words)" << endl;	
		}
	}
}


//
//  ask for name of file to analyze
//  construct Analyzer object
//  read file and print data
//
void main()
{
	char fileName[MAXSTR];
	
	do {
		getString("Enter the name of your file (\"none\" to exit) : ",
		          fileName, MAXSTR);
		Analyzer robot( fileName );				// construct Analyzer object
		
		if ( strcmp(fileName, "none") == 0) {
			break;								// exit loop
		} else {
			if ( robot.readFile() == 0 ) {		// read worked OK
				robot.printData();				// print data
			}
		}
	} while ( true );
	
	exit( 0 );
}
