var Mission = {};

Mission.Sliders = {
    activating: false,
    deactivating: false,
    sliders: [],
    register: function(slider) {
        this.sliders.push(slider);
    },
    unregister: function(slider) {
        var sliders = [];
        for (var i=0; i<this.sliders.length;i++) {
            if (this.sliders[i] != slider) {
                sliders.push(this.sliders[i]);
            }
        }
        this.sliders = sliders;
        this.thread(this.bind(slider.__destroy__, slider));
    },
    activate: function(slider) {
        if (!this.inProgress()) {
            if (slider.options.deactivate) {
                var actives = this.actives();
                for (var i=0;i<actives.length;i++) {
                    actives[i].deactivate();
                }
                this.deactivating = actives[i];
            }
            this.activating = slider;
            slider.options.beforeActivate(slider);
            slider._activate();
        }
    },
    deactivate: function(slider) {
        if (!this.inProgress()) {
            this.deactivating = slider;
            slider.options.beforeDeactivate(slider);
            slider._deactivate(slider);
        }
    },
    activated: function(slider) {
        if (this.activating == slider) {
            this.activating = false;
            slider.options.onActivate(slider);
        }
    },
    deactivated: function(slider) {
        if (this.deactivating == slider) {
            this.deactivating = false;
            slider.options.onDeactivate(slider);
        }
    },
    actives: function() {
        var actives = [];
        for (var i=0;i<this.sliders.length;i++) {
            if (this.sliders[i].active()) {
                actives.push(this.sliders[i]);
            }
        }
        return actives;
    },
    deactivateActives: function() {
        for (var i=0;i<this.actives.length;i++) {
            this.actives[i].deactivate();
        }
        for (var i=0;i<this.activating.length;i++) {
            this.activating[i].cancel();
            this.activating[i].deactivate();
        }
    },
    thread: function(method) {
        window.setTimeout(method, 0);
    },
    bind: function(method, obj) {
        return function() {
            method.apply(obj, arguments);
        };
    },
    listen: function(elem, eventName, method) {
        if (elem.addEventListener) {
            elem.addEventListener(eventName, method, false);
        } else {
            elem.attachEvent("on" + eventName, method);
        }
    },
    inProgress: function() {
        return this.activating || this.deactivating;
    }
}
function MissionSlider() {
    this.__init__.apply(this, arguments)
}
MissionSlider.prototype = {
    __init__: function(wrapper, slider, trigger) {
        this._active = false;
        this.wrapper = this.elementify(wrapper);
        this.slider = this.elementify(slider);
        this.trigger = this.elementify(trigger);
        this.options = this.extend({
            time: 0.25, //number of seconds over which the transition takes place
            fps: 50,
            active: false,
            deactivate: true,
            onActivate: function() {},
            onDeactivate: function() {},
            beforeActivate: function() {},
            beforeDeactivate: function() {}
        }, arguments[3]);
        this._active = this.options.active;
        this.registerHandlers();
        Mission.Sliders.register(this);
    },
    __destroy__: function() { 
        this.wrapper = null;
        this.slider = null;
        this.trigger = null;
        this.options = null;
    },
    destroy: function() {
        Mission.Sliders.unregister(this);
    },
    registerHandlers: function() {
        Mission.Sliders.listen(this.trigger, 'click', Mission.Sliders.bind(this.toggle, this));
        // For IE6.  It seems that when we attach the click listener in IE6, CSS hover
        // event stop working.
        Mission.Sliders.listen(this.trigger, 'mouseover', Mission.Sliders.bind(this.light, this));
        Mission.Sliders.listen(this.trigger, 'mouseout', Mission.Sliders.bind(this.unlight, this));
    },
    toggle: function() {
        return (this.active()) ? this.deactivate():this.activate();
    },
    light: function() {
        this.trigger.style.backgroundPositionY = "-22px";
    },
    unlight: function() {
        this.trigger.style.backgroundPositionY = "0";
    },
    activate: function() {
        Mission.Sliders.activate(this);
    },
    _activate: function() {
        this.prep(1);
        this.start(1);
        this._active = true;
    },
    deactivate: function() {
        Mission.Sliders.deactivate(this);
    },
    _deactivate: function() {
        this.prep(-1);
        this.start(-1);
        this._active = false;
    },
    prep: function(direction) {
        this.widthify(this.slider);
        this.wrapper.style.overflow = 'hidden';
        this.wrapper.style.width = (direction > 0) ? '0px':this.slider.style.width;
        this.wrapper.style.visibility = 'visible';
    },
    cleanup: function(direction) {
        this.dewidthify(this.slider);
        this.wrapper.style.overflow = '';
        this.dewidthify(this.wrapper);
        this.wrapper.style.visibility = (direction > 0) ? 'visible':'hidden';
        Mission.Sliders[(direction > 0) ? 'activated':'deactivated'](this)
    },
    start: function(direction) {
        this._direction = direction;
        this.slide();
    },
    slide: function(direction) {
         var width = parseInt(this.wrapper.style.width)+(Math.floor(parseInt(this.slider.style.width)/((this.options.time*1000)/this.options.fps))*this._direction)
         if (width >= parseInt(this.slider.style.width) || width <= 0) {
             return this.cleanup(this._direction);
         }
         this.wrapper.style.width = width+'px';
         window.setTimeout(Mission.Sliders.bind(this.slide, this), Math.floor(1000/this.options.fps));
    },
    widthify: function(elem) {
        var width = elem.offsetWidth;
        elem.style.width = elem.offsetWidth + 'px';
        elem.style.width = (elem.offsetWidth-(elem.offsetWidth-width))+'px';
    },
    dewidthify: function(elem) {
        elem.style.width = '';
    },
    elementify: function(elem) {
        if (elem.constructor == String) {
            return document.getElementById(elem);
        }
        return elem
    },
    extend: function(obj1, obj2) {
        for (i in obj2) {
            obj1[i] = obj2[i];
        }
        return obj1;
    },
    active: function() {
        return this._active; 
    }
}

