/*!
 * jLayout Grid Layout - JavaScript Layout Algorithms v0.41
 *
 * Licensed under the new BSD License.
 * Copyright 2008-2009, Bram Stein
 * All rights reserved.
 */

// Imported into Bespin 2010/05/03

"define metadata";
({
    "dependencies": {
        "jlayout": "1.0.0"
    }
});
"end";

var jLayout = exports.jLayout = require("jlayout").jLayout;
 
jLayout = typeof jLayout === 'undefined' ? {} : jLayout;

jLayout.grid = function (spec, shared) {
	var my = shared || {},
		that = {};

	my.hgap = spec.hgap || 0;
	my.vgap = spec.vgap || 0;

	// initialize the number of columns to the number of items
	// we're laying out.
	my.items = spec.items || [];
	my.columns = spec.columns || my.items.length;
	my.rows = spec.rows || 0;
	my.fillVertical = spec.fill && spec.fill === 'vertical';

	if (my.rows > 0) {
		my.columns = Math.floor((my.items.length + my.rows - 1) / my.rows); 
	} else {
		my.rows = Math.floor((my.items.length + my.columns - 1) / my.columns);
	}

	that.items = function () {
		var r = [];
		Array.prototype.push.apply(r, my.items);
		return r;
	};

	that.layout = function (container) {
		var i, j,
			insets = container.insets(),
			x = insets.left,
			y = insets.top,
			width = (container.bounds().width - (insets.left + insets.right) - (my.columns - 1) * my.hgap) / my.columns,
			height = (container.bounds().height - (insets.top + insets.bottom) - (my.rows - 1) * my.vgap) / my.rows;

		for (i = 0, j = 1; i < my.items.length; i += 1, j += 1) {
			my.items[i].bounds({'x': x, 'y': y, 'width': width, 'height': height});

			if (!my.fillVertical) {
				if (j >= my.columns) {
					y += height + my.vgap;
					x = insets.left;
					j = 0;
				}
				else {
					x += width + my.hgap;
				}
			} else {
				if (j >= my.rows) {
					x += width + my.hgap;
					y = insets.top;
					j = 0;
				} else {
					y += height + my.vgap;
				}
			}
			my.items[i].doLayout();
		}
		return container;
	};

	function typeLayout(type) {
		return function (container) {
			var i = 0, 
				width = 0, 
				height = 0, 
				type_size,
				insets = container.insets();

			for (; i < my.items.length; i += 1) {
				type_size = my.items[i][type + 'Size']();
				width = Math.max(width, type_size.width);
				height = Math.max(height, type_size.height);
			}
			return {
				'width': insets.left + insets.right + my.columns * width + (my.columns - 1) * my.hgap, 
				'height': insets.top + insets.bottom + my.rows * height + (my.rows - 1) * my.vgap
			};
		};
	}

	// this creates the min and preferred size methods, as they
	// only differ in the function they call.
	that.preferred = typeLayout('preferred');
	that.minimum = typeLayout('minimum');
	that.maximum = typeLayout('maximum');
	return that;
};
