/**
 * new module handler pseudocode
 *
 **/

// receive full question response, and next Q image preload data

// populate first question

// set timeout on creating images in background (see YUI imageloader). Maybe even create full markup for next Q. Can be done via AJAX whilst user is answering question

// save answer responses client side

// once all answers have been completed, show demographics

// if demographics completed, submit response

/* Checks if userId cookie was set
 * Redirects to url after success 
 */
var VDNA_setComplete = false;
function checkCookieComplete(url, rid)
{
	if (rid == null)
		return document.location.assign(url);
	if (!VDNA_setComplete) setTimeout('checkCookieComplete("' + url + '");', 100);
		else document.location.assign(url);
}

YAHOO.namespace("Youniverse");

YAHOO.Youniverse.module = function()
{
    /**
     * The internal module reference
     * @var string
     */
    var moduleId;
    
    /**
     * The name of the module
     * @var string
     */
	var moduleName;
    
    /**
	 * Set to true when a click has been made, so extra clicks can't be made. Reset upon AJAX success
	 */
    var hasClicked;
    
    /**
     * Original JSON data containing statements
     */
    var sData;
    
    /**
     * Array containing the statements for this module
     * @var array
     */
    var statements;
    
    /**
     * Array containing choice image objects
     * @var array
     */
    var choiceImages;
    
    /**
     * The ID of the current statement being shown
     * @var int
     */
    var currentStatement;
    
    /**
     * Array containing the user's statement choices
     * @var array
     */
    var userChoices;
    
    /**
     * Defines if a user has completed a module
     * @var boolean
     */
    var completedModule;
    
    var choiceCount = 1;
    
    /**
     * Contains the cookie value
     * @var string
     */
 	var loadCookie = "";

	/**
     * Load a module
     * 
     */
    this.loadModule = function (modId, modName, statementID, choiceID)
    {
		hasClicked      = false;
        moduleId        = modId;
		moduleName      = modName;  
		userChoices     = new Array;
        choiceImages    = new Array;
        completedModule = false;

		this.checkHomepageModule();

        // callback for module fetch AJAX call
        var callback =
		{
			success: this.onLoadModule,
			failure: this.ajaxFailure,
			cache: false
		};
        
        // create the URL
        var urlString = "/statement/module_process/" + moduleId;
        
        // append the statement and choiceID if passed
		if (statementID && qnID) 
		{
			urlString += "/" + statementID + "/" + choiceID;
		}
		
		var request = YAHOO.util.Connect.asyncRequest('GET', urlString, callback);
    }
    
    /**
	 * Check if module is loaded on homepage and do the required modifications 
	 * 
	 */
	this.checkHomepageModule = function ()
	{
		// check if cookie is loaded to jump to next quiz question!
		
		c_name = "moduleClickChoice";
		if ( document.cookie.length > 0 )
		{
			c_start = document.cookie.indexOf(c_name + "=");
			if (c_start != -1)
			{ 
				c_start = c_start + c_name.length+1; 
				c_end = document.cookie.indexOf(";",c_start);
				if (c_end == -1)
					c_end = document.cookie.length;
				
				loadCookie = unescape(document.cookie.substring(c_start,c_end));
				
				//erase the cookie, we dont need it anymore
				var exdate=new Date();
				exdate.setDate(exdate.getDate() -1);
				document.cookie = "moduleClickChoice=" + ";expires=" + exdate.toGMTString(); 
			} 
		}		
	}

    /**
     * onLoadModule callback function
     * 
     * @param o
     */
    this.onLoadModule = function (o)
    {
        // responseText is JSON. Parse it to get the response object
        var responseObject = YAHOO.lang.JSON.parse(o.responseText);
        
        // reset the has clicked flag
        clicked = false; 
        
        // check the current module status
        if (responseObject.status == 'statements')
		{
			floatingModule.createStatements(responseObject);
		}
		else if (responseObject.status == 'demographics')
		{
			// Analytics
			pageTracker._trackPageview('/statement/module/' + moduleName + '/' + moduleId + '/demographics');
            
			floatingModule.createDemographics(responseObject);
		}
		else
		{
            // Analytics
			pageTracker._trackPageview('/statement/module/' + moduleName + '/' + moduleId + '/completed');
            
			floatingModule.createProcessingPage(responseObject.resultsPage);
		}
    }
    
    /**
	 * Create the statements for the current module
	 * 
	 */
	this.createStatements = function (responseObject)
	{

        // stick the statements into an array - it's easier to go from one t'other this way
        statements = new Array;
        
        sData = responseObject.statements;
        
        var statementCount = 0;
        for (statement in sData)
		{
            statements[statementCount] = sData[statement];
            statementCount++;
        }
        
        // begin preloading of first statement images
        this.preloadStatementImages(0);
        
        // create the basic statement markup
		var modulePanelBD = document.createElement('div');
		modulePanelBD.setAttribute('id', 'modulePanelBD');
		
		var inner = document.createElement('div');
		inner.setAttribute('id', 'inner');
		inner.className = 'inner';
		
        // display the first statement
        var statementTitle = this.fetchNextStatement(0);
        var markup         = this.createStatementMarkup();
        
        modulePanelBD.innerHTML = "<h2 class='module' id='statementTitle'>" + statementTitle + "</h2>";
        inner.appendChild(markup);
		modulePanelBD.appendChild(inner);
		
		modulePanelBD.innerHTML += '<div id="progressBar"><div id="progressDone"></div></div>';
		modulePanelBD.innerHTML += "<div id='cancelButton' class='imageLabel'>or <a class='captionLink cancelLnk'  onclick='floatingModule.cancelButton(); return false;' href='#' tip='" + responseObject.statementButtons.cancel + "'>" + responseObject.statementButtons.cancel + "</a></div>";
		modulePanelBD.innerHTML += "<div id='redoButton' class='imageLabel'><a class='captionLink redoBtn' onclick='floatingModule.redoModule(\""+moduleId+"\"); return false;' href='#' tip='" + responseObject.statementButtons.redo + "'>" + responseObject.statementButtons.redo + "</a></div>";

		this.displayModule(modulePanelBD);

		// used only if module's first question was answered from homepage 
		if ( loadCookie != "")
		{
			var choiceArr = new Array();
			choiceArr["statementId"] = statements[0].statement_id;
			choiceArr["id"] = loadCookie;
			this.saveStatement("", choiceArr ,"");
		}
	}
    
    /**
     * Begins preloading all images in a specific statement
     *
     * @param statementId - the numeric statementId (1 to numStatements)
     */
    this.preloadStatementImages = function (statementId)
    {
        var statement = statements[statementId];
        
        var choicesObj = statement.choices;
        
		for (choice in choicesObj)
		{
            choiceImages[choice] = new Image;
            choiceImages[choice] = choicesObj[choice].src;
		}
    }
    
    /**
     * Fetches the next statement, and triggers the preloading of the images for the statement after that
     *
     */
    this.fetchNextStatement = function (statementID)
    {
        if (statementID == undefined)
        {
            currentStatement++;
        }
        else
        {
            currentStatement = statementID;
        }
        
        if (currentStatement >= statements.length)
        {
            completedModule = true;
            return false;
        }
        
        if (currentStatement < statements.length - 1)
        {
            this.preloadStatementImages(currentStatement + 1);
        }
        
        return statements[currentStatement].statement_text;
    }
    
    /**
     * Creates the markup for the current statement
     * 
     */
    this.createStatementMarkup = function ()
    {
		var statement  = statements[currentStatement];
        var choicesObj = statement.choices;
        var markup     = '';
        
        var statementBlock = document.createElement('div');
		statementBlock.setAttribute('id', 'statementBlock');
        
		for (choice in choicesObj)
		{
            var choiceId = choicesObj[choice].id;
            var link = document.createElement('a');
            link.setAttribute('href', '#' + moduleId);
            link.setAttribute('id', 'choice-' + choiceId);
            
            var choiceImg = document.createElement('img');
            choiceImg.setAttribute('id', 'choice-' + choiceCount);
            choiceImg.setAttribute('alt', '');
            choiceImg.setAttribute('src', choicesObj[choice].src);
            
            link.appendChild(choiceImg);
            
            statementBlock.appendChild(link);
            
			YAHOO.util.Event.addListener('choice-' + choiceCount, 'click', floatingModule.saveStatement, choicesObj[choice], floatingModule);
			
			choiceCount++;
		}
        
		// Analytics
		pageTracker._trackPageview('/statement/module/' + moduleName + '/' + moduleId + '/statement/' +  statement.statement_id);
        
        return statementBlock;
    }
    
    /**
     * Outputs the module markup
     *
     */
    this.displayModule = function (moduleContent)
    {
        var moduleContainer = document.getElementById('moduleContainer');
        
		// This is an IE-safe equivalent of doing innerHTML = '';
		while (moduleContainer.hasChildNodes()) moduleContainer.removeChild(moduleContainer.firstChild);
        
		moduleContainer.appendChild(moduleContent);
		
		var cap = document.createElement('div');
		cap.className = 'cap';
		
		moduleContainer.appendChild(cap);
    }
    
    /**
     * Creates the progress bar for a modul
     * 
     */
    this.displayProgressBar = function ()
    {
        var percentageDone = (currentStatement / statements.length);
        var width = (288 * percentageDone);
        document.getElementById('progressDone').style.width = width + 'px';
    }
    
    /**
	 * Save the statement response and display the next statement in the module
	 * 
	 * @param statementID
	 * @param choiceID
	 */
	this.saveStatement = function (e, choicesObj, a)
	{
		// check if user has already clicked an image. Ignore the click if they have
		if (hasClicked == false)
		{
            var statementID = choicesObj.statementId;
            var choiceID    = choicesObj.id;
            
            hasClicked = true;
            userChoices[statementID] = choiceID;
            
            var statementTitle = floatingModule.fetchNextStatement();
            
            if (statementTitle == false)
            {
                // user has completed the module, save response and check demographics status
                this.saveResponses();
            }
            else
            {
				var markup = this.createStatementMarkup();
                document.getElementById('statementTitle').innerHTML = statementTitle;
                var inner = document.getElementById('inner');
                while (inner.hasChildNodes()) inner.removeChild(inner.firstChild);
                inner.appendChild(markup);
                this.displayProgressBar();
            }

			hasClicked = false;
		}
	}
    
    /**
	 * Save the statement response in a cookie and redirect to the module page
	 * 
	 * @param statementID
	 * @param choiceID
	 */
	this.saveStatementInCookie = function (e, choicesObj, a)
	{
		// check if user has already clicked an image. Ignore the click if they have
		if (hasClicked == false)
		{
            var statementID = choicesObj.statementId;
            var choiceID    = choicesObj.id;
            
			// hold the choise in cookie
			document.cookie = "moduleClickChoice=" + escape(choiceID);
			//redirect to module page
			window.location = '/statement/retake/'+ moduleName + '/' + moduleId;
		}
	}

    /**
     * Saves the responses and checks if the demographics page should be loaded
     *
     */
    this.saveResponses = function ()
    {
        // callback for module fetch AJAX call
        var callback =
		{
			success: this.onSaveResponse,
			failure: this.ajaxFailure,
			cache: false
		};
        
        // create the URL
        var urlString = "/statement/save_response/" + moduleId;
        
        var postData = '';
        // create the choices POST data
        for (statement in userChoices)
        {
            if (typeof(userChoices[statement]) == "string") postData += '&data[Response][' + statement + ']=' + userChoices[statement];
        }
        
		var request = YAHOO.util.Connect.asyncRequest('POST', urlString, callback, postData);
    }
    
    /**
     * Callback function called when a user's responses are saved
     * 
     * @param o JSON response object
     */
    this.onSaveResponse = function (o)
    {
        // responseText is JSON. Parse it to get the response object
        var responseObject = YAHOO.lang.JSON.parse(o.responseText);
        rid = responseObject.rid;
		if (rid)
			VDNA_FlashGetUserID(responseObject.userId);

        if (responseObject.showDemographics == true)
        {
	        // verify if user is logged and action in consequence
			$.getJSON("/register/checkUserStatus", function(o){ 
				if (o.isLogged)
					floatingModule.createProcessingPage(responseObject.resultsPage);
				else
					floatingModule.createDemographics(responseObject);
			});
			return false;
        }
        else
        {
			floatingModule.createProcessingPage(responseObject.resultsPage, rid);
        }
    }

	/**
	 * Create Demographics markup
	 * 
	 */
	this.createDemographics = function (responseObject)
	{
		// move register form to the left for correct alignment
		$("#moduleContainer").css({'margin-left': '0'});
		
		// load the register form via ajax
		$("#moduleContainer").hide();
		// hide quiz description
		$("#moduleDescription").hide();

		$.get('/register', {}, function(response) {
			content = $(response);
			content.find('#encodedtarget').val(escape(responseObject.resultsPage));
			content.find('#module_id_container').val(moduleId);
			$("#pageRegisterDiv").html(content);
			$("#pageRegisterDiv").show();
		});

//		$("#pageRegisterDiv").load("/register");		
		
//		setTimeout('$("#module_id_container").val("' + moduleId + '")', 2000);
		
		
		
		/*
		var modulePanelBD = document.createElement('div');
		modulePanelBD.setAttribute('id', 'modulePanelBD');
		
		var col1 = document.createElement('div');
		col1.setAttribute('id', 'col1');
		modulePanelBD.appendChild(col1);
		
		col1.innerHTML = responseObject.demographicHeader;
		
		var col2 = document.createElement('div');
		col2.setAttribute('id', 'col2');
		col2.className = "demog";
		modulePanelBD.appendChild(col2);
		
		var profileContentForm = document.createElement('form');
		profileContentForm.setAttribute('id', 'profileContentForm');
		profileContentForm.setAttribute('method', 'post');
		profileContentForm.setAttribute('action', 'javascript: floatingModule.saveDemographics(); return false;');
		
		var demographics = responseObject.demographics;
		
		for (var i in demographics)
		{
			if (i == "dob")
			{
				var dob = document.createElement('div');
				dob.className = 'input';
				
				dob.innerHTML += "<label for='SettingsDobMonth'>" + demographics[i].label + "</label>";
				
				var day = document.createElement('select');
				day.setAttribute('id', 'SettingsDobDay');
				day.setAttribute('name','data[Settings][dob][day]');
				
				day.options[0] = new Option(demographics[i].dayLabel,'');
				
				for (var count = 1; count <= 31; count++)
				{
					day.options[count] = new Option(count, count);
				}
				dob.appendChild(day);
				
				var month = document.createElement('select');
				month.setAttribute('id', 'SettingsDobMonth');
				month.setAttribute('name','data[Settings][dob][month]');
				var count = 0;
				for (var entry in demographics[i].months.entries)
				{
					month.options[count] = new Option(demographics[i].months.entries[entry], entry);
					count++;
				}
				dob.appendChild(month);
				
				var year = document.createElement('select');
				year.setAttribute('id', 'SettingsDobYear');
				year.setAttribute('name','data[Settings][dob][year]');
				year.options[0] = new Option(demographics[i].yearLabel, '');
				
				var currentTime = new Date();
				var currentYear = currentTime.getFullYear();
				
				var count = 1;
				for (var i = currentYear - 13; i > 1920; i--)
				{
					year.options[count] = new Option(i, i);
					count++;
				}
				
				dob.appendChild(year);
				
				profileContentForm.appendChild(dob);
			}
			else
			{
				var settings = demographics[i].settings;
				var entries = demographics[i].entries;
				
				if (settings)
				{
					var demog = document.createElement('div');
					demog.className = 'input';
					demog.innerHTML += "<label for='" + settings.forInput + "'>" + settings.label + "</label>";
					var demogSel = document.createElement('select');
					demogSel.setAttribute('id', settings.id);
					demogSel.setAttribute('name',settings.name);
					//demogSel.options[0] = new Option('', '');
					
					var count = 0;
					for (var entry in entries)
					{
						demogSel.options[count] = new Option(entries[entry], entry);
						count++;
					}
					
					demog.appendChild(demogSel);
					
					profileContentForm.appendChild(demog);
				}
			}
		}
		
		profileContentForm.innerHTML += responseObject.demographicFooter;
		
		var formButtons= document.createElement('div');
		
		formButtons.className = 'formButtons';
		profileContentForm.appendChild(formButtons);
		var extraStyle = "";
        if (responseObject.demographicSubmitStyle)
        {
            extraStyle = responseObject.demographicSubmitStyle;
        }
		
        formButtons.innerHTML += "<div id='submitDemogButton' class='imageLabel'><a href='#' class='image' style='float: left;" + extraStyle + "' title='" + responseObject.demographicSubmit + "' onclick='floatingModule.saveDemographics();return false;'/></a><div class='caption' style='float: left; display: table;'><a class='captionLink' style='position: absolute; bottom: 0px;' onclick='floatingModule.saveDemographics(); return false;' href='#' tip='" + responseObject.demographicSubmit + "'>" + responseObject.demographicSubmit + "</a></div></div>";
        formButtons.innerHTML += "<div id='cancelButton' class='imageLabel'><a  href='#' class='image' style='float: left;' title='" +responseObject.demographicCancel + "' onclick='floatingModule.cancelButton(); return false;'/></a><div class='caption' style='float: left; display: table;'><a class='captionLink' style='position: absolute; bottom: 0px;' onclick='floatingModule.cancelButton(); return false;' href='#' tip='" + responseObject.demographicCancel + "'>" + responseObject.demographicCancel + "</a></div></div>";
		
		col2.appendChild(profileContentForm);
		
		this.displayModule(modulePanelBD);
		*/
	}
    
    /**
	 * Send Demographics
	 * 
	 */
	this.saveDemographics = function ()
	{
		var postData = '';
		
		var SettingsDobDay = document.getElementById('SettingsDobDay');
		if (SettingsDobDay)
		{
			postData += 'data[Settings][dob][day]=' + SettingsDobDay.value;
		}
		var SettingsDobMonth = document.getElementById('SettingsDobMonth');
		if (SettingsDobMonth)
		{
			postData += '&data[Settings][dob][month]=' + SettingsDobMonth.value;
		}
		var SettingsDobYear = document.getElementById('SettingsDobYear');
		if (SettingsDobYear)
		{
			postData += '&data[Settings][dob][year]=' + SettingsDobYear.value;
		}
		var SettingsGender = document.getElementById('SettingsGender');
		if (SettingsGender)
		{
			postData += '&data[Settings][gender]=' + SettingsGender.value;
		}
		var SettingsCountry = document.getElementById('SettingsCountry');
		if (SettingsCountry)
		{
			postData += '&data[Settings][country]=' + SettingsCountry.value;
		}
		

		// 13 years old verification
		var today = new Date();
		var dob = new Date(SettingsDobYear.value, SettingsDobMonth.value - 1, SettingsDobDay.value);
		// Set 1 day in milliseconds
		var oneDay = 1000 * 60 * 60 * 24;
		
		// Calculate difference btw the two dates, and convert to days
		var diff = Math.ceil((today.getTime() - dob.getTime()) / (oneDay * 365.25));

		if (diff <= 13)
		{
			jQuery.facebox({ ajax: '/dialog/thirteen/' })
		}
		else
		{
			var callback =
			{
				success: this.onSaveDemographics, 
				failure: this.ajaxFailure,
				cache: false
			};

			var cObj = YAHOO.util.Connect.asyncRequest('POST', '/settings/demographic_updates/' + moduleId, callback, postData);	
		}
	}
	
    
    /**
     * Callback function called when demographics are saved
     *
     */
    this.onSaveDemographics = function (o)
    {
        eval(o.responseText);
		if (demographicsSaved == 1)
		{
			// all good... create processing page, and redirect to results page
            floatingModule.createProcessingPage(resultsPage);
		}
    }
    
    /**
	 * Create processing page
	 * 
	 */
	this.createProcessingPage = function (resultsPage, rid)
	{
		$("#moduleContainer").css({'margin-left': '100px'});
				
		var modulePanelBD = document.createElement('div');
		modulePanelBD.setAttribute('id', 'modulePanelBD');
        // This is an IE-safe equivalent of doing innerHTML = '';
		while (modulePanelBD.hasChildNodes()) modulePanelBD.removeChild(modulePanelBD.firstChild);
        
		var inner = document.createElement('div');
		inner.setAttribute('id', 'inner');
		inner.className = 'inner';
        
		modulePanelBD.appendChild(inner);
		
		var process = document.createElement('div');
		process.setAttribute('id', 'moduleProcess');
		inner.appendChild(process);
        
		if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6)
		{
			process.innerHTML = "<img src='/img/module/loader_circles_02a_forgif.gif' />";
		}
        else
		{
			process.innerHTML = '<object width="115" height="100"><param name="movie" value="/swf/module/loader_circles.swf"><embed src="/swf/module/loader_circles.swf" width="115" height="100"></embed></object>';	
		}
		
		this.displayModule(modulePanelBD);
		checkCookieComplete(resultsPage, rid);
	}
	
    /**
	 * Ajax Failure - usually happens when the error occurs server side and a 500 response is returned. GTB HACK?
	 * 
	 */
	this.ajaxFailure = function (o)
	{
		if (o.status > -1) // if not user abort
		{
			alert(msg.translate('err02'));
		}
	}
    
    /**
	 * Cancel the module and return
	 *
	 */
	this.cancelButton = function ()
	{
		window.location = '/';
	}
	
	/**
	 * Redo module
	 *
	 */
	this.redoModule = function ()
	{
		window.location = '/statement/retake/'+ moduleName + '/' + moduleId;
	}
    
}


