
var conditionOptions = [
	{ name: 'width', value: 'Display Width', autocomplete: '', tests: [ { name: 'equals', value: 'Equals'}, { name: 'lt', value: 'Less Than' }, { name: 'ltequals', value: 'Less Than or Equal' }, { name: 'gt', value: 'Greater Than' },{ name: 'gtequals', value: 'Greater Than or Equal' } ] },
	{ name: 'height', value: 'Display Height', autocomplete: '', tests: [ { name: 'equals', value: 'Equals'}, { name: 'lt', value: 'Less Than' }, { name: 'ltequals', value: 'Less Than or Equal' }, { name: 'gt', value: 'Greater Than' },{ name: 'gtequals', value: 'Greater Than or Equal' } ] },
	{ name: 'vendor', value: 'Vendor', autocomplete: '/properties/lookup/vendor', tests:  [ { name: 'is', value: 'Is' }, { name: 'is not', value: 'Is Not' } ] },
	{ name: 'model', value: 'Model', autocomplete: '/properties/lookup/model', tests:  [ { name: 'is', value: 'Is' }, { name: 'is not', value: 'Is Not' } ] },
	{ name: 'os', value: 'Operating System', autocomplete: '/properties/lookup/os', tests: [ { name: 'is', value: 'Is' }, { name: 'is not', value: 'Is Not' } ] },
	{ name: 'browser', value: 'Browser', autocomplete: '/properties/lookup/browser', tests: [ { name: 'is', value: 'Is' }, { name: 'is not', value: 'Is Not' } ] },
	{ name: 'xhtmllevel', value: 'XHTML Level', autocomplete: '', tests:  [ { name: 'equals', value: 'Equals'}, { name: 'lt', value: 'Less Than' }, { name: 'ltequals', value: 'Less Than or Equal' }, { name: 'gt', value: 'Greater Than' },{ name: 'gtequals', value: 'Greater Than or Equal' } ] },
	{ name: 'ismobile', value: 'Is Mobile ?', autocomplete: '', tests:  [ { name: 'is', value: 'Is' }, { name: 'is not', value: 'Is Not' } ] },
	{ name: 'isconsole', value: 'Is Console ?', autocomplete: '', tests:  [ { name: 'is', value: 'Is' }, { name: 'is not', value: 'Is Not' } ] },
	{ name: 'istablet', value: 'Is Tablet ?', autocomplete: '', tests:  [ { name: 'is', value: 'Is' }, { name: 'is not', value: 'Is Not' } ] } ];

var ruleElements = [];
var ruleInstanceCount = 0;
var conditionInstanceCount = 0;

function isNumber (input) {
  return (input - 0) == input && input.length > 0;
}

// Note : rulecount will be shared among all instanced of the class.
var HDRule = {
	options: {
		errorcheck: true,
		title: 'New Rule',
		conditionsany: [],
		conditionsall: [],
		action: '',
		parent: '',
		block: '',
		self: '',
		seq: 0,
		condSeq: 0,
		error: 0
	},
	
	_create: function() {
		var self = this, o = this.options;
		o.seq = ruleInstanceCount++;
		o.condSeq = 0;
		o.self = this;
		o.parent = this.element;
		
		// Template for this widget
		var template = "<div class='ruleouter'>";
		template += "<div class='rule' id='ruleid%' name='ruleid%'>";
		// Title Bar
		template += "<div class='rulebar'>";
		template += "<span class='rulebartitle'>Title</span>";
		template += "<span class='rulebartoggle' title='Show/Hide this Rule'>&nbsp;</span>";
		template += "<span class='rulebarremove' title='Remove this Rule'>&nbsp;</span>";
		template += "</div>";
		// Body
		template += "<div class='rulebody' style='display:none'><hr/>";
		template += "<div class='rulecondheader'>Rule Name</div>";
		template += "<div><input class='ruletitle' name='data[Site][rules]["+o.seq+"][title]' size='40' value='"+o.title+"'/><div class='ruleerrmsg clearfix' style='display:none'></div></div>";
		template += "<div class='rulecondheader'><span class='ruleaddanytitle'>Match ANY of these conditions</span><a href='#' class='ruleaddany noeffects' title='Add an ANY Condition'>&nbsp;</a></div><div class='ruleanyconditions clearboth'></div>";
		template += "<div class='rulecondheader'><span class='ruleaddalltitle'>Match ALL of these conditions</span><a href='#' class='ruleaddall noeffects' title='Add an ALL Condition'>&nbsp;</a></div><div class='ruleallconditions clearboth'></div>";
		template += "<div class='rulecondheader'>Redirect to this URL</div>";
		template += "<div><input class='ruleaction' size='40' name='data[Site][rules]["+o.seq+"][action]' value='"+o.action+"'/><div class='ruleerrmsg clearfix' style='display:none'></div></div>";
		template += "</div></div></div>";
		o.block = $(template).appendTo(o.parent);
		$('.ruleaddany', o.block).click($.proxy(this, "newAnyCondition"));
		$('.ruleaddall', o.block).click($.proxy(this, "newAllCondition"));
		
		// Show & hide rule body
		$('.rulebartoggle', o.block).click(function() {
			$(this).parent().next('.rulebody').slideToggle(450, function() {
				var self = $(this), hidden = $(this).is(":hidden"), parent = $(this).parent();
				if (hidden)
					$('.rulebartoggle', parent).css('background-image','url(/icon24/right.png)');
				else
					$('.rulebartoggle', parent).css('background-image','url(/icon24/download.png)');
						
				//debugger;
			});
		});
		$('.rulebarremove', o.block).click(function() { $(this).parent().parent().parent().remove(); });
		
		// Reset title when title field changes
		$('.ruletitle', o.block).change($.proxy(this, "setTitle"));
		if (o.errorcheck)
			$('.ruletitle', o.block).change();

		// Same for action.
		$('.ruleaction', o.block).change($.proxy(this, "setAction"));
		if (o.errorcheck)
			$('.ruleaction', o.block).change();
		
		//$('.rulebartitle', o.block).text(o.title);
		for (var i in o.conditionsany) {
			this.newConditionBlock($('.ruleanyconditions', o.block).first(), 'any', o.conditionsany[i], true);
		}
		for (var i in o.conditionsall) {
			this.newConditionBlock($('.ruleallconditions', o.block).first(), 'all', o.conditionsall[i], true);
		}
		if (o.error) $('.rulebartoggle', o.block).click();
		
		this._trigger("added", null, o.block);
	},
	
	setTitle: function(evt) {
		var o = this.options;
		var block = $(evt.currentTarget).parent();
		if (evt.currentTarget.value == "") {
			$('.ruleerrmsg', block).show().text('Please enter a title');
			$(evt.currentTarget).css('border','3px solid #EC1D25');
			o.error = 1;
			return false;
		}
		o.error = 0 || o.error;
		$('.ruleerrmsg', block).hide().text('');
		$(evt.currentTarget).css('border','');
		o.title = evt.currentTarget.value;
		$('.rulebartitle', o.block).text(o.title);
	},

	setAction: function(evt) {
		var o = this.options;
		var block = $(evt.currentTarget).parent();
		if (evt.currentTarget.value == "") {
			$('.ruleerrmsg', block).show().text('Please enter an address for redirection (a URL)');
			$(evt.currentTarget).css('border','3px solid #EC1D25');
			o.error = 1;
			return false;
		}
		o.error = 0 || o.error;
		$('.ruleerrmsg', block).hide().text('');
		$(evt.currentTarget).css('border','');
		o.action = evt.currentTarget.value;
	},
	
	newAnyCondition: function(evt) {
		var self = this, o = self.options;
		this.newConditionBlock($('.ruleanyconditions', o.block).first(), 'any', { name: '', test: '', value: '' }, false );
		return false;
	},
	
	newAllCondition: function(evt) {
		var self = this, o = self.options;
		this.newConditionBlock($('.ruleallconditions', o.block).first(), 'all', { name: '', test: '', value: '' }, false );
		return false;
	},
	
	// Conditon block consists of a condition (dropdown), a test (dropdown), a value (input) and a button for removing the condition (link)
	// Node id DOM node, type is 'any' | 'all'
	newConditionBlock: function(node, type, condition, errchk) {
		var self = this, o = self.options;

		// Condition
		var selStr = "<select class='rulecinput' name='data[Site][rules]["+o.seq+"][conditions"+type+"]["+o.condSeq+"][name]'>";
		for (var i in conditionOptions) selStr += "<option value='"+conditionOptions[i].name+"'>"+conditionOptions[i].value+"</option>";
		selStr += "</select>";

		// Test -
		var coIndex = this.findCoIndex(condition);
		var tstStr = "<select class='rulecinput' name='data[Site][rules]["+o.seq+"][conditions"+type+"]["+o.condSeq+"][test]'>"
		for (var i in conditionOptions[coIndex].tests) tstStr += "<option value='"+conditionOptions[coIndex].tests[i].name+"'>"+conditionOptions[coIndex].tests[i].value+"</option>";
		tstStr += '</select>';
		
		// Value
		if (condition.value == undefined) condition.value == '';
		var valStr = "<input class='rulecinput rulecvalue' name='data[Site][rules]["+o.seq+"][conditions"+type+"]["+o.condSeq+"][value]' value='"+condition.value+"'/>";
		
		// Remove Condition Link
		var rmStr = "<a href='#' class='rulecremove noeffects' title='Remove this condition'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a>";
		var htmlStr = "<div class='rulecondition clearfix smallselect' id='condition"+o.seq+"-"+o.condSeq+"' name='condition"+o.seq+"-"+o.condSeq+"'>"+selStr+tstStr+valStr+rmStr+"<div class='ruleerrmsg clearfix' style='display:none'></div></div>";
		var block = $(htmlStr).appendTo(node);

		if (conditionOptions[coIndex].autocomplete != '') {
		  $(".rulecvalue", block).autocomplete({ source: conditionOptions[coIndex].autocomplete, minLength: 0, delay: 150 });  
		}
		
		$('.rulecinput', block).first().attr('selectedIndex',coIndex);

		testIndex = this.findTestIndex(condition, coIndex);
		$('.rulecinput', block).next().attr('selectedIndex',testIndex);
		
		$('.rulecvalue', block).blur($.proxy(this, "validateField"));
		if (errchk)
			$('.rulecvalue', block).trigger('blur');
		
		$('select', block).first().change($.proxy(this, "changeProperty"));
		$('a', block).click($.proxy(this, "removeCondition"));
		o.condSeq++;
	},
	removeCondition: function(evt) {
		$(evt.currentTarget).parent().remove();
		return false;
	},
	validateField: function(evt) {
		var self = this;
		var o = self.options;
		var value = evt.currentTarget.value;
		var block = $(evt.currentTarget).parent();
		var coIndex = $('.rulecinput', block).first()[0].selectedIndex;
		var condition = conditionOptions[coIndex];
		var errmsg = '';
		switch (condition.name) {
			case 'width' :
			case 'height' :
				if (! isNumber (value)) {
					errmsg = 'Please enter a number for this field.';
				} break;
			case 'ismobile' :
				if (value != 'true' && value != 'false') {
					errmsg = 'Is Mobile value must be true or false (lowercase).'
				} break;
			case 'istablet' :
				if (value != 'true' && value != 'false') {
					errmsg = 'Is Tablet value must be true or false (lowercase).'
				} break;
			case 'isconsole' :
				if (value != 'true' && value != 'false') {
					errmsg = 'Is Console value must be true or false (lowercase).'
				} break;
			case 'xhtmllevel' :	
				if (! isNumber (value)) {
					errmsg = 'Please enter a number for the XHTML level (between 0 and 5).';
				} else if (value > 5 || value < 0) {
					errmsg = 'Please enter a number between 0 and 5.';
				} break;
			case 'vendor' :
			case 'model' :
			case 'os' :
			case 'browser' :
				if (value.match(/[<|>]/)) {
					errmsg = 'This field can be made up of letters, numbers and most punctuation but not < and >';
				} break;
		}
		if (errmsg != '') {
			$('.ruleerrmsg', block).show().text(errmsg);
			$(evt.currentTarget).css('border','3px solid #EC1D25');
			o.error = 1;
		} else {
			$('.ruleerrmsg', block).hide().text('');
			$(evt.currentTarget).css('border','');
			o.error = 0 || o.error;
		}
		//debugger;
	},
	findTestIndex: function(condition, index) {
		for (var i in conditionOptions[index].tests) {
			if (conditionOptions[index].tests[i].name == condition.test)
				return i;
		}
		return 0;
	},
	findCoIndex: function(condition) {
		for (var i in conditionOptions) {
			if (condition.name == conditionOptions[i].name)
				return i;
		}
		return 0;
	},
	changeProperty: function(evt) {
		var self = this, o = self.options, tstStr = '';
		var coIndex = evt.currentTarget.selectedIndex;
		// Clear out tst select
		$(evt.currentTarget).next()[0].options.length = 0;
		// Generate tst options
		for (var i in conditionOptions[coIndex].tests)
			tstStr += "<option value='"+conditionOptions[coIndex].tests[i].name+"'>"+conditionOptions[coIndex].tests[i].value+"</option>";
		// Add new options
		$(evt.currentTarget).next().append(tstStr);
		valuefield = $(evt.currentTarget).next().next()[0];
		valuefield.value = "";
		$(valuefield).autocomplete('destroy');
		if (conditionOptions[coIndex].autocomplete != '') {
		  $(valuefield).autocomplete({ source: conditionOptions[coIndex].autocomplete, minLength: 0, delay: 150  });  
		}
	},
	setFields: function(field) {
		alert(this.data.options.options[field][0]);
	},
	destroy: function() {			
		this.element.next().remove();
	}
}
$.widget("ui.hdrule", HDRule);

function RuleSet() {
	var parent = $('.rulesetbox').get(0);
	for(var i in rulesData) {
		$('<div></div>').appendTo(parent).hdrule(rulesData[i]);
	}
	$(".rulesetbox").sortable();
	$('.ruleadd').click(function() {
		var obj = $('<div></div>').appendTo(parent).hdrule({errorcheck: false});
		$('.rulebartoggle', obj).click();
		return false;
	}); 
}

var HDDetectionWidget = {
	options: {
		header: '',
		priority: '',
		filter: '',
		match: '',
		seq: 0
	},
	
	_create: function() {
		var self = this, o = this.options;
		o.seq = ruleInstanceCount++;
		o.condSeq = 0;
		o.self = this;
		o.parent = this.element;
		
		// Template for this widget
		var template = "";
		template += "<div class='dwouter'>";
		
		if (o.seq == 0) {
		// Header
		  template += "<div class='dwheader'>";
		  template += "<div class='dwstdcol'>Matching Header</div>";
		  template += "<div class='dwsmlcol'>Priority</div>";
		  template += "<div class='dwstdcol'>Filter String</div>";
		  template += "<div class='dwstdcol'>Match String</div>";
		  template += "</div>";
		}
		
		// Body
		template += "<div class='dwitem clearboth'>";
		template += "<input class='dwheader dwstdcol' id='dwheader%' name='data[Device][detection][%][header]' size='40' value='"+o.header+"'/>";
		template += "<input class='dwpriority dwsmlcol' id='dwpriority%' name='data[Device][detection][%][priority]' size='40' value='"+o.priority+"'/>";
		template += "<input class='dwfilter dwstdcol' id='dwfilter%' name='data[Device][detection][%][filter]' size='40' value='"+o.filter+"'/>";
		template += "<input class='dwmatch dwstdcol' id='dwmatch%' name='data[Device][detection][%][match]' size='40' value='"+o.match+"'/>";
		template += "<span class='dwsmltst dwbutton cssbutton bluegradient'>Mini Test</span>";
		template += "<span class='dwbigtst dwbutton cssbutton bluegradient'>Full Test</span>";
		template += "<span class='dwremove cssbutton orangegradient dwbutton '>Remove</span>";		
		template += "</div></div>";
		
		template = template.replace(/%/g,o.seq);
		o.block = $(template).appendTo(o.parent);
		$('.dwsmltst', o.block).click($.proxy(this, "smltest"));
		$('.dwbigtst', o.block).click($.proxy(this, "fulltest"));
		$('.dwremove', o.block).click($.proxy(this, "removeCondition"));
		$('#loadingDiv')
	      .hide()  // hide it initially
	      .ajaxStart(function() {
	          $(this).show();
	      })
	      .ajaxStop(function() {
	          $(this).hide();
	      });
	},
	
	removeCondition: function(evt) {
		$(evt.currentTarget).parent().remove();
		return false;
	},
	
	smltest: function(evt) {
		var self = this, o = self.options;
		$('#result').load('/admin/devices/minitest',
		  {
			'data[Device][_id]': $("#DeviceId").val(),
			'data[Device][vendor]': $("#DeviceHdSpecsGeneralVendor").val(),
			'data[Device][model]': $("#DeviceHdSpecsGeneralModel").val(),
			'data[Device][rule][header]': $("#dwheader"+o.seq).val(),
			'data[Device][rule][priority]': $("#dwpriority"+o.seq).val(),
			'data[Device][rule][filter]': $("#dwfilter"+o.seq).val(),
			'data[Device][rule][match]': $("#dwmatch"+o.seq).val()
		  });	  
	},
	
	fulltest: function(evt) {
		var self = this, o = self.options;
		$('#result').load('/admin/devices/fulltest',
		  {
			'data[Device][_id]': $("#DeviceId").val(),
			'data[Device][vendor]': $("#DeviceHdSpecsGeneralVendor").val(),
			'data[Device][model]': $("#DeviceHdSpecsGeneralModel").val(),
			'data[Device][rule][header]': $("#dwheader"+o.seq).val(),
			'data[Device][rule][priority]': $("#dwpriority"+o.seq).val(),
			'data[Device][rule][filter]': $("#dwfilter"+o.seq).val(),
			'data[Device][rule][match]': $("#dwmatch"+o.seq).val()
		  });	  	  
	},
	
	destroy: function() {			
		this.element.next().remove();
	}
}
$.widget("ui.hddetectionwidget", HDDetectionWidget);

// Helps out with managing detection rules for profiles.
function DetectionWidget() {
	var parent = $('.devicedetectionwidget').get(0);
	for(var i in detectionData) {
		$('<div></div>').appendTo(parent).hddetectionwidget(detectionData[i]);
	}
	$('.devicedetectionAdd').click(function() {
		var obj = $('<div></div>').appendTo(parent).hddetectionwidget({errorcheck: false});
		return false;
	}); 	
}

// Format Form Errors
$(document).ready(function() {
	
	$("div.text input").wrap("<div class='input-wrapper'></div>");
	$("div.password input").wrap("<div class='input-wrapper'></div>");
	$("div.textarea textarea").wrap("<div class='input-wrapper'></div>");
	$("div.file input").wrap("<div class='input-wrapper'></div>");
	
	$("input.form-error").parent().css( 'background-color', '#EF756F' );
	//$("input.form-error").css( 'border-color', '#777' );
	
});
