// Copyright 1999
// College of Computer Science
// Northeastern University Boston MA 02115

// This software may be used for educational purposes as long as this copyright
// notice is retained at the top of all files

// Should this software be modified, the words "Modified from Original" must be
// included as a comment below this notice

// All publication rights are retained.  This software or its documentation may
// not be published in any media either in whole or in part.

///////////////////////////////////////////////////////////////////////////////

//	Exercises 7:	Using string, writing functions with reference arguments
//					and return values

//	STUDENT NAME:	¥?¥?¥
//	STUDENT ID:		¥?¥?¥
//	DATE:			¥?¥?¥

///////////////////////////////////////////////////////////////////////////////

// The standard include files that include traditional C and C++ headers and
// many other Core Tools headers ... see CHeaders.h for additional details

#include "IOTools.h"
#include "Graphics.h"
#include "Random.h"

// Enter project specific include files here as well as classes and functions
// that you choose to define in the main shell rather than in separate files

// prototypes

void ToUpper(char& c);
void Exercise1();

bool IsLess(const string& s1, const string& s2);
void Exercise2();

void Exercise3();
void Exercise4();

void Swap(int& a, int& b);
void OrderThree(int& x, int& y, int& z);
void Exercise5();

void ReverseString(const string& s1, string& s2);
void NumToString(int n, string& s);
void Exercise6();

void Exercise7();


bool MyStringToInteger(const string& s, int& n);
void Exercise8();

 
// definitions

void ToUpper(char& c){
// Convert a lower case character to upper case
// Leave other characters intact

	if (('a' <= c) && (c <= 'z'))
		c = c + ('A' - 'a');
};

void Exercise1(){
// Write and test a function that will convert a character to upper case.
// If the character is not a lower case letter, it will remain unchanged.

	cout << "Input string will be converted to all upper case letters" << endl;

	string s;
	RequestString("Type in a word", s);			// get a test string
	int len = s.length();
	int i;
	
	for (i = 0; i < len; i++){					// traverse all letters in the string
		ToUpper(s[i]);							// convert to upper case
		cout << s[i];							// and print
	};
	cout << endl;

};

void Exercise2(){
// Write and test a function that will convert a character to lower case.
// If the character is not an upper case letter, it will remain unchanged.
	

};

bool IsLess(const string& s1, const string& s2){
// compare two strings and return true if the first string
// comes before the second in alphabetical order
	
	int len1 = s1.length();
	int len2 = s2.length();
	
	int len = len1;					// len is the length of the shorter string
	if (len2 < len1)
		len = len2;
	
	int i;
	char c1; char c2;				// we need to copyt the string characters
									// so the original string is not destroyed
	
	for (i = 0; i < len; i++){
	
		c1 = s1[i];					// copy the current characters
		c2 = s2[i];
		
		ToUpper(c1);				// convert both to upper case
		ToUpper(c2);
		
		if (c1 == c2)				// if letters match, advance to the next letter
			i++;
		else if (c1 < c2)			// first non-matching pair determines the order
			return true;
		else
			return false;
	};
	
	// if the first part of the strings matches: the shorter string is smaller
	if (len1 <= len2)
		return true;
	else 
		return false;

};

void Exercise3(){
// Write and test a function that compare two strings and return true 
// if the first string comes before the second string in alphabetical order
// Assume that any leading blanks have been removed from the string.
// If the string consists of more than one word, each two words are separated by a single blank
// Capital and lower case letters are considered as the same

	cout << "Two input strings will be printed in alphabetical order.:" << endl;

	string first;
	string second;
	
	RequestString("First string:", first);		// get the first input string
	RequestString("Second string:", second);	// get the second input string
	
	if (IsLess(first, second)) {				// compare the strings
		cout << first << endl;					// print in order
		cout << second << endl;
	}
	else {
		cout << second << endl;					// reverse the order
		cout << first << endl;
	
	}
	

};

void Exercise4(){
// Write and test a function GetUpper that will receive a character as a value argument
// and return as a function value the same character converted to upper case
// following the rules of Exercise 1. 

	
};

void Swap(int& a, int& b){
// exchange the values of two integer reference arguments
	
		int temp = a;
		a = b; 
		b = temp;
};

void OrderThree(int& x, int& y, int& z){
// reorder the values of three integer reference arguments 
// so they are in ascending order

	if (x > y)
		Swap(x, y);				// x is smaller of x and y
	if (x > z)
		Swap(x, z);				// x is smallest of the three
	if (y > z)
		Swap(y, z);				// z is now the largest

};

void Exercise5(){
// Write and test a function that will receive three integer variables 
// as reference arguments and order them in ascending order.
// Actually, it means that the three varaibles will have their values 
// interchanged as necessary

	cout << "The three numbers typed in will be put in ascending order" << endl;

	int a = RequestInt("The first number:");
	int b = RequestInt("The second number:");
	int c = RequestInt("The third number:");
	
	OrderThree(a, b, c);		// call the function that swaps the values
								// into ascending order
	
	cout << "The number in order are: " << a << ", " << b << ", " << c << endl;

};

void ReverseString(const string& s1, string& s2){
// make string s2 be a revese of string s1

	int len = s1.length();		// find the length of string s1
	int i;
	s2 = s1;					// allocate enough space for s2
	
	for (i = 0; i < len; i++){
		s2[i] = s1[len - i - 1];	// traverse and reverse
	};
	
};

void NumToString(int n, string& s){
// convert integer n into a string of digit characters

	int i = 0;
	string ss;						// copy of the truncated reversed string
	s = "          ";				// reserve enough space for the digits
	
	// show how the string is built: the units will be first (reversed order)
	cout << "Print the string as it is built in reverse order" << endl;
	
	while (n > 0){					// s[0] get units, s[1] gets tens, s[i] gets 10^i digit
	
		s[i] = '0' + (n % 10);		// get the digit
		n = n / 10;					// divide by ten to get the next digit into units place
		cout << s[i] << endl;		// show the digit we extracted
		i++;						// move along in the string
	};
	
	// string s has possible extra blanks at the end

	ss = s.substr(0, i);			// copy only the relevant digits
	cout << "The reverse string is:" << ss << endl << endl;
	
	// put the digits in the right order
	ReverseString(ss, s);
	cout << "The number as a string is: " << s << endl << endl;
	
};

void Exercise6(){
// Write and test a function that will convert an integer to a string
// The function will receive the number as a value argument
// and will return the string as a reference argument

	cout << "We will convert an integer into a string of digits" << endl;

	int n = RequestInt("Type in  number:");
	string s;
	NumToString(n, s);
	
	// print one digit at a time, both forwards and backwards
	cout << "To verify the function call worked correctly" << endl;
	cout << "we print the digits both forwards and backwards." << endl;
	
	int len = s.length();
	int i;
	for (i = 0; i < len; i++){
		cout << s[i] << "   " << s[len - i - 1] << endl;
	};

};

void Exercise7(){
// Write and test a function IsInteger that will take a sting as a value argument
// and return true if all characters in the string are digits and return false otherwise
 	
 	
};

bool MyStringToInteger(const string& s, int& n){

	return true;
};


void Exercise8(){
// Write and test a function MyStringToInteger that will receive one string as a value argument
// and will return as a refernce integer argument the numeric value represented by the string
// If the string is too long (more than 8 digits, or it contains characters other than digits
// the function return value will be false, otherwise it will be true
// The function prototype is given.


};



int main(int argc, char* argv[]) {

	// Use the following line if you choose NOT to open any graphics windows
	// InitializeConsole();

	// Build graphics window 0
	GraphicsWindow GW0(300, 300);

	// Move the console below graphics window 0
	ConsolePlaceBelow(0);

	// Give the console the focus for user interaction
	MakeConsoleForeground();

//////////

	// Enter the main program here
	SetRandomSeed();

	int i = 1;
	
	while (Confirm("Another exercise?", true)){		// loop to run another exercise
		i = RequestInt("Exercise number: ", i);		// determine which exercise to run
													// the default moves you to the next one
		cout << endl << "Exercise " << i << endl;	// notify user of the accepted selection
		switch (i){									// un the appropriate exercise
			case 1: {
					Exercise1();
					break;
					}
			case 2: {
					Exercise2();
					break;
					}
			case 3: {
					Exercise3();
					break;
					}
			case 4: {
					Exercise4();
					break;
					}
			case 5: {
					Exercise5();
					break;
					}
			case 6: {
					Exercise6();
					break;
					}
			case 7: {
					Exercise7();
					break;
					}
			case 8: {
					Exercise8();
					break;
					}
			default:
					Exercise1();
		
		};
		i = (i+1);									// next time, continue with the next exercise
		if (i > 8)									// we only have 10 exercises - cycle through again
			i = 1;
		cout << endl;

	}
	
//////////

	// The lines below make sure that the graphics windows remain open just
	// before the program terminates

	PressReturn("\nThe main program is about to terminate\n");

	return 0;
}

