// Flexible JavaScript Events - John Resig
// http://ejohn.org/projects/flexible-javascript-events/

// Ammended to rewrite window.onload as window.DOMContentLoaded where available (Firefox/Gecko)

function addEvent( obj, type, fn )
{	
	if (obj == window && type == "load" && window.addEventListener) {
		window.addEventListener("DOMContentLoaded", function(e) {
			fn(e);
			fn.done = true;
		}, false);
	}
	
	if (obj.addEventListener) {
		if (obj == window && type == "load") {
			obj.addEventListener( type, function(e) {
				if (!fn.done) {
					fn(e);
				}
			}, false );			
		} else {
			obj.addEventListener(type, fn, false);
		}
	} else if (obj.attachEvent)
	{
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
	}
}

function removeEvent( obj, type, fn )
{
	if (obj.removeEventListener)
		obj.removeEventListener( type, fn, false );
	else if (obj.detachEvent)
	{
		obj.detachEvent( "on"+type, obj[type+fn] );
		obj[type+fn] = null;
		obj["e"+type+fn] = null;
	}
}

// Fix Array.push() for IE 5.0
// from sIFR - http://www.mikeindustries.com/sifr/

/* IE 5.0 does not support the push method, so here goes */
if(Array.prototype.push == null){
	Array.prototype.push = function(){
		var i = 0, index = this.length, limit = arguments.length;
		while(i < limit){
			this[index++] = arguments[i++];
		};
		return this.length;
	};
};	

// Slices lists into smaller lists, mainly to be used as visual columns
// Dependent on Prototype.lite or greater
function slice_list(original_list, options) {
	// Setup the default options
	default_options = {
		max_lists: null,
		min_lists: 1,
		max_items: null, // unimplemented
		min_items: 1//,
	};
	
	// We return an array of the generated lists.
	var generated_lists = [];
	
	// Find original list(s) (parameter can be an HTML id string, an HtmlElement object, or an array of either.)
	original_list = $(original_list);
	
	if (!original_list) {
		return generated_lists; // empty array
	} else if (original_list.length) {
		// If original_list is an array, we recurse, making sure to collect the returned arrays
		var original_list_length = original_list.length; // optimization
		
		for (var i = 0; i < original_list_length; i++) {
			generated_lists.push(slice_list(original_list[i], options));
		}
		
		return generated_lists; // nested array of generated lists
	}
	
	// Merge default options into the passed options
	for (var i in default_options) {
		if (typeof options[i] == "undefined") {
			options[i] = default_options[i];
		}
	}
	
	// Grab the children list items
	var all_list_items = original_list.getElementsByTagName("li");
	
	// Grab only the immediate children of the original list
	var list_items = [];
	var all_list_items_length = all_list_items.length; // optimization
	
	for (var i = 0; i < all_list_items_length; i++) {
		if (all_list_items[i].parentNode == original_list) {
			list_items.push(all_list_items[i]);
		}
	}
	
	// Check to make sure we still have list items to work with.
	if (!list_items.length) {
		return generated_lists; // empty array
	}
	
	var list_items_length = list_items.length; // optimization

	// If the list is bigger than max_items, we'll need to page.
	// get_num_lists accounts for paging too.
	var	num_lists = get_num_lists(list_items_length, options);
	
	// Calculate the number of items per list
	var items_per_list   = Math.floor(list_items_length / num_lists);
	var items_remainder  = list_items_length % num_lists;
	var items_additional = 0;
	var items_counter    = 0;

	// Do paging
	var paging = options.max_items && options.max_items < list_items_length;
	var pages = (paging)?Math.ceil(list_items_length / options.max_items):1;
	var list_per_page = Math.floor((paging)?num_lists/pages:num_lists);

	// Generate lists
	for (var i = 0; i < num_lists; i++) {
		generated_lists[i] = original_list.parentNode.insertBefore(document.createElement("ul"), original_list);
		Element.addClassName(generated_lists[i], "sliced-list");
		if (i >= list_per_page) {
			// hide everything beyond the first page.
			generated_lists[i].style.display = "none";
		}
		
		if (items_remainder) {
			items_additional = 1;
			items_remainder--;
		} else {
			items_additional = 0;
		}
		
		for (var j = 0; j < (items_per_list + items_additional); j++) {
			generated_lists[i].appendChild(list_items[items_counter]);
			items_counter++;
		}
	}

	var pager = null;
	if (paging) {
		pager = document.createElement("p");
		pager.style.width = "100%";
		pager.style.textAlign = "right";
		pager.page = 1;
		
		
		// Paging links.
		var next = document.createElement("a");
		next.href = "#";
		var prev = document.createElement("a");
		prev.href = "#";
		var sep = document.createElement("span");
		sep.appendChild(document.createTextNode(" | "));
		sep.style.display = "none";
		
		// This function does the paging of lists.
		var turnPage = function (page) {
			var min_list = (page - 1) * list_per_page;
			var max_list = (page * list_per_page);
			max_list = (max_list > num_lists)?num_lists:max_list;
			for (var i = 0; i < generated_lists.length; i++) {
				if (i < min_list || i >= max_list) {
					generated_lists[i].style.display = "none";
				} else {
					generated_lists[i].style.display = "";
				}
			}
			
			if (page > 1) { prev.style.display = "inline";	} else { prev.style.display = "none"; }
			if (page < pages) {	next.style.display = "inline"; } else {	next.style.display = "none"; }
			if (page > 1 && page < pages) { sep.style.display = "inline"; } else { sep.style.display = "none"; }
		};
		
		next.onclick = function() {
			pager.page++;
			turnPage(pager.page);
			return false;
		} 
		
		prev.onclick = function() {
			pager.page--;
			turnPage(pager.page);
			return false;
		}
		
		next.innerHTML=("next");
		prev.innerHTML=("previous");
		prev.style.display = "none";
		pager.appendChild(prev);
		pager.appendChild(sep);
		pager.appendChild(next);
		original_list.parentNode.insertBefore(pager, original_list);
	}
	
	// Remove original list
	Element.remove(original_list);
	
	// Return an array of the generated lists
	return generated_lists;
}

function get_num_lists(list_items_length, options) {
	// Calculate the number of lists we'll need to generate.
	var paging = options.max_items && options.max_items < list_items_length;
	var pages = (paging)?Math.ceil(list_items_length / options.max_items):1;
	options.max_lists *= pages;
	options.min_lists *= pages;
	if (options.max_lists) {
		if (list_items_length < options.min_items) {
			return 1;
		} else if (list_items_length > (options.max_lists * options.min_items)) {
			return options.max_lists;
		} else {
			if (list_items_length < options.min_lists) {
				return list_items_length;
			} else {
				return Math.floor(list_items_length / options.min_items);
			}
		}
	} else {
		if (list_items_length < (options.min_lists * options.min_items)) {
			if (list_items_length < options.min_lists) {
				return list_items_length;
			} else {
				return options.min_lists;
			}
		} else if (list_items_length < options.min_items) {
			return 1;
		} else {
			return Math.floor(list_items_length / options.min_items);
		}
	}
}

// This function is called when the filmstrip finishes animating
function updateFilmstripNav(currentStop) {
	var pageItems = pagination.getElementsByTagName("li");

	for (var i = 0; i < pageItems.length; i++) {
		Element.removeClassName(pageItems[i], "filmstrip-current");

		if (i == currentStop) {
			Element.addClassName(pageItems[i], "filmstrip-current");
		}
	}
}
