/*
	Copyright (c) 2007-2008 JB Interactive Pty. Ltd.
	All Rights Reserved
	http://www.jbinteractive.com.au/
*/

(function ($) {

// jQuery prototype additions.
$.fn.extend({

	/**
	 * Shorthand for $.fn.animate.
	 */
	left: function (left, speed, callback) {
		return this.animate({ marginLeft: left }, speed, callback);
	},
	
	/**
	 * Shake effect for elements, similar to the effect seen in OS X when a
	 * login dialog has failed authentication.
	 */
	shake: function (params) {
		if (typeof(params) == 'function') params = { callback: params };
		var o = $.extend({}, $.fn.shake.defaults, params);
		return this.each(function () {
			var el = $(this), off = o.offset;
			var left      = window.parseInt(el.css('marginLeft'));
			var delay     = window.parseInt(o.delay / (1 + 2 * o.count));
			var halfDelay = Math.floor(delay / 2);
			
			// Put el in starting position.
			el.left(left + off, halfDelay);
			
			for (var i = 1; i < o.count; i++) {
				if (i > o.falloff) off = Math.max(off - 1, 1);
				el.left(left - off, delay).left(left + off, delay);
			}
			
			// Return el to initial position.
			el.left(left, halfDelay, o.callback);
		});
	},
	
	/**
	 * Checks for empty fields in the login form. If empty fields are found 
	 * then they are highlighted. The return value
	 */
	checkEmpty: function () {
		var vals = {};
		this.find(':text,:password').each(function () {
			var $this = $(this);
			var val = $this.val();
			if (!val) {
				$this.focus();
				vals = false;
				return false;
			}
			vals[$this.attr('name')] = val;
		});
		return vals;
	},

	/**
	 * Shorthand for binding multiple events to the one jQuery object. Uses 
	 * livequery if it's available, otherwise just binds normally. You can 
	 * optionally provide an object as the base to override if required.
	 */
	bindAll: function (base, events) {
		if (typeof(events) == 'object') base = $.extend({}, base, events);
		var fn = ($.livequery) ? 'livequery' : 'bind';
		for (var event in base) $(this)[fn](event, base[event]);
		return this;
	}

});

/**
 * General utility additions to the jQuery namespace.
 */
$.extend({
	
	/**
	 * Returns a function that calls fn passing the callback function to is
	 * as the first parameter.
	 */
	extendFn: function (callback, fn) {
		var c = callback;
		return function () { fn(c); };
	},
	
	
	/**
	 * Returns the target part of a url, i.e. $.getTarget('index.php#foo?bar=1')
	 * would return 'foo'.
	 */
	getTarget: function (href) {
		if (href) {
			var match = href.match(/#([^?]+)\??/);
			if (match) return match[1];
		}
		return false;
	},
	
	/**
	 * Returns the query part of a url as an object containing key/value 
	 * pairs, i.e. $.parseQuery('index.php?foo=bar&baz=1') would return:
	 * {foo: 'bar', baz: '1'}. Numbers are not parsed.
	 */
	parseQuery: function (query) {
		var params = {};
		if (!query) return params;

		var pairs = query.split(/[;&]/);	
		for (var i in pairs) {
			var keyVal = pairs[i].split('=');
			if (!keyVal|| keyVal.length != 2) continue;
			params[unescape(keyVal[0])] = unescape(keyVal[1]).replace(/\+/g, ' ');
		}

		return params;
	}
	
});

/**
 * Defaults for shake effect. Variable effects are described below.
 */
$.fn.shake.defaults = {
	count:  10,               // Number of times to shake.
	offset:  6,               // Offset of shake in px.
	falloff: 2,               // Shakes before offset falloff.
	delay: 400,               // Total length of shake.
	callback: function () { } // Function to call when shake complete.
};
	
})(jQuery);

