////////////////////////////////////////////////////////////////////////////////
//
// Dave Ramsey Ask Dave Widget
//
// Authors: Ken Pruiksma (with some inspiration from Phil Harvey ;) )
// Date: July 2009
// Copyright (c) The Lampo Group, Inc. All rights reserved.
// http://www.daveramsey.com
//
////////////////////////////////////////////////////////////////////////////////

var lampo = lampo || {}; // preserve the lampo namespace if it already exists

lampo.util = {
	loadCSS: function(url) {
		var head = document.getElementsByTagName('head')[0];
		var l = document.createElement('link');
		l.rel = 'stylesheet';
		l.type = 'text/css';
		l.href = url;
		head.appendChild(l);
	},
	mergeHash: function(dest, source) {
		for(var property in source) {
			dest[property] = source[property];
		}
		return dest;
	},
	getOptions: function(options, defaults) {
		return lampo.util.mergeHash(defaults || {}, options || {});
	}
};

lampo.browser = {
	IE: !!(window.attachEvent && !window.opera)
};

// IE fix for indexOf()
if(!Array.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
                return i;
            }
        }
        return -1;
    }
}

lampo.Delegate = function() {}
lampo.Delegate.create = function (o, f) {
	var a = new Array() ;
	var l = arguments.length ;
	for(var i = 2 ; i < l ; i++) a[i - 2] = arguments[i] ;
	return function() {
		var aP = [].concat(arguments, a) ;
		f.apply(o, aP);
	}
}

lampo.animation = {
	Tween: function(object, property, easingFunc, from, to, duration, interval, callback, unit) {
		this.init(object, property, easingFunc, from, to, duration, interval, callback, unit);
	},
	clearTween: function(tweenNum) {
		if (tweenNum) {
			clearInterval(tweenNum);
			if (activeTweens.indexOf(tweenNum) > -1){
				activeTweens.splice(activeTweens.indexOf(tweenNum), 1);
			}
		} else {
			for (var i = activeTweens.length; i >= 0; i--){
				clearTween(activeTweens.pop());
			};
		}
	},
	activeTweens: new Array(),
	
	easeLinear: function(percent) {
		return percent;
	},
	easeOut: function(t) {
		t--;
		return (t * t * t + 1);
	},
	easeIn: function(t) {
		return (t * t * t);
	},
	easeInOut: function(t) {
		if (t <= .5){
			return lampo.animation.easeIn(t * 2) / 2;
		} else {
			t -= .5;
			return .5 + lampo.animation.easeOut(t * 2) / 2;
		}
	}
	
}

lampo.animation.Tween.prototype = {
	activeTweens: new Array(),
	init: function(object, property, easingFunc, from, to, duration, interval, callback, unit){
		this.object = object;
		this.property = property;
		this.easingFunc = easingFunc;
		this.from = parseFloat(from);
		if (isNaN(this.from)) this.from = 0;
		this.to = parseFloat(to);
		if (isNaN(this.to)) this.to = 0;
		this.duration = duration;
		this.interval = interval || 50;
		this.callback = callback;
		this.unit = unit || "px";
		this.currentTime = 0;
		this.killDupes();
		this.activeTweens.push(this);
	},
	start: function() {
		this.id = setInterval(lampo.Delegate.create(this, this.tick), this.interval);
	},
	stop: function() {
		clearInterval(this.id);
	},
	die: function() {
		this.stop();
		for (var i = 0; i < this.activeTweens.length; i++) {
			if (this.activeTweens[i] == this) {
				this.activeTweens.splice(i, 1);
			}
		}
		delete this.object;
	},
	tick: function() {
		this.currentTime += this.interval;
		var percentDone = this.easingFunc(this.currentTime / this.duration);
		if (percentDone >= 1){
			percentDone = 1;
			this.stop();
			if (this.callback){
				this.callback();
			}
		}
		this.setPosition(this.from + (this.to - this.from) * percentDone);
	},
	setPosition : function(p){
		this.object.style[this.property] = p + this.unit;
	},
	killDupes : function(){
		for (var i = 0; i < this.activeTweens.length; i++){
			var tween = this.activeTweens[i];
			if (tween.object == this.object && tween.property == this.property){
				tween.die();
			}
		}
	}
}

lampo.ask_dave = {
	Widget: function(options){
		this.options = lampo.util.getOptions(options, lampo.ask_dave.Widget.defaults);
		this.dontAnimate = !this.options.animate;
		this.type = this.options.type;
		this.width = this.type == 'sidebar' ? 150 : 250;
		this.height = this.type == 'sidebar' ? 201 : 173;
		this.baseUrl = this.options.baseUrl;
		lampo.util.loadCSS(options.stylesheet);
		
		this.buildDOM();
		
		this.open = false;
		this.animating = false;
		//this.render();
	}
};

lampo.ask_dave.Widget.prototype = {
	open: Boolean = false,
	element: {},
	page: Number = 1,
	xmlhttp: null,
	baseUrl: "",
	questionText: "Type your question here.",
	buildDOM: function() {
		
		/* 	Write a div tag out to the document, in place, as an
			 anchor, and get a reference to it */
		
		var CSS = lampo.ask_dave.Widget.CSS.Elements;
		var CSS_Class = lampo.ask_dave.Widget.CSS.Classes;
		
		document.write('<div id="' + CSS.Widget + '"></div>');
		var widgetDiv = document.getElementById(CSS.Widget);
		/* Using DOM functions, create all the necessary elements
			on the fly and add it to the first div */
		
		var widgetPulldownDiv = this.buildElement('div', CSS.WidgetPulldown, CSS_Class.WidgetPulldown);
		var widgetSlider = this.buildElement('div', CSS.WidgetSlider);
		
		var widgetFrames = [];
		for (var i = 0; i < 4; i++){
			var frame = this.buildElement('div', CSS["WidgetFrame" + (i + 1)], CSS_Class.WidgetFrame);
			widgetFrames.push(frame);
			widgetSlider.appendChild(frame);
		}
		
		// Frame 1
		var nameInputWrapper = this.buildElement('div', CSS.WidgetFieldNameWrapper, CSS_Class.WidgetFieldLarge);
		var nameInput = this.buildElement('input', CSS.WidgetFieldName, undefined, {type: "text", name: "name", value: "Name"});
		nameInput.onclick = this.clearValue;
		nameInputWrapper.appendChild(nameInput);
		
		var emailInputWrapper = this.buildElement('div', CSS.WidgetFieldEmailWrapper, CSS_Class.WidgetFieldLarge);
		var emailInput = this.buildElement('input', CSS.WidgetFieldEmail, undefined, {type: "text", name: "email", value: "Email"});
		emailInput.onclick = this.clearValue;
		emailInputWrapper.appendChild(emailInput);

		var cityInputWrapper = this.buildElement('div', CSS.WidgetFieldCityWrapper, CSS_Class.WidgetFieldMedium);
		var cityInput = this.buildElement('input', CSS.WidgetFieldCity, undefined, {type: "text", name: "city", value: "City"});
		cityInput.onclick = this.clearValue;
		cityInputWrapper.appendChild(cityInput);
		
		var stateInput = this.buildElement('select', undefined, CSS_Class.WidgetFieldSelect, {name: "state"});
		var states = ['State','AK','AL','AR','AZ','CA','CO','CT','DC','DE','FL','GA','HI','IA','ID','IL','IN','KS','KY','LA','MA','MD','ME','MI','MN','MO','MS','MT','NC','ND','NE','NH','NJ','NM','NV','NY','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VA','VT','WA','WI','WV','WY']
		for (var i = 0; i < states.length; i++){
			var option = this.buildElement('option', undefined, undefined, {value: states[i]});
			option.innerHTML = states[i];
			stateInput.appendChild(option);
		}
		var stateInputWrapper = this.buildElement('div', CSS.WidgetFieldState, CSS_Class.WidgetFieldSelectWrapper);
		stateInputWrapper.appendChild(stateInput);
		var next1 = this.buildElement('a', CSS.WidgetNext1, CSS_Class.WidgetNext, {href: '#'});
		widgetFrames[0].appendChild(nameInputWrapper);
		widgetFrames[0].appendChild(emailInputWrapper);
		widgetFrames[0].appendChild(cityInputWrapper);
		widgetFrames[0].appendChild(stateInputWrapper);
		widgetFrames[0].appendChild(next1);
		
		// Frame 2
		var counter = this.buildElement('div', CSS.WidgetQCharCounter);
		counter.innerHTML = "500 Characters Remaining";
		
		var questionInputWrapper = this.buildElement('div', CSS.WidgetFieldQuestionWrapper, CSS_Class.WidgetFieldTextArea);
		var questionInput = this.buildElement('textarea', CSS.WidgetFieldQuestion, undefined);
		questionInput.innerHTML = this.questionText;
		questionInput.onclick = this.clearValue;
		questionInputWrapper.appendChild(questionInput);
		
		var next2 = this.buildElement('a', CSS.WidgetNext2, CSS_Class.WidgetNext, {href: '#'});
		widgetFrames[1].appendChild(counter);
		widgetFrames[1].appendChild(questionInputWrapper);
		widgetFrames[1].appendChild(next2);
		
		// Frame 3
		var signupText = this.buildElement('div', undefined, CSS_Class.WidgetTextSignup);
		var check1 = this.buildElement('input', CSS.WidgetFieldCheck1 ,CSS_Class.WidgetFieldCheckBox ,{type: 'checkbox', name: 'check1', checked: 'checked'});
		var check2 = this.buildElement('input', CSS.WidgetFieldCheck2 ,CSS_Class.WidgetFieldCheckBox ,{type: 'checkbox', name: 'check2', checked: 'checked'});
		var submitButton = this.buildElement('a', CSS.WidgetSubmit, undefined, {href: '#'} );
		widgetFrames[2].appendChild(signupText);
		widgetFrames[2].appendChild(check1);
		widgetFrames[2].appendChild(check2);
		widgetFrames[2].appendChild(submitButton);
		
		// Frame 4
		var thanksText = this.buildElement('div', undefined, CSS_Class.WidgetTextThanks);
		var closeLink = this.buildElement('a', undefined, CSS_Class.WidgetLinkClose, {href: '#'});
		closeLink.innerHTML = "close"
		widgetFrames[3].appendChild(thanksText);
		widgetFrames[3].appendChild(closeLink);
		
		var closeButton = this.buildElement('a', undefined, CSS_Class.WidgetCloseButton, {href: '#'});
		
		widgetPulldownDiv.appendChild(widgetSlider);
		widgetPulldownDiv.appendChild(closeButton);
		
		var widgetHeader = document.createElement('div');
		widgetHeader.className = CSS_Class.WidgetHeader;
		
		// Hook in the events
		widgetHeader.onclick = this.toggle;
		closeButton.onclick = this.toggle;
		next1.onclick = this.next;
		next2.onclick = this.next;
		submitButton.onclick = this.submit;
		questionInput.onkeypress = this.restrictQuestionLength;
		questionInput.onkeyup = this.updateQuestionCharacterLength;
		nameInput.onblur = this.checkName;
		emailInput.onblur = this.checkEmail;
		cityInput.onblur = this.checkCity;
		questionInput.onblur = this.checkQuestion;
		closeLink.onclick = this.toggle;
		
		// set pages that can't be seen as invisible so they can't get focus
		widgetFrames[1].style.visibility = "hidden";
		widgetFrames[2].style.visibility = "hidden";
		widgetFrames[3].style.visibility = "hidden";
		
		widgetDiv.appendChild(widgetPulldownDiv);
		widgetDiv.appendChild(widgetHeader);
		
		// IE bug: checked must be set after the element is rendered.
		check1.checked = true;
		check2.checked = true;
		
		// References
		this.element = widgetDiv;
		this.element.pulldown = widgetPulldownDiv;
		this.element.slider = widgetSlider;
		this.element.frames = widgetFrames;
		this.element.qCounter = counter;
		this.field = {};
		this.field.name = nameInput;
		this.field.email = emailInput;
		this.field.city = cityInput;
		this.field.state = stateInput;
		this.field.stateWrapper = stateInputWrapper;
		this.field.question = questionInput;
		this.field.check1 = check1;
		this.field.check2 = check2;
		
	},
	buildElement: function(type, id, className, props) {
		var element = document.createElement(type);
		if (id != undefined) element.id = id;
		if (className != undefined)	element.className = className;
		if (props != undefined) {
			for (var propname in props){
				element[propname] = props[propname];
			}
		}
		return element;
	},
	tweenTest: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		var tween = new lampo.animation.Tween(widget.element, "width", lampo.animation.easeOut, 400, 600, 3000, 10);
		tween.start();
	},
	toggle: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		if (widget.open){
			var tween = new lampo.animation.Tween(widget.element.pulldown, "height", lampo.animation.easeOut, widget.element.pulldown.style.height, 0, 300, 20);
			tween.start();
			widget.open = false;
		} else {
			var tween = new lampo.animation.Tween(widget.element.pulldown, "height", lampo.animation.easeOut, widget.element.pulldown.style.height, widget.height, 300, 20);
			tween.start();
			widget.open = true;
		}
		return false;
	},
	next: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		if (widget.validate()) {
			widget.nextPage();
		}
		return false;
	},
	nextPage: function() {
		this.element.frames[this.page].style.visibility = "visible";
		this.page++;
		var tween = new lampo.animation.Tween(this.element.slider, "left", lampo.animation.easeInOut, this.element.slider.style.left, (this.page - 1) * -this.width, 300, 20, this.hideOld);
		tween.start();
	},
	hideOld: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		widget.element.frames[widget.page - 2].style.visibility = "hidden";
	},
	validate: function() {
		var returnValue = true;
		//return true;
		switch(this.page){
			case 1:
				var name = this.field.name;
				if (name.value == "Name" || name.value == ""){
					returnValue = false;
					this.markError(name);
				} else {
					this.unmarkError(name);
				}
				
				var email = this.field.email;
				var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
				if (!filter.test(email.value)) {
					returnValue = false;
					this.markError(email);
				} else {
					this.unmarkError(email);
				}
				
				var city = this.field.city;
				if (city.value == "City" || city.value == ""){
					returnValue = false;
					this.markError(city);
				} else {
					this.unmarkError(city);
				}
				
				var state = this.field.state;
				if (state.value == "State"){
					returnValue = false;
					this.markError(state);
				} else {
					this.unmarkError(state);
				}
				break;
			case 2:
				var question = this.field.question;
				if (question.value == "Type your question here." || question.value == ""){
					returnValue = false;
					this.markError(question);
				} else {
					this.unmarkError(question);
				}
				break;
		}
		return returnValue;
	},
	retFalse: function() {
		return false;
	},
	submit: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		this.onclick = widget.retFalse;
		
		var script = document.createElement("script")
	    script.type = "text/javascript";
		var callback = widget.submitResult();
	
	    if (script.readyState){  //IE
	        script.onreadystatechange = function(){
	            if (script.readyState == "loaded" ||
	                script.readyState == "complete"){
	                script.onreadystatechange = null;
	                callback();
	            }
	        };
	    } else {  //Others
	        script.onload = function(){
	            callback();
	        };
	    }
	
		var url = widget.baseUrl + "/widgets/process.widget.ask.dave";
		var postString = 
			"name=" + escape(widget.field.name.value) + 
			"&email=" + escape(widget.field.email.value) +
			"&city=" + escape(widget.field.city.value) +
			"&state=" + escape(widget.field.state.value) +
			"&question=" + escape(widget.field.question.value) +
			"&zanderSignup=" + escape(widget.field.check1.value) +
			"&drSignup=" + escape(widget.field.check2.value);
		
		if (url.indexOf("?") == -1){
			url += "?" + postString;
		} else {
			url += "&" + postString;
		}
		
	    script.src = url;
	    document.getElementsByTagName("head")[0].appendChild(script);
		
		return false;
	},
	restrictQuestionLength: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		widget.updateQuestionCharacterLength();
		return (this.value.length < 500);
	},
	updateQuestionCharacterLength: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		widget.element.qCounter.innerHTML = ((widget.field.question.value == widget.questionText) ? 500 : 500 - widget.field.question.value.length) + " Characters Remaining";
	},
	submitResult: function() {
		var widget = lampo.ask_dave.Widget.getInstance();
		widget.nextPage();
	},
	clearValue: function() {
		var elements = lampo.ask_dave.Widget.CSS.Elements;
		switch (this.id) {
			case elements.WidgetFieldName:
				if (this.value == "Name") this.value = "";
				break;
			case elements.WidgetFieldEmail:
				if (this.value == "Email") this.value = "";
				break;
			case elements.WidgetFieldCity:
				if (this.value == "City") this.value = "";
				break;
			case elements.WidgetFieldQuestion:
				if (this.value == "Type your question here.") this.value = "";
				break;
		}
	},
	checkName: function() {
		this.value = (this.value == "") ? "Name" : this.value;
	},
	checkEmail: function() {
		this.value = (this.value == "") ? "Email" : this.value;
	},
	checkCity: function() {
		this.value = (this.value == "") ? "City" : this.value;
	},
	checkQuestion: function() {
		this.value = (this.value == "") ? "Type your question here." : this.value;
	},
	markError: function(element) {
		element.parentNode.style.border = "1px solid red";
		element.parentNode.style.padding = "2px";
	},
	unmarkError: function(element){
		element.parentNode.style.border = "";
		element.parentNode.style.padding = "3px";
	}
};
lampo.ask_dave.Widget.getInstance = function() {
	return window.ask_dave_widget;
};
lampo.ask_dave.Widget.defaults = {
	stylesheet: '',
	type: 'standard'
};
lampo.ask_dave.Widget.CSS = {
	Classes: {
		Body: 'dr_ask_dave_body',
		WidgetPulldown: 'dr_ask_dave_pulldown_closed',
		WidgetFrame: 'dr_ask_dave_frame',
		WidgetHeader: 'dr_ask_dave_header',
		WidgetFieldLarge: 'dr_ask_dave_field_large',
		WidgetFieldMedium: 'dr_ask_dave_field_medium',
		WidgetFieldSelect: 'dr_ask_dave_field_select',
		WidgetFieldSelectWrapper: 'dr_ask_dave_field_select_wrapper',
		WidgetFieldTextArea: 'dr_ask_dave_field_textarea',
		WidgetFieldCheckBox: 'dr_ask_dave_checkbox',
		WidgetNext: 'dr_ask_dave_next',
		WidgetTextSignup: 'dr_ask_dave_signup_text',
		WidgetTextThanks: 'dr_ask_dave_thanks_text',
		WidgetCloseButton: 'dr_ask_dave_close_button',
		WidgetLinkClose: 'dr_ask_dave_close_link'
	},
	Elements: {
		Widget: 'dr_ask_dave',
		WidgetPulldown: 'dr_ask_dave_pulldown',
		WidgetSlider: 'dr_ask_dave_slider',
		WidgetFrame1: 'dr_ask_dave_frame1',
		WidgetFrame2: 'dr_ask_dave_frame2',
		WidgetFrame3: 'dr_ask_dave_frame3',
		WidgetFrame4: 'dr_ask_dave_frame4',
		WidgetFieldName: 'dr_ask_dave_name',
		WidgetFieldNameWrapper: 'dr_ask_dave_name_wrapper',
		WidgetFieldEmail: 'dr_ask_dave_email',
		WidgetFieldEmailWrapper: 'dr_ask_dave_email_wrapper',
		WidgetFieldCity: 'dr_ask_dave_city',
		WidgetFieldCityWrapper: 'dr_ask_dave_city_wrapper',
		WidgetFieldState: 'dr_ask_dave_state',
		WidgetQCharCounter: 'dr_ask_dave_qchar_counter',
		WidgetFieldQuestion: 'dr_ask_dave_question',
		WidgetFieldQuestionWrapper: 'dr_ask_dave_question_wrapper',
		WidgetFieldCheck1: 'dr_ask_dave_check1',
		WidgetFieldCheck2: 'dr_ask_dave_check2',
		WidgetNext1: 'dr_ask_dave_next1',
		WidgetNext2: 'dr_ask_dave_next2',
		WidgetSubmit: 'dr_ask_dave_submit'
		
	}
};

window.ask_dave_widget = new lampo.ask_dave.Widget({
	baseUrl: '//www.daveramsey.com'
	
		,stylesheet: '//www.daveramsey.com/widgets/widget.ask.dave.sidebar.css',
		type: 'sidebar'
		
});