// This example introduces us to C++ and classes. We'll work with a class Rational.

// History: 2/25/26 - Implemented overloaded stream insertion (<<) for Rational objects. Updated
//                    our getters so they're now constant functions. Constant objects can only
//                    invoke constant functions. Thus, if we wanted to work with constant references
//                    in the stream insertion operator, we need to modify our getters to be
//                    constant. Constant functions can't modify data members of the class. We started
//                    working with file processing. See the code in main () for that.
// 
//          2/23/26- Discussed operator overloading in detail. We implemented
//                   an overloaded assignment op (=) and addition (+) for
//                   Rational objects. We discussed the Rule of Three.
// 
//          2/20/26 - Discussed C++ references and pass-by-reference. A reference
//                    is an alias or another name for an existing variable or
//                    object. We implemented a copy constructor and constructor
//                    with default arguments.
// 
//          2/18/26 - Declared the Rational class. Discussed class vs. object.
//                    Discussed and applied private and public specifiers. Implemented
//                    the necessary getters and getters, along with one
//                    constructor and the destructor.

#include "Rational.hpp"

void update_int(int& n); // we are passing-by-reference with this function

int main(void)
{
	int n1 = 50, num = 0, den = 0;
	char slash = '\0';
	int &refn1 = n1; // C++ reference operator
	// The instantiation of a class is called an object - it's the constructed
	// "building" - memory is now allocated for the data members of the object
	Rational r1 /*invokes constructor with the numerator default to 0 and
		denomoinator default to 1*/, // the default constructor is implicitly called here
		r2(r1) /*invokes copy constructor*/, r3 = r1 /*invokes copy constructor*/,
		r4(5)/*invokes constructor with the denomoinator default to 1*/, r5(7, 3);
	
	// basic file processing here
	std::ifstream inputStream;
	char line[100] = "";
	inputStream.open("RationalData.txt", std::ios::in); // in means "r" - read/input mode
	inputStream >> num;
	r1.setNumerator(num);
	inputStream >> slash;
	inputStream >> den;
	r1.setDenominator(den);
	std::cout << r1 << std::endl;

	inputStream.getline(line, 100); // reads the newline at the end of the last Rational number
	inputStream.getline(line, 100); // read the next line in the file
	std::cout << line << std::endl;

	inputStream.close(); // close the stream

	//refn1 = 75; // refn1 is another name for n1; so n1 is actually being modified here

	//update_int(n1);
	//update_int(refn1); // this is another name for n1 so n1 is modified inside the function

	//std::cout << "refn1: " << refn1 << std::endl;
	//std::cout << "n1: " << n1 << std::endl;


	

	//std::cout << "address of r2: " << &r2 << std::endl;

	//// r2 = r2;
	//// r2 = refr2;

	////r4 = r2 = r3; // copy assignment operator

	//r1.setNumerator(3); // we need to use our well-defined interface to access the data members
	//r1.setDenominator(17);

	//r3 = r1 + r5; // this invokes our overloaded addition operator (+) and overloaded assignment (=)

	//std::cout << r1 << " " << r3 << std::endl;

	//std::cout << r1.getNumerator () << " / " << r1.getDenominator () << std::endl;

	return 0;
}

void update_int(int& n)
{
	std::cout << "Enter an integer: ";
	std::cin >> n;
}
