//Caleb Hays
//CSIS 240
//Open Lab Assignment 9

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;

double TotalCharge (int, int);
void BubbleSort (int[], int [], double [], const int, string []);
int BinarySearch (int[], int, int, int);


int main()
{
	//Define Variables
	char sentinel;
	int Index, numcustomers, result, key;
	double amountdue, totalcharges, averagekwh, averagecharge, kwhsum;

	//Initialize Variables
	Index=0;
	numcustomers=0;
	amountdue=0.0;
	totalcharges=0.0;
	averagekwh=0.0;
	averagecharge=0.0;
	kwhsum=0.0;
	result=0;
	key=0;
	sentinel='Y';
	
	//Define Arrays
	const int max_num=100;
	string Name[max_num];
	int Usage[max_num], CustomerNumbers[max_num];
	double AmountDue[max_num];
	
	Initialize Arrays
	for (Index = 0; Index < max_num; Index++)
	{CustomerNumbers[Index]=0;}
	
	for (Index = 0; Index < max_num; Index++)
	{Usage[Index]=0;}
	
	for (Index = 0; Index < max_num; Index++)
	{AmountDue[Index]=0;}
	
	//Pre-formatting
	cout<<endl
		<<"----------------------------------------------------\n"
		<<"| Run Calculations for Monthly Electricity Charges |\n"
		<<"----------------------------------------------------"
		<<endl
		<<endl;
	
	//Input
	ifstream data ("/data.txt", ios::in);
	if (!data)
	{
		cerr << "File could not be opened\n";
		exit(1);
	}
	for (int read=0; read<50; read++)
	{
		data>>CustomerNumbers[read];
		data.ignore(1);
		getline (data, Name[read]);
		data>>Usage[read];		
		if(data.eof()) 
		{break;}
		numcustomers=read;
	}
		//Process the customer
		for (Index = 0; Index < numcustomers; Index++)
		{AmountDue[Index]=TotalCharge(Usage[Index], numcustomers);}
	
		cout<<endl<<endl<<endl;
	
		//Sum the KWHs
		for (Index = 0; Index < numcustomers; Index++)
		{kwhsum=kwhsum+Usage[Index];}
		
		//Sum the charges
		for (Index = 0; Index < numcustomers; Index++)
		{totalcharges=totalcharges+AmountDue[Index];}
		
		//Average KWHs
		averagekwh=kwhsum/numcustomers;
		
		//Average Customer Charge
		averagecharge=totalcharges/numcustomers;
	
	//Call BubbleSort
	BubbleSort (Usage, CustomerNumbers, AmountDue, numcustomers, Name);
	
	//Calcuations for all customers
	
	//Formatting
	cout<<"Customer #     Name                   Usage (kwh)     Amount Due (Dollars) \n"
	<<"-------------------------------------------------------------------------------\n";
	for (Index = 0; Index < numcustomers; Index++)
	{
	cout<<setw(15) <<left <<CustomerNumbers[Index] 
		<<setw(20) <<Name[Index] 
		<<setw(10) <<right<<Usage[Index]  
		<<setw(10) <<fixed <<setprecision(2) <<"$" <<AmountDue[Index]<<endl;
	}
	
	cout<<endl
		<<endl
	<<"---------------------------------------------------------------------------\n"
		<<"Total   "
		<<setw(37) <<fixed <<setprecision(0) <<kwhsum     <<setw(10) <<"$" <<setprecision(2) <<totalcharges
		<<endl
		
		<<"Average "
		<<setw(37) <<setprecision(1)         <<averagekwh <<setw(10) <<"$" <<setprecision(2) <<averagecharge;
	
	cout<<endl<<endl;
	
	//BinarySearch
	while (sentinel == 'Y' || sentinel == 'y')
	{
		cout<<"Enter a Customer Number to search: ";
		cin>>key;
	
		//Check for Accuracy
		while (key < 1000 || key > 9999)
			{
				cout<<"Customer Number must contain four digits. Please re-enter: ";
				cin>>key;
			}
	
	cout<<key <<endl;
	
		result=BinarySearch(CustomerNumbers, key, 0, max_num-1);
	
		if (result != -1)
			{
				cout<<'\n' <<key << " found in array element: " <<result <<endl;
				cout<<CustomerNumbers[result] <<" " <<Name[result] <<" " <<Usage[result] << " " <<AmountDue[result];
			}
		else
			cout<<'\n' <<"Customer #" <<key <<" was not found." <<endl;
			
		//Sentinel
		cout<<"Search another customer? (Y/N): ";
		cin>>sentinel;
		while (sentinel != 'Y' && sentinel != 'y' && sentinel != 'N' && sentinel != 'n')
		{
			cout<<"You did not enter a correct response.\nPlease enter 'Y' to search another customer or 'N' to end: ";
			cin>>sentinel;
		}
		cout<<endl;
		
		for (int b=0; b<=100; b++)
		{cout<<CustomerNumbers[b]<<endl;}
	}
	
	cout<<endl<<endl<<endl;
	return 0;
}
	
double TotalCharge (int kwh, int numcustomers)
{
	//Define local variables
	double charge;
	
	//Initialize local variables
	charge=0;

		if (kwh <= 300) charge=kwh*(.10);
			else if (kwh > 300 && kwh <= 800) charge=(.09)*(kwh-300)+30;
				else if (kwh > 800 && kwh <= 1300) charge=(.07)*(kwh-800)+75;
					else charge=(.055)*(kwh-1300)+110;
	
	return charge;
}

void BubbleSort (int a[], int b[], double c[], const int arraySize, string d[])
{
	int swap=1, Index, hold1, hold2;
	double hold3;
	string hold4;
	
	for (int pass = 0; swap==1; pass++) //passes
		{
			swap=0;
			for (Index = 0; Index < arraySize - 1 - pass; Index++) //one pass
				if (b [Index] > b[Index + 1])
					{
						 hold1=b[Index];
						 b[Index]=b[Index + 1];
						 b[Index + 1]=hold1;
						 swap=1;
						 
						 hold2=a[Index];
						 a[Index]=a[Index + 1];
						 a[Index + 1]=hold2;
						 swap=1;
						 
						 hold3=c[Index];
						 c[Index]=c[Index + 1];
						 c[Index + 1]=hold3;
						 swap=1;
						 
						 hold4=d[Index];
						 d[Index]=d[Index + 1];
						 d[Index + 1]=hold4;
						 swap=1;
					}
		}
}

int BinarySearch (int a[], int search_key, int low, int high)
{
	int middle;
	
	while (low <= high)
	{
		middle = (low+high)/2;
		
		if (search_key == a[middle]) //match
			return middle;
		else if (search_key < a[middle]) 
			high = middle-1; //search low end of array
		else
			low = middle+1;	//search high end of array
	}
	
	cout<<search_key <<endl;

	for (int b=0; b<=100; b++)
	{cout<<a[b]<<endl;}
	
	return -1; //key not found
}
