
// script that handles window.domready and window.load in the correct order
// call via customLoad.dom.push(func) or customLoad.load.push(func)
var CustomLoad		= function() {
	var obj		= this;
	obj.done	= [];	// register which objs (DOM and load) are loaded
	obj.dom		= [];	// when DOM is loaded
	obj.load	= [];	// when all is loaded
	obj.unload	= [];	// when document is unloaded
	obj.exe		= function(kind) {
		if (kind=='load' && !obj.done['dom']) {obj.done[kind]=true}
		else {
			for (var i=0; i<obj[kind].length; i++) {if (obj[kind][i]()) break}
			obj.done[kind]	= true;
			if (kind=='dom' && obj.done['load']) {obj.exe('load')}
		}
	};

	jQuery(document).bind('ready'	, function() {obj.exe('dom')});
	jQuery(window).bind('load'	, function() {obj.exe('load')});
	jQuery(window).bind('unload'	, function() {obj.exe('unload')});
};
var customLoad = new CustomLoad();

jQuery.fn.extend({
	test:		function() {return this.length ? this:null},
	convert:	function() {
		return this.length<=1 ? this : this.map(function() {return jQuery(this)})
	},
	unconvert:	function() {
		return this.length<=1 ? this : this.map(function() {return this.context || this})
	},
	log:		function (msg) {
		console.log("%s: %o", msg, this);
		return this;
	},
	// custom fadeTo() that hides elms when completely faded out
	fadeTo: function(speed , to , easing , callback) {
		// original:
		// return this.filter(":hidden").css("opacity", 0).show().end()
		// 	.animate({opacity: to}, speed, easing, callback);

		return this.filter(":hidden").css("opacity", 0).show().end()
			.animate({opacity: to}, speed, easing, function() {
				if (to===0) $(this).hide();

				// more about call() and apply(), see: http://www.webreference.com/js/column26/call.html
				if (callback) callback.apply(this , arguments);
			}
		);
	}
});

// load any amount of scripts and stylesheets with a single call and callback function
jQuery.external	= function() {
	// fill urls hash with urls that already have been loaded
	var urls		= {};
	var location		= (document.location.protocol + '//' + document.location.hostname).toLowerCase();
	var locationRegExp	= new RegExp(location , 'i');
	$('script , link').each(function(i,elm) {
		if	(elm.src)											urls[makeURL(elm.src)]=1
		else if	((!elm.rel || elm.rel=='stylesheet') && (!elm.type || elm.type=='text/css') && elm.href)	urls[makeURL(elm.href)]=1
	});

	// only at the 1st call: redefine jQuery.external and call getAllFiles manually
	jQuery.external = function() {getAllFiles(arguments); };
	getAllFiles(arguments);

	/*** functions ***/
	function getAllFiles(vrs) {
		var total	= 0 , loaded=0 , callback=null , cache=vrs[vrs.length-1];
		cache		= cache===true || cache=='1' ? true : cache===false || cache=='0' ? false : null;

		// if cache is passed, set last element of vrs to cache's value, so typeof() will return 'boolean'
		if (cache===true || cache===false)		vrs[vrs.length-1]=cache;

		// if last arg is a function
		if (typeof(vrs[vrs.length-1])=='function')	callback=vrs[vrs.length-1];

		for (var i=0; i<vrs.length; i++) {
			if (typeof(vrs[i])=='string') {
				var url	= makeURL(vrs[i]);
				if (!cache || !urls[url]) {
					total++;
					getOneFile(url , done , cache);
				}
//				else	alert('from cache: ' + url)
			}
		}

		// if no external files are loaded (maybe because of cache), callback is not called. so call it
		if (total==0 && callback) callback()

		function done(url) {urls[url]=1; if (callback && (++loaded)==total) callback(); }
	}

	function getOneFile(url, callback, cache) {
		if	(url.match(/\.js(\?|$)/i)) jQuery.ajax({type:"GET" , url:url , success:function() {callback(url); } , dataType:"script" , cache:cache});
		else if	(url.match(/\.css(\?|$)/i)) {
			// preload stylesheet through ajax and append on succes
			jQuery.ajax({type:"GET" , url:url , success:function(data) {
				$('head').append($('<link>').attr({type:'text/css' , rel:'stylesheet' , href:url}));
				callback(url);
			} , dataType:"text" , cache:cache});
		}
		else alert('ERROR: invalid URL (jQuery > regs.js > $.external)\n\n"' + url + '"\n\n')
	}

	// if location is in url, replace it with a lowercase one
	function makeURL(url) {return location + url.replace(locationRegExp , ''); }
};








/*!
 * jQuery serializeObject - v0.2 - 1/20/2010
 * http://benalman.com/projects/jquery-misc-plugins/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */

// Whereas .serializeArray() serializes a form into an array, .serializeObject()
// serializes a form into an (arguably more useful) object.

(function($,undefined) {
	$.fn.serializeObject = function(){
		var obj = {};
		$.each(this.serializeArray(), function(i,o) {
			var n	= o.name;
			var v	= o.value;
			obj[n]	= obj[n] === undefined ? v
				: $.isArray( obj[n] ) ? obj[n].concat( v )
				: [ obj[n], v ];
		});
		return obj;
	};
})(jQuery);





/*
 * Special event for image load events, needed because some browsers does not trigger the event on cached images.
 * MIT License
 * Paul Irish     | @paul_irish | www.paulirish.com
 * Andree Hansson | @peolanha   | www.andreehansson.se
 *
 * Usage: $(images).bind('load', onLoadFunc);
 *
 * Error alerts:	IE: 'Out of memory at line: 49', FF: 'Too many recursions'
 * Solution:		Rename function from load to load2
 *
 */
(function($) {
	$.event.special.load2 = {
		add: function(callback) {
			if (this.nodeType===1 && this.tagName.toLowerCase()==='img' && this.src!=='') {
				// Image is already complete, fire the callback (fixes browser issues were cached images isn't triggering the load event)
				if	(this.complete || this.readyState===4)					callback.handler.apply(this);
				// Check if data URI images is supported, fire 'error' event if not
				else if (this.readyState==='uninitialized' && this.src.indexOf('data:')===0)	$(this).trigger('error');
				else										$(this).bind('load', callback.handler);
			}
		}
	};
}(jQuery));












