/* File: pigs2.c

   This file contains a program that translates
   from English to pig latin.  It uses the 
   strategy developed in class on Nov 7, 1995.
   The class had agreed on the following rules.

       Non-alphabetic characters such as digits and punctuation
	  should be passed through.
       Build a string with the translated text.
       Extra white space should be removed.
       All upper case letters will be changed to lower case.
       The letter "y" is a vowel, always.

  The class had also decided to use a character by character
  strategy  --- yuk :p

  This version does handles extra white space as specified.
*/

#include <stdio.h>
#include "genlib.h"
#include "simpio.h"
#include "strlib.h"
#include "ctype.h"

/* Function Prototypes */
bool IsVowel(char) ;
void HandleSpaces(char c) ;
void HandlePunctuation(char c) ;
void HandlePrefix(char c) ; 
void HandleAlpha(char c) ;

/* Type definition for the states of the program */
typedef enum {Spaces, Consonants, MiddleOfWord, Punctuation} state_type ;

/* Global Variable */
state_type state ;
string result ;
string prefix ;


main() {
   char c ;
   string input ;
   int index, length ;

   result = "" ;
   prefix = "" ;
   index = 0 ;
   state = Spaces ;

   printf("Enter an English sentence: ") ;
   input = GetLine() ;
   length = StringLength(input) ;

   /* Process the input line character by character */
   for(index = 0 ; index <= length ; index++) {
      c = IthChar(input,index) ;
      c = tolower(c) ;
      switch(state) {
	case Spaces : HandleSpaces(c) ; break ;
	case Consonants : HandlePrefix(c) ; break ;
	case MiddleOfWord : HandleAlpha(c) ; break ;
	case Punctuation : HandlePunctuation(c) ; break ;
	default : Error("Oops, something is very wrong!") ;
      }
/*
  The debugging statements:
  
     printf("input[%d] = %c: %d\n   result = %s\n   prefix = %s\n", 
	 index, c, state, result, prefix) ;
*/
   }

   printf("Pig Latin: %s\n", result) ;
}


/*
  This function handles the case where the program has
  just seen a space.
*/
void HandleSpaces(char c) {

  if (IsVowel(c)) {
     /* New English word, starting with a vowel */
     prefix = "way" ;
     result = Concat(result, CharToString(c)) ;
     state = MiddleOfWord ;
  } else if (isalpha(c)) {
     /* New English word, starting with a consonant */
     prefix = CharToString(c) ;
     state = Consonants ;
  } else if (!isspace(c)) {
     /* Punctuation marks, digits or special character found */
     result = Concat(result, CharToString(c)) ;
     state = Punctuation ;
  }
}

/*
  This function handles the case where the program has
  just seen a punctuation mark or digit.
*/
void HandlePunctuation(char c) {

  if (IsVowel(c)) {
     /* New English word, starting with a vowel */
     prefix = "way" ;
     result = Concat(result, CharToString(c)) ;
     state = MiddleOfWord ;
  } else if (isalpha(c)) {
     /* New English word, starting with a consonant */
     prefix = CharToString(c) ;
     state = Consonants ;
  } else {
     /* Between word character found */
     result = Concat(result, CharToString(c)) ;
     if (isspace(c)) state = Spaces ;
  }
}


/*
  This function handles the case where a word begins with
  a consonant.  The initial sequence of consonants is
  stored in the global variable prefix.
*/
void HandlePrefix(char c) {
   if (IsVowel(c)) {
      /* End of consonants detected */
      prefix = Concat(prefix, "ay") ;
      result = Concat(result, CharToString(c)) ;
      state = MiddleOfWord ;
   } else if (isalpha(c)) {
      /* More consonants detected */
      prefix = Concat(prefix, CharToString(c)) ;
   } else {
      /* End of word detected. This word is all consonants. */
      prefix = Concat(prefix, "ay") ;
      result = Concat(result, prefix) ;
      result = Concat(result, CharToString(c)) ;
      prefix = "" ;
      if (isspace(c)) {
        state = Spaces ;
      } else {
	state = Punctuation ;
      }
   }
}


/*
  This function handles the case where the program is
  reading in the characters in the middle of an English word.
*/
void HandleAlpha(char c) {
   if (isalpha(c)) {
     /* Still in the word */
     result = Concat(result, CharToString(c)) ;
   } else {
     /* End of the word is detected */
     result = Concat(result, prefix) ;
     result = Concat(result, CharToString(c)) ;
     prefix = "" ;
     if (isspace(c)) {
        state = Spaces ;
     } else {
	state = Punctuation ;
     }
   }
}


/* 
   Returns true if the given character is a vowel.
*/
bool IsVowel(char c) {
   
   c = tolower(c) ;

   /* Check if c i s a vowel or a 'y' */
   if ( (c == 'a') || (c == 'e') || (c == 'i') ||
	(c == 'o') || (c == 'u') || (c == 'y') ) {
      return(TRUE) ;
   } else {
      return(FALSE) ;
   }
}



