// Modal Visitor Poll v. September 07, 2011
// in this release:
// - only async code
// - works for both timer and load
// - works for all stationary browsers, blocking several mobile
// - free text in separate folder for answers /other/free/
// - questions are numbered /Q1/, /Q2/ - for up to five questions
/* Change Log
   - 2011-09-07: Always block IE6
   - 2011-09-06: Consecutive questions will only be displayed during the same session
*/

var ModalVisitorPoll = function(id, language) {
	var settings = {
		displayFrequency: 100,
		cookieExpireDays: 30,
		currentForm: null,
		forms: [],
		loaded: false,
		userParticipate: true,
		formPreviouslyDisplayed: false,
		precedingForm: true,
		noPrecedingForm: true,
		closeRedirectUrl:  null,
		formIsVisible: false,
		answered: false,
		languageCode: language,
		loadingText: {"en" : "The questionnaire is loading.",
					  "nb" : "Laster opp sp&#248;rreskjemaet.",
					  "de" : "Ihre Antworten werden &#252;bermittelt.",
					  "nl" : "De vragenlijst wordt geladen.",
					  "ru" : "Анкета загружается",
					  "es" : "Cargando el cuestionario",
					  "da" : "Loader unders&#248;gelse",
					  "it" : "Sta caricando il questionario...",
					  "fr" : "Le questionnaire est en cours de chargement&#8230;",
					  "fi" : "Kysely latautuu"}
	};
	



	var waiting = false;
	var sla = [];
	
	function init() {
		jQuery(function() {
			jQuery.get("/ModalVisitorPoll/config-" + settings.languageCode + ".xml", load);
		});
	}
	
	function settingsLoaded(func) {
		if(typeof(func) == "undefined" && settings.loaded) {
			for(var i = 0; i < sla.length; i++) {
				sla[i]();
			}
		}
		else
		{
			sla.push(func);
		}
	}
	
	function load(data) {
		
		// Block mobile browsers and IE6
		var agent = navigator.userAgent.toLowerCase();
		if(agent.match("msie 6|iphone|blackberry|nokia|palm|symbian|android|opera mini|s60|htc2|mobile|sonyericsson")) {
			return;
		}

		var displayFrequency = jQuery(data).find("poll").attr("displayFrequency");
		var cookieExpireDays = jQuery(data).find("poll").attr("cookieExpireDays");
		if(displayFrequency != "") {
			settings.displayFrequency = displayFrequency;
		}
		if(cookieExpireDays != "") {
			settings.cookieExpireDays = cookieExpireDays;
		}
		
		// Check if the visitor should participate in the poll
		settings.userParticipate = participateCheck();
		if(!settings.userParticipate) {
			return;
		}
		
		// Load all qustionnaires
		loadForms(data);
		
		// Check that the form hasn't been displayed before
		settings.formPreviouslyDisplayed = formPreviouslyDisplayed();
		// Check preceding questionnarie
		settings.precedingForm = precedingFormCheck();
		// Check reversed preceding questionnaire
		settings.noPrecedingForm = noPrecedingFormCheck();
		
		// All settings are loaded
		settings.loaded = true;
		settingsLoaded();
		
		// Initalize Coookie
		var cookie = new Cookie(settings.currentForm.id, settings.cookieExpireDays);
		if(!cookie.load()) {
			cookie.setVal("state", "init");
			cookie.save();
		}
		
		// Display the form now or later
		if(settings.currentForm.displayEvent == "load") {
			showForm();
		}
		else if(settings.currentForm.displayEvent == "timer") {
			setTimeout(function() { showForm(); }, getDisplayDelay());
		}
		else if(settings.currentForm.displayEvent == "leave") {
			attachLinkEvent();
		}
		else if(settings.currentForm.displayEvent == "wait") {
			waiting = true;
			setInterval(function() { waitAndShow(); }, 250);
		}
	}

	function waitAndShow() {
		if (waiting && precedingFormCheck()) {
			waiting = false;
			showForm();
		}
	}

	function isFirstForm() {
		var firstFormId = '';
		$(settings.forms).each(function(){
		    if(typeof this.precedingForm !== "string") {
		    	firstFormId = this.id;
		        return false;
		    }
		});
		return settings.currentForm.id === firstFormId;
	}

	function isFirstFormSession() {
		var sessionCookie = new Cookie('modalVisitorPollSession');
		var isSameSessionAsFirstForm = sessionCookie.load();
		return isSameSessionAsFirstForm;		
	}

	function showForm() {
		if(!precedingFormCheck() || !noPrecedingFormCheck() || settings.formPreviouslyDisplayed) {
			return;
		}
		if(!isFirstForm() && !isFirstFormSession()) {
			return; // Not on the same session as the first form. Abort.
		}

		if(!self._mvcFormVisible) {
			jQuery(document).ready(function() {
				jQuery('<div id="MVPjqm" class="jqmWindow" />').prependTo('body')
					.jqm({ ajax: settings.currentForm.src, 
						ajaxText: settings.loadingText[settings.languageCode], 
						modal: false, 
						onLoad: initForm, 
						onHide: closeForm })
					.jqmShow();
				self._mvcFormVisible = true;
			});
		}
	}
	
	// Event to run when the window is initialized
	function initForm() {
		// The form should never be displayed more than once
		// TODO: Custom var ska sättas - användare exponerad
		updateCookieState("displayed");
		settings.formPreviouslyDisplayed = true;
		document.cookie = 'modalVisitorPollSession=|';
		
		jQuery("form#MVPVisitorPollForm").submit(function() { return false; });
		jQuery("#MVPjqm").jqmAddClose("#MVPClose"); 
		jQuery("input[type=radio]", "form#MVPVisitorPollForm").click(function() {
			if (jQuery(this).attr("class") == "MVPFreeTextChoice")
				jQuery("#" + jQuery(this).attr("name") + "FreeText").removeAttr("disabled").focus();
			else
				jQuery("#" + jQuery(this).attr("name") + "FreeText").attr("disabled", "disabled");
			jQuery("input[name=" + jQuery(this).attr("name") + "]", "form#MVPVisitorPollForm").each(function() { jQuery(this).attr("clicked", "true"); });
			if (isCompleted()) { 
				jQuery("#MVPSubmitButton").removeAttr("disabled").attr("src", "/ModalVisitorPoll/Images/submit-" + settings.languageCode + ".gif").attr("class", "MVPActiveButton");
			}
		});
		jQuery("select", "form#MVPVisitorPollForm").change(function() {
			jQuery(this).children("option").attr("clicked", "true");
			if (isCompleted()) { 
				jQuery("#MVPSubmitButton").removeAttr("disabled").attr("src", "/ModalVisitorPoll/Images/submit-" + settings.languageCode + ".gif").attr("class", "MVPActiveButton");
			}
		});
		jQuery("#MVPSubmitButton").click(function() { 
			if(!isCompleted()) { 
				var errorMessage = jQuery('#messageNotCompleted').val();
				alert(errorMessage);
			} else {
				saveVisitorPoll();
			}			
		});
	}
	
	// Event to run when the window is closed
	function closeForm(jqm) {
		if(!settings.answered) {
			try {
				updateCookieState("denied");
				//_gaq.push(["b._trackPageview", ["/action/user-poll/", settings.currentForm.id ,"/denied" ].join("")]);
				_gaq.push(["b._trackEvent", settings.currentForm.trackerValue, "Denied", "Denied", undefined, true]);
			} catch(ex) { }
		}
		jqm.w.hide();
		jqm.o.hide();
		self._mvcFormVisible = false;
		
		if(settings.closeRedirectUrl !== null) {
			location.href = settings.closeRedirectUrl;
		}
	}
	
	// Check if all form fields are filled out
	function isCompleted() {
		if (jQuery("select", "form#MVPVisitorPollForm").length !== 0)
			return (jQuery("select option[clicked!=true]", "form#MVPVisitorPollForm").length === 0);
		if (jQuery("input[type=radio]", "form#MVPVisitorPollForm").length !== 0)
			return (jQuery("input[type=radio][clicked!=true]", "form#MVPVisitorPollForm").length === 0);
	}
	
	// Event that occurs when the save button is clicked
	function saveVisitorPoll() {
		if(isCompleted()) {
			var pageViewVal = "";
			for(var i = 0; i < settings.currentForm.questions.length; i++) {
				var q = settings.currentForm.questions[i];
				
				switch(jQuery(q).attr("registerMethod")) {
					case "customVar" :
						var val = getSelectedValue(q);
						_gaq.push(["b._setCustomVar", jQuery(q).attr("slot"), jQuery(q).attr("customVarName"), settings.currentForm.trackerValue + val, jQuery(q).attr("scope") ]);
						_gaq.push(["b._trackEvent", "Visitor Poll", "Answered" ]);
						//console.log("customvar: ", jQuery(q).attr("slot"), " ", jQuery(q).attr("customVarName"), " ", settings.currentForm.trackerValue + val, " ", jQuery(q).attr("scope"));
						break;
					/*
					case "trackPageViewOneAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q1/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;
					case "trackPageViewTwoAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q2/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;		
					case "trackPageViewThreeAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q3/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;		
					case "trackPageViewFourAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q4/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;		
					case "trackPageViewFiveAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q5/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;				
					*/
					case "trackEventOneAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackEvent", settings.currentForm.trackerValue, "Q1", "Q1: " + pageViewVal, undefined, true ]);
						//_gaq.push(["b._trackEvent", settings.currentForm.trackerValue + 'Q1/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;
					case "trackEventTwoAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackEvent", settings.currentForm.trackerValue, "Q2", "Q2: " + pageViewVal, undefined, true ]);
						//_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q2/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;		
					case "trackEventThreeAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackEvent", settings.currentForm.trackerValue, "Q3", "Q3: " + pageViewVal, undefined, true ]);
						// _gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q3/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;		
					case "trackEventFourAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackEvent", settings.currentForm.trackerValue, "Q4", "Q4: " + pageViewVal, undefined, true ]);
						//_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q4/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;		
					case "trackEventFiveAsync" :
						pageViewVal = getSelectedValue(q);
						_gaq.push(["b._trackEvent", settings.currentForm.trackerValue, "Q5", "Q5: " + pageViewVal, undefined, true ]);
						//_gaq.push(["b._trackPageview", settings.currentForm.trackerValue + 'Q5/' + pageViewVal ]);
						//console.log("trackpage: ", settings.currentForm.trackerValue + pageViewVal);
						break;		
				}
			}
			updateCookieState("completed");
			settings.answered = true;
			jQuery("#MVPjqm").jqmHide();
		}
		return false;
	}
	
	// Get's the selected value for a question
	function getSelectedValue(q) {
		// Look for checkbox or radiobutton
		var selectedElement = jQuery("#MVPVisitorPollForm input[name=" + jQuery(q).attr("id")  + "]:checked");
		// Look for a stand alone text-filed if not checkbox or radiobutton was found
		if(selectedElement.length === 0) {
			selectedElement = jQuery("#MVPVisitorPollForm :text[name=" + jQuery(q).attr("id")  + "]");
		}
		if (typeof selectedElement.val() !== "undefined" && selectedElement.val().toLowerCase() == "annat") {
			val = "other/free/" + selectedElement.nextAll(":text").val();
		}
		else {
			val = selectedElement.val();
		}
		// If still nothing, go for select
		if (typeof val === "undefined") {
			selectedElement = jQuery("select#" + jQuery(q).attr("id"));	
			val = selectedElement.val();
		}
		return val;
	}
	
	function loadForms(data) {
		// TODO: possible to rewrite to load only the current form? - that's all we need
		jQuery(data).find("form").each(function() {
			settings.forms.push({
				id: getAttrSafe(jQuery(this).attr("id")),
				src: getAttrSafe(jQuery(this).attr("src")),
				trackerValue: getAttrSafe(jQuery(this).attr("trackerValue")),
				displayEvent: getAttrSafe(jQuery(this).attr("displayEvent")),
				displayDelay: getAttrSafe(jQuery(this).attr("displayDelay")),
				precedingForm: getAttrSafe(jQuery(this).attr("precedingForm")),
				noPrecedingForm: getAttrSafe(jQuery(this).attr("noPrecedingForm")),
				urlRestriction: getAttrSafe(jQuery(this).attr("urlRestriction")),
				questions : null
			});
		});
		settings.currentForm = getForm(id);
		settings.currentForm.questions = loadQuestions(data);
	}
	
	// Gets all questions for the current form
	function loadQuestions(data) {
		var selector = [ "#", settings.currentForm.id, " > question" ].join("");
		var questions = [];
		jQuery(data).find(selector).each(function() {
			questions.push({
				"id" : getAttrSafe(jQuery(this).attr("id")),
				"customVarName" : getAttrSafe(jQuery(this).attr("customVarName")),
				"registerMethod" : getAttrSafe(jQuery(this).attr("registerMethod")),
				"slot" : getAttrSafe(jQuery(this).attr("slot")),
				"scope" : getAttrSafe(jQuery(this).attr("scope"))
			});
		});
		return questions;
	}
	
	// Attaches click event to external links to dipslay the poll when leaving the site
	function attachLinkEvent() {
		var pattern = /^[a-zA-Z]+:\/\/([^\/]+)\/.*?$/;
		var match = pattern.exec(location.href);
		jQuery("a[href]").click(function() {
			if(this.href.indexOf(match[1]) == -1) {
				settings.closeRedirectUrl = this.href;
				showForm();
				return false;
			}
		});
	}

	function waitForPrecedingForm() {
		//Check for cookie
		/*var cookie = new Cookie(settings.currentForm.precedingForm);
		var exists = cookie.load();
		console.log(exists);*/
//function() { showForm(); }
//		setInterval(console.log(function() { precedingFormCheck(); }),1000);

		
	}
	
	// Sets the state of the cookie to keep track of if the form has been displayed, denied, completed
	function updateCookieState(state) {
		var cookie = new Cookie(settings.currentForm.id, settings.cookieExpireDays);
		if(cookie.load()) {
			cookie.setVal("state", state);
			cookie.save();
		}
	}
	
	// Returns the remaining time to display the form. Looks for a date value in cookie or creates a new date value in cookie
	function getDisplayDelay() {
		var cookie = new Cookie(settings.currentForm.id, settings.cookieExpireDays);
		var delay = 0;
		if(settings.currentForm.displayEvent == "timer") {
			if(cookie.load() && cookie.getVal("displayTime") !== null) {
				var displayTime = cookie.getVal("displayTime");
				if(displayTime !== null) {
					var diff = new Date(parseInt(displayTime)).getTime() - new Date().getTime();
					delay = diff > 0 ? diff : 0;
				}
			}
			else {
				delay = Number(settings.currentForm.displayDelay);
				var date = new Date();
				date.setMinutes(date.getMinutes() + delay);
				cookie.setVal("displayTime", date.getTime());
				cookie.save();
				delay = delay * 60000;
			}
		}
		return delay;
	}
	
	// Checks if the form has been previously displayed
	function formPreviouslyDisplayed() {
		var cookie = new Cookie(settings.currentForm.id);
		var exists = cookie.load();
		var cookieState = cookie.getVal("state");
		return exists && (cookieState == "completed" || cookieState == "denied" || cookieState == "displayed");
	}

	// Check if the poll should be displayed to this visitor
	function participateCheck() {
		var cookie = new Cookie("modalVisitorPoll", settings.cookieExpireDays);
		
		if(cookie.load()) {
			return cookie.getVal("participate") == 1;
		}
		else {
			var val = "0";
			if(settings.displayFrequency == 100 || Math.random()*100 < settings.displayFrequency) {
				val = "1";
			}
			cookie.setVal("participate", val);
			cookie.save();
			return val == "1";
		}
	}
	
	// Checks if a preceding form has been answered
	function noPrecedingFormCheck() {
		var precedingOk = true;
		if(settings.currentForm.noPrecedingForm !== null) {
			var cookie = new Cookie(settings.currentForm.noPrecedingForm);
			precedingOk = !cookie.load() || cookie.getVal("state") == "init";
		}
		return precedingOk;
	}
	
	// Checks if a preceding form has been answered
	function precedingFormCheck() {
		var precedingOk = true;
		if(settings.currentForm.precedingForm !== null) {
			var cookie = new Cookie(settings.currentForm.precedingForm);
			var exists = cookie.load();
			precedingOk = exists && cookie.getVal("state") == "completed"; 
		}
		return precedingOk;
	}
	
	// Returns the value as null if it's undefined, null or empty
	function getAttrSafe(val) {
		if(typeof(val) == "undefined" || val === null || val == "") {
			return null;
		}
		return val;
	}
	
	// Get a form by ID
	function getForm(id) {
		if(typeof(id) == "undefined") {
			return getFormByUrl(location.href);
		}
		
		for(var i = 0; i < settings.forms.length; i++) {
			if(settings.forms[i].id == id) {
				return settings.forms[i];
			}
		}
		
		return null;
	}
	
	// Get a form by url
	function getFormByUrl(url) {	
		var matches = [];
		var exactmatch;

		// Check if there are any form that matches this url
		for(var i = 0; i < settings.forms.length; i++) {
			if(url.indexOf(settings.forms[i].urlRestriction) != -1) {
				matches.push(settings.forms[i]);
			}
		}
		
		// If no matches were found. Check if there are any reversed matches for this url
		if(matches.length === 0) {
			for(var i = 0; i < settings.forms.length; i++) {
				if(settings.forms[i].urlRestriction[0] == "!" && url.indexOf(settings.forms[i].urlRestriction) == -1) {
					matches.push(settings.forms[i]);
				}
			}
		}
		
		if(matches.length === 0) {
			return null;
		}

		matches.sort(function(a, b) {
			return a.urlRestriction.length < b.urlRestriction.length;
		});

		// plocka url som matchar exakt
		if(matches[0].urlRestriction == url) {
			return matches[0];
		}

		// plocka den längsta url som är relativ och matchar
		for(var i = 0; i < matches.length; i++) {
			if(matches[i].urlRestriction.indexOf("http://") == -1) {
				return matches[i];
			}
		}

		// plocka url som innehåller, startar med och är längst
		return matches[0];
	}
	
	// Cookie handlig class
	var Cookie = function(_id, _expDays) {
		var values = [];
		var id, expires;
		
		// Adds a key/value pair to the value array
		function setVal(k,v) {
			values.push( {"k" :k , "v" : v } );
		}
		
		// Gets the value for the specified key or index
		function getVal(k) {
			if(typeof(k) == "string") {
				var index = indexOf(k);
				return index !== null ? values[indexOf(k)].v : null;
			}
			else if(typeof(k) == "number") {
				return k < values.length ? values[k].v : null;
			}
			return null;
		}
		
		// Returns the index of the specified key
		function indexOf(k) {
			for(var i = 0; i < values.length; i++) {
				if(values[i].k == k) {
					return i;
				}
			}
			return null;
		}
		
		// Initialize the cookie object
		function init() {
			id = _id;
			expires = new Date();
			expires.setDate(expires.getDate()+_expDays);
			expires = expires.toUTCString();
		}
		
		// Try load cookie data. Returns true if data was loaded and false if no cookie data was found
		function load() {
			var cookies = document.cookie.split("; ");
			for(var i = 0; i < cookies.length; i++) {
				var cookie = cookies[i].split("=");
				if (cookie[0] == id) {
					loadValues(cookie[1]);
					return true;
				}
			}
			return false;
		}
		
		// Removes the key/value pair at the specified key or index
		function removeVal(k) {
			if(typeof(k) == "string") {
				var index = indexOf(k);
				if(index < values.length) {
					values.splice(index, 1);
				}
			}
			else if(typeof(k) == "number") {
				if(k < values.length) {
					values.splice(k, 1);
				}
			}
		}
		
		// Loads the cookies key/value pairs and adds them to the value array
		function loadValues(_vals) {
			var vals = _vals.split("|");
			for(var j = 0; j < vals.length; j++) {
				var kv = vals[j].split("#");
				if(kv[0] != "") {
					setVal( kv[0], kv[1] );
				}
			}
		}
		
		// Initialize the cookie object
		init();
		
		// Public members
		return {
			// Call the private setVal function
			setVal : function (k,v) {
				if(getVal(k) !== null) {
					removeVal(k);
				}
				setVal(k,v);
			},
			// Clears the value of the cookie
			clear : function(k) {
				document.cookie = [ id, "=" ].join("");
			},
			// calls the private getVal function
			getVal : function(k) {
				return getVal(k);
			},
			// Calls the private indexOf function
			indexOf : function(k) {
				return indexOf(k);
			},
			// Call the private load function
			load : function() {
				return load();
			},
			// Save the cookie. Separates keys and values with # and key/value pairs with |
			save : function () {
				var vals = "";
				for(var i = 0; i < values.length; i++) {
					vals += [values[i].k, "#", values[i].v, "|"].join("");
				}
				document.cookie = [ id, "=", vals, "; expires=", expires, "; path=/;" ].join("");
			},
			// Calls the private removeVal function
			removeVal : function(k) {
				removeVal(k);
			}
		};
	};
	
	init();
	
	return {
		show: function() {
			if(settings.userParticipate && !settings.formPreviouslyDisplayed && precedingFormCheck() && noPrecedingFormCheck()) {
				if(!settings.loaded) {
					settingsLoaded(showForm);
				}
				else {
					showForm();
				}
			}
		}
	};
};
