;(function($) {


// BACKWARDS-COMPATIBILITY PACK (jQuery 1.0) PLUS OTHERS BY ALLPRO
$.each("id,name,title,href,src,className".split(","), function (i,n) {
	$.fn[n] = function (h) { return this.attr(n, h); };
});

// TAGNAME - either return the tagName OR do a comparison to the passed string
$.fn.tagName = function (s, addType) {
	if (!this.length) return '';
	var el=this[0], t = (typeof s=='string') ? el.tagName===s.toUpperCase() : el.tagName;
	if ((addType || s===true) && el.type) t += "."+ el.type.toLowerCase(); // eg: INPUT.text
	return t;
};


// BACKWARDS-COMPATIBILITY for .attr VS .prop
if (!$.fn.prop)
	$.fn.prop = $.fn.attr;
else {
	$.fn.attr = function (n, v) {
		// redirect dynamic properties to the .prop() method instead of .attr()
		if ($.type(n) === "string" && n.match(/^(checked|disabled|readOnly|selected|selectedIndex|defaultChecked|defaultSelected|tagName)$/i)) {
			if ($.type(v) === "string")
				// to boolean: .attr("checked", "checked") => .prop("checked", true) & .attr("checked", "") => .prop("checked", false)
				v = v.toLowerCase() === n.toLowerCase() ? true : v === "" ? false : v;
			return $.access( this, n, v, true, $.prop );
		}
		else
			return $.access( this, n, v, true, $.attr );
	};
	$.fn.removeAttr = function (n) {
		// handle common errors for setting properties 'false'
		if ( n.match(/^(checked|disabled|selected|readOnly)$/i) )
			$.access( this, n, false, true, $.prop ); // set the property 'false' instead of 'removing' the property
		else
			return this.each(function(){ $.removeAttr( this, n ); });
	};
	/* COMPLETE list of 'properties'
	(checked|disabled|selected|readOnly|selectedIndex|defaultChecked|defaultSelected|tagName|nodeName|nodeType|ownerDocument|autobuffer|autofocus|autoplay|async|compact|controls|declare|defaultMuted|defer|draggable|formNoValidate|hidden|indeterminate|isMap|itemscope|loop|multiple|muted|noHref|noResize|noShade|noWrap|noValidate|open|pubDate|required|reversed|scoped|seamless|spellcheck|trueSpeed|visible) */
}


/**
 * $.mousePosition
 *
 * Tracks the mouse to allow checking its position at any time
 */
$.mousePosition = {
	x:	0
,	y:	0
,	initialized: false

,	set: function (evt) {
		var m = $.mousePosition;
		m.x = evt.pageX;
		m.y = evt.pageY;
	}
,	init: function () {
		var _ = $.mousePosition;
		if (_.initialized) return;
		$(document).bind("mousemove.mousePosition", $.mousePosition.set);
		_.initialized = true;
	}
,	destroy: function () {
		$(document).unbind("mousemove.mousePosition");
	}
,	isOver: function (el, varianceX, varianceY) {
		var M	= $.mousePosition
		,	$E	= $(el || '');
		if (!$E.length) return false;
		if (!M.initialized) M.init(); // in case not already
		var
			vX	= varianceX || 0
		,	vY	= varianceY || 0
		,	d	= $E.offset()
		,	T	= d.top  - vY
		,	L	= d.left - vX
		,	R	= L + $E.outerWidth()  + (vX *2)
		,	B	= T + $E.outerHeight() + (vY *2)
		,	x	= M.x
		,	y	= M.y
		;
		/* DEBUGGING OUTPUT
		console.log(
		   ' el = '+	el
		+'\n $E = '+	$E.text()
		+'\n === horizontal ==='
		+'\n L = '+		L
		+'\n x = '+		x
		+'\n R = '+		R
		+'\n varianceX = '+	vX
		+'\n == vertical ==='
		+'\n T = '+		T
		+'\n y = '+		y
		+'\n B = '+		B
		+'\n varianceY = '+	vY
		+'\n == calculate ==='
		+'\n isOver = '+ ( (x >= L && x <= R) && (y >= T && y <= B) )
		);
		var $E = $('#mouser');
		if (!$E.length) $E = $('<div id="mouser" style="position:absolute; border: 1px solid red;"></div>').appendTo('body');
		$E.css({
			left:	L +'px'
		, 	top:	T +'px'
		,	width:	(R-L) +'px'
		,	height:	(B-T) +'px'
		});
		*/

		return (x >= L && x <= R) && (y >= T && y <= B);
	}
};
$.fn.isMouseOver = function ( varX, varY ) {
	var is = false
	,	isOver = $.mousePosition.isOver;
	if (this.length === 1) return isOver( this[0], varX, varY );
	this.each(function(){ if (is = isOver( this, varX, varY )) return false; });
	return is;
};
// mouse-tracking like this is expensive, so will be initialized only when/if needed
//$.mousePosition.init();


/**
 * MouseWheel Extension 3.0.2
 *
 * Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 */
var a=["DOMMouseScroll","mousewheel"];
$.event.special.mousewheel={
	setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],mousewheelHandler,false)}}else{this.onmousewheel=mousewheelHandler}}
,	teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],mousewheelHandler,false)}}else{this.onmousewheel=null}}
};
$.fn.extend({
	mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")}
,	unmousewheel:function(d){return this.unbind("mousewheel",d)}
});
function mousewheelHandler(f){var d=[].slice.call(arguments,1),g=0,e=true;f=$.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return $.event.handle.apply(this,d)};


/**
 *	cssMenu Object - requires instantiation
 *
 */
function cssMenu (el, opts) {
	// self-instantiation
	//if ( !(this instanceof arguments.callee) )  generic syntax
	if ( !(this instanceof cssMenu) ) 
		return new cssMenu(el, opts);

	this.options = $.extend({		// for persistance - can be updated after instantiation
		closeMenuDelay:	500
	,	animateOpen:	false
	,	animateSpeed:	'normal'
	,	exclude:		''		// jQuery selector of items to NOT include
	}, opts );
	//debugData( this.options, 'cssMenu.options' );

	var
	//	static vars
		options		= this.options	// needed for closures
	,	topUL		= el
	//	processing vars
	,	$MenuPath	= $("")			// empty jQuery object
	,	timer		= { hide: 0, show: 0 }

	/*
	 *	private methods
	 */

	,	clearTimer = function (type) {
			if (timer[type]) {
				clearTimeout( timer[type] );
				timer[type] = 0;
			}
		}

	,	hide = function (LI) {
			timer.hide = null; // clear var
			// if mouseOver parent-LI, unhighlight ONLY this-LI - NOT entire menu
			var parent = LI.parentNode;
			if ($(parent).isMouseOver() || $(parent.parentNode).isMouseOver()) {
				var c = $MenuPath.length, isThis;
				for (var i = c-1; i >= 0; i--) {
					isThisLI = $MenuPath[i] == LI;
					$MenuPath.eq(i).removeClass('hover').stop(true,true);
					$MenuPath = $MenuPath.slice(0,-1);
					if (isThisLI) break;
				}
			}
			else // unhover ENTIRE MENU and clear MenuPath
				$MenuPath = $MenuPath.removeClass('hover').stop(true,true).slice(0,0); // EMPTY the object
		}

	,	show = function (LI) {
			timer.show = null;
			clearTimer("hide");	// stop timer.hide - using createNewPath() instead
			// remove all items NOT a *parent of this item*
			createNewPath(LI);
			var $LI = $(LI);
			// animate submenu, if applicable and if not already open
			//if (options.animateOpen && $LI.hasClass('submenu') && !$LI.hasClass('hover'))
			if (options.animateOpen && $LI.children('UL').length && !$LI.hasClass('hover'))
				$LI.children('UL')
					.hide()	// manually hide the sub-menu so hover-class doesn't show it
					.addClass('hideArrows') // prevents semi-opaque arrows from 'flashing' during fadeIn
					.fadeIn(options.animateSpeed, function(){
						var $E = $(this);
						$E.removeClass('hideArrows'); // animate 'show'
						// fix opacity for IE
						if ($.browser.msie && $E.css("opacity") === 1)
							this.style.removeAttribute('filter'); // OPACITY FIX for IE
					})
				;
			$LI.addClass('hover');
		}

	,	hideClosure = function (LI) {
			return (function(){ hide(LI); }); // return setTimeout function with a 'LI' object-pointer
		}
	,	showClosure = function (LI) {
			return (function(){ show(LI); }); // return setTimeout function with a 'LI' object-pointer
		}

	,	createNewPath = function (newLI) {
			// save previous path
			var $OldPath = $($MenuPath);
			// create the new Path
			$MenuPath = $(newLI).parents('LI').andSelf()
			// make sure we don't go higher than the topUL
			while (!$.contains(topUL, $MenuPath[0]))
				$MenuPath = $MenuPath.slice(1); // remove first item

			// remove hover from old path items
			var c = $MenuPath.length;
			for (var i = $OldPath.length-1; i >= 0; i--) {
				if ( i > c || $OldPath[i] != $MenuPath[i] )
					$OldPath.eq(i).removeClass('hover');
				else
					break; // found a match in the path - done!
			}
			// now add hover to all new path items
			$MenuPath.slice(0,-1).addClass('hover'); // skip LAST item - handled by show()
		}

	;

	this.hoverOn = function (evt) {
		show(this); // no delay
		//clearTimer('show'); // only the 'last item hovered' has a timer
		//timer.show = setTimeout( showClosure(this), 50 );
	};
	this.hoverOff = function (evt) {
		clearTimer('hide'); // only the 'last item un-hovered' has a timer
		timer.hide = setTimeout( hideClosure(this), options.closeMenuDelay );
	};
};

$.fn.cssMenu = function (opts) {
	var options = opts || {};
	return this.each(function() {
		if (!this.tagName == "UL")
			return; // SKIP - *must* be a UL
		var
			$UL = $(this)
		,	Instance = $UL.data('cssMenu')
		;
		if (Instance) { // already a cssMenu, so just update options
			$.extend( Instance.options, options );
		}
		else { // init a new cssMenu
			var m = new cssMenu( this, options );
			$UL.data('cssMenu', m);
			$('LI', this).not( options.exclude || ".dummy" ).hover( m.hoverOn, m.hoverOff );
		}
	});
};


/**
 * jquery.url 1.0
 *
 * Copyright (c) 2012 
 *   Kevin Dalman (http://allpro.net)
 *
 * Dual licensed under the GPL and MIT licenses.
 *
 * var url_data = $.url.data;
 * var url_keys = $.url.keys;
 * $.url.parse(); // re-parse URL search string
 *
 * http://layout.jquery-dev.net/url_parsing.html 
 */
$.url={};$.url.parse=function(){var D=$.url.data={},K=$.url.keys=[],s=self.location.search.substr(1),p,d,k,v,A,i;if(!s)return'';p=s.split('&');for(i=0;i<p.length;i++){d=p[i].split('=');k=$.trim(d[0]);if(k){v=parse(d[1]);if(!D[k]){D[k]=v;K.push(k)}else{if(!$.isArray(D[k])||($.isArray(v)&&typeof D[k][0]!='object'))D[k]=[D[k]];D[k].push(v)}}};return $.url.data;function parse(x){if(x===undefined)return true;x=decodeURIComponent(x);var c=x.length;if(!c)return'';var f=x.charAt(0),l=x.charAt(c-1),A=f=='['&&l==']',H=f=='{'&&l=='}',r;if(A||H){try{r=$.parseJSON(x)}catch(ex){r=A?[]:{}}}else r=!isNaN(x)?Number(x):(x==='true'||x==='false')?x==='true':x;return r}};$.url.parse();

})(jQuery);
