﻿function Rectangle(x, y, width, height) {
	this.x = x ? x : 0;
	this.y = y ? y : 0;
	this.width = width ? width : 0;
	this.height = height ? height : 0;
};

Rectangle.prototype.normalize = function() {
	if (this.width < 0) {
		this.x += this.width;
		this.width = -this.width;
	}
	
	if (this.height < 0) {
		this.y += this.height;
		this.height = -this.height;
	}
};

Rectangle.prototype.offset = function(x, y) {
	this.x += x;
	this.y += y;
};

Rectangle.prototype.inflate = function(width, height) {
	height = typeof(height) == "undefined" ? width : height;
	this.x -= width;
	this.y -= height;
	this.width += 2 * width;
	this.height += 2 * height;
};

Rectangle.prototype.contains = function(x, y) {
      if (((this.x <= x) && (x < (this.x + this.width))) && (this.y <= y))
            return (y < (this.y + this.height));
      return false;
};

Rectangle.prototype.containsPoint = function(p) {
	return this.contains(p.x, p.y);
};

Rectangle.prototype.intersectsWith = function(rect) {
      if (((rect.x < (this.x + this.width)) && (this.x < (rect.x + rect.width))) && (rect.y < (this.y + this.height)))
            return (this.y < (rect.y + rect.height));
      return false;
};

Rectangle.prototype.toString = function() {
	return "{x: " + this.x + ", y: " + this.y + ", width: " + this.width + ", height: " + this.height + "}";
};

Rectangle.prototype.clone = function() {
	return new Rectangle(this.x, this.y, this.width, this.height);
};

function Point(x, y) {
	this.x = x ? x : 0;
	this.y = y ? y : 0;
};

Point.prototype.add = function(x, y) {
	this.x += x;
	this.y += y;
};

Point.prototype.addPoint = function(point) {
	this.x += point.x;
	this.y += point.y;
};

Point.prototype.clone = function() {
	return new Point(this.x, this.y);
};

Point.prototype.toString = function() {
	return "{x: " + this.x + ", y: " + this.y + "}";
};

Point.parse = function(str) {
	return Size.parse(str).toPoint();
};

Point.deserialize = function(str) {
	return Point.parse(str);
};

Point.prototype.serialize = function() {
	return this.x.toString() + "," + this.y.toString();
};

function Size(width, height) {
	this.width = width ? width : 0;
	this.height = height ? height : 0;
};

Size.prototype.invert = function() {
	this.width = -this.width;
	this.height = -this.height;
};

Size.prototype.add = function(width, height) {
	this.width += width;
	this.height += height;
};

Size.prototype.addSize = function(size) {
	this.width += size.width;
	this.height += size.height;
};

Size.clip = function(size, minSize, maxSize) {
	var s = new Size();
	s.width = Math.max(Math.min(size.width, maxSize.width), minSize.width);
	s.height = Math.max(Math.min(size.height, maxSize.height), minSize.height);
	return s;
};

Size.prototype.clone = function() {
	return new Size(this.width, this.height);
};

Size.prototype.toPoint = function() {
	return new Point(this.width, this.height);
};

Size.prototype.toString = function() {
	return "{width: " + this.width + ", height: " + this.height + "}";
};

Size.parse = function(str) {
	var parts = str.replace(/\s/g, "").split(",");
	var size = new Size();
	
	if (parts.length > 0)
		size.width = parts[0];
		
	if (parts.length > 1)
		size.height = parse[1];
		
	return size;
};

Size.deserialize = function(str) {
	return Size.parse(str);
};

Size.prototype.serialize = function() {
	return this.width.toString() + "," + this.height.toString();
};