//
//
//  analyze.cc
//
//      AUTHOR: Russell Lowke
//         T.F: Francis Crick
//  CSCIE-s111: Unit Three, Main - question 8 [worth 10pts],  7/9/2002
//
// Description: Opens a text file and counts the number of
//				"small", "medium", and "large" 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
//
//        Note: Version superceeds 7/8/2002
//

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


// constants
const int MAXSTR  = 80;							// max char string size
const int W_SMALL = 4;							// small word length < 4
const int W_BIG   = 7;							// big word length > 7


//
//  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		pSmallWords,					// count of small words in file
			 	pLargeWords,					// count of large words in file
				pMediumWords;					// count of medium 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;
	pSmallWords  = 0;
	pLargeWords  = 0;
	pMediumWords = 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 ( c == ' ' || inStream.eof() ) {
			
				// add word to data
				if (wordLength == 0) {
					; 							// skip 0 word length issues 
				} else if ( wordLength < W_SMALL ) {
					pSmallWords++;				// small words
				} else if ( wordLength > W_BIG ) {
					pLargeWords++;				// big words
				} else {
					pMediumWords++;				// else medium words 
				}
				wordLength = 0;					// reset wordLength
			} else if ( (c >= 'A' && c <= 'Z') ||   
			            (c >= 'a' && c <= 'z') ) {
				wordLength++;					// count the regular characters
			}
			
		} while (! inStream.eof() );
		
		inStream.close();						// close pFileName
	}
	
	return 0;									// readFile worked
}

//
//  Print data for Analyzer 
//
void Analyzer :: printData()
{	
	int totalWords = pSmallWords + pMediumWords + pLargeWords;
	
	cout << "Data for " << pFileName << endl;
	
	cout << "    # of small words  = " << setw(8) << pSmallWords  << " = "
	     << setw(8) << (pSmallWords  / (float) totalWords) * 100 << "%" << endl;
	      
	cout << "    # of medium words = " << setw(8) << pMediumWords << " = "
		 << setw(8) << (pMediumWords / (float) totalWords) * 100 << "%" << endl;
		 
	cout << "    # of large words  = " << setw(8) << pLargeWords  << " = "
		 << setw(8) << (pLargeWords  / (float) totalWords) * 100 << "%" << endl;
		 
	cout << 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);
}
