
//*****************************************************************************
////  Course:             COMS 2203 Foundations of Computer Programming II Sect. 2
////  Semester:           Fall 2004
////  Assignment Number:  #10 - Final Project                            
////  Author Name:        DarC KonQuesT                       
////  Date Written:       November 20, 2004
////                                                         
////  Description of Program:                              
////  Program acts as a simple banking program allowing the client to load, create,
////  save, and alter customer records and balances.  Some menu duties are segmented
//    into functions while others are written in line to avoid difficulties in
//    passing parameters to and from functions.  At run-time the program automagically                              
//    loads "account.dat" into a doubly linked list for all work to be done on.
////*****************************************************************************

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

struct NodeType  //linked list nodetype
{
      string first_name, last_name; //account holder's info
      float balance;  //account balance
      int accnt_number;  //account number
      NodeType *next;  //pointer to next in list
      NodeType *back;  //pointer to previous item in list
};



void print_menu()
{
  cout << "--- Menu ---" << endl << "1.  Add" << endl << "2.  Delete" << endl << "3.  Find" << endl << "4.  Update" << endl << "5.  Save" << endl << "9.  Quit" << endl << "------------" << endl;
  cout << "Enter 1, 2, 3, 4, 5, or 9 ==>";
}

NodeType* find_record(int id, NodeType *p, NodeType *head, NodeType *tail)//FIND_RECORD FUNCTION
{
   bool found = false;
   p = head;
   while(p != NULL)
   {
	  if(p->accnt_number == id)
	  {
      found = true;
	    return p;
	  }
  	else
	  p = p->next;
   }
   if(found == false)
	   return 0;
   
}

NodeType* add_record(int accnt_number)//ADD RECORD FUNCTION
{
  NodeType *p = new NodeType;
  p->accnt_number = accnt_number;
  cout << "Account Holder's First Name:  ";
  cin >> p->first_name;
  cout << endl << "Account Holder's Last Name:  ";
  cin >> p->last_name;
  cout << endl << "Beginning Balance:  ";
  cin >> p->balance;
  p->next = NULL;
  return p;
}

void save_records(NodeType *head, NodeType *p, string fname)//SAVE RECORDS FUNCTION
{
  ofstream outfile;
  p = head;
  outfile.open(fname.c_str());
  while(p != NULL)
  {
    outfile << fixed << showpoint << setprecision(2);
    outfile << p->accnt_number << " " << p->first_name <<  " " << p->last_name << " " << p->balance << endl;
    p = p->next;
  }
}




int main()
{
  NodeType *head = NULL;
  NodeType *tail = NULL;
  NodeType *p;
  string menu_choice;
  int accnt_search, search_int;
  bool saved = false;
  char save_choice;
  float new_bal;
  
  ifstream infile;
  string fname = "account.dat"; //account to load data from
 
//load info from account.dat into doubly linked list  
  infile.open(fname.c_str());
    if(!infile) 
    {
     cerr << "Error: Can't open file." << endl;
     return 1;
     }

   p = new NodeType; 
   infile >> p->accnt_number >> p->first_name >> p->last_name >> p->balance;
   p->back = head;
   head = tail = p;
   while(infile)
   {
      p = new NodeType;
      infile >> p->accnt_number >> p->first_name >> p->last_name >> p->balance;
      tail->next = p;
      p->back = tail;
      tail = p;
   }     
  tail = p->back;
  print_menu(); 
  cin >> menu_choice;
 while(1)
 {
    if(menu_choice == "1")
    {
      //check for existing record before calling function
      int accnt_number;  //account number to create
      NodeType *temp = new NodeType; //temporary pointer for comparison
 
      cout << endl << endl << "-----------------Add Record-----------------" << endl;
      cout << endl << "New Account Number:  " ;
      cin >> accnt_number;
   //   * !!!check for duplicate account number!!!
      temp = find_record(accnt_number, p, head, tail);
      if(temp != 0)
        cout << endl << "Account number " << accnt_number << " already exists!" << endl;
      else                     
      {
        p = add_record(accnt_number);
        tail->next = p; 
        p->back = tail;
        p->next = NULL;
        tail = p;
        saved = false;
      }
    }
    else if(menu_choice == "2")
    {
     //DELETE RECORD SECTION
    	saved = false;      
    	cout << endl << "Enter account number:  ";
      cin >> accnt_search;
      NodeType *temp = new NodeType; //temporary pointers for comparison and deletion
    	NodeType *temptr = new NodeType;
      
      //Check to make sure record to be deleted exists
    	temp = find_record(accnt_search, p, head, tail);
    	if(temp == 0)
         cout << endl << "Record " << accnt_search << " not found!" << endl;
      else if(temp != 0)  
         while(temp != NULL)
         {
            if(temp != head && temp != tail)
			    	{
				      //remove and relink list around temp
    				  temptr = temp;
		    		  temp->back->next = temp->next;  
				      temp->next->back = temp->back->back;
				      delete temptr;
				      break;
				    }
			    	else if(temp == head) //special statement in case portion to delete is the HEAD of the list
				    {
    				  temptr = temp;
		    		  temp->next->back = NULL;
				      delete temptr;
    				  head = temp->next;
		    		  break;
				    }
				    else if(temp == tail) //special statement in case portion to delete is the TAIL of the list
    				{ 
		  		    temptr = temp;
			  	    temp->back->next = NULL;
  			  	  tail = temp->back;
              delete temptr;
				      break;
            }
//			   else
//			     temp = temp->next;
         }
    }   
      else if(menu_choice == "3") //FIND RECORD menu choice
    	{ 
	      saved = false;
  	    p = head;
	      cout << endl << "Enter Account Number:  ";
	      cin >> accnt_search;
  	    p = find_record(accnt_search, p, head, tail);
	      if(p == 0)
	        cout << endl << "Record " <<  accnt_search << " not found!" << endl << endl;
    	  else
	      {	  
      	  cout << fixed << showpoint << setprecision(2);
      	  cout << endl << "Account Number:  " << p->accnt_number << endl << "Customer first name:  " << p->first_name << endl <<  "Customer last name:  " << p->last_name << endl <<  "Current balance:  " << p->balance << endl << endl;
        }
      }		   
    	
    else if(menu_choice == "4")  //UPDATE RECORD segment
    {      
      saved = false;
      p = head;
      NodeType *temp = new NodeType;
      cout << endl << "Enter account number:  ";
      cin >> accnt_search;
      temp = find_record(accnt_search, p, head, tail);
      if(temp == 0)
	      cout << endl << "Account number " << accnt_search << " does not exist!" << endl;
      else
      { 
         cout << endl << "Enter new balance:  ";
         cin >> new_bal;
      	 temp->balance = new_bal;
      }
    }
    
    else if(menu_choice == "5") //SAVE RECORDS function call
    {
      save_records(head, p, fname);
      saved = true;
    }

    else if(menu_choice == "9" && saved == false) //QUIT menu choice IF records NOT SAVED
    {
      cout << endl << "Records altered since last save, would you like to save before quitting? ";
      cin >> save_choice;
      if(save_choice == 'y' || save_choice == 'Y')
      {
        save_records(head, p, fname);
        return 0;
      }
      else if(save_choice == 'n' || save_choice == 'N')
        return 0;
      else
        cout << "Invalid Input:  Please enter y/Y or n/N" << endl;
    }
    
    else if(menu_choice == "9" && saved == true)  //QUIT menu choice IF record ARE SAVED
      return 0;
    
 /*  ----- CHECK FOR INVALID MENU INPUT HERE -------*/
    else
    	cout << endl << "Invalid Choice" << endl;
 
 print_menu(); 
 cin >> menu_choice;
    }

  return 0;
 }



