/**

*/ !function($) {

'use strict';

function SkipLink($el) {

        Gumby.debug('Initializing Skiplink', $el);

        this.$el = $el;
        this.targetPos = 0;
        this.duration = 0;
        this.offset = false;
        this.easing = '';
        this.update = false;

        // set up module based on attributes
        this.setup();

        var scope = this;

        // skip to target element on click or trigger of gumby.skipTo event
        this.$el.on(Gumby.click+' gumby.skip', function(e) {
                e.preventDefault();

                if(e.namespace === 'skip') {
                        Gumby.debug('Skip event triggered', scope.$el);
                }

                // calculate target on each click if update var set to true
                if(scope.update) {
                        scope.calculateTarget(scope.skipTo);

                // skip straight to target
                } else {
                        scope.skipTo();
                }
        }).on('gumby.initialize', function() {
                Gumby.debug('Re-initializing Skiplink', scope.$el);
                scope.setup();
        });
}

// set up module based on attributes
SkipLink.prototype.setup = function() {
        this.duration = Number(Gumby.selectAttr.apply(this.$el, ['duration'])) || 200;
        this.offset = Gumby.selectAttr.apply(this.$el, ['offset']) || false;
        this.easing = Gumby.selectAttr.apply(this.$el, ['easing']) || 'swing';
        this.update = Gumby.selectAttr.apply(this.$el, ['update']) ? true : false;

        this.calculateTarget();
};

// calculate target px point to skip to
SkipLink.prototype.calculateTarget = function(cb) {

        var scope = this,
                target = Gumby.selectAttr.apply(this.$el, ['goto']),
                $target;

        // 'top' specified so target is 0px
        if(target == 'top') {
                this.targetPos = 0;

        // px point specified
        } else if($.isNumeric(target)) {
                this.targetPos = Number(target);
        } else {

                // check for element with target as selector
                $target = $(target);

                // target does not exist, we need a target
                if(!$target.length) {
                        Gumby.error('Cannot find skiplink target: '+target);
                        return false;
                }

                this.targetPos = $target.offset().top;
        }

        if(cb) {
                cb.apply(this);
        }
};

// animate body, html scrollTop value to target px point
SkipLink.prototype.skipTo = function() {

        Gumby.debug('Skipping to target', this.$el);

        var scope = this;

        // slide to position of target
        $('html,body').animate({
                'scrollTop' : this.calculateOffset()
        }, this.duration, this.easing).promise().done(function() {

                Gumby.debug('Triggering onComplete event', scope.$el);
                scope.$el.trigger('gumby.onComplete');
        });
};

// calculate offset with current target point
SkipLink.prototype.calculateOffset = function() {
        // no offset so return target here
        if(!this.offset) {
                return this.targetPos;
        }

        // negative / positive
        var op = this.offset.substr(0, 1),
                off = Number(this.offset.substr(1, this.offset.length));

        // subtract offset from target position
        if(op === '-') {
                return this.targetPos - off;
        // add offset to target position
        } else if(op === '+') {
                return this.targetPos + off;
        }
};

// add initialisation
Gumby.addInitalisation('skiplink', function(all) {
        $('.skiplink > a, .skip').each(function() {
                var $this = $(this);

                // this element has already been initialized
                // and we're only initializing new modules
                if($this.data('isSkipLink') && !all) {
                        return true;

                // this element has already been initialized
                // and we need to reinitialize it
                } else if($this.data('isSkipLink') && all) {
                        $this.trigger('gumby.initialize');
                        return true;
                }

                // mark element as initialized
                $this.data('isSkipLink', true);
                new SkipLink($this);
        });
});

// register UI module
Gumby.UIModule({
        module: 'skiplink',
        events: ['initialize', 'onComplete', 'skip'],
        init: function() {
                Gumby.initialize('skiplink');
        }
});

}(jQuery);