
/**
 * SurveyLogic
 * This class should handle all client side business logic associated with a survey.
 * This includes, but should not be limited to:
 * 		Client side validation bindings
 * 		Immediate branching rules or actions
 * 		Local (page) branching/piping logic
 * 
 * @param {Object} logic
 * 		variables: Array of objects containing at least an 'id' attribute
 */

function getVariableQuery(variable){
	variable = variable.replace(/(:|\.)/g,'\\$1');
	
	return $(
		'#x' + variable + ' input ,' +
		'#x' + variable + ' select ,' +
		'#x' + variable + ' textarea ,' +
		'.x' + variable + ' input ,' +
		'.x' + variable + ' select, ' +
		'.x' + variable + ' textarea '  
	);
}

function SurveyLogic(config){
	var that = this;

	if (!config) config = {};
	if (!config.variables) config.variables = [];
	
	var wordCountValidation = function(ele, variable) {
			var parent = ele.parents('div:first');
			if (!parent.find('.word-count').length) {
				parent.append($('<span><\/span>', {'class': 'word-count'}).html(gettext('<br/>Words entered: <span class="entered"></span>. Min: <span class="min"></span> Max: <span class="max"></span>')));
				parent.find('.word-count .min').text(variable.validation.minWords);	
				parent.find('.word-count .max').text(variable.validation.maxWords);
			}
			var val = ele.val();

			val = val.replace(/[\n\r\ ]/gi, ' ');
			val_split = val.split(' ');
			count = 0;
			for (i = 0; i < val_split.length; i++) {
				if (val_split[i].trim() != '') {
					count++;
				}
			}
			
			parent.find('.word-count .entered').text(count);
	};

	$.each(config.variables, function(i, variable){
		(function(variable){
			that[variable.id] = {};
			$.extend(that[variable.id], variable, {
				element: getVariableQuery(variable.id)
			});

			if (variable.validation) {
				//On page load if the textarea has wordCount validation and has a value show some info
				if (variable.validation.type == 'wordCount' && that[variable.id].element.val() != '') {
					wordCountValidation(that[variable.id].element, variable);
				}

				variable.validation.regex = variable.validation.regex || '.*';
				that[variable.id].element.bind('keyup mouseup', function(e){
					if (variable.validation.maxLength && $(this).val().length > variable.validation.maxLength){
						//$(this).val($(this).val().substr(0, variable.validation.maxLength));
					}
					
					if (variable.validation.type == 'wordCount') {
						wordCountValidation($(this), variable);
					}
				}).blur(function(e){
					var valid = true;
					if ((new RegExp(variable.validation.regex, 'm')).test($(this).val())) {
						if (variable.validation.maxLength && $(this).val().length > variable.validation.maxLength){
							//$(this).val($(this).val().substr(0, variable.validation.maxLength));
							
						}
					}
					else {
						valid = false;
					}
					
					if (variable.validation.precision){
						try {
							if ($(this).val().split('.')[1].length > variable.validation.precision){
								valid = false;
							}
						}
						catch(e){}
					}
					if (valid){
						curVal = $(this).val();
						if((variable.validation.type == 'postal-ca' && curVal.charAt(3) != ' ') || (variable.validation.type == 'postal' && curVal.length == 6 && curVal.charAt(3) != ' ')){
							curVal = curVal.replace(/(\S{3})/,"$1 ");
							$(this).val(curVal);
						}
						if(variable.validation.type == 'percentage-bound' || variable.validation.type == 'percentage-unbound'){
							curVal = curVal.replace(/%$/,'');
							$(this).val(curVal);
						}						
						if(variable.validation.type == 'currency'){
							curVal = curVal.replace(/(^\$|\$$)/,'');
							$(this).val(curVal);
						}
						that[variable.id]._cached_value = curVal;
						$(this).parent().find('.inlineValidationError').remove();
						//$('input[type="submit"]').removeAttr('disabled');
					}else if($(this).val()===''){
						//empty string, do nothing
					}
					else {
						errorDiv = $(this).parent().find('.inlineValidationError');
						if (errorDiv.length > 0) {
							errorDiv.html('<li>' + $(this).val() + " : " + ((variable.validation.errorMsg) ? variable.validation.errorMsg : gettext("Invalid Entry")) + '<\/li>');
						}
						else {
							$('<ul><\/ul>')
								.addClass('inlineValidationError')
								.addClass('errorlist')
								.append($('<li></li>', { 
										text: $(this).val() + " : " + (variable.validation.errorMsg) ? variable.validation.errorMsg : gettext("Invalid Entry")
									})
								)
								.insertBefore($(this));
							//$('input[type="submit"]').attr('disabled', 'disabled');
						}
						//$(this).val(that[variable.id]._cached_value || '');
					}
				});
			}

		})(variable);
	});
};

//Redirect in kiosk mode.
$(function() {
	if (KIOSK_REDIRECT) {
		setTimeout(function() {
			window.location = KIOSK_REDIRECT;
		}, 5000);
	}
});

/*******
* Scrolls to the first enabled question on a page
* so that it doesn't seem like the entire form is disabled
*******/
function scrollToFirstEnabled() {
	var hasDisabled = false;
	$("input,select", "#survey-form").each(function() {
		if(!$(this).attr('disabled')) {
			if(hasDisabled && !$(this).parents('div.question:first').hasClass('buttons')) {
				window.scroll(0,$(this).parents('div.question:first').position().top);
				return false;
			}
		} else {
			hasDisabled = true;
		}
	});	
}

/* Must be a global*/
onSurveyLoad = function(){
	$('input[type="submit"]').removeAttr('disabled');

	$('#survey-form').submit(function(e) {
		$.Watermark.HideAll();
		
		setTimeout(function() {
			$('input[type="submit"]').attr('disabled', 'disabled');
		}, 5);
	});

	$('div.question.file-upload').each(function() {
		var q = $(this);

		q.find('input.delete[type=checkbox]').bind('click change keydown', function() {
			if ($(this).attr('checked')) {
				q.find('.upload').hide('fast');
				q.find('input[type=file]').val('');
			} else {
				q.find('.upload').show('fast');
			}
		}).trigger('change');
	});	

	if ($.browser.msie && $.browser.version.substr(0,1)<7) {
		$('#survey table.grouped-table tbody tr, #survey ul.matrix li').hover(
			function() { $(this).addClass('hover'); },
			function() { $(this).removeClass('hover'); }
		);

		$('#survey_footer').css({ 
			width: $('#survey').css('width'),
			margin: '0 auto'
		});
	}
	/*$('#survey div.question legend .question-header').unwrap();
	$('#survey div.question fieldset .question-header').unwrap();*/
	$('#survey div.question fieldset').hide();
	setTimeout(function(){$('#survey div.question fieldset').show();},0)
	
	$('.question.text-response-grid').each(function() {
		var original = $('.sum-label-hidden', this);
		var inputs = $('input[type=text], textarea', this);
		var that = this;

		var calcTotal = function() {
			var total = 0;
			inputs.each(function() {
				var matched = $(this).val().replace(',','').replace(' ','').match(/([^\d])?(\d*(\.\d+)?)/);
				if (matched && matched[0]){
					var val = parseFloat(matched[2]);
					if (!isNaN(val)) {
						total += val;
					}
				}
			});
			return total;
		};

		var update = function(e) {
			$('.sum-label',that).text(original.text().replace(/\{x\}/g, $('span.sumtotal',that).text()).replace(/\{y\}/g, calcTotal()));
		}

		inputs.keyup(update);

		update();
	});
	$('.question.threed-grid').each(function() {
		var that = this;
		var columns = $('tbody tr:first td.variable', this).map(function(i,el){ return $('td:eq(' + i + ')', $('tbody tr, tfoot tr',that)); });
		$.each(columns, function(){
			var that = this;
			var original = $('.sum-label-hidden', this);
			var inputs = $('input[type=text], textarea', this);
			console.log(original, inputs, this)
			var calcTotal = function() {
				var total = 0;
				inputs.each(function() {
					var val = parseFloat($(this).val());
					if (!isNaN(val) && val == $(this).val()) {
						total += val;
					}
				});
				return total;
			};
	
			var update = function(e) {
				$('.sum-label',that).text(original.text().replace(/\{x\}/g, $('span.sumtotal',that).text()).replace(/\{y\}/g, calcTotal()));
			}
	
			inputs.keyup(update);

			update();	
		});
	});
	
	var timeZone = calculateTimeZone();

	$('.datetime a.date', this).click(function(e) {
		$($(this).attr('href')).datepicker('show');
		return false;
	});

	$('.datetime').each(function() {
		var dateInput = $('input.date', this);
		var timeInput = $('input.time', this);
		var zoneInput = $('select.zone', this);

		if (zoneInput.hasClass('guess')) {
			$('option', zoneInput).filter(function() { return $(this).text().indexOf(timeZone) >= 0; }).attr('selected', 'selected');
		}

		var parseTime = function() {
			try {
				var time = parseTimeString(timeInput.val());
			} catch (e) {
				return null;
			}

			return !time || isNaN(time.getTime()) ? null : time;
		};

		dateInput.Watermark(dateInput.attr('title'));
		timeInput.Watermark(timeInput.attr('title'));

		dateInput.datepicker({ dateFormat: dateInput.attr('alt'), constrainInput: false, changeMonth: true, changeYear: true, yearRange: 'c-80:c+20' });

		timeInput.add(dateInput).bind('focus', function(e) {
			this.select();
		});

		timeInput.bind('change', function(e) {
			var time = parseTime();

			$(this).val(time ? time.format($(this).attr('alt')) : '');
		});

		dateInput.bind('change', function(e) {
			//var date = $(this).datepicker('getDate');

			//$(this).datepicker('setDate', date ? date : null);
		});
	});
	
	//Allow clicking a cell to toggle the checkbox or radio button
	$('.group-table-container table, .grouped-table').delegate('td', 'click', function(e){
		if (!$(e.target).is('input') && $(e.target).find('input:enabled').length == 1) {
			$(this).find('input:enabled').focus().click().change();
		}
	});
	var checkbox_done = [];
	$('input[type="checkbox"]').each(function(e){
		var that = this;
		var parent = $(that).parents('.question-body');
		if (checkbox_done.indexOf(parent[0]) < 0){
			checkbox_done.push(parent[0]);
		} else {
			return;
		}
			
		var exclusives = parent.find('input[type="checkbox"].na-choice');
		var inclusives = parent.find('input[type="checkbox"]:not(.na-choice):not(.check-all)');
		var selectAll = parent.find('input[type="checkbox"].check-all');
		exclusives.unbind('click').bind('click change', function(){
			parent.find('input[type="checkbox"]').not($(this)).removeAttr('checked');
			parent.find('input[type=text]').val('');
			
			var current;
			if($(this).attr('checked') == false)
				current = 0;
			else
				current = 1;
			$('.current-checked', parent).text(current);
		});
		selectAll.unbind('click').bind('click change',function(){
			if ($(this).attr('checked')){
				inclusives.attr('checked', 'checked');
			} else {
				inclusives.removeAttr('checked');
			}
			$('.current-checked', parent).text(inclusives.filter(':checked').length);
		});

		var checkSelectAll = function(){
			if (inclusives.filter(':checked').length == inclusives.length) {
				selectAll.attr('checked', 'checked')
			} else {
				selectAll.removeAttr('checked', 'checked')
			}
		};
		inclusives.unbind('click').bind('click change', function(){
			var current = 0;
			parent.find('.na-choice').removeAttr('checked');
		 	current=(inclusives.filter(':checked').length);
			$('.current-checked', parent).text(current);
			checkSelectAll();
		});
		checkSelectAll();
		$('.current-checked', parent).text(inclusives.filter(':checked').length);
	});
	
	$('select.drilldown').hide().each(function() {
		var that = this;
		var name = $(this).attr('name');

		var choices = $('<select>', {
			'size':5,
			'class': 'drill-down-selector',
			change: function() {
				console.log($(that).val(), $('option:selected', this).val());
				$(that).val($('option:selected', this).val());
			}
		});

		var categories = $('<select>', {
			'size':5,
			'class': 'drill-down-selector',
			change: function() {
				choices.empty();
				var group = $('option:selected', this).data('optgroup');
				if (group) {
					group.find('option').clone().appendTo(choices);
					choices.val($(that).val());
				}
			}
		});

		$('optgroup', this).each(function(i) {
			categories.append($('<option />', {
				val: i,
				text: $(this).attr('label'),
				data: {
					optgroup: $(this)
				}
			}));

			if ($('option:selected', this).length) {
				categories.val(i);
			}
		});
		choices.insertAfter(this);
		categories.insertAfter(this);
		categories.trigger('change');
		
	});
	
	//Allow unchecking of radio buttons
	$('input[type="radio"]').each(function(){
		var checked = $(this).is(':checked');
		$(this).data('wasChecked',checked);
	});
	
	$('input[type="radio"]').click(function(e){
		if($(this).data('wasChecked')) {
			$(this).attr('checked','');
			$(this).data('wasChecked',false);
		} else {
			$('input[name="'+$(this).attr('name')+'"]').data('wasChecked',false);
			$(this).data('wasChecked',true);
		}
	});
	
		
	$('.grouped-error-row').each(function(i) {
		var that = this;
		$('input',this).click(function(e) {
			$('.grouped-error-box',that).removeClass('grouped-error-box');
			$(that).removeClass('grouped-error-row');
		});
	});
	
	$('.grouped-error-row').each(function(i) {
		if( $('input[type="radio"]:checked',this).length > 0) {
			$('input[type="radio"]:checked',this).parent().addClass('grouped-error-box');
			$(this).removeClass('grouped-error-row');
		}
	});
	
	$('.funique').each(function(i) {
		var that = this;
		$('input',this).click(function(x) {
			var that2 = this;
			$('input',that).each(function(z) {
				if(this.value == that2.value && that2 != this) {
					$(this).attr('checked','');
				}
			});
		});
	});
	
	//disable form submission on enter key in text input fields
	$('input[type="text"]').keypress(function(e){
		if(window.event) key = window.event.keyCode;
		else key = e.which;	//for firefox		
		if(key == 13) e.preventDefault();	
	});
	
	$('input[type="reset"]').click(function(e) {
		e.preventDefault();
		$('input[type="text"]').val('');
		$('textarea').val('');
		$('input[type="radio"]').attr('checked','');
		$('input[type="checkbox"]').attr('checked','');
		$('option').attr('selected','');
	});
		
	$('input[name="exit"]').click(function(e) {
		if (!confirm(gettext('Are you sure you wish to exit this survey? Any responses you have provided will be discarded.'))) {
			e.preventDefault();
		}
		else
		{
			if($('input[name="_terminated_redirect"]').length > 0)
				if($('input[name="_terminated_redirect"]')[0].value)
				{
					e.preventDefault();
					window.location=$('input[name="_terminated_redirect"]')[0].value;
				}
		}
	});

	// Timer question
	$('#survey-form').delegate('a.timer', 'click', function(e) {
		var msTaken, startTime, endTime;

		if (!$(this).hasClass('running')) {
			startTime = new _.date();

			$(this).addClass('running').data('startTime', startTime);
			$('span', this).addClass('icon icon-spinner').text('Stop Timer');

			$(this).next('span').html('Start time: ' + startTime.format('isoTime'));
		} else {
			startTime = $(this).data('startTime');
			endTime = new _.date();

			$(this).removeClass('running');
			$('span', this).removeClass('icon icon-spinner').text('Start Timer');

			msTaken = endTime.getTime() - startTime.getTime();

			msTaken = Math.floor(msTaken / 100) / 10;

			$(this).next('span').html(
				'Time taken: ' + msTaken + 's (from ' +
				startTime.format('isoTime') + ' to ' +
				endTime.format('isoTime') + ')'
			);

			$(this).prev('input').val(msTaken);
		}
	});

	/********** Dynamic grid client side script *********/
	
	$('input.grid-select-all').click(function(){
		var scope = $(this).parents('tr:first');
		if ($(this).attr('checked')){
			$('input[type="checkbox"]:not(.grid-select-all)', scope).attr('checked', 'checked')
				.each(function(){
					$(this).trigger('change');
				});
		}
		else {
			$('input[type="checkbox"]:not(.grid-select-all)', scope).removeAttr('checked')
				.each(function(){
					$(this).trigger('change');
				});
		}
	});
	
	$('.dynamic-grid-question')
		.find('input[type="checkbox"]:not(.grid-select-all)')
		.bind('click', function(){
			if (!$(this).attr('checked')){
				$('.grid-select-all:checked', $(this).parents('tr:first')).removeAttr('checked');
			}
		});
	
	/****************************************************/
	
	/************** Branching Info JS *******************/
		var branchingInfo = $('#survey div.branching-info');
		//If this runs they have JS so use the JS Suited class
		branchingInfo.removeClass('branching-info');
		branchingInfo.addClass('branching-info-js');
		
		var branchUl = $('span:first',branchingInfo).hide();
		var branchingInfoToggler = $('<div>').prependTo(branchingInfo);
		branchingInfoToggler.append($('<a href="#" title="'+ gettext('Toggle Branching Info') +'">').click(function(e) {
			e.preventDefault();
			if (branchUl.is(':visible')) {
				branchUl.slideUp();
				$(this).removeClass('open');
			} else {
				branchUl.slideDown();
				$(this).addClass('open');
			}
		}).html('<img src="/media/img/icons/page_skip.png" />'));
	/****************************************************/
	
	$('input.other').keyup(function(event) {
		if (event.keyCode != '9'){
			
			$(this).parents('li:first')
				.find('input[type="radio"]')
				.attr('checked', 'checked');
				
			if (typeof AUTOSELECT_CHECKBOXES != "undefined" && AUTOSELECT_CHECKBOXES) {
				$(this).parents('li:first')
					.find('input[type="checkbox"]')
					.attr('checked', 'checked')
					.end()
					.siblings()
					.find('input[type="checkbox"].na-choice')
					.attr('checked', '');
				
			}	
		}
	});
	if ($.browser.msie && $.browser.version <=7){
		//fix ie dropdown problem
		$('select').each(function(el){
			var select = this;
			if ($(this).attr('size')>1) return;
			// THIS FUNCTION IS ONLY CONCERNED WITH INTERNET EXPLORER NON-MULTIPLE SELECT NODES THAT HAVE A SPECIFIC WIDTH DEFINED
			if(!select.attachEvent || select.multiple || select.currentStyle.width == "auto") { return; }
	
			var body = document.getElementsByTagName("body").item(0);
	
			var si = select.selectedIndex;
	
			var clone = select.cloneNode(true);
			clone.style.position = "absolute";
			clone.style.visibility = "hidden";
			clone.style.width = "auto";
			body.appendChild(clone);
	
			clone._initialOffsetWidth = select.offsetWidth;
			clone._initialOffsetHeight = select.offsetHeight;
			clone._autoWidth = clone.offsetWidth;
	
			clone = body.removeChild(clone);
			clone.style.visibility = "visible";
			clone.style.width = clone._initialOffsetWidth + "px";
	
			var span = document.createElement("span");
			span._isIeDropDownContainer = true;
			span.style.position = "relative";
			span.style.width = clone._initialOffsetWidth + "px";
			span.style.height = clone._initialOffsetHeight + "px";
			span.style.marginBottom = "-4"; //hmm...quirky...
			span.appendChild(clone);
	
			if (select.parentNode._isIeDropDownContainer){
				select.parentNode.parentNode.replaceChild(span, select.parentNode);
			}else{
				select.parentNode.replaceChild(span, select);
			}
	
			if (clone._autoWidth > clone._initialOffsetWidth){
				var expand = function(){
					event.srcElement.parentNode.style.zIndex = 1;
					event.srcElement.style.width = "auto";
					if (event.srcElement.offsetWidth > event.srcElement._initialOffsetWidth){
						event.srcElement.style.width = "auto";
					}else{
						event.srcElement.style.width = event.srcElement._initialOffsetWidth + "px";
					}
				};
				var contract = function(){
					event.srcElement.parentNode.style.zIndex = 0;
					event.srcElement.style.width = event.srcElement._initialOffsetWidth + "px";
				};
				clone.attachEvent("onactivate", expand);
				clone.attachEvent("ondeactivate", contract);
			}
			clone.selectedIndex = si;
		});	
	}
	
};
$(window).unload( function () { } );
$(document).ready(onSurveyLoad);

