/* rectangle.cpp */
#include <iostream>
#include <string>
#include <cmath>
using namespace std;


class Rectangle;


class Point {
	double x, y;
public:
  Point(double x = 0, double y = 0);
  ~Point();
  void print() const;
  friend class Rectangle;
};


Point::Point(double x /* = 0 */, double y  /*= 0 */) : x(x), y(y) {
	cout << "Point(double, double) called\n";
}


Point::~Point() {
	cout << "~Point() called\n";
}


void Point::print() const {
	cout << "x: " << x << " , y: " << y;
}


class Rectangle {
	Point origin;
	double width;
	double height;
	string name;
public:
	Rectangle(
	  const Point& origin = Point(), double width = 1, double height = 1,
	  const string& name = "noname");
	Rectangle(
	  const Point& centre, const Point& lowerLeft, const string& name = "noname");
	~Rectangle();
	void print() const;
};

Rectangle::Rectangle(
	const Point& origin /* = Point()*/, double width /* = 1 */, double height /* = 1 */,
	const string& name /* = "noname" */)
  : origin(origin), width(width), height(height), name(name)
{
	cout << "Rectangle(const Point& = Point(), double = 1, double = 1) called\n";
}


Rectangle::Rectangle(
  const Point& centre, const Point& lowerLeft, const string& name /* = "noname" */)
  : name(name) {
	origin = centre;
	double w = fabs(origin.x - lowerLeft.x);
	double h = fabs(origin.y - lowerLeft.y);
	width = 2 * w;
	height = 2 * h;
	origin.x -= w;
	origin.y -= h;
	cout << "Rectangle(const Point&, const Point&) called\n";
}


Rectangle::~Rectangle() {
	cout << "~Rectangle() called\n";
}


void Rectangle::print() const {
	cout << "Rectangle " << "\"" << name << "\"" << endl;
	cout << "  origin: ";
	origin.print();
	cout << "\n  width: " << width << "\n  height: " << height << endl;
}


int main() {
	cout << "S T A R T" << endl;
	{
		cout << "Stack demo" << endl;
		cout << "==========" << endl;
	  Rectangle r1;
	  r1.print();

	  Rectangle r2(Point(4, 3), Point(1, 5), "Foo");
	  r2.print();
	}
	
	cout << endl << endl;
	
	{
		cout << "Heap demo" << endl;
		cout << "=========" << endl;
		Rectangle *pr1 = new Rectangle;
		pr1->print();
		delete pr1;
		pr1 = 0;
		
		Rectangle *pr2 = new Rectangle(Point(4, 3), Point(1, 5));
		pr2->print();
		delete pr2;
		pr2 = 0;
	}
	
	cout << endl << endl;
	
	{
		cout << "Aggregate demo" << endl;
		cout << "==============" << endl;
		const int len = 6;
		Rectangle rarr[len] = {Rectangle()};
	}

	return 0;
}
