

var Question = Class.create({
    initialize: function(qid) {
        this.qid = qid;
        this.data = new Array();
        
        // slider
        this.min = false;
		this.max = false;
		this.defaultSingleSlider = false;
		this.sliderDirection = "";
       
       
        // triggers
        this.setter = new Hash();
        this.manualSingleSliderSetter = false;
        this.manualDoubleSliderSetter = false;
    },
    
    /**
     * Generic Data Setter
     */    
    set:function(paramName,paramValue){
        this.data[paramName]=paramValue;
    },
    
    /**
     * Generic Data Getter
     */    
    get:function(paramName){
        return this.data[paramName];
    },    
    
    /**
     * Check if question is answered (has a selected answer)
     * IMPORTANT - Don't check slider value!!
     * @return Boolean - is answered?
     */
    isAnsweredQuestion: function(){
        return $$("#question_"+this.qid+" input:checked").size()>0;
    },
    
    /**
     * Get array with answer objects of unanswered answers of this question
     * @return array with answer objects
     */
    getUnansweredAnswerObjects: function(){   

        var returnList = new Array();

        var answer = $$("#question_"+this.qid+" input:not(:checked)").each(function(input){
            returnList.push(LU.getAnswer(input.value));
           
        });
        return returnList;
    },
    
    /**
     * Check if question is a slider question (single or double)
     * @return true|false
     */
    isSliderQuestion:function(){
    	return ($$("#question_"+this.qid+".type_singleslider").size() || $$("#question_"+this.qid+".type_doubleslider").size())>0;
    },
    
    /**
     * Returns question type with focus on sliders
     * @return "singleslider"|"doubleslider"|""
     */
    getType:function(){
    	if($$("#question_"+this.qid+".type_singleslider").size() > 0)
    		return "singleslider";
    	else if ($$("#question_"+this.qid+".type_doubleslider").size() > 0){
    		return "doubleslider";
    	}
    	else
    		return "";
    },
    
    /**
     * Get DOM reference to question
     * @return DOM reference of this question
     */
    getReference:function(){
    	return $("question_"+this.qid);
    }
	
});


var SliderQuestion = Class.create(Question, {
	 

	initialize: function(qid) {
	    this.qid = qid;
	    this.data = new Array();
	    
	    // slider
		this.min = false;
		this.max = false;
		this.defaultSingleSlider = false;
		this.sliderDirection = "";
	   
	   
	    // triggers
	    this.setter = new Hash();
	    this.manualSingleSliderSetter = false;
	    this.manualDoubleSliderSetter = false;
	},
	
	
	/**
	 * Initializer of single slider
	 */
	initializeSingleSlider: function(values, preselectedvalue, sliderDirection) {
		this.min = values.min();
		this.max = values.max();
		this.defaultSingleSlider = preselectedvalue;
		this.sliderDirection = sliderDirection;
	
	}, 
		
	/**
	 * Initializer of double slider
	 */
	initalizeDoubleSlider: function(value){
		this.setDoubleSliderManualTrigger(value);
		this.set("lastTriggerValues", value); // set last trigger value to detect manual trigger
	},	
	
	/**
	 * Observer of single slider
	 */
	notifySingleSlider: function(value){
		var a = this.get("triggerInAction"); // update manual trigger only if there is no trigger in action
		if(a == undefined || a == false){
			this.setSingleSliderManualTrigger(value);
		}
	}, 
	
	
	/**
	 * Update the slider after removing of slider trigger of checkbox or radio
	 * @return none
	 */
	updateStatus: function(){
	
		if(this.getType() == "singleslider"){
	
			// get manual
			var manual = this.getSingleSliderManualTrigger();
			
			// get active trigger
			var activeTriggerValue = false;
			this.setter.each(function(s){
				activeTriggerValue = s.value;
			});
			
			var newValue;
			if(activeTriggerValue && manual){ // check if there is a manual and trigger value
				
				// get relevant value depending on value direction
				if(activeTriggerValue < manual){
					newValue = (this.getSliderDirection() == "high2low")?activeTriggerValue:manual;
				} else {
					newValue = (this.getSliderDirection() == "high2low")?manual:activeTriggerValue;
				}
			}else if(manual){ // only manual value -> take it
				newValue = manual;
			}else // only activeTriggerValue value -> take it
				newValue = activeTriggerValue;
	
		 	// set new value to slider, but set slider into trigger mode (important for manual detection)
			var sliderManager = window["sliderManager_"+this.qid];
			this.set("triggerInAction", true);
			sliderManager.setSingleSlider(newValue);
			this.set("triggerInAction", false);
		
		}else {
		
			var currentValues = this.getCurrentDoubleSliderValues();
        	
        	// ################ get current manual double slider trigger #################
        	var lastTriggerValues = this.get("lastTriggerValues");
        	if(lastTriggerValues == undefined ) lastTriggerValues = [,];

        	if(currentValues[0] != lastTriggerValues[0])
        		this.setDoubleSliderManualTrigger([currentValues[0],]);
        	if(currentValues[1] != lastTriggerValues[1])
        		this.setDoubleSliderManualTrigger([,currentValues[1]]);
        	// ################ get current manual double slider trigger #################
			
			
			// get manual
			var manual = this.getDoubleSliderManualTrigger();

			
			// get active trigger
			var activeTriggerValue = false;
			this.setter.each(function(s){
				// TODO get highest value
				activeTriggerValue = s.value;
			});	
			
			
			// get correct value by checking manual trigger and existing triggers
			var newValue = (activeTriggerValue == false)?manual:activeTriggerValue;
			
			
			var newMin = newValue[0];
			var newMax = newValue[1];
			
			
			
			// set new value to slider, but set slider into trigger mode (important for manual detection)
			var sliderManager = window["sliderManager_"+this.qid];
			this.set("triggerInAction", true);
			sliderManager.setDoubleSlider(newMin, newMax);
			this.set("lastTriggerValues",[newMin, newMax]);
			this.set("triggerInAction", false);
			
			
		}
	},

	
	
	/**
	 * Returns current values of single slider
	 * @return value of slider (type: float)
	 * 
	 */
	
	getCurrentSingleSliderValue: function() {
		return parseFloat($("answer_"+this.qid).value);	
	}, 
	
	/**
	 * Returns current values of double slider
	 * @return value -> array with [0]-minValue, [1]-maxValue (type: float)
	 * 
	 */
	getCurrentDoubleSliderValues: function() {
		return [parseFloat($("answer_"+this.qid).value),parseFloat($("answer_"+this.qid+"_2").value)];
	},

	/**
	 * Returns value direction of single slider
	 * @return "high2low"|"low2high"
	 */
	getSliderDirection: function(){
		// return saved value from initalizeSlider method
		return this.sliderDirection;
	},
	
	// -------------------------------- SETTER ----------------------------------
	
	addSingleSliderSetter: function(aid_start, value){
	    if(this.setter == false)
	        this.setter = new Hash();
	    
	    this.setter.set(aid_start,value);
	    LU.getAnswer(aid_start).addSliderTrigger(this.qid);  
	    
    },
    
    addDoubleSliderSetter: function(aid_start, value_min, value_max){   
	    
    	if(this.setter == false)
	        this.setter = new Hash();
	    
	    this.setter.set(aid_start,[value_min, value_max]);
    	
    	LU.getAnswer(aid_start).addSliderTrigger(this.qid);  

    },
	
    removeSliderSetter: function(aid){
    	this.setter.unset(aid);

	}, 
	// ------------------------------ TRIGGER ----------------------------------
	
	
	/**
	 * Setter of manual trigger value
	 * @param value - value setted manually
	 */
	setSingleSliderManualTrigger: function(value){
		// set class variable
		this.manualSingleSliderSetter = value;
	}
	
	/**
	 * Getter of manual trigger value
	 * @return value - value setted manually (number or false->no manual trigger)
	 */
	,getSingleSliderManualTrigger: function(){	
		// get class variable
		return this.manualSingleSliderSetter;
	},
	
	/**
	 * Setter of manual trigger value for double slider
	 * 
	 * @param value -> array with [0]-minValue, [1]-maxValue
	 */
	setDoubleSliderManualTrigger: function(value){
		if(value[0] != undefined && value[1] != undefined){
			// set class variable
			this.manualDoubleSliderSetter = value;
		} else if(value[0] != undefined){ // only first
			this.manualDoubleSliderSetter[0] = value[0];
		} else if(value[1] != undefined){ // only second
			this.manualDoubleSliderSetter[1] = value[1];
		}
	},
	
	/**
	 * Getter of manual trigger value of double slider
	 * 
	 * @return value -> array with [0]-minValue, [1]-maxValue
	 * 
	 */
	getDoubleSliderManualTrigger: function(){	
		// get class variable
		return this.manualDoubleSliderSetter;
	}
});


var Answer = Class.create({
    initialize: function(aid) {
        this.aid = aid;
        this.data = new Array();
       
        this.trigger = new Hash(); // aid -> true
        this.sliderTrigger = new Hash(); // qid -> true
        this.setter = new Hash();
        this.manualSetter = false;
    },
    
    
    /**
     * Generic Data Setter
     */
    set:function(paramName,paramValue){
        this.data[paramName]=paramValue;
    },
    
    /**
     * Generatic Data Getter
     */
    get:function(paramName){
        return this.data[paramName];
    },
   
    /**
     * Returns qid of question including this answer
     * @return question id
     */
    getQuestionId:function(){
        return $$("input[value="+this.aid+"]")[0].name;
    },
   
    /* ------- TRIGGER (add reference to source) ------ */
   
    
    addTrigger: function(aid_target){
        this.trigger.set(aid_target,true);
       
    },addSliderTrigger: function(aid_target){
            this.sliderTrigger.set(aid_target,true);   
    },
            
    
    /**
     * Undo all triggers of this answer
     */
    undoTriggers:function(){

        var changedQuestions = new Array();
        var thisAnswer = this.aid;
       
        this.trigger.each(function(answer){ // loop check triggers
           
            var answerObj = LU.getAnswer(answer[0]);
            if(answerObj.getSetter() != "manual" && answerObj.setter.size() == 1){ // check if there is no manual trigger and only this trigger
                
            	// uncheck and add question to list of changed questions
            	answerObj.uncheck();
                changedQuestions.push(answerObj.getQuestionId());
            }
            answerObj.removeSetter(thisAnswer); // undo setter
        });
        
        
        this.sliderTrigger.each(function(question){ // loop slider triggers

        	var sliderQuestionId = question[0];
        	LU.getQuestion(sliderQuestionId).removeSliderSetter(thisAnswer); // remove setter to this slider
        	LU.getQuestion(sliderQuestionId).updateStatus(); // update slider; value can be changed or not; depending other setter on this slider
        });

        return changedQuestions;
    },
    
    
            
    /* ------- SETTER (add reference to target) ------ */   
            
             
    addSetter: function(aid_start){
        if(this.setter == false)
            this.setter = new Hash();
        this.setter.set(aid_start,true);
        LU.getAnswer(aid_start).addTrigger(this.aid);
    },
    
    removeSetter: function(aid){
        this.setter.unset(aid);
       
    },
    
    /**
     * Return "highest" setter. 
     * manual > trigger > {empty string=no setter to this question}
     * 
     * @return "manual"|"trigger"|""
     */
    getSetter: function(){
        if(this.manualSetter)
            return "manual";
       
        if(typeof this.setter.index(true) != "undefined"){ // search for true in setter list with aid
                return "trigger";
        }

        return "";
       
    },
    
    
    
    /**
     * Add information that answer is setted manually
     */
    setManualSetter:function(){
        this.manualSetter = true;
    },
    
    /**
     * Remove all setter (manual and triggerSetter)
     */
    resetSetter:function(){
        this.setter = false;
        this.manualSetter = false;
    },
    
    /**
     * Uncheck this answer
     */
    uncheck:function(){
        $$("input[value="+this.aid+"]")[0].checked="";
        $$("input[value="+this.aid+"]")[0].removeClassName("checked");
    },
    
    
    check:function(){}
});


if(!questionHighlightColor) {
    var questionHighlightColor = "#ffff99";
}

if(!questionHighlightDuration) {
    var questionHighlightDuration = 2;
}

var liveUpdate = Class.create({
    /////////////////////////////////////////////////////////////////////////////////////

    initialize: function(a) {
        this.ajaxRequest = null;
        this.runningEffects = 0;
        this.questions = new Array(); // list of question objects
        this.answers = new Array(); // list of answer objects
    },
    
    
    
    /**
     * Handle triggers and liveupdate
     * This function will be called in checkboxes, radio buttons and special links
     * 
     * @param t -> reference to caller dom element (a, input)
     * @param type -> type of caller question
     * @param parameter -> json string with question id and trigger information
     * @param evt -> reference to caller javascript event
     */
    
    update: function(t,type,parameter) {
    	
    	// --------------- initialize core variables -----
    	
    	// question update variables
        var livePreviewIDs = new Array(); // liveUpdate - list with updated questions
        var triggeredQuestions = new Array();

        // answer setter information
        var answerId = t.value;
        var answerObject = this.getAnswer(answerId);
        
        // get reference to question object
        var question = this.getQuestion(parameter.qid);
        
        // --------------- add caller question to list of updated questions -----
        livePreviewIDs.push(parameter.qid);
        
        // --------------- question highlighting -----
        if(question.isAnsweredQuestion() || type.indexOf("slider") != -1 ){
            question.getReference().addClassName("answeredQuestion");
        }else{
            question.getReference().removeClassName("answeredQuestion");
        }
        
        // --------------- register setter and undo previous trigger events on radio answers
        if(t.checked){ // new status of updated input (radio, checkbox) is checked
        	
            if(type.indexOf("radio") != -1){ 	// if question is radio 
            									// --> undo all trigger of sibling answers

            	// get all other unanswered radio answers in this question
            	var unansweredAnswers = this.getQuestion(parameter.qid).getUnansweredAnswerObjects(); 
                
            	// loop unanswered answers of radio question to undo triggers and get updated questions
                unansweredAnswers.each(function(answerObj){
                    var checkedQuestions = answerObj.undoTriggers(); // undo triggers on this answer
                    checkedQuestions.each(function(checkedQuestion){
                    	livePreviewIDs.push(checkedQuestion); // add all questions to update array
                    });
                });
            }
            
         // set manual trigger, so it is clear, that this element has be clicked by the user and by a trigger
            answerObject.setManualSetter(); 
           
        }else{ // new status not checked (unchecked checkbox)
            answerObject.resetSetter();
        }

        
        // --------------- SMARTDIALOG ------------------------
       
        // questions
        var questions = parameter.questions;
        if(questions){
            for(var q=0;q<questions.size();q++){
            	if(questions[q].version != 0 && questions[q].version != 10) // do not update result after "version change"
            		livePreviewIDs = livePreviewIDs.without(questions[q].qid);
            	
                this.smartDialog(t,type,questions[q]);
                $("t"+questions[q].qid).value=parameter.triggerQuestion;
                this.runningEffects++;
            }
        }
   
        // answers
        var answers = parameter.answers;
        if(answers){
            for(var a=0;a<parameter.answers.size();a++){
               
                var answerObject = this.getAnswer(answers[a].answer);
               
                if(t.type!="checkbox" || (t.type=="checkbox" && t.checked)) { // checkbox selecting or radio
                    answerObject.addSetter(answerId);
                   
                    var answerId2 = "a"+answers[a].qid+answers[a].answer;
                    $(answerId2).checked="checked";
                    $(answerId2).addClassName("checked");
                    //new Effect.Highlight($$("label[for="+answerId+"]")[0],{duration:2, restorecolor:"transparent"});
                    new Effect.Highlight($$("#question_"+answers[a].qid+" div.content_inner2")[0],{duration:questionHighlightDuration, startcolor: questionHighlightColor, restorecolor:"transparent"});
                   

                }else{
                    answerObject.removeSetter(t.value);
                   
                    if(answerObject.getSetter()==""){ // no more trigger
                        answerObject.uncheck();
                        new Effect.Highlight($$("#question_"+answers[a].qid+" div.content_inner2")[0],{duration:questionHighlightDuration, startcolor: questionHighlightColor, restorecolor:"transparent"});
                        
                    }
                }
                triggeredQuestions.push(answers[a].qid);
                livePreviewIDs.push(answers[a].qid);
                
            }
        }
       
        // slider
        var sliders = parameter.sliders;
        if(sliders){
            for(var a=0;a<parameter.sliders.size();a++){
            	
            	var sliderQuestion = this.getQuestion(sliders[a].qid);
            	var sliderManager = window["sliderManager_"+sliders[a].qid];
            	
                if(t.type != "checkbox" || (t.type=="checkbox" && t.checked)) { // checkbox selecting or radio

                    if(sliders[a].value){ // single slider
                        
                        sliderQuestion.set("triggerInAction", true);
                        
                        if(sliderQuestion.getSliderDirection() == "high2low"){
	                        if(sliderQuestion.getCurrentSingleSliderValue()  >  sliders[a].value)
	                        	sliderManager.setSingleSlider(sliders[a].value);
                        }else{ // low2high
                        	if(sliderQuestion.getCurrentSingleSliderValue()  <  sliders[a].value)
	                        	sliderManager.setSingleSlider(sliders[a].value);
                        }
                        
                        sliderQuestion.addSingleSliderSetter(t.value, sliders[a].value);
                        sliderQuestion.set("triggerInAction", false);
                    }
                    else{ // double slider
                    	
                    	sliderQuestion.set("triggerInAction", true);
                    	
                    	var currentValues = sliderQuestion.getCurrentDoubleSliderValues();                	
                    
                    	// ################ get current manual double slider trigger #################
                    	var lastTriggerValues = sliderQuestion.get("lastTriggerValues");
                    	if(lastTriggerValues == undefined ) lastTriggerValues = [,];

                    	if(currentValues[0] != lastTriggerValues[0])
                    		sliderQuestion.setDoubleSliderManualTrigger([currentValues[0],]);
                    	if(currentValues[1] != lastTriggerValues[1])
                    		sliderQuestion.setDoubleSliderManualTrigger([,currentValues[1]]);
                    	// ################ get current manual double slider trigger #################
                    	
                    	var newMin, newMax;
                    	
                    	// NO MANUAL TRIGGER CHECK - 2011-01-25
                    	//if(currentValues[0] < sliders[a].value_min) // new min value is higher than old min value
                    		newMin = sliders[a].value_min;
                    	//if(currentValues[1] > sliders[a].value_max) // new max value is lower than old max value
                    		newMax = sliders[a].value_max;

                    	sliderManager.setDoubleSlider(newMin, newMax);  

                    	sliderQuestion.set("lastTriggerValues",[newMin, newMax]);
                    	sliderQuestion.addDoubleSliderSetter(t.value, sliders[a].value_min, sliders[a].value_max);
                        sliderQuestion.set("triggerInAction", false);
                    }
                    
                    new Effect.Highlight($$("#question_"+sliders[a].qid+" div.line")[0],{duration:questionHighlightDuration, startcolor: questionHighlightColor, restorecolor:"transparent",queue: { position: "end", scope: "highlightScope" }});
                    livePreviewIDs.push(sliders[a].qid);
                    triggeredQuestions.push(sliders[a].qid);
               
                }else{
                	
                	sliderQuestion.removeSliderSetter(t.value);
                	sliderQuestion.updateStatus();
                }
            }
        }
       
        // questionReplace
        var replace = parameter.replace;
        if(replace){
            livePreviewIDs.push(replace.old);
            livePreviewIDs.push(replace.appear);
            this.questionReplace(replace.appear,replace.old);
            this.runningEffects++;
        }
        
  
        // --------------- loop all updates questions to correct css classes -----
        livePreviewIDs.uniq();
        for(var q = 0; q < livePreviewIDs.length;q++) {
        	this.updateQuestionMarking(livePreviewIDs[q]);
        }
        
        // --------------- call liveUpdate to enable update of intermediate result -----
        if(livePreviewIDs.size() > 0)
	        this.liveUpdate(livePreviewIDs);
	       
        // --------------- fire own javascript events -----
        document.fire("sis:updateQuestion");
        document.fire("sis:triggeredQuestions",triggeredQuestions);
    },
    
    
    
    /**
     * Adopt iframe height, f.e. if number of products in result has been changed
     */
    adjustIframe: function(a) {
        this.runningEffects--;
        if(typeof adjustIframe == "function" && this.runningEffects <= 0) {
            adjustIframe(false);
        }
        if(this.runningEffects < 0) this.runningEffects = 0;
    },
    
    /**
     * Set answeredQuestion-CSS class
     */
    updateQuestionMarking: function(qid){
    	
    	var question = this.getQuestion(qid);
    	if(question.isAnsweredQuestion() || question.isSliderQuestion() ){
            question.getReference().addClassName("answeredQuestion");
        }else{
            question.getReference().removeClassName("answeredQuestion");
        }
    	
    	
    },stopLoading: function(b) {
        // Stop loading ajax request
        if(this.ajaxRequest != null) {
            try{
                this.ajaxRequest.abort();
                if (Ajax.activeRequestCount < 0) {
                    Ajax.activeRequestCount = 0;
                }
            }catch( ex ){
            }
        }
        // Stop all running effects
        var queue = Effect.Queues.get("loaderscope");
        if(queue){
            queue.each(function(el){
                el.cancel();
            });   
        }
    },   
   
   
     /**
      * Toggle answers of a sequence question
      * Source - DisplayQuestions
      */
     toggleQuestionAnswers:function(qid, keepInnerHeader){

         $("question_" + qid ).down(".content").toggle();
         $$("#question_" + qid + " .toggleQuestion")[0].toggleClassName("statusShow").toggleClassName("statusHide");
         $("question_" + qid ).toggleClassName("hiddenContent");
          
          if(keepInnerHeader){
              if($("question_" + qid ).hasClassName("hiddenContent")){
                 window["sequenceQuestions_"+qid+"_height"]=$$(".sequenceQuestions")[0].style.height; // store height
                  $$(".sequenceQuestions")[0].style.height=($("question_" + qid ).down(".title").getHeight())+"px";
                  $$(".previousSequenceQuestionButton")[0].hide();
                  $$(".nextSequenceQuestionButton")[0].hide();
              }else{
                  $$(".sequenceQuestions")[0].style.height=window["sequenceQuestions_"+qid+"_height"]; // reset height
                  $$(".previousSequenceQuestionButton")[0].show();
                 $$(".nextSequenceQuestionButton")[0].show();
              }
          }
          
          // TODO not generic
          if($("question_" + qid ).hasClassName("hiddenContent")){ // hidden content
              hideInfo(qid);   
          }else{ // visible content
              showInfo(qid, $("question_" + qid ));
          }
     },
     hideQuestionAnswers:function(qid){
    	 $("question_" + qid ).down(".content").hide();
         $$("#question_" + qid + " .toggleQuestion")[0].removeClassName("statusShow").addClassName("statusHide");
         $("question_" + qid ).addClassName("hiddenContent");
     },
     showQuestionAnswers:function(qid){
    	 $("question_" + qid ).down(".content").show();
         $$("#question_" + qid + " .toggleQuestion")[0].addClassName("statusShow").removeClassName("statusHide");
         $("question_" + qid ).removeClassName("hiddenContent");
     },     
     /**
      * Source - DisplayQuestions
      */
     viewAnswerImage:function(questionid,imageurl){
        
         $("answerInfoPic_"+questionid).style.visibility="visible";
         $("answerInfoPic_"+questionid).src=imageurl;
     },
     /**
      * Source - DisplayQuestions
      */
     hideAnswerImage:function(questionid){

        var q = this.getQuestion(questionid);
        $("answerInfoPic_"+questionid).style.visibility="hidden"; 
     },
     
     
    /**
     * Source - DisplayQuestions
     */
     initializeSlider:function(qid, values, preselected_value, sliderDirection){
    
    	 this.getQuestion(qid).initializeSingleSlider(values, preselected_value, sliderDirection);
         window["sliderManager_" + qid ]  = new SliderManager(qid);

         window["slider_" + qid ] = new Control.Slider("handle_"+qid, "track_" + qid, {
        	onSlide: function(v,s) {
        	 	window["sliderManager_" + qid ].onSlide(qid,v);
         	},
        	onChange: function(v,s) { 
         		window["sliderManager_" + qid].onChange(qid,v);
         		LU.getQuestion(qid).notifySingleSlider(v);
        	},
        	values: values,
        	sliderValue:preselected_value,
            range:$R(values.first(),values.last(),false)
        });
         window["sliderManager_" + qid ].addSlider(qid,window["slider_" + qid ] ,preselected_value,$("text_" + qid ),$("answer_" + qid));	 
    },
    
    
    /**
     * Source - DisplayQuestions
     */
    initializeDoubleSlider:function(qid, values, preselected_value1, preselected_value2, minSpan){
        
       	window["sliderManager_" + qid ]  = new SliderManager(qid);
    	
        var handles = [$("handle_"+qid), $("handle_"+qid+"_2")];
        
        LU.getQuestion(qid).initalizeDoubleSlider([preselected_value1, preselected_value2]);
        
        
        
        
        window["slider_" + qid ] = new Control.Slider(handles, "track_" + qid, {
    	 	onSlide: function(v,s) { 
	     	 	window["sliderManager_" + qid ].onSlide(qid,v);
	      	},
	     	onChange: function(v,s) { 
	      		window["sliderManager_" + qid].onChange(qid,v);
	     	},
          
	     	values: values,
	     	sliderValue:[preselected_value1,preselected_value2],
          
			range:$R(values.first(),values.last(),false),
			spans:["span_"+qid],
			restricted: true
        });
           
		window["sliderManager_" + qid ].addDoubleSlider(qid,window["slider_" + qid ],preselected_value1,$("text_" + qid ),$("answer_" + qid));	 
		window["sliderManager_" + qid ].addDoubleSlider(qid+"_2",window["slider_" + qid ],preselected_value2,$("text_" + qid +"_2"),$("answer_" + qid+"_2"));	 
		window["sliderManager_" + qid ].setMinSpan(minSpan);

        
    },
    
	 /* =======================================================
	                     PRIVATE METHODS
	 ======================================================= */
	/**
	 * replaceQuestions()
	 *
	 * Change a question into another
	 *
	 * @param displayQuestionId         (number) ID of new question
	 * @param hideQuestionId         (number) ID of old question
	 *
	 * @return - NOTHING
	*/
    
    questionReplace: function(displayQuestionId,hideQuestionId){
        
    	if(!$("question_"+displayQuestionId) || !$("question_"+hideQuestionId)){
             if(typeof console != "undefined" ){
                 console.error("questionReplace function with undefined elements.");
             }
             return;
         }
    
         // start morph effect
         morph("question_"+hideQuestionId,"question_"+displayQuestionId);
    
         // change hidden version inputs
         $("v"+displayQuestionId).value=10;
         $("v"+hideQuestionId).value=0;
    
         // disable all answers in old question
         LU.disableQuestion(hideQuestionId);
    
         // enable all answers in new question
         LU.enableQuestion(displayQuestionId);

     },
    

    /**
     * update result with AJAX
     * 
     * @param livePreviewIDs -> list of changed questions
     */
    liveUpdate: function(livePreviewIDs){
    	if(!window.isLivePreview) // using livepreview functionality?
    		return; // end if no livepreview
        
    	if(!livePreviewIDs) livePreviewIDs = new Array();
        
    	this.stopLoading();
    	
		// array with attributes
		var attributes = new Array();

		for(var q = 0; q < livePreviewIDs.length;q++) {

             var question_id = livePreviewIDs[q];
             var attributeCounter = 0;
    
             // loop all values
             var result = document.getElementsByName(question_id);
    
             for(var i=0;i<result.length;i++){
                 if($F(result[i]) && !result[i].disabled){
                     attributes.push(question_id+"="+$F(result[i]));
                     attributeCounter++;
                 }
             }

             // no data
             if(attributeCounter==0){
                 attributes.push("clean="+question_id);
             }

             // get version
             if(document.getElementsByName("v"+question_id).length > 0){
                 var version = document.getElementsByName("v"+question_id)[0].value;
                 if(version){
                     attributes.push("v"+question_id+"="+version);
                 }
             }
         }

         // built url
         if(window.ajax_url_live)
             var url = ajax_url_live;
         else
             var url = "QuickResultUpdate.do?currentid="+currentid;

         if(attributes.length>0){
             url+= "&"+attributes.join("&");
         }
        
         if(document.getElementsByName("intermediateResultSortBy").length > 0){
             url += "&sortBy="+document.getElementsByName("intermediateResultSortBy")[0].value;
         }

         if(!window.newProductUpdateEffect){ // check if magic product effect should be used
         
	         // effects & ajax
	         if($("intermediateresults_loader")){
	             new Effect.Appear("intermediateresults_loader", {duration: 0.2});
	         }
	      
	         this.ajaxRequest = new Ajax.Updater(
	             "intermediateresults_result",
	             url,
	             {
	                 evalScripts:true,onSuccess:function(){
	             	
	                     if($("intermediateresults_loader")){
	                    	 
	                         new Effect.Fade("intermediateresults_loader",{
	                             duration: 0.2,
	                             afterFinish:function(){
	                       
	                                 // Adjusting Iframe Size
	                                 if(typeof adjustIframe == "function") {
	                                     adjustIframe(false);
	                                 }
	                 
	                                 // Call onIntermediateLoadFinish if exists
	                                 if(typeof onIntermediateLoadFinish == "function") {
	                                     onIntermediateLoadFinish();
	                                 }
	                             }        
	                         });
	                         
	                     }else{ // Error
	                     	if(typeof(console)!="undefined" && console.error){console.error("no intermediate result loader");}
	                     }
	                },onComplete:function(){ document.fire("sis:resultUpdate");}
	             }
	         );
	         
	         
	      //  ------------------------------------------------------------
	      //  ----------- PRODUCT CHANCE MAGIC ---------------------------
	      //  ------------------------------------------------------------
	     
         } else {
            
	         new Effect.Appear("intermediateresults_loader", {duration: 0.2});
	         
	         // get general size and dimensions
	         if(!window["animateBoxHeight"]){ 
	        	 var originalBox = $("intermediateresults_products").down(".product-wrapper");
	        	 window["animateBoxHeight"]=originalBox.getHeight();
	        	 window["animateBoxWidth"]=originalBox.getWidth();
	         }
	         
	         
	         this.ajaxRequest = new Ajax.Request(url, {
	        	  evalScripts:true,
	        	  onSuccess: function(response) {
	        	 
	        	 // Fade out loader
	        	 new Effect.Fade("intermediateresults_loader", {duration: 0.1});

	        	 // helper code to get elements from request
	        	 var div = document.createElement("div");
	        	 div.innerHTML = response.responseText;
	        	 var elements = div.childNodes;
		
		         // set css to enable relative absolute position 
		         $("intermediateresults_products").style.position="relative";
		        	 

		        	// Firefox
		        	if(Prototype.Browser.Gecko){
			        	for(var i=0;i<elements.length;i++){
			        		 if(elements[i].nodeType == elements[i].ELEMENT_NODE){
			        			 var right = elements[i];
			        		 } 
			        	 }	
		        	}else if(Prototype.Browser.IE){
		        		var right = elements.item(0);
		        	
		        	}else{
		        		$("intermediateresults_products").innerHTML=response.responseText;
		        		document.fire("sis:resultUpdate");
		        		return;
		        	}
	 
		        	var allOld = $("intermediateresults_products").getElementsBySelector(".product-wrapper");
		        	var moveElements = Element.getElementsBySelector(right, ".product-wrapper");
		        	
		        	var pos = 0;

		        	var alltime = 0;
		        	moveElements.each(function(a){
		        				
		        		var starttime = (new Date()).getTime();
			
        				 //get oid
        				 var oid = a.readAttribute("oid");;
        				
        				 // get old node				 
        				 var old =  $("intermediateresults_products").down(".product-wrapper[oid="+oid+"]");
        				 
        				 // insert into dom
        				 a.style.position="absolute";
        				 //a.style.zIndex = 100-pos;
        				 
        				 var defaultWidth = window["animateBoxWidth"];
        				 var defaultHeight = window["animateBoxHeight"];
        				 var topSpace = 0;
        				 
        				 
        				 // old position -> move to new pos
        				 if(old){
	        				var frameCorr = $("intermediateresults_products").viewportOffset();
	        				var oldCorr = old.viewportOffset();
	        				
	        				var oldLeft = oldCorr.left - frameCorr.left;
	        				var oldTop = oldCorr.top - frameCorr.top;
	        				
	        				var newLeft = (pos%3)*defaultWidth;
	        				var newTop = Math.floor(pos/3)*defaultHeight+topSpace;
	        				
	        				a.setStyle({left:oldLeft+"px",
	        							top: oldTop+"px"});
	        				

	        				$("page1").insert(a);
	        				new Effect.Move(a, { x: newLeft-oldLeft , y: newTop-oldTop , mode: "relative", duration: 0.65 });
	        				

	        			// fade in new product	
        				 }else {
        					 a.style.left = (pos%3)*defaultWidth+"px";
		        			 a.style.top = Math.floor(pos/3)*defaultHeight+topSpace+"px"; 

		        			 $("page1").insert(a);
		        			 a.fade({ from: 0, to: 1, duration:0.7 });
        				 }

        				 a.observe("mouseenter",function(){
        					 a.style.zIndex=100;
        				 });
        				 a.observe("mouseleave",function(){
        					 a.style.zIndex=10;
        				 });
        				 pos++;
        				 
        				 var resulttime = (new Date()).getTime() - starttime;
        				 alltime += resulttime;
        			 });

	        		allOld.each(function(old){
	        			old.remove();
	        		});
	         	},
	        	onComplete:function(){ document.fire("sis:resultUpdate");}
	         });
         }
     },
     
     /**
      * return a list of all questions
      */
     getAllQuestions: function(){
    	  var allQuestions = new Array();
    	  $$(".question").each(function(el){
    		  allQuestions.push(LU.getQuestion(el.id.replace("question_","")));
    	  });
    	  return allQuestions;
     },
    
    /**
     * return question object
     * @param question id
     * @return question object
     */
	getQuestion: function(qid){
	    if(this.questions[qid]) 
	    	// return existing object
	    	var question = this.questions[qid];
	    else{  
	    	// create new object
	    	if($$("#question_"+qid+".type_singleslider").size()>0 || $$("#question_"+qid+".type_doubleslider").size()>0){
	    		var question = new SliderQuestion(qid);
	    	}else{
	    		var question = new Question(qid);
	    	}			
	    	this.questions[qid] = question;
	    }
    	return question;
    },
    
    /**
     * return answer object
     * @param answer id
     * @return answer object
     */
    getAnswer: function(aid){
		if(this.answers[aid]) 
			// return existing object
		    var answer = this.answers[aid];
		else{ 
			// create new object
		    var answer = new Answer(aid);
		    this.answers[aid]=answer;
		}
    	return answer;
    },
    
    /////////////////////////////////////////////////////////////////////////
    setAnswer: function(ao){
    	alert("Error: unused method - please contact system administrator!");
    	//this.answers[ao.aid]=ao;
    },
    /////////////////////////////////////////////////////////////////////////
     
    /* ----- SmartDialog ------------- */
    smartDialog: function(t,type,question){
        changeVersion(t,question.qid,question.version,question.preVersion,type);   
    },
    disableQuestion: function(qid){
        $$("#question_"+qid+" input").each(function(elem){
            elem.disabled="disabled";
            elem.checked=false;
        });
    },
    enableQuestion: function(qid){
        $$("#question_"+qid+" input").each(function(elem){
            elem.disabled="";
        });
    }
});


/////////////////////////////////////////////////////////////////


// create global instance
var LU = new liveUpdate();




/**
* changeVersion()
*
* Handles dynamic change of question version.
* 0 or 10 = show or hide whole question
* !(0 or 10) = add or remove answers
*
* @param t                 (object) reference to input
* @param questionID     (number) question ID
* @param version         (number) new version
* @param preVersion     (number) initial version
* @param type            (String) type of question (radio, checkbox_pic, ...
*
* @return - NOTHING
*/

function changeVersion(t,questionID,version,preVersion,type){

    if(t.type=="checkbox" && !t.checked){ // checkbox deselecting -> set question to preVersion
        version=preVersion;
    }

    if(version==10){ // show question
    	// caused bug in IE9 - not really necessary
        //$("question_"+questionID).style.opacity="0.0";
    	
        // reset overflow hack
        $("question_"+questionID).addClassName("displayedQuestion");
        
        /********* new and untested (slider disappearing content bugfix - only works for replace-questions of the same height) *********/
    	if($$("#question_" + questionID + " .content")[0].getStyle("opacity") < 1) {
        	$$("#question_" + questionID + " .content")[0].setStyle({"opacity":1});
        }
        /********* new and untested *********/

        // appear effect
        Effect.Appear("question_"+questionID,{from:0.0,duration:0.4,
                    afterFinish:function(){
                        LU.adjustIframe();
                     }
        });

        // enable question value inputs
        LU.enableQuestion(questionID);

    }else if(version==0){ // hide question
       
        $("question_"+questionID).removeClassName("displayedQuestion");
       
        // fade effect
        Effect.Fade("question_"+questionID,{duration:0.2,
                    afterFinish:function(){
                        LU.adjustIframe();
                     }
        });

        // disable all value inputs
        LU.disableQuestion(questionID);

    }   
    else{ // version != 0 && 10
    	
        // show question, if hidden
        if($("question_"+questionID).hasClassName("displayedQuestion") == false){
            changeVersion(t,questionID,10,preVersion,type); // TODO could be better ...
        }
       
        // get ALL answers in the question
        var allElems = $$(".answer_"+questionID);
        allElems.each(function(elem){ // loop answers

            // get current visibility
            var display = elem.style.display == "" ? "block" : elem.style.display;

            // get answer input reference
            var input = elem.getElementsByTagName("input")[0];
            if(type.search("_pic") != 1)
                input = elem.lastChild;

            if(display == "block" && !elem.hasClassName("answer_"+questionID+"_"+version)){ // element will be hidden
               
                if(!elem.hasClassName("specialAnswer")){
                    Effect.Fade(elem,{duration:0.4,to:0.0,
                        afterFinish:function(){
                            LU.adjustIframe();
                         }
                    }); // fade effect
                }else{
                    elem.style.display = "none";
                }
               
                input.disabled="disabled"; // disable hidden answers
                input.checked = false;
            }else if (display == "none" && elem.hasClassName("answer_"+questionID+"_"+version)){ // element will be displayed
               
                if(!elem.hasClassName("specialAnswer")){
                    Effect.Appear(elem,{duration:0.4,from:0.1,to:1.0,
                        afterFinish:function(){
                            LU.adjustIframe();
                         }
                    }); // appear effect
                }else{
                    elem.style.display = "block";
                }
               
                input.disabled=""; // enable displayed answers
            }
        });

    }

    // set new version in hidden version field
    $("v"+questionID).value=version;
   
}


/**
 * Handles interaction for question replace.
 * 1.) fade out answers of question before
 * 2.) resize height to dimensions of question after & change question text
 * 3.) fade in answers of question after
 * 
 * @param id_before - html id of question before
 * @param id_after - html id of question after
 * @return
 */
function morph(id_before, id_after){
	
    // get all elements
    var before = $(id_before);
    var after =  $(id_after);	
	
    // get all elements
    var before = $(id_before);
    var after =  $(id_after);

    if(!after || !before){
        if(typeof console != "undefined"){
            console.error("Morph function with undefined elements.");
        }
        return;
    }
   
    after.addClassName("displayedQuestion");
    after.style.display="none";
    after.style.overflow="";
    after.style.height="auto";


    var before_content = $$("#"+id_before+" .content")[0];
    var after_content = $$("#"+id_after+" .content")[0];

    // get heights
    var height_before = before.getHeight();
    var height_after = after.getHeight();
    
    var scale = 0;
    
    // check if height_before is null, otherwise there would be division / 0 that causes errors
    if(height_before > 0) {
    	scale = Math.round((height_after/height_before)*100);
    } 

    new Effect.Fade(before_content,{duration:0.2,to:0.01,afterFinish:function(){
    	 // TODO: check if this has any effects (scale makes problems on triggers, which trigger smaller or bigger questions
         //new Effect.Scale(before,scale,{scaleX:false,duration:0.2,afterFinish:function(){
            before.style.display="none";
            after.style.display="block";
           
            before.addClassName("hiddenQuestion");
            after.removeClassName("hiddenQuestion");
            
            if(!Prototype.Browser.IE){ // nice fade-in effect for all nun IE6-Browsers
                 new Effect.Appear( after_content,{from:0.01,to:1.0,duration:0.4,
                     afterFinish:function(){
                        LU.adjustIframe();
                     }
                 });
            }else{ // Because of an internet explorer bug, the font became unreadable.
                 after_content.setStyle({"opacity":1});
                 LU.adjustIframe();
            }
         //}});
     }});
     after.style.fontSize="";         
}




/**
 * Adopts visibility of question depending on their state in hidden fields
 * 
 */
document.observe("dom:loaded",function() {
    var questions = $$(".question");
    questions.each(function(q){
       
    	
    	var id = q.id.replace("question_","");
        if($("v"+id))
            var version = $("v"+id).value;
        else
            var version = "";


        // hide and show questions depending their version in hidden field
        if(version != ""){
            //alert(id + " " + version);
            if(version==10){
                q.addClassName("displayedQuestion");
            }else if(version==0){
                q.style.display="none";
            }else{
                $$(".answer_"+id).each(function(elem){ // get ALL answers and hide these
                    elem.style.display="none";
                    var checkbox = elem.firstChild.firstChild;
                    checkbox.disabled="disabled";
                });

                $$(".answer_"+id+"_"+version).each(function(elem){ // show all version questions
                    elem.style.display="block";
                    var checkbox = elem.firstChild.firstChild;
                    checkbox.disabled="";
                });
            }
        }
        
        // set slider correctly
        var question = LU.getQuestion(id);
        var type = question.getType();
        
        if(type == "singleslider"){
        	var value1 = $("answer_"+id).value;
        	window["sliderManager_" + id ].setSingleSlider(value1);
        }else if(type == "doubleslider"){
        	var value1 = $("answer_"+id).value;
        	var value2 = $("answer_"+id+"_2").value;
        	window["sliderManager_" + id ].setDoubleSlider(value1, value2);
        }

    });
});



///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////




function previousSequenceQuestion(sequenceQuestion){
    $$$("#question_"+sequenceQuestion+" .sequenceQuestions").retrieve("sequenceBox").previous();
}
function nextSequenceQuestion(sequenceQuestion){
    $$$("#question_"+sequenceQuestion+" .sequenceQuestions").retrieve("sequenceBox").next();
}
document.observe("dom:loaded",function() {
    if($$(".sequenceQuestions").length > 0){
        var box = new SequenceBox($$$(".sequenceQuestions"),".question", $("sequenceQuestionPageInfo"), "previousSequenceQuestionButton","nextSequenceQuestionButton");
        $$$(".sequenceQuestions").store("sequenceBox",box);
    }
});

// Optimize Box Height again (specially for safari)
Event.observe(window,"load",function() {
    if($$(".sequenceQuestions").length > 0){
        if($$$(".sequenceQuestions").retrieve("sequenceBox"))
        	$$$(".sequenceQuestions").retrieve("sequenceBox").setHeight();
    }
});



////////////// picAnswer ///////////////////////////////////


// for questions of type checkbox_pic_click or radio_pic_click
function picAnwerChanged(qid){
    $$("input[name="+qid+"]").each(function(input){       
        if(input.checked)
            $$("label[for="+input.id+"] > img")[0].addClassName("answerPicChecked");
        else
            $$("label[for="+input.id+"] > img")[0].removeClassName("answerPicChecked");

    });
}


var compareOverlay = false;
if(!comparePopupWidth){
    var comparePopupWidth=794;
}
var comparePopupHeight=650;
var comparePopupParameter="scrollbars=no,status=no,toolbar=no,location=no,directories=no,resizable=no,menubar=no";

function compareProducts(formName){

    var formName = formName ? formName : "consresult";
    
        var xpos=(screen.width-comparePopupWidth)/2;
        var ypos=(screen.height-comparePopupHeight)/2;
        if(xpos<1) xpos=1;
        if(ypos<1) ypos=1;
        var comparewindow=window.open("", "smartcompare", comparePopupParameter + ",width="+comparePopupWidth+",height="+comparePopupHeight+",screenX="+xpos+",screenY="+ypos+",top="+ypos+",left="+xpos);
        
        
        
        var oldTarget = document[formName].target;
        document[formName].target="smartcompare";
        try {
            comparewindow.opener = top;
        } catch(ex) {
            // do nothing
        }
        comparewindow.focus();
       
   
    document[formName].submit();
    document[formName].target = oldTarget;
    
    
    return false;
}
