///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//         This example code is from the book:
//
//           Object-Oriented Programming with C++ and OSF/Motif, 2nd Edition
//         by
//           Douglas Young
//           Prentice Hall, 1995
//           ISBN 0-13-20925507
//
//         Copyright 1995 by Prentice Hall
//         All Rights Reserved
//
//  Permission to use, copy, modify, and distribute this software for 
//  any purpose except publication and without fee is hereby granted, provided 
//  that the above copyright notice appear in all copies of the software.
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////
// CountWordsCmd.C: A simple test of the InterruptibleCmd class
///////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "CountWordsCmd.h"
#include "InfoDialogManager.h"


CountWordsCmd::CountWordsCmd ( char *name, 
			       int   active, 
			       char *filename ) : 
InterruptibleCmd ( name, active )
{
    struct stat statInfo;
    
    // Initialize data members
    
    _bytesRead = 0;       
    _fileSize  = 0;       
    _percentDone = 0;
    
    // Open the given file and post a warning in case of failure
    
    if( ( _fd = fopen ( filename, "r" ) ) == NULL ) 
    {
	char buf[BUFSIZ];
	
	sprintf ( buf, "Can't open %s", filename );
	theInfoDialogManager->post ( buf );
    }
    else
    {
	// Check the size of the file, to use as a basis for
	// reporting progress 
	// Don't bother counting if the file is empty.
	
	char buf[BUFSIZ];
	
	if ( stat ( filename, &statInfo ) == 0 )
	    _fileSize = statInfo.st_size;
	
	if ( _fileSize == 0 )
	{
	    sprintf ( buf, "%s is empty!", filename );
	    theInfoDialogManager->post ( buf );
	    
	    fclose ( _fd );
	    _fd = 0;
	}
    }
}
CountWordsCmd::~CountWordsCmd ()
{
    // Only close the file if it was successfully opened
    
    if ( _fd )
	fclose ( _fd );
}
void CountWordsCmd::doit()
{
    char  buf[BUFSIZ];
    char *sep = " !@#$%^&*()_+=-}{][|\';:\"?></.,`~\\\n\t";
    int   percent;
    
    // If the file has not been opened, indicate that the task 
    // is finished
    
    if ( !_fd )
    {
	_done = TRUE;
	return;
    }
    
    // Read a few lines each time doit() is called
    for ( int i = 0; i < 20; i++ )
    {
	char *result;
	char *word;
	
	// Read in one line of text, indicating that the
	// task is done if we reach end-of-file
	
	if ( ( result = fgets ( buf, BUFSIZ, _fd ) ) == NULL )
	{
	    _done = TRUE;
	    return;
	}
	
	// Compute the total characters read for progress report
	
	_bytesRead += strlen ( buf );
	
	// Extract the first full word and save it in the word list
	
	word = strtok ( buf, sep );
	
	saveWord ( word );
	
	// Continue to extract words until the line is exhausted
	
	while ( ( word = strtok ( NULL, sep ) ) != NULL )
	    saveWord ( word );
    }
    
    // Update the busy dialog and report progress as 
    // the percentage of the file read so far 
    // Only report if the percent done has changed
    
    percent =  ( int ) (( float ) _bytesRead / ( float ) _fileSize * 100);
    
    if ( _percentDone != percent )
    {
	_percentDone = percent;
	
	sprintf ( buf, "Counting, Please Wait...\n %d %% Completed",
		  _percentDone );
	
	updateMessage( buf );
    }
}
void CountWordsCmd::saveWord ( char * word )
{
    // Check for valid input
    
    if ( !word )
	return;
    
    // Search for the word and increment the count if found
    
    for ( int i = 0; i < _list.size(); i++ )	
    {
	if ( strcmp(_list[i]->word(), word ) == 0)
	{
	    _list[i]->increment();
	    return;
	}
    }
    
    // If not found, create a new Word object and add it to the
    // list
    
    _list.add ( new Word ( word ) );
}



























































































