/*
# $Id$
#
# This global object is used by the assessment templates for managing common
# tasks carried out during the response.
*/

var Response = {

	/*
	# @property int aidZIndex
	# Keeps track of the current z-index of the aiding-text popups.
	*/
	aidZIndex: 0,

	/*
	# @property object position
	# Holds some info about the current position within the assessment.
	*/
	position: {
		assessmentId: 0,
		sectionWeight: 0,
		pageWeight: 0,
		maxSectionWeight: 0,
		maxPageWeight: 0
	},

	/*
	# @property array responses
	# Contains info on the responses given to each of the statements.
	*/
	responses: [],

	/*
	# @property array statements
	# Contains info on each statements in the current page.
	*/
	statements: [],

	/*
	# @function void init()
	#
	# Initialise the interface.
	*/
	init: function() {

		// Gather some key elements
		var stmtForm = $('stmt-form');
		var stmtPosition = $('stmt-position');
		var stmtContainer = $('stmt-container');

		// Prepare form, hidden fields and next/previous buttons.
		stmtForm.action = '';
		stmtForm.method = 'post';
		stmtForm.addEvent('submit', function() {
			return true;
		});
		var position = Response.getPosition();
		stmtPosition.value = JSON.encode(position);
		if(!$('stmt-hidden-statements')) {
			(new Element('input', {type:'hidden', id:'stmt-hidden-statements', name:'stmt-hidden-statements', value:''})).inject(stmtForm, 'top');
		}
		$('btn-next').addEvent('click', function() {
			var pos = Response.getNextPosition();
			stmtForm.action = Buan.UrlCommand.createUrl('respond', pos.assessmentId, pos.sectionWeight, pos.pageWeight);
			return true;
		});
		if(position.sectionWeight>=position.maxSectionWeight && position.pageWeight>=position.maxPageWeight) {
			$('btn-next').set('value', App.I18n.translate('[t:Finish]'));
		}
		$('btn-previous').addEvent('click', function() {
			var pos = Response.getPreviousPosition();
			stmtForm.action = Buan.UrlCommand.createUrl('respond', pos.assessmentId, pos.sectionWeight, pos.pageWeight);
			return true;
		});

		// Hide all aiding texts and replace with clickable links
		$$('span.stmt-aidtext').each(function(e, i) {
			var aid = new Element('div', {
				id: 'aiding-text-'+i,
				'class': 'aiding-text',
				html: e.innerHTML
			}).setStyles({
				display: 'none',
				position: 'absolute'
			});
			aid.inject($$('body')[0]);
			((new Element('a', {href:'#', html:'<img src="/images/aiding-text-icon.png" width="16" height="16" alt="" border="0" align="bottom" />'})).addEvent('mouseover', function(e) {
				var pos = this.getPosition();
				$('aiding-text-'+i).setStyles({
					display: $('aiding-text-'+i).getStyle('display')=='block' ? 'none' : 'block',
					left: pos.x-16,
					top: pos.y-16,
					zIndex: ++Response.aidZIndex
				}).addEvents({
					'mouseout': function(ev) {
						$('aiding-text-'+i).setStyle('display', 'none');
					}
				});
				return false;
			})).inject(e.empty());
			e.setStyle('visibility', 'visible');
		});

		// Add handlers to answer-options that will execute the displaylogic on
		// all statements, enable each one and auto-select any options the
		// respondent has already submitted.
		$$('#stmt-container .stmt-answer input[type="radio"]', '#stmt-container .stmt-answer input[type="checkbox"]').each(function(e, i) {
			e.disabled = false;
			e.addEvent('click', function() {
				Response.executeDisplayLogic();
			});
		});
		$$('#stmt-container .stmt-answer input[type="text"]', '#stmt-container .stmt-answer textarea').each(function(e, i) {
			e.disabled = false;
			e.addEvent('change', function() {
				Response.executeDisplayLogic();
			});
		});

		// Execute display logic
		if(Response.executeDisplayLogic()) {

			// Display form, if first run of DisplayLogic executed ok
			stmtForm.setStyle('visibility', 'visible');
		}
	},

	/*
	# @function void setStatements( string data )
	# data	= JSON encoded statements data
	#
	# Stores info about all statements in this page.
	*/
	setStatements: function(data) {
		try {
			Response.statements = JSON.decode(data);
		}
		catch(e) {
			alert(e);
			return;
		}
	},

	/*
	# @function void setResponses( string data )
	# data	= JSON encoded responses data
	#
	# Stores info about all responses in this page.
	*/
	setResponses: function(data) {
		try {
			Response.responses = JSON.decode(data);
		}
		catch(e) {
			alert(e);
			return;
		}
	},

	/*
	# @function void setPosition( int assessmentId, array sectionWeight, array pageWeight, int previousMaxPageWeight)
	# assessmentId			= Assessment ID
	# sectionWeight			= Current and max section weight (0+)
	# pageWeight			= Current and max page weight (0+)
	# previousMaxPageWeight	= The max page weight of the previous section
	#
	# Sets the active position within the assessment, and also specify values
	# that will help determine the next/previous section/page.
	# The "Previous" button is also enabled unless we're on the very first page
	# of the assessment.
	*/
	setPosition: function(assessmentId, sectionWeight, pageWeight, previousMaxPageWeight) {
		Response.position = {
			assessmentId: assessmentId,
			sectionWeight: sectionWeight[0],
			maxSectionWeight: sectionWeight[1],
			pageWeight: pageWeight[0],
			maxPageWeight: pageWeight[1],
			previousMaxPageWeight: previousMaxPageWeight
		};
		if($('btn-previous')) {
			$('btn-previous').disabled = (Response.position.sectionWeight>0 || Response.position.pageWeight>0) ? false : true;
		}
	},

	/*
	# @function object getPosition()
	#
	# Returns the current position within the assessment.
	*/
	getPosition: function() {
		return Response.position;
	},

	/*
	# @function object getNextPosition()
	#
	# Returns an object representing the next page/section in the assessment.
	*/
	getNextPosition: function() {
		var pos = Response.getPosition();
		return {
			assessmentId: pos.assessmentId,
			sectionWeight: pos.pageWeight>=pos.maxPageWeight ? pos.sectionWeight+1 : pos.sectionWeight,
			pageWeight: pos.pageWeight>=pos.maxPageWeight ? 0 : pos.pageWeight+1
		};
	},

	/*
	# @function object getPreviousPosition()
	#
	# Returns an object representing the previous page/section in the assessment.
	*/
	getPreviousPosition: function() {
		var pos = Response.getPosition();
		return {
			assessmentId: pos.assessmentId,
			sectionWeight: pos.pageWeight>0 ? pos.sectionWeight : (pos.sectionWeight>0 ? pos.sectionWeight-1 : pos.sectionWeight),
			pageWeight: pos.pageWeight>0 ? pos.pageWeight-1 : pos.previousMaxPageWeight
		};
	},

	/*
	# @function void executeDisplayLogic()
	#
	# Execute the display logic on ALL statements in the current form.
	*/
	executeDisplayLogic: function() {

		// Check that all required fields have been answered, execute
		// displaylogic and display custom-trigger inputs if their trigger
		// radio/checkbox has been selected
		if(Response.statements.length>0) {

			// Gather data from the selections made by the user.
			var missingRequired = [];
			for(var i=0; i<Response.statements.length; i++) {

				// Check answered status and trigger inputs
				missingRequired[i] = false;
				var stmt = Response.statements[i];
				var isAnswered = false;
				for(var j=0; j<stmt.AnswerType.AnswerOption.length; j++) {
					var option = stmt.AnswerType.AnswerOption[j];
					var response = Response.responses[stmt.weight] && Response.responses[stmt.weight][option.id] ? Response.responses[stmt.weight][option.id] : null;
					var eOpt = $('statement-'+stmt.weight+'-'+option.id);
					var eTriggeredInput = $('triggeredinput-'+stmt.weight+'-'+option.id);
					if(eOpt) {
						var tag = eOpt.get('tag');

						// Text/textarea
						if(eOpt.get('tag')=='textarea' || eOpt.type=='text') {
							if(eOpt.value!='') {
								isAnswered = true;
								if(!Response.responses[stmt.weight]) {
									Response.responses[stmt.weight] = {};
								}
								Response.responses[stmt.weight][option.id] = option;
								Response.responses[stmt.weight][option.id].answer_value = eOpt.value;
							}
							else if(Response.responses[stmt.weight] && Response.responses[stmt.weight][option.id]) {
								delete(Response.responses[stmt.weight][option.id]);
							}
						}

						// Radio/checkbox
						else if(eOpt.type=='radio' || eOpt.type=='checkbox') {

							// Show/hide triggered input
							if(eTriggeredInput) {
								if(eOpt.checked) {
									eTriggeredInput.setStyle('display', 'block');
									if(eTriggeredInput.innerHTML=='') {
										var val = response===null ? '' : Response.responses[stmt.weight][option.id].answer_value;
										if(option.customtype=='textarea') {
											eTriggeredInput.innerHTML = '<textarea name="statement['+stmt.weight+']['+option.id+']">'+val+'</textarea>';
										}
										else {
											eTriggeredInput.innerHTML = '<input type="text" name="statement['+stmt.weight+']['+option.id+']" value="'+val+'" />';
										}
									}
								}
								else {
									eTriggeredInput.setStyle('display', 'none');
									eTriggeredInput.innerHTML = '';
								}
							}

							// Deal with checked inputs
							if(eOpt.checked) {

								// Flag this statement as having been answered
								isAnswered = true;

								// Add the chosen AnswerOption to the
								// "Response.responses" object
								if(response===null) {
									if(!Response.responses[stmt.weight]) {
										Response.responses[stmt.weight] = {};
									}
									Response.responses[stmt.weight][option.id] = option;
								}
							}

							// Deal with unchecked inputs
							else {

								// Remove the chosen AnswerOption from the
								// "Response.responses" object
								if(response!==null) {
									delete(Response.responses[stmt.weight][option.id]);
								}
							}
						}
					}
				}

				// If the statement is required and has NOT been answered then
				// flag it as missing.
				if(stmt.isrequired==1 && !isAnswered) {
					missingRequired[i] = true;
				}
			}

			// Execute DisplayLogic on all statements
			// This is performed AFTER the gathering of field data so that the
			// "Response.responses" object is up to date.
			// Any hidden statements have their weight's stored in the
			// "stmt-hidden-statements" hidden form field.
			var numberSequence = 1;
			var dl = $('stmt-container').getChildren('dl')[0];
			var hiddenStmts = [];
			for(var i=0; i<Response.statements.length; i++) {
				var stmt = Response.statements[i];
				var stmtVisible = DisplayLogic.execute(stmt);
				dl.getChildren('dt')[stmt.weight].setStyle('display', stmtVisible ? 'block' : 'none');
				dl.getChildren('dd')[stmt.weight].setStyle('display', stmtVisible ? 'block' : 'none');
				if(!stmtVisible) {
					missingRequired[i] = false;
					hiddenStmts.push(stmt.weight);
				}
				else {
					dl.getChildren('dt')[stmt.weight].getChildren('label')[0].getElements('.stmt-number')[0].innerHTML = numberSequence++;
				}
			}
			$('stmt-hidden-statements').value = hiddenStmts.join(",");

			// Disable the "next" button if any required fields have not been
			// completed
			missingRequired = missingRequired.some(function(item){ return item===true; });
			if(missingRequired) {
				$('btn-next').disabled = true;
				$('btn-next').addClass('disabled');
			}
			else {
				$('btn-next').disabled = false;
				$('btn-next').removeClass('disabled');
			}

			// Check if ALL statements have been hidden due to their
			// DisplayLogic, and if so move onto the next/previous page
			//
			// TODO:
			// This is temporary solution to hiding entire Pages according to
			// DisplayLogic. Once/if the proper solution is in place, remove this.
			if(hiddenStmts.length===Response.statements.length) {

				// Display message to user
				var msg = new Element('div', {html: App.I18n.translate('[t:Please wait whilst we take you to the relevant section of the assessment.]')});
				msg.setStyles({
					position: 'absolute',
					top: 0,
					left: 0,
					background: '#0000FF',
					padding: '1em',
					textAlign: 'center',
					color: '#FFFFFF',
					width: '100%'
				});
				msg.inject($(document.body));

				// Determine if next/previous button was pressed from last page,
				// generate target URL for form and create new hidden fields
				// to mimic the next/previous button being pressed
				var direction = $('assessment-direction').value=='previous' ? 'previous' : 'next';
				var form = $('stmt-form');
				var pos = direction=='previous' ? Response.getPreviousPosition() : Response.getNextPosition();
				form.action = Buan.UrlCommand.createUrl('respond', pos.assessmentId, pos.sectionWeight, pos.pageWeight);
				(new Element('input', {type:'hidden', name:$('btn-'+direction).name, value:''})).inject(form, 'top');

				// Submit form
				form.submit();
				return false;
			}
		}

		// No statements exist in the current page, so enable the "next" button
		else {
			$('btn-next').disabled = false;
			$('btn-next').removeClass('disabled');
		}

		// Result
		return true;
	}
};