var Accordion = Class.create({
    initialize: function(id, options) {
        this.accordion = $(id);
        if(this.accordion == undefined) throw ("ID: " + id + " not found!");
        this.extendOptions(options);
        this.togglers = this.accordion.select('.' + this.options.toggleClassName);
        this.contents = this.accordion.select('.' + this.options.contentClassName);
        this.isAnimating = false;
        this.setupAccordion();
    },
    
    extendOptions: function(options){
        this.options = Object.extend({
            toggleClassName: 'toggle', //done
            contentClassName: 'toggle-content', //done
            mouseEvent: 'click',
            start: 0, //done
            speed: .3, //done
            fixedHeight: false,
            fixedWidth: false, // for when horizontal capabilities are added
            alwaysHide: false, //done
            onActive: function(){}, //done
            onBackground: function(){}, //done
            height: true,
            opacity: true, //done
            width: false
        }, options || {});
    },

    setupAccordion: function() {
        this.togglers.each(function(el) {
            el.observe(this.options.mouseEvent, this.handleAction.bindAsEventListener(this, el));
        }.bind(this));
        this.initStart();
    },
    initStart: function() {
        if (this.options.start == -1) return;
        if(Object.isArray(this.options.start)) {
            this.options.start.each(function(toExpand) {
                this.showThis(this.togglers[toExpand]);
            }.bind(this));
        } else {
            this.showThis(this.togglers[this.options.start]);
        };
    },

    showThis: function(el) {
        var activeIndex = this.togglers.indexOf(el);
        var element = (!!this.options.notSiblings) ? $$('.'+this.options.contentClassName)[0] : this.contents[activeIndex];
        new Effect.BlindDown(element,{
            duration: this.options.speed,
            beforeStart: function() {this.isAnimating = true; this.options.onActive.apply();}.bind(this),
            afterFinish: function() {this.isAnimating = false;}.bind(this)
        });
        if (this.options.opacity) new Effect.Appear(element, {duration: this.options.speed});
        el.removeClassName('collapsed');
    },

    hideThis: function(el) {
        var activeIndex = this.togglers.indexOf(el);
        var element = (!!this.options.notSiblings) ? $$('.'+this.options.contentClassName)[0] : this.contents[activeIndex];
        new Effect.BlindUp(element,{
            duration: this.options.speed,
            beforeStart: function() {this.isAnimating = true; this.options.onBackground.apply();}.bind(this),
            afterFinish: function() {this.isAnimating = false;}.bind(this)
        });
        if (this.options.opacity) new Effect.Fade(element, {duration: this.options.speed});
        el.addClassName('collapsed');
    },

    showThisHideOthers: function(el) {
        var activeIndex = this.togglers.indexOf(el);
        var element = (!!this.options.notSiblings) ? $$('.'+this.options.contentClassName)[0] : this.contents[activeIndex];
        if (!this.isCollapsed(el)) return;
        this.togglers.each(function(toggler) {
            if(this.isCollapsed(toggler) && (toggler.next() == element)) {
                this.showThis(toggler);
            } else {
                this.hideThis(toggler);
            }
        }.bind(this));
    },

    handleAction: function(e, el) {
        var toggle = el;
        if(!this.isAnimating) {
            if(this.options.alwaysHide) {
                this.showThisHideOthers(toggle);
            } else {
                if (this.isCollapsed(toggle)) {
                    this.showThis(toggle);
                } else {
                    this.hideThis(toggle);
                }
            }
        }
    },

    isCollapsed: function(el) {
         if(el.hasClassName('collapsed')) {
            return true;
        };
    },

    showAll:function() {
        this.togglers.each(function(toggler) {
            if(toggler.hasClassName('collapsed')) {
                this.showThis(toggler);
            }
        }.bind(this));
    },

    hideAll:function() {
        this.togglers.each(function(toggler) {
            if(!toggler.hasClassName('collapsed')) {
                this.hideThis(toggler);
            }
        }.bind(this));
    }
});

var ViewAllToggleFactory = Class.create({
    initialize: function(linkArray) {
        this.links = linkArray;
        this.constructToggles();
    },

    constructToggles: function() {
        this.links.each(function(link, i) {
            var constructor = link + i;
            constructor = new ViewAllToggle(link, i);
        }.bind(this));
    }
});

var ViewAllToggle = Class.create({
    toggleState:0,

    initialize: function(link, i) {
        this.link = link;
        this.index = i;
        this.attachClicks();
    },

    attachClicks: function() {
            $(this.link).observe('click', this.handleToggle.bindAsEventListener(this));
    },

    handleToggle: function() {
        if (this.toggleState == 0) {
            window.accordions[this.index].showAll();
            var oldMsg = 'HIDE ALL ANSWERS';
            $(this.link).update(oldMsg);
            this.toggleState = 1;
        } else {
            window.accordions[this.index].hideAll();
            var newMsg = 'SHOW ALL ANSWERS';
            this.toggleState = 0;
            $(this.link).update(newMsg);
        }
    }
});