/*
Title:      jquery.modularGrid

Description:Assists the creation of modular grids in HTML with jQuery

Developer:  Matt Lenz (http://mattlenz.com/)

Date:       February 2010

Version:    1.0

Usage:      // Define module size and gutter (just like a page layout application)
            $('#wrapper').modularGrid({
                  selector: '.module',
                  columns: 5,
                  module_width: 180,
                  module_height: 80,
                  gutter: 18
            });
            
            // Show the grid
            $.fn.modularGrid.debug();
            
            // Build your layout with elements like this
            <div class="module { w: 6, h: 3 }">Six by three module div</div>


Notes:      

To Do:      * Try and keep this thing rolling while dynamic content is loaded.
            * Speed benchmarks?
            * Hide the page before modulation. To stop content shuffling on slow loads.

License:    Dual licensed under the MIT and GPL licenses:
            http://www.opensource.org/licenses/mit-license.php,
            http://www.gnu.org/licenses/gpl.html
*/
(function() {
	
	var opts, v, o, c, pagewidth, target, target_w, target_h, target_x, target_y, target_width, target_height, target_height_occupancy, canvas, ctx, grid_data;
	
	$.fn.modularGrid = function(options) {

		$.fn.modularGrid.defaults.that = this;
		opts = $.extend($.fn.modularGrid.defaults, options);
		
		pagewidth = opts.columns * (opts.module_width + opts.gutter);
		this.css({ width: pagewidth });
		
		$(opts.selector).css({ float: 'left' });

		$(opts.selector).each(function(i) {

			target = $(this);
			
			o = [];
			
			c = target.attr('class');
			c = c.split('{')[1].split('}')[0].split(' ').join('').split(',');
			$.each(c, function(index, value) {
				i = value.split(':')[0];
				v = value.split(':')[1];
				o[i] = v;
			});

			if(!o.w) { o.w = 'auto'; }
			if(!o.h) { o.h = 'auto'; }

			target_w = o.w;
			target_h = o.h;

			if(target_w > opts.columns || isNaN(target_w)) { target_w = opts.columns; }
			target_width = target_w * (opts.module_width + opts.gutter) - (opts.gutter);

			target.css({ width: target_width });

			if(isNaN(target_h)) {
				target_height_occupancy = Math.ceil((target.height()) / (opts.module_height + opts.gutter));
				target_height = target_height_occupancy * (opts.module_height + opts.gutter) - (opts.gutter);
			} else {
				target_height = target_h * (opts.module_height + opts.gutter) - (opts.gutter);
			}
			
			target.css({ height: target_height });

			if($(this).children('.module').length === 0) {
				$(this).css({ padding: 0, margin: opts.gutter / 2 });
			} else {
				$(this).css({ margin: 0, padding: 0, width: $(this).width() + opts.gutter, height: $(this).height() + opts.gutter });
			}

			if(!isNaN(o.y)) {
				target_y = +o.y;
				target_y = target_y * (opts.module_height + opts.gutter);
			} else { target_y = 0; }

			if(!isNaN(o.x)) {
				target_x = +o.x;
				target_x = target_x * (opts.module_width + opts.gutter);
			} else { target_x = 0; }

			if(!isNaN(o.y) || !isNaN(o.x)) {

				target.css({
					position: 'relative',
					top: target_y,
					left: target_x
				});

			}

		});	

		if(opts.debug) { $.fn.modularGrid.debug(); }

		return this;

	};

	$.fn.modularGrid.debug = function() {

		opts = $.fn.modularGrid.defaults;

		if(opts.debug === false) {

			$.fn.modularGrid.drawGrid();

			$.fn.modularGrid.defaults.debug = true;

		} else {

			$(opts.selector).each(function() {
				$(this).css('background-color', 'transparent');
			});

			opts.that.css('background-image', 'none');

			$.fn.modularGrid.defaults.debug = false;

		}

	};

	$.fn.modularGrid.drawGrid = function() {

		opts = $.fn.modularGrid.defaults;

		canvas = $('<canvas id="canvas" />').attr('width', opts.module_width + opts.gutter).attr('height', opts.module_height + opts.gutter);

		$('body').prepend(canvas);
		canvas = document.getElementById('canvas');
		ctx = canvas.getContext('2d');

		ctx.fillStyle = 'rgba(99, 175, 230, 0.25)';
		
		ctx.fillRect(0, opts.gutter / 2, opts.module_width + opts.gutter, 1);
		ctx.fillRect(opts.module_width + opts.gutter / 2, 0, 1, opts.module_width + opts.gutter);
		
		ctx.fillRect(opts.gutter / 2, 0, 1, opts.module_height + opts.gutter);
		ctx.fillRect(0, opts.module_height + opts.gutter / 2, opts.module_width + opts.gutter, 1);

		grid_data = canvas.toDataURL();
		$('#canvas').remove();

		opts.that.css({ 'display': 'inline-block', 'background-image': 'url('+grid_data+')' });

	};

	$.fn.modularGrid.defaults = {
		that: '',
		selector: '.module',
		columns: 16,
		size: 50,
		gutter: 10,
		debug: false
	};
	
})(jQuery);
