#include <iostream>
#include <sstream>

using namespace std;

// Widget.h:
class Widget {
private:
string name;

// We want the serial number to be constant for each widget, but we each should get its own value.
// We will mark the serial number as constant but not give it a value yet, which seems a little strange.
// Remember that the .h is just a template, nothing is really being created.
const int serialNumber;
// In this context static means that there is only one nextSerialNumber value, not one for each object.
// All instance of the class can see and set this value, but they all see the same value. In other
// languages this is called a "Class variable" indicating that it is shared by all instances of the
// class.
static int nextSerialNumber;
public:
Widget(string);
string ToString();

int PeekAtNextSerialNumber();
};

// Widget.cpp

// The next line has two interesting features:
//  1) When we create a new widget we can use initialization to give it a value for the constant serialnumber!
//     This is allowed because when the constructor is executed, a new widget is coming into existence and
//     needs to know what value it's constant should have.
//  2) As noted above, there is only one variable called nextSerialNumber, we can use that to set the new
//     widget's serial number and then add one, in preparation for the next widget to be created.
Widget::Widget(string aName) : name(aName), serialNumber(nextSerialNumber++){
}

string Widget::ToString() {
ostringstream tempstream("");

tempstream << "Name: \"" << name << "\"\tSerial Number: " << serialNumber;
return tempstream.str();

}

// This method is hear ONLY for educational or debugging purposes, generally you would not have such a method.
int Widget::PeekAtNextSerialNumber() {
return nextSerialNumber;
}

// We need to set the first serial number, like methods identified in the .h but not defined until in the .cpp
// we can do that with variables too.
int Widget::nextSerialNumber = 0;

// end of what would be in Widget.cpp

int main() {
cout << "Create wheelWidget." << endl;
Widget wheelWidget("A Wheel");

cout << "wheelWidget contents: " << wheelWidget.ToString() << endl;
cout << endl;
cout << "AFTER having created the wheelWidget the value of nextSerialNumber is : " << wheelWidget.PeekAtNextSerialNumber() << endl;
cout << endl << endl;

cout << "Create leverWidget." << endl;
Widget leverWidget("A Lever");

cout << "leverWidget contents: " << leverWidget.ToString() << endl;
cout << endl;
cout << "AFTER having created the leverWidget the value of nextSerialNumber is : " << leverWidget.PeekAtNextSerialNumber() << endl;
cout << "Because nextSerialNumber is shared by all instance of Widget, wheelWidget also sees the value of nextSerialNumber as: " << wheelWidget.PeekAtNextSerialNumber() << endl;
cout << endl << endl;

cout << "Create rampWidget." << endl;
Widget rampWidget("A Ramp");

cout << "rampWidget contents: " << rampWidget.ToString() << endl;
cout << endl;
cout << "AFTER having created the rampWidget the value of nextSerialNumber is : " << rampWidget.PeekAtNextSerialNumber() << endl;
cout << "Because nextSerialNumber is shared by all instance of Widget, leverWidget also sees the value of nextSerialNumber as: " << leverWidget.PeekAtNextSerialNumber() << endl;
cout << "Because nextSerialNumber is shared by all instance of Widget, wheelWidget also sees the value of nextSerialNumber as: " << wheelWidget.PeekAtNextSerialNumber() << endl;

//system("pause");

return 0;
}