// This code depends on glow version 1.2.2 only. 

var Carousel=function(){
    var e = glow.dom.get(Carousel.arguments[0]);
    if(e.length>0)
        return this._init(e);
    else
        this._load = false;
};

Carousel.prototype = {

    // build glow carousel with arguments provided.
    _build:function(e,o){

        // Create a new glow carousel object.
        var c = new glow.widgets.Carousel(
            e,{
            theme:"aps",
            animDuration:o.animDuration,
            scrollOnHold:o.scrollOnHold,
            loop:o.loop,
            step:o.step
        });

        Carousel._load = true;

        // return bitesized glow object as well as original.
        return glow.lang.apply({
            // original glow carousel object
            carousel:c,
            // quick access properties.
            window:c._viewWindow,
            element:c.element,
            list:c.content,
            items:c.items,
            step:c._opts.step
            },
        o);

    },

    // determine the direction from click event.
    _direction:function(str,o){

        // Increase count position.
        if(/next/.test(str))
            o.position++;

        // Reduced count position.
        else if(/prev/.test(str))
            o.position--;

        return o;

    },

    // determine the position but remedy if beyond / below the overall count slicing. 
    // In this case the slicing is set to one marker for єach item. 
    // Bugs will surface if the slicing of the count position was changed ... kind of a custom build for APS.
    _position:function(o){

        var p,l;

        p = o.position;
        l = o.items.length;

        // If count posiiton is beyond item count do something.
        if(p>l)
            o.position=1;

        // if count position is below or zero'd do something.
        if(p<0||p==0) 
            o.position=l;

        return o;

    },

    // Update the markers to reflect present count position.
    _display:function(o){

        if(!o.markers) return;

        // Get the present count position
        this.item = o.markers.get('.slot-'+o.position);

        // collect all markers.
        this.items = o.markers.children();

        // Remove the /on/ clause from the markers.
        this.items.removeClass('slot-on');

        // Assign the newly established count position.
        this.item.toggleClass('slot-on');

        return o;

    },

    // Restructure the default glow DOM inserts and override some glow imposed styling.
    _apply:function(o){

        // Remove glow imposed window width.
        o.window.css("width","");

        // Insert carousel status div where the markers and CTA's will be.
        o.status = glow.dom.create('<div class="carousel-status clearme"><ol class="slot-marker"><!--v--></ol></div>').insertBefore(o.element);

        // Target CTA's and remove glow imposed height of CTA links.
        o.nav = o.element.get('.carousel-nav').css("height","");

        // Take CTA's and slip them in before the markers list.
        o.markers = o.nav.removeAttr("style").insertBefore('.slot-marker').parent().get('.slot-marker');

        // Slightly amend the contents of each CTA to aid APS styling.
        o.nav.each(function(){
            var e = o.status.get(this);
            if(e.text().match(/Previous/))
                e.attr("title","View the previous item")
            else
                e.attr("title","View the next item")
            e.html('<span class="link-box">'+ e.html() +'</span>');
        });

        // step through each item and insert a corrisponding marker with the marker list.
        if(o.items.length>o.step){

            o.items.each(function(i){
                var count = (i+1);
                var item = o.list.get(this);
                // Account for the last item in the list to aid styling.
                var last = (i==o.items.length-1) ? " last" : "" ;
                // Create marker items as required and make a more accessible to non-visual rendering.
                o.markers.append('<li title="View item '+ count +'" class="slot-'+count+''+last+'"><a href="#slot-'+count+'"><span>View item '+count+'</span></a></li>');
                // Assert slot ID.
                item.attr({id:'slot-'+count});
            });

            // Assert the present position.
            o.markers.get('.slot-'+o.position).toggleClass('slot-on');

        }

        return o;

    },

    _init:function(e){


        // Build the object.
        var o = this._build(e,{
            position:1,
            step:1,
            animDuration:0.5,
            scrollOnHold:false,
            loop:true
        });

        // Apply the controls.
        this._apply(o);

        // Assign listeners events to carousel and CTA's
        if(typeof o=="object"){

            // Pipe glow namespace to local variable.
            var event = glow.events;

            event.addListener(o.carousel,"afterScroll",function(){
                // Assert position.
                Carousel.prototype._position(o);
                // Update display.
                Carousel.prototype._display(o);
                // Disable player locking.
                o.playing = false;
                return;
            });

            // CTA events piped to determine directionṡ
            event.addListener(o.nav,"click",function(){
                if(o.playing) return;
                Carousel.prototype._direction(this.className,o);
                // Assert player locking.
                o.playing = true;
                return false;
            });

            // Pipe marker items to local variable.
            var markers = o.markers.children();

            // Add over, out and click events to marker /li's/.
            // The over and out state is done via JS as it appears mostly eye candy but could also complicate the structure of the HTML if done via CSS.
            event.addListener(markers,"mouseover",function(){
                var e = o.markers.get(this); 
                // Ignore if over the existing count position.
                if(e.hasClass('slot-on')) return;
                e.toggleClass('slot-on');
            });

            event.addListener(markers,"mouseout",function(){
                var e = o.markers.get(this);
                // Ignore if over the existing count position.
                if(e.hasClass('slot-'+o.position)) return;
                e.toggleClass('slot-on');
            });

            // Assert /go to/ event for each marker.
            // This allows the markers to be used in order to go directly to a desired item.
            event.addListener(markers,"click",function(){

                if(o.playing) return false;

                var p,i,n,c;

                n = 1;
                i = this.className.match(/slot-([0-9]+)/)[1];
                p = o.position;
                c = o.carousel;

                // Ignore if the requested /go to/ position is equal to the current slot.
                if(p==i) return false;

                // Determine the sum of the difference between the present position and the requested /go to/ position.
                // The resulting value is used to instruct glow on how far to jump.
                if(i>p||i<p) {
                    var n = parseInt(i-p);
                    o.position = p+n;
                }

                // Update the markers display.
                Carousel.prototype._display(o);

                // Make your move.
                c.moveBy(n);
                
                return false;

            });
        }
        
        return o.carousel;

    }

};

glow.onDomReady(function(){

    // Presently takes only one argument ~ the target elements ID or classname.
    var carousel = new Carousel("#carousel");

    // Slip the first item to the middle of the view
    if(carousel._load)
        carousel.moveBy(-1,false);

});

