/**
* jQuery.LocalScroll
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 3/11/2009
*
* @projectDescription Animated scrolling navigation, using anchors.
* http://flesler.blogspot.com/2007/10/jquerylocalscroll-10.html
* @author Ariel Flesler
* @version 1.2.7
*
* @id jQuery.fn.localScroll
* @param {Object} settings Hash of settings, it is passed in to jQuery.ScrollTo, none is required.
* @return {jQuery} Returns the same jQuery object, for chaining.
*
* @example $('ul.links').localScroll();
*
* @example $('ul.links').localScroll({ filter:'.animated', duration:400, axis:'x' });
*
* @example $.localScroll({ target:'#pane', axis:'xy', queue:true, event:'mouseover' });
*
* Notes:
*	- The plugin requires jQuery.ScrollTo.
*	- The hash of settings, is passed to jQuery.ScrollTo, so the settings are valid for that plugin as well.
*	- jQuery.localScroll can be used if the desired links, are all over the document, it accepts the same settings.
*  - If the setting 'lazy' is set to true, then the binding will still work for later added anchors.
*	- If onBefore returns false, the event is ignored.
**/
; (function($) {
    var URI = location.href.replace(/#.*/, ''); // local url without hash

    var $localScroll = $.localScroll = function(settings) {
        $('body').localScroll(settings);
    };

    // Many of these defaults, belong to jQuery.ScrollTo, check it's demo for an example of each option.
    // @see http://flesler.demos.com/jquery/scrollTo/
    // The defaults are public and can be overriden.
    $localScroll.defaults = {
        duration: 1000, // How long to animate.
        axis: 'y', // Which of top and left should be modified.
        event: 'click', // On which event to react.
        stop: true, // Avoid queuing animations 
        target: window, // What to scroll (selector or element). The whole window by default.
        reset: true // Used by $.localScroll.hash. If true, elements' scroll is resetted before actual scrolling
        /*
        lock:false, // ignore events if already animating
        lazy:false, // if true, links can be added later, and will still work.
        filter:null, // filter some anchors out of the matched elements.
        hash: false // if true, the hash of the selected link, will appear on the address bar.
        */
    };

    // If the URL contains a hash, it will scroll to the pointed element
    $localScroll.hash = function(settings) {
        if (location.hash) {
            settings = $.extend({}, $localScroll.defaults, settings);
            settings.hash = false; // can't be true

            if (settings.reset) {
                var d = settings.duration;
                delete settings.duration;
                $(settings.target).scrollTo(0, settings);
                settings.duration = d;
            }
            scroll(0, location, settings);
        }
    };

    $.fn.localScroll = function(settings) {
        settings = $.extend({}, $localScroll.defaults, settings);

        return settings.lazy ?
        // use event delegation, more links can be added later.		
			this.bind(settings.event, function(e) {
			    // Could use closest(), but that would leave out jQuery -1.3.x
			    var a = $([e.target, e.target.parentNode]).filter(filter)[0];
			    // if a valid link was clicked
			    if (a)
			        scroll(e, a, settings); // do scroll.
			}) :
        // bind concretely, to each matching link
			this.find('a,area')
				.filter(filter).bind(settings.event, function(e) {
				    scroll(e, this, settings);
				}).end()
			.end();

        function filter() {// is this a link that points to an anchor and passes a possible filter ? href is checked to avoid a bug in FF.
            return !!this.href && !!this.hash && this.href.replace(this.hash, '') == URI && (!settings.filter || $(this).is(settings.filter));
        };
    };

    function scroll(e, link, settings) {
        var id = link.hash.slice(1),
			elem = document.getElementById(id) || document.getElementsByName(id)[0];

        if (!elem)
            return;

        if (e)
            e.preventDefault();

        var $target = $(settings.target);

        if (settings.lock && $target.is(':animated') ||
			settings.onBefore && settings.onBefore.call(settings, e, elem, $target) === false)
            return;

        if (settings.stop)
            $target.stop(true); // remove all its animations

        if (settings.hash) {
            var attr = elem.id == id ? 'id' : 'name',
				$a = $('<a> </a>').attr(attr, id).css({
				    position: 'absolute',
				    top: $(window).scrollTop(),
				    left: $(window).scrollLeft()
				});

            elem[attr] = '';
            $('body').prepend($a);
            location = link.hash;
            $a.remove();
            elem[attr] = id;
        }

        $target
			.scrollTo(elem, settings) // do scroll
			.trigger('notify.serialScroll', [elem]); // notify serialScroll about this change
    };

})(jQuery);