// *************************************************************
// ******   Image Grid v1.0                          ***********
// ******   Copyright 2009 Next Communications Inc.  ***********
// ******                                            ***********
// *************************************************************
	
(function($){  
	$.fn.imagegrid = function(options) {  
		// Overrides default options with passed arguments
		var opts = $.extend({}, $.fn.imagegrid.defaults, options);
		
		return this.each(function() { 
			// Initiallize grid
			build_table($(this), opts);
			
			
			var gallery = $(this).find('.imagegrid');
			var switch_interval;
			
			// Switches out image on interval
			switch_interval = setInterval(function(){get_image(gallery);}, opts.speed);
			
			setTimeout(function(){clearInterval(switch_interval)}, opts.stop);
			
		});  
	};

	// Public
	
	// Default options for ImageGrid
	$.fn.imagegrid.defaults = {
		cols: 4,
		rows: 4,
		spacing: 0,
		speed: 2000,
		stop: 7000
	};
	
	// Private	
	
	// Get a new image
	function get_image(gallery) {
		// Temp implementation to get an image
		// To be replaced with server side script to serve up random images
		var random_image_num = null;
		var random_image_url = null;
		
		do{
			random_image_num = Math.floor(Math.random() * 8) + 1;
			random_image_url = "images/grid/" + random_image_num + ".jpg";
		}while(image_exists(gallery, random_image_url))
		
		$.get(random_image_url, null, switch_image(gallery, random_image_url));
	}
	
	// Switches out an image
	function switch_image(gallery, url) {
		var col_number = choose_column(gallery);
		var col = gallery.find(col_number);
		var old_row = -1;
				
		col.filter('.full').find('img').fadeOut(250, function(){
			old_row = new Number($(this).parent().parent().attr('class').match(/(row)\d/)[0].match(/\d/));
			$(this).parent().parent().removeClass('full');
			$(this).remove();
			add_image(gallery, $(col), url, old_row);
		});
	
		if(gallery_full(gallery) == false){
			add_image(gallery, col, url, old_row);
		}
	};
	
	function add_image(gallery, col, url, old_row) {
		var row = null;
		var possible_rows = new Array();
		
		for (var i=0; i<row_count(gallery); i++){
			row = '.row' + i;
			if(i != old_row){
				if(sides_full(gallery, col, row) == false){
					possible_rows.push('.row' + i);
				}
			}
		}

		var random_index = Math.floor(Math.random() * possible_rows.length);
		var random_row = possible_rows[random_index];
		var new_image_tag = '<img src="' + url + '" />';	
		
		set_alignment(gallery, col, random_row);
		
		col.filter(random_row).addClass('full').children('div').append(new_image_tag).children('img').load().fadeIn(250);
	};
	
	function set_alignment(gallery, col, row) {
		col_num = $(col).attr('class').match(/(col)\d/)[0].match(/\d/);
		row_num = row.match(/\d/);
		
		if(col_num != 0 && col_num != col_count(gallery) - 1){
			if(Math.random() >= .5){
				$(col).filter(row).addClass('push_right');
			}
			else{
				$(col).filter(row).addClass('push_left');
			}
		}
		if(row_num != 0 && row_num != row_count(gallery) - 1){
			if(Math.random() >= .5){
				$(col).filter(row).addClass('push_up');
			}
			else{
				$(col).filter(row).addClass('push_down');
			}
		}
	};
	
	function sides_full(gallery, col, row) {
		var response = false;
	
		var left = $(col).prev('td').filter(row);
		var right = $(col).next('td').filter(row);
	
		if(check_full(left) == true || check_full(right) == true){
			response = true;
		}
		
		return response;
	};
	
	function image_exists(gallery, image){
		var response = false;
		var src = null;
		image = image.match(/[^\s\/]+(?=\.(jpg|gif|png))\.(jpg|gif|png)/)[0];

		gallery.find('img').each(function(){
			src = $(this).attr('src').match(/[^\s\/]+(?=\.(jpg|gif|png))\.(jpg|gif|png)/)[0];
			if(src == image){
				response = true;
			}
		});
		return response;
	}
	
	// Chooses a column to switch image on
	function choose_column(gallery) {
		var col_number = 0;
		if(gallery_full(gallery)){
			col_number = Math.floor(Math.random() * col_count(gallery));
		}
		else{
			var empty_cols = new Array();
			for (var i=0; i<col_count(gallery); i++){
				var col = gallery.find('.col' + i);
				if(is_full(col) == false){
					empty_cols.push(i);
				}
			}
			random_col =  Math.floor(Math.random() * empty_cols.length);
			col_number = empty_cols[random_col];
		}
		return '.col' + col_number;
	};
	
	// Builds required structure
	function build_table(gallery, opts) {
		// Setup basic table code to be inserted in obj
		var table_code = '<table cellspacing="' + opts.spacing + '" cellpadding="0">';
		for (var x=0; x<opts.rows; x++){
			table_code += '<tr>';
			for (var y=0; y<opts.cols; y++){
				table_code += '<td></td>';
			}
			table_code += '</tr>';
		}
		table_code += '</table>'
		
		// Insert table code to create table in obj
		gallery.html(table_code);
		gallery.find('table').addClass('imagegrid');
		gallery.find('td').append('<div></div>');
		gallery.append('<div class="overlay"></div>');
		gallery.find('.overlay').append(table_code);
		
		// Style overlay
		var overlay = gallery.find('.overlay table');
		var imagegrid = gallery.find('.imagegrid');
		
		if(gallery.css('position') == 'static'){
			gallery.css('position', 'relative');
		}		
		
		overlay.width(imagegrid.width());
		overlay.height(imagegrid.height());
		
		// Populate table cell with selector classes
		imagegrid.find('tr').each(function(i){
			$(this).children('td').each(function(i){
				$(this).addClass('col' + i);
			});
			$(this).children('td').addClass('row' + i);
		});
		
		// Set alignment classes for outside cells
		imagegrid.find('.row0').addClass('push_down');
		imagegrid.find('.row' + (row_count(imagegrid) - 1)).addClass('push_up');
		imagegrid.find('.col0').addClass('push_right');
		imagegrid.find('.col' + (col_count(imagegrid) - 1)).addClass('push_left');
	};
	
	
	
	// Full check functions
	// Check if set of cells contains a full
	function check_full(cell) {
		var cell_test = false;
		cell.each(function(){
			if(/(full)+/.test($(this).attr('class')) == true){
				cell_test = true;
			}
		});
		return cell_test;
	};
	
	// Check if object contains a full
	function is_full(obj) {
		if(obj.is('td')){
			return check_full(obj);
		}
		else{
			return check_full(obj.find('td'));
		}
	};
	
	// Check if gallery cols are all full
	function gallery_full(gallery) {
		
		for (var i=0; i<col_count(gallery); i++){
			var col = gallery.find('.col' + i);
			if(is_full(col) == false){
				return false;
			}
		}
		return true;
	};
	
	
	
	// Counting functions
	// Gets column count
	function col_count(gallery) {
		return gallery.find('tr').eq(0).find('td').size();
	};
	
	// Gets row count
	function row_count(gallery) {
		return gallery.find('tr').size();
	};
	
})(jQuery);


