// Overload.cpp : main project file.

#include "stdafx.h"

using namespace System;

// The Dbl struct definition
value struct Dbl
{
	double val;
	double hr, min, sec;     // creation or assignment time

	public:
		Dbl(double v)
		{  val = v; }

		double getVal() { return val; }
		// The addition operator for the Dbl struct
		static Dbl operator+(Dbl lhs, Dbl rhs)
		{
			Dbl result(lhs.val + rhs.val);
			return result;
		}
		
		// Adding a Dbl and an int
		static Dbl operator+(Dbl lhs, int rhs)
		{
			Dbl result(lhs.val + rhs);
			return result;
		}

		// Adding an int and a Dbl
		static Dbl operator+(int lhs, Dbl rhs)
		{
			Dbl result(lhs + rhs.val);
			return result;
		}

		// The equality operator for the Dbl struct
		static bool operator==(Dbl lhs, Dbl rhs)
		{
			return lhs.val == rhs.val;
		}

		// The inequality operator for the Dbl struct
		static bool operator!=(Dbl lhs, Dbl rhs)
		{
			return !(lhs == rhs);   // calls operator!=()
		}

		// The Equals() function for the Dbl struct...
		// override the base class (coz the original is Equals(x, y),
		// here only 1 argument, then it need virtual keyword...
		// Using implicit boxing, this code can be ommited
		virtual bool Equals(Object^ pOther) override
		{
			// Cast d2 to the same type as d1, that is Dbl struct type
			Dbl^ s = dynamic_cast<Dbl^>(pOther);
			// then, test the 'value' either null pointer or not...
			if (s == nullptr)
			{
				// Some test...
				Console::WriteLine("s == {0}", s);
				return false;
			}
			else
			{
				// Some test...
				Console::WriteLine("s == {0}", s);
				return (s->val == val);
			}
		}

		// The increment operator for the Dbl struct
		static Dbl operator++(Dbl d)
		{
			d.val += 1;
			return d;
		}
};

int main(array<System::String ^> ^args)
{
	Dbl d1(10.0);
	Dbl d2(20.0);
	Dbl d3(0.0);

	Console::WriteLine("d1 = {0}", d1.val);
	Console::WriteLine("d2 = {0}", d2.val);
	Console::WriteLine("d3 = {0}", d3.val);
	Console::WriteLine(); // blank line

	// Add two Dbl’s
	d3 = d1 + d2;
	Console::Write("d3 = d1 + d2, value of d3 is ");
	Console::WriteLine(d3.getVal());

	// Add a Dbl and an int
	d3 = d1 + 5;
	Console::Write("d3 = d1 + 5, value of d3 is now ");
	Console::WriteLine(d3.getVal());

	// Add an int and a Dbl
	d3 = 5 + d2;
	Console::Write("d3 = 5 + d2, value of d3 is now ");
	Console::WriteLine(d3.getVal());

	// Console::Write("Value of d3 is ");
	// Console::WriteLine(d3.getVal());

	Console::WriteLine(); // blank line
	if (d1 == d2)
		Console::WriteLine("d1 and d2 are equal");
	else
		Console::WriteLine("d1 and d2 are not equal");

	if (d1.Equals((Object^)d3))
		Console::WriteLine("d1 and d3 are equal");
	else
		Console::WriteLine("d1 and d3 are not equal");

	Console::WriteLine(); // blank line
	// Create a Dbl, and increment it
	Dbl d5(1.0);
	Console::Write("Initial value of d5 is ");
	Console::WriteLine(d5.getVal());

	// Increment it
	d5++;
	Console::Write("Value of d5 is now ");
	Console::WriteLine(d5.getVal());

	return 0;
}
