/*
 * jQuery.ScrollTo
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 06/05/2009
 *
 * @projectDescription Easy element scrolling using jQuery.
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 * Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7/8, Opera 9.5/6, Safari 3, Chrome 1 on WinXP.
 *
 * @author Ariel Flesler
 * @version 1.4.2
 *
 * @id jQuery.scrollTo
 * @id jQuery.fn.scrollTo
 * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
 *	  The different options for target are:
 *		- A number position (will be applied to all axes).
 *		- A string position ('44', '100px', '+=90', etc ) will be applied to all axes
 *		- A jQuery/DOM element ( logically, child of the element to scroll )
 *		- A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
 *		- A hash { top:x, left:y }, x and y can be any kind of number/string like above.
 *		- A percentage of the container's dimension/s, for example: 50% to go to the middle.
 *		- The string 'max' for go-to-end. 
 * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
 * @param {Object,Function} settings Optional set of settings or the onAfter callback.
 *	 @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
 *	 @option {Number} duration The OVERALL length of the animation.
 *	 @option {String} easing The easing method for the animation.
 *	 @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
 *	 @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
 *	 @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
 *	 @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
 *	 @option {Function} onAfter Function to be called after the scrolling ends. 
 *	 @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
 * @return {jQuery} Returns the same jQuery object, for chaining.
 *
 * @desc Scroll to a fixed position
 * @example $('div').scrollTo( 340 );
 *
 * @desc Scroll relatively to the actual position
 * @example $('div').scrollTo( '+=340px', { axis:'y' } );
 *
 * @desc Scroll using a selector (relative to the scrolled element)
 * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
 *
 * @desc Scroll to a DOM element (same for jQuery object)
 * @example var second_child = document.getElementById('container').firstChild.nextSibling;
 *			$('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
 *				alert('scrolled!!');																   
 *			}});
 *
 * @desc Scroll on both axes, to different values
 * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } );
 */
(function(A){var C=A.scrollTo=function(E,F,D){A(window).scrollTo(E,F,D)};C.defaults={axis:"xy",duration:parseFloat(A.fn.jquery)>=1.3?0:1};C.window=function(D){return A(window)._scrollable()};A.fn._scrollable=function(){return this.map(function(){var E=this,F=!E.nodeName||A.inArray(E.nodeName.toLowerCase(),["iframe","#document","html","body"])!=-1;if(!F){return E}var D=(E.contentWindow||E).document||E.ownerDocument||E;return A.browser.safari||D.compatMode=="BackCompat"?D.body:D.documentElement})};A.fn.scrollTo=function(E,F,D){if(typeof F=="object"){D=F;F=0}if(typeof D=="function"){D={onAfter:D}}if(E=="max"){E=9000000000}D=A.extend({},C.defaults,D);F=F||D.speed||D.duration;D.queue=D.queue&&D.axis.length>1;if(D.queue){F/=2}D.offset=B(D.offset);D.over=B(D.over);return this._scrollable().each(function(){var J=this,I=A(J),K=E,H,L={},M=I.is("html,body");switch(typeof K){case"number":case"string":if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(K)){K=B(K);break}K=A(K,this);case"object":if(K.is||K.style){H=(K=A(K)).offset()}}A.each(D.axis.split(""),function(N,S){var P=S=="x"?"Left":"Top",T=P.toLowerCase(),U="scroll"+P,O=J[U],R=C.max(J,S);if(H){L[U]=H[T]+(M?0:O-I.offset()[T]);if(D.margin){L[U]-=parseInt(K.css("margin"+P))||0;L[U]-=parseInt(K.css("border"+P+"Width"))||0}L[U]+=D.offset[T]||0;if(D.over[T]){L[U]+=K[S=="x"?"width":"height"]()*D.over[T]}}else{var Q=K[T];L[U]=Q.slice&&Q.slice(-1)=="%"?parseFloat(Q)/100*R:Q}if(/^\d+$/.test(L[U])){L[U]=L[U]<=0?0:Math.min(L[U],R)}if(!N&&D.queue){if(O!=L[U]){G(D.onAfterFirst)}delete L[U]}});G(D.onAfter);function G(N){I.animate(L,F,D.easing,N&&function(){N.call(this,E,D)})}}).end()};C.max=function(F,I){var J=I=="x"?"Width":"Height",H="scroll"+J;if(!A(F).is("html,body")){return F[H]-A(F)[J.toLowerCase()]()}var D="client"+J,E=F.ownerDocument.documentElement,G=F.ownerDocument.body;return Math.max(E[H],G[H])-Math.min(E[D],G[D])};function B(D){return typeof D=="object"?D:{top:D,left:D}}})(jQuery);