/*
 * @glider effect based on
 * @url http://www.missingmethod.com/projects/glider/
 * @version 0.0.3
 */

Glider = Class.create();
//Object.extend(Object.extend(Glider.prototype, Abstract.prototype), {
Glider.prototype = {
    initialize: function(wrapper, options) {
        this.scrolling  = false;
        this.wrapper    = $(wrapper);
        this.scroller   = this.wrapper.down('div.scroller');
        this.sections   = this.wrapper.getElementsBySelector('div.section');
        this.quickJump  = this.wrapper.getElementsBySelector('div.controls');
        this.options    = Object.extend({ duration: 1.0, frequency: 3 }, options || {});

        this.sections.each( function(section, index) {
            section._index = index;
        });    

        this.events = { click: this.click.bind(this) };

        //this.addObservers();

        if(this.options.initialSection) 
            this.moveTo(this.options.initialSection,
            this.scroller, { duration:this.options.duration });  
        // initialSection should be the id of the section you want to show up on
        // load
        if(this.options.autoGlide) this.start();
    },
    addObservers: function() {
        var controls = this.wrapper.getElementsBySelector('div.controls div.quickjump a');
        controls.invoke('observe', 'click', this.events.click);
    },    
    click: function(event) {
        this.stop();
        var element = Event.findElement(event, 'a');
        if (this.scrolling) this.scrolling.cancel();
        this.jumpTo(element.href.split("#")[1] - 1);
        //this.moveTo(
        //    element.href.split("#")[1], this.scroller,
        //    { duration:this.options.duration }
        //);     
        Event.stop(event);
    },
    moveTo: function(element, container, options) {
        this.current = $(element);

        Position.prepare();
        var containerOffset = Position.cumulativeOffset(container),
        elementOffset = Position.cumulativeOffset($(element));
        this.scrolling = new Effect.SmoothScroll(
                container, 
                {
                    duration:options.duration,
                    x:(elementOffset[0]-containerOffset[0]),
                    y:(elementOffset[1]-containerOffset[1])
                }
        );
        return false;
    },
    jumpTo: function(n){
        this.moveTo(
            this.sections[n], this.scroller, 
            { duration: this.options.duration }
        );
    },
    next: function(){
        if (this.current) {
            var currentIndex = this.current._index;
            var nextIndex = (this.sections.length - 1 == currentIndex) ? 0 : currentIndex + 1;      
        } else var nextIndex = 1;

        this.moveTo(
            this.sections[nextIndex], this.scroller, 
            { duration: this.options.duration }
        );
    },
    previous: function(){
        if (this.current) {
            var currentIndex = this.current._index;
            var prevIndex = (currentIndex == 0) ? this.sections.length - 1 : 
            currentIndex - 1;
        } else 
            var prevIndex = this.sections.length - 1;

        this.moveTo(
            this.sections[prevIndex], this.scroller, 
            { duration: this.options.duration }
        );
    },
    stop: function() {
        clearTimeout(this.timer);
    },
    start: function() {
        this.periodicallyUpdate();
    },
    periodicallyUpdate: function() { 
        if (this.timer != null) {
            clearTimeout(this.timer);
            this.next();
        }
        this.timer = setTimeout(this.periodicallyUpdate.bind(this),
            this.options.frequency*1000);
    }
};

Effect.SmoothScroll = Class.create();
Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), {
    initialize: function(element) {
        this.element = $(element);
        var options = Object.extend(
            {
                x: 0,
                y: 0,
                mode: 'absolute'
            }, arguments[1] || {}  );
        this.start(options);
    },
    setup: function() {
        if (this.options.continuous && !this.element._ext ) {
            this.element.cleanWhitespace();
            this.element._ext=true;
            this.element.appendChild(this.element.firstChild);
        }

        this.originalLeft=this.element.scrollLeft;
        this.originalTop=this.element.scrollTop;

        if(this.options.mode == 'absolute') {
            this.options.x -= this.originalLeft;
            this.options.y -= this.originalTop;
        } 
    },
    update: function(position) {   
        this.element.scrollLeft = this.options.x * position +
            this.originalLeft;
        this.element.scrollTop  = this.options.y * position + this.originalTop;
    }
});

/*
 *      GliderBox is an interface to be implemented by any page that needs to
 *      use the glider effect to present structured content, like a set of
 *      images accompanied by text. Thus, there is no constructor method
 *      defined.
 *
 *      For an example on using this interface, refer to solution.js 
 *
 *      @ Martin Rio
 *      @ 6/7/2007
 */

var GliderBox = Class.create();
GliderBox.prototype = {
    gotoSlide: function(e) {
        Event.stop(e);
        var i = Event.element(e).href.split("#")[1] - 1;
        this.glider.jumpTo(i);
        this.currentSlide = i;
        this.updateControls();
    },
    glideToProject: function(n) {
        this.glider.jumpTo(n);
        this.currentslide = n;
    },
    loadImages: function(a) {
        // takes in an array of objects with properties 'name' and 'uri'            
        var imgs = new Array; 
        a.each(function(e) {
            var i = new Image();
            i.src = e.uri;
            i.alt = e.alt;
            imgs.push(i);
        });
        return imgs;
    },
    composePlayer: function() {
        if (!this.images) 
            throw new Error('composePlayer: this.images not defined')
        var g = document.createElement('div');
        g.id = this.container; 
        var s = document.createElement('div');
        s.className = 'scroller';
        g.appendChild(s);
        var p = document.createElement('div');
        p.className = 'inner';
        p.id = 'panel';
        this.images.each( function(i) {
            var d = document.createElement('div');
            d.className = 'section';
            d.id = i.alt;
            d.appendChild(i);
            p.appendChild(d);
        }.bind(this));
        s.appendChild(p);
        g.appendChild(this.composeControls());
        return g;
    },
    composeControls: function() {
        var c = document.createElement('div');
        c.className = 'controls';
        var q = document.createElement('div');
        q.className = 'quickjump';
        var p = document.createElement('div');
        p.className = 'prevnextProj';
        // Quickjump links
        if (!this.noquickjump) {
            this.images.each( function(i,index) {
                ++index; // want to start at 1
                var a = document.createElement('a');
                a.href = '#' + index;
                a.innerHTML = index;
                q.appendChild(a);
            });
        }
        // Slide Previous/next links
        if (!this.noprevnextSlide) {
            var r = document.createElement('a');
            r.href = "#";
            r.className = "prev";
            r.appendChild(document.createTextNode('PREV SOLUTION'));
            p.appendChild(r);
            var n = document.createElement('a');
            n.href = "#";
            n.className = "next";
            n.appendChild(document.createTextNode('NEXT SOLUTION'));
            p.appendChild(n);
        }
        // Project Previous/next links
        if (!this.noprevnextProj) {
            // Prev
            var prev = document.createElement('a');
            prev.className = 'buttonL';
            prev.href = '#';
            var ql = document.createElement('div');
            ql.className = 'button_l';
            ql.appendChild(document.createTextNode('Previous Solution'));
            var qr = document.createElement('div');
            qr.className = 'button_r';
            prev.appendChild(ql);
            prev.appendChild(qr);
            p.appendChild(prev);
            // Next
            var b = document.createElement('a');
            b.className = 'buttonR';
            b.href = '#';
            var bl = document.createElement('div');
            bl.className = 'button_l';
            bl.appendChild(document.createTextNode('Next Solution'));
            var br = document.createElement('div');
            br.className = 'button_r';
            b.appendChild(bl);
            b.appendChild(br);
            p.appendChild(b);
        }
        // Append
        c.appendChild(q);
        c.appendChild(p);
        return c;
    },
    updateControls: function() {
        if (!this.noquickjump) {
            var controls = this.player.getElementsBySelector('div.controls div.quickjump a');
            for (var i = 0; i < controls.length; ++i) {
                if (i == this.currentSlide) {
                    controls[i].className = 'red';
                } else {
                    controls[i].className = '';
                }
            } 
        }
        if (!this.noprevnextSlide) {
        }
        if (!this.noprevnextProj) {
            var controls = 
                this.player.getElementsBySelector('DIV.prevnextProj A');
            if (this.currentslide == 0) controls[0].style.visibility = 'hidden';
            if (this.currentslide > 0 ) controls[0].style.visibility = 'visible';
            if (this.currentslide == this.set.projects.length - 1)
                controls[1].style.visibility = 'hidden';
            if (this.currentslide < this.set.projects.length - 1)
                controls[1].style.visibility = 'visible';
        }
    },
    composeLoader: function() {
        if(this.loader) return this.loader;
        this.loader = document.createElement('div');
        this.loader.id =  this.container;
        var s = document.createElement('span');
        s.id = 'loader';
        var i = document.createElement('img');
        i.src = 'images/loader.gif';
        i.alt = 'Loading Project';
        s.appendChild(i);
        this.loader.appendChild(s);
        return this.loader;
    },
    composeContentObject: function() {
        // define components
        this.content = new Object();
        this.content.div = document.createElement('div');
        this.content.div.id = 'projectContent'; 
        this.content.title = document.createElement('h1');
        this.content.url = document.createElement('span');
        this.content.url.className = 'url';
        this.content.body = document.createElement('div');
        this.content.body.className = 'bodyWrap';
        this.content.section = new Object();
        this.content.section.div = document.createElement('div');
        this.content.section.div.className = 'sectionWrap';
        this.content.section.title = document.createElement('h2');
        this.content.section.title.className = 'sectionTitle';
        this.content.section.body = document.createElement('div');
        this.content.section.body.className = 'sectionBody';
        // build hierarchy
        this.content.div.appendChild(this.content.title);
        this.content.div.appendChild(this.content.url);
        this.content.div.appendChild(this.content.body);
        this.content.section.div.appendChild(this.content.section.title);
        this.content.section.div.appendChild(this.content.section.body);
    },
    loadEventListeners: function() {
        if (!this.noquickjump) {
            var controls = this.player.getElementsBySelector('div.controls div.quickjump a');
            for (var i = 0; i < controls.length; ++i) {
                Event.observe(controls[i], "click",
                        this.gotoSlide.bindAsEventListener(this), false);
            }
        }
        if (!this.noprevnextProj) {
            var as = this.player.getElementsBySelector('div.prevnextProj a');
            Event.observe(as[1], "click", this.nextProj.bindAsEventListener(this),
                    false);
            Event.observe(as[0], "click",
                    this.prevProj.bindAsEventListener(this), false);
        }
        if (!this.noprevnextSlide) {
            var as = this.player.getElementsBySelector('div.prevnextSlide a');
            Event.observe(as[1], "click", this.nextProj.bindAsEventListener(this),
                    false);
            Event.observe(as[0], "click",
                    this.prevProj.bindAsEventListener(this), false);
        }
    },
    showLoader: function(opts) {
        $(this.container).up().replaceChild(this.composeLoader(),$(this.container));
    },
    loadGliderBox: function(opts) {
        this.m = false;
        this.player = this.composePlayer();
        this.draw();
        this.glider = new Glider(this.player, {duration:0.5});
        this.loadEventListeners();
    },
    draw: function() {
        $(this.container).up().replaceChild(this.player,$(this.container));
    },
    // Interface methods
    loadProject: function(e) {
        //makes glider of project,
        //loads project content
        // displays 1st image
    },
    selectFx: function(e) {
        // handle select box change event 
    }
};
