var Raster = {
	baselineHelper: {
		SHOW_BASELINE_CLASS_NAME: 'raster-show-baseline',
		BASELINE_CLASS_NAME: 'raster-baseline',
		setup: function() {
			var showBaselineElements = document.getElementsByClassName(this.SHOW_BASELINE_CLASS_NAME);
			for (var i = 0; i < showBaselineElements.length; i++) {
				var baselineElement = showBaselineElements[i];
				var baselineContainer = this.containerForElement(baselineElement);
				this.showBaseline(baselineContainer);
			}
		},

		showBaseline: function(container) {
			container.style.height = "auto";
			container.style.width = "100%";

			var containerHeightInt = container.clientHeight;
			var parentHeightInt = container.parentNode.clientHeight;

			var counter = 0; // Use a counter to limit to 30 children to prevent infinite loops
			while (containerHeightInt < parentHeightInt && counter < 200) {
				// Add an element to contain the baseline
				var baselineElement = document.createElement("p");
				this.resetCSS(baselineElement);
				baselineElement.appendChild(document.createTextNode('\u00A0'));

				// Draw the baseline on a canvas element
				var canvas = document.createElement("canvas");
				baselineElement.style.position = "relative";
				canvas.setAttribute("width", 1);
				canvas.setAttribute("height", 1);
				canvas.style.position = "absolute";
				canvas.style.left = "0";
				canvas.style.bottom = "0";
				canvas.style.width = "100%";
				canvas.style.height = "1px";
				if (canvas && canvas.getContext) {
					context = canvas.getContext('2d');
					context.strokeStyle = "rgba(148, 235, 255, 0.5)";
					context.lineWidth = 1;
					context.strokeRect(0, 0, 1, 1);
				}
				baselineElement.appendChild(canvas);
				container.appendChild(baselineElement);
				containerHeightInt = container.clientHeight;
				counter++;
			}
		},

		// Helpers

		containerForElement: function(element) {
			var container = document.createElement("div");
			element.appendChild(container);
			this.makeContainer(container);
			return container;
		},

		makeContainer: function(element) {
			var parent = element.parentNode;
			parent.style.position = "relative";

			var height = parent.offsetHeight;
			var width = parent.offsetWidth;

			element.classList.add(this.BASELINE_CLASS_NAME);
			element.setAttribute("width", width);
			element.setAttribute("height", height);
			element.style.width = width + "px";
			element.style.height = height + "px";
			element.style.position = "absolute";
			element.style.left = "0";
			element.style.top = "0";
		},

		resetCSS: function(element) {
			element.style.border = 0;
			element.style.margin = "0";
			element.style.padding = "0";
			element.style.outline = "0";
			element.style.fontSize = "100%";
			element.style.verticalAlign = "baseline";
			element.style.background = "transparent";
		}
	},

	guidelineHelper: {
		SHOW_GUIDELINES_CLASS_NAME: 'raster-show-guidelines',
		GUIDELINES_CLASS_NAME: 'raster-guidelines',
		setup: function() {
			var showGuidelinesElements = document.getElementsByClassName(this.SHOW_GUIDELINES_CLASS_NAME);
			for (var j = 0; j < showGuidelinesElements.length; j++) {
				var guidelinesElement = showGuidelinesElements[j];
				var guidelinesContainer = this.containerForElement(guidelinesElement);
				this.showGuidelines(guidelinesContainer);
			}
		},
		showGuidelines: function(container) {
			this.fillContainerWithClassName(container, 'raster-column');
			var rasterColumns = container.getElementsByClassName('raster-column');
			for (var i = 0; i < rasterColumns.length; i++) {
				var rasterColmun = rasterColumns[i];
				this.fillContainerWithClassName(rasterColmun, 'raster-unit');
			}
		},
		fillContainerWithClassName: function(container, className) {
			var computedWidth = 0;
			var containerWidth = container.clientWidth;
			var counter = 0; // Use a counter to limit to 30 children to prevent infinite loops
			while (computedWidth < containerWidth && counter < 30) {
				var element = document.createElement("div");
				element.classList.add(className);
				container.appendChild(element);
				computedWidth = this.widthForChildElementsWithClassName(container, className);
				counter++;
			}
		},

		widthForChildElementsWithClassName: function(parent, className) {
			var nodeList = parent.getElementsByClassName(className);
			var calculateWidth = function(initial, element) {
				var style = window.getComputedStyle(element);
				var marginRight = parseInt(style.marginRight, 10);
				var width = element.clientWidth;
				var totalWidth = width + marginRight;
				return initial + totalWidth;
			};
			var width = Array.prototype.reduce.call(nodeList, calculateWidth, 0);
			return width;
		},
		containerForElement: function(element) {
			var container = document.createElement("div");
			element.appendChild(container);
			container.classList.add(this.GUIDELINES_CLASS_NAME);
			var height = element.offsetHeight;
			container.setAttribute("height", height);
			container.style.height = height + "px";
			element.style.position = "relative";
			return container;
		}
	},

	redraw: function() {
		var classNames = [this.baselineHelper.BASELINE_CLASS_NAME, this.guidelineHelper.GUIDELINES_CLASS_NAME];
		for (var i = 0; i < classNames.length; i++) {
			var className = classNames[i];
			var nodeList = document.getElementsByClassName(className);
			for (var j = nodeList.length - 1; j >= 0; --j) {
				var element = nodeList[j];
				element.parentNode.removeChild(element);
			}
		}

		this.setup();
	},

	setup: function() {
		this.baselineHelper.setup();
		this.guidelineHelper.setup();
	}
};

window.addEventListener('load', function () { Raster.setup(); }, false);