/*
 * Daniel Arvesen
 * CS127
 * Project 2: Election
 *
 * Included files:
 *   - election.cpp      - source
 *   - documentation.txt - documentation
 *   - runs.txt          - example runs
 */

#include <iostream>
#include <fstream>  // file streams
#include <cstdlib>
#include <string>   // strings for filenames
#include "cs127.h"  // don't know if I will need this

using namespace std;
const int size = 1000; // the size of the arrays used with the getline function

void open_ifstream(ifstream&, char*);
void open_ofstream(ofstream&, char*);
void welcome();
char getPresVote();
char getViceVote();
char repeat();

int main(int argc, char* argv[])
{
  ifstream input;  // the input stream
  ofstream output; // the output stream
  char line[size];
  char pres[size], vice[size];
  char presA[size], presB[size], presC[size];
  char viceA[size], viceB[size], viceC[size];
  char presVote, viceVote;
  int presAtally = 0, presBtally = 0, presCtally = 0;
  int viceAtally = 0, viceBtally = 0, viceCtally = 0;
  char repeatVote;
  
  if (argc != 3)
    {
      cout << "Usage: " << argv[0] << " [Candidates File] [Results File]\n";
      return 1;
    }

  open_ifstream(input, argv[1]);
  open_ofstream(output, argv[2]);
      
  do
    {
      welcome();
      while (!input.eof())
	{
	  input.getline(pres, size);  // using the getline function to get a line from the file and place it in a C string array
	  cout << pres;
	  input.getline(presA, size);
	  cout << "\n\tA. " << presA;
	  input.getline(presB, size);
	  cout << "\n\tB. " << presB;
	  input.getline(presC, size);
	  cout << "\n\tC. " << presC << "\n";
	  input.getline(line, size);

	  presVote = getPresVote();
	  
	  if (presVote == 'a' || presVote == 'A')
	    {
	      presAtally++;
	    }
	  else if (presVote == 'b' || presVote == 'B')
	    {
	      presBtally++;
	    }
	  else if (presVote == 'c' || presVote == 'C')
	    {
	      presCtally++;
	    }
      
	  input.getline(vice, size);
	  cout << vice;
	  input.getline(viceA, size);
	  cout << "\n\tA. " << viceA;
	  input.getline(viceB, size);
	  cout << "\n\tB. " << viceB;
	  input.getline(viceC, size);
	  cout << "\n\tC. " << viceC << "\n";
	  input.getline(line, size);
	  
	  viceVote = getViceVote();
	  
	  if (viceVote == 'a' || viceVote == 'A')
	    {
	      viceAtally++;
	    }
	  else if (viceVote == 'b' || viceVote == 'B')
	    {
	      viceBtally++;
	    }
	  else if (viceVote == 'c' || viceVote == 'C')
	    {
	      viceCtally++;
	    }
      	  repeatVote = repeat();
	}
      
      //      input.close();
      //      output.close();
      rewind(input);
    } while (repeatVote == 'y' || repeatVote == 'Y');

  // results

  cout << "Results:\n\n";

  // for president
  cout << pres << ":\n"; // for president, prints to screen
  output << "Results for: " << pres << "\n"; // outputs to a file

  if (presAtally > presBtally && presBtally > presCtally) // A wins
    {
      cout << "\t" << presA << "!\n";
      output << "  " << presA << " won by ";
      if (presBtally > presCtally)
	{
	  output << presAtally - presBtally << " vote(s) over " << presB << endl;
	}
      else if (presCtally > presBtally)
	{
	  output << presAtally - presCtally << " vote(s) over " << presC << endl;
	}
      else 
	{
	  output << presAtally - presBtally << " vote(s) over " << presB << " and " << presC << endl; // a tie
	}
    }

  else if(presBtally > presAtally && presBtally > presCtally) // B wins
    {
      cout << "\t" << presB << "!\n";
      output << "  " << presB << " won by ";
      if (presAtally > presCtally)
        {
          output << presBtally - presAtally << " vote(s) over " << presAtally << endl;
        }
      else if(presCtally > presAtally)
        {
          output << presBtally - presCtally << " vote(s) over " << presB << endl;
        }
      else
        {
          output << presAtally - presBtally << " vote(s) over " << presBtally << " and " << presCtally << endl; // a else
        }
    }

  else if(presCtally > presAtally && presCtally > presBtally)//C wins
    {
      cout << "\t" << presC << "!\n";
      output << "  " << presC << " won by ";
      if (presAtally > presBtally)
        {
          output << presCtally - presAtally << " vote(s) over " << presAtally << endl;
        }
      else if(presBtally > presAtally)
        {
          output << presCtally - presBtally << " vote(s) over " << presBtally << endl;
        }
      else
        {
          output << presCtally - presAtally << " vote(s) over " << presAtally << " and " << presBtally << endl; // a tie
        }
    }

  // real ties from here on out  

  else if(presAtally > presBtally && presAtally == presCtally) //A and C win
    {
      cout << "\t" << presA << endl;
      cout << "\tAND " << presC << "!" << endl;
      output << "  " << presA << " and " << presC <<  " won by " << presAtally - presBtally << " vote(s)over " << presB << endl;
    }

  else if(presAtally > presCtally && presAtally == presBtally) //A and B win
    {
      cout << "\t" << presA << endl;
      cout << "\tAND " << presB << "!\n";
      output << "  " << presA << " and " << presB <<  " won by " << presAtally - presCtally << " vote(s)over " << presC << endl;
    }

  else if(presBtally > presAtally && presBtally == presCtally) //B and C win
    {
      cout << "\t" << presB << endl;
      cout << "\tAND " << presC << "!\n";
      output << "  " << presB << " and " << presC <<  " won by " << presBtally - presAtally << " vote(s)over " << presA << endl;
    }

  else if(presAtally == presBtally && presBtally == presCtally) //3 way tie
    {
      cout << "\tEveryone wins!\n";
      cout << "\t" << presA << ", " << presB << " AND " << presC << "!\n";
      output << "  " << presA << " and " << presB << " and " << presC << " tied.\n";
    }

  // prints detailed information into the output file
  output << "\tA   " << presAtally << "  " << presA << endl;
  output << "\tB   " << presBtally << "  " << presB << endl;
  output << "\tC   " << presCtally << "  " << presC << endl;
  output << "\n";


  // ********** VICE PRESIDENT **********

  cout << vice << ":\n"; // for vice presiident, prints to screen
  output << "Results for: " << vice << "\n"; // outputs to a file
  
  if (viceAtally > viceBtally && viceBtally > viceCtally) // A wins
    {
      cout << "\t" << viceA << "!\n";
      output << "  " << viceA << " won by ";
      if (viceBtally > viceCtally)
	{
	  output << viceAtally - viceBtally << " vote(s) over " << viceB << endl;
	}
      else if (viceCtally > viceBtally)
	{
	  output << viceAtally - viceCtally << " vote(s) over " << viceC << endl;
	}
      else 
	{
	  output << viceAtally - viceBtally << " vote(s) over " << viceB << " and " << viceC << endl; // a tie
	}
    }

  else if(viceBtally > viceAtally && viceBtally > viceCtally) // B wins
    {
      cout << "\t" << viceB << "!\n";
      output << "  " << viceB << " won by ";
      if (viceAtally > viceCtally)
        {
          output << viceBtally - viceAtally << " vote(s) over " << viceAtally << endl;
        }
      else if(viceCtally > viceAtally)
        {
          output << viceBtally - viceCtally << " vote(s) over " << viceB << endl;
        }
      else
        {
          output << viceAtally - viceBtally << " vote(s) over " << viceBtally << " and " << viceCtally << endl; // a else
        }
    }

  else if(viceCtally > viceAtally && viceCtally > viceBtally)//C wins
    {
      cout << "\t" << viceC << "!\n";
      output << "  " << viceC << " won by ";
      if (viceAtally > viceBtally)
        {
          output << viceCtally - viceAtally << " vote(s) over " << viceAtally << endl;
        }
      else if(viceBtally > viceAtally)
        {
          output << viceCtally - viceBtally << " vote(s) over " << viceBtally << endl;
        }
      else
        {
          output << viceCtally - viceAtally << " vote(s) over " << viceAtally << " and " << viceBtally << endl; // a tie
        }
    }

  // real ties from here on out  

  else if(viceAtally > viceBtally && viceAtally == viceCtally) //A and C win
    {
      cout << "\t" << viceA << endl;
      cout << "\tAND " << viceC << "!" << endl;
      output << "  " << viceA << " and " << viceC <<  " won by " << viceAtally - viceBtally << " vote(s)over " << viceB << endl;
    }

  else if(viceAtally > viceCtally && viceAtally == viceBtally) //A and B win
    {
      cout << "\t" << viceA << endl;
      cout << "\tAND " << viceB << "!\n";
      output << "  " << viceA << " and " << viceB <<  " won by " << viceAtally - viceCtally << " vote(s)over " << viceC << endl;
    }

  else if(viceBtally > viceAtally && viceBtally == viceCtally) //B and C win
    {
      cout << "\t" << viceB << endl;
      cout << "\tAND " << viceC << "!\n";
      output << "  " << viceB << " and " << viceC <<  " won by " << viceBtally - viceAtally << " vote(s)over " << viceA << endl;
    }

  else if(viceAtally == viceBtally && viceBtally == viceCtally) //3 way tie
    {
      cout << "\tEveryone wins!\n";
      cout << "\t" << viceA << ", " << viceB << " AND " << viceC << "!\n";
      output << "  " << viceA << " and " << viceB << " and " << viceC << " tied.\n";
    }

  // prints detailed information into the output file
  output << "\tA   " << viceAtally << "  " << viceA << endl;
  output << "\tB   " << viceBtally << "  " << viceB << endl;
  output << "\tC   " << viceCtally << "  " << viceC << endl;
  output << "\n";

  return 0;
}  

void open_ifstream(ifstream& input, char* file)
{
  input.open(file); // open the input stream
  if (input.fail())
    {
      cout << "Cannot open file " << file << " for input\n";
      exit(1);
    }
  return;
}

void open_ofstream(ofstream& output, char* file)
{
  output.open(file);
  if (output.fail())
    {
      cout << "Cannot open file " << file << " for output\n";
      exit(1);
    }
  return;
}

void welcome()
{
  cout << "Welcome to the International Election of 2003\n";
  cout << "Please vote responsibly, we do not want to end up like Diebold\n\n";
  return;
}


char getPresVote()
{
  char vote;
  cout << "Please enter your vote: ";
  cin >> vote;

  while (vote != 'A' && vote != 'a' && vote != 'B' && vote != 'b' && vote != 'C' && vote != 'c')
    {
      cout << "You have entered an invalid selection. Please choose again\n";
      cout << "Please enter your vote: ";
      cin >> vote;
    }
  
  cout << "************\n";

  return vote;
}


char getViceVote()
{
  char vote;
  cout << "Please enter your vote: ";
  cin >> vote;

  while (vote != 'A' && vote != 'a' && vote != 'B' && vote != 'b' && vote != 'C' && vote != 'c')
    {
      cout << "You have entered an invalid selection. Please choose again\n";
      cout << "Please enter your vote: ";
      cin >> vote;
    }

  cout << "************\n\n";
  cout << "********************\n";
  cout << "Thank You for voting\n";
  cout << "********************\n\n";
  return vote;
}


char repeat()
{
  char choice;
  cout << "Is there another voter? [y|n] ";
  cin >> choice;

  while (choice != 'y' && choice != 'Y' && choice != 'n' && choice != 'N')
    {
      cout << "Invalid choice. Please enter again.\n\n";
      cout << "Is there another voter? [y|n] ";
      cin >> choice;
    }
  return choice;
}
