﻿if (typeof Effect == 'undefined')
	throw("wizard.js requires including script.aculo.us' effects.js library!");

var question = Class.create();
question.prototype = {
    wizard: null,
    container: null,
    questionText: null,
    optionGroups: null,
    selected: null,
    selectedIndex: -1,
    chooseAgain: null,
    initialize: function(container, wizard) {
        this.wizard = wizard;
        this.container = $(container);
        this.questionText = container.select('.questionText').first();
        this.optionGroups = container.select('.options');   
        this.container.descendants().invoke('cleanWhitespace');
        this.container.immediateDescendants().invoke('hide');
        this.chooseAgain = container.select('.questionReset').first();
        this.chooseAgain.hide();
    },
    registerEvents: function()
    {
        this.optionGroups.each(function(group){
            group.getElementsBySelector('li').each(function(item){
                item.observe('mouseout', function(item) {
	                item.removeClassName('linkhover');
	            }.bind(this, item));
	            item.observe('mouseover', function(item) {
		            item.addClassName('linkhover');			    
	            }.bind(this, item));
                item.observe('click', this.selectItem.bind(this, item));
                item.addClassName('link');
            }.bind(this));
        }.bind(this));
        this.chooseAgain.stopObserving();
        new Effect.Fade(this.chooseAgain, {duration: .5});
    },
    unregisterEvents: function()
    {
        this.optionGroups.each(function(group){
            group.getElementsBySelector('li').each(function(item){
                item.stopObserving();
                item.removeClassName('linkhover');
                item.removeClassName('link');
            }.bind(this));
        }.bind(this));
        new Effect.Appear(this.chooseAgain, {duration: .5, delay: .5});
        this.chooseAgain.observe('click', this.wizard.rollback.bind(this.wizard, this));
    },   
    show: function()
    {
        if(this.selected)
            return this; 
        this.registerEvents();
        if(!this.container.visible())  
            new Effect.Appear(this.container, {duration: .1, queue: {scope:'wizard',position: 'end'}});
        if(!this.questionText.visible())
            new Effect.Appear(this.questionText, {duration: .3, queue: {scope:'wizard',position: 'end'}});
        this.optionGroups.each(function(group){   
            var limit = group.readAttribute('limit');
            if(this.wizard.validateOptions(limit))     
                new Effect.Appear(group, {duration: .3, queue: {scope:'wizard',position: 'end'}});       
       }.bind(this));
       return this;
    },
    repick: function()
    {
        this.chooseAgain.stopObserving();
        new Effect.Fade(this.selected, {duration: .3,
            afterFinish: function(){                
                this.optionGroups.each(function(group){
                    group.getElementsBySelector('li').invoke('show');
                    group.hide();
                }.bind(this)); 
                this.selected = null; 
                this.selectedIndex = -1;                                   
                this.show();               
            }.bind(this)
        });   
    },
    reset: function() {
        this.selected = null; 
        this.selectedIndex = -1;
        new Effect.Fade(this.container, {duration: .3, 
            afterFinish: function(){
                this.container.hide();
                this.container.immediateDescendants().invoke('hide');
                this.optionGroups.each(function(group){
                    group.getElementsBySelector('li').invoke('show');
                }.bind(this));
            }.bind(this)
        });       
        return this;
    },
    selectItem: function(item) {  
        if(this.selected == item)
            return this;  
        this.unregisterEvents();       
        this.selected = item;
        this.optionGroups.each(function(group, index){                        
            this.selectedIndex = group.getElementsBySelector('li').indexOf(item);            
            if(this.selectedIndex != -1) {
                this.selectedGroup = group;
                this.selectedGroupIndex = index;
                return true;
            }
            new Effect.Fade(group, {duration: .2});
            return false;                
        }.bind(this));
        
        item.siblings().each(function(item){            
            new Effect.Fade(item, {duration: .2});
        });
        (function(){ this.wizard.advanceQuestion(); }.bind(this)).delay(.3);
        return this;
    },
    getResults: function()
    {
        if(this.selected == null)
            return;
         var results = this.selected.readAttribute('results');
         if(results)
             return $w(results);            
    }
    
};

var wizard = Class.create();
wizard.prototype = {
    animating: false,
    questions : null,
    container: null,
    current: 0,
    resultsContainer: null,
    initialize: function(container)
    {
        this.container = $(container);
        this.questions = [];
        this.resultsContainer = this.container.select('.results').first();
        this.resultsContainer.hide();
        this.container.setStyle({height: this.container.scrollHeight});
        var blocks = this.container.select('.question');
        blocks.each(function(element){
            var q = new question(element, this);
            this.questions.push(q);
            element.hide();
        }.bind(this));   
        this.displayQuestion();
    }, 
    rollback: function(current)
    {
        if(this.resultsContainer.visible())
            new Effect.Fade(this.resultsContainer, {duration: .5}); 
        this.questions.reverse(false).find(function(item, index){
            if(item == current)
            {
                item.repick();
                this.current = this.questions.length - index - 1;
                return true;                                
            }
            item.reset();
        }.bind(this));
    },
    displayQuestion: function()
    {
       var q = this.questions[this.current];
       if(q) q.show();
       return this;
    },
    advanceQuestion: function()
    {
        if(this.questions.length > (this.current + 1))
        {
            this.current++;
            this.displayQuestion();
        } else {
            this.displayResults();
        }
        return this;
    },
    displayResults: function()
    {
        var results = this.questions[this.current].getResults();
        if(results)
        {
            this.resultsContainer.select('.result').each(function(item){
                if(results.indexOf(item.identify()) >= 0)
                    item.show();
                else
                    item.hide();              
            }.bind(this));
            
            new Effect.Appear(this.resultsContainer, {duration: .6, queue: {scope:'wizard',position: 'end'}});
        }
    },
    validateOptions: function(limit)
    {
        if(limit === undefined || limit === null)
            return true;        
        limit = eval('$H({' + limit + '})');        
        var ret = true;
        this.questions.find(function(question, index){ //we're not actually finding something...
            if(limit.get('q' + index) !== undefined)
                if(limit.get('q' + index) != question.selectedIndex)
                    ret = false;                    
            if(index > this.current)
                return true;
            if(ret == false) //if we've failed a test, return out of this loop
                return true;
        }.bind(this));            
        return ret;      
    }
};
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();