////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	$.fn.exists = function() { return ($(this).length > 0); }
	$.fn.visible = function() { return $(this).is(':visible'); }
	$.fn.disableSelection = function() { return $(this).css('user-select', 'none').css('-khtml-user-select', 'none').css('-moz-user-select', 'none').css('-o-user-select', 'none').css('-webkit-user-select', 'none'); }
	$.fn.enableSelection = function() { return $(this).css('user-select', 'text').css('-khtml-user-select', 'text').css('-moz-user-select', 'text').css('-o-user-select', 'text').css('-webkit-user-select', 'text'); }
	$.fn.setBusy = function() { $(this).trigger('restoreCursor'); var cursor = $(this).css('cursor'); $(this).bind('restoreCursor', function() { $(this).css('cursor', cursor).unbind('restoreCursor'); }).css('cursor', 'wait'); return $(this); }
	$.fn.unsetBusy = function() { $(this).trigger('restoreCursor'); return $(this); }
	$.fn.enableMe = function() { if ($(this).attr('_af_disabled') == 'disabled') $(this).removeAttr('_af_disabled').unsetBusy().fadeTo(0, 1); return $(this); }
	$.fn.disableMe = function() { if ($(this).attr('_af_disabled') != 'disabled') $(this).attr('_af_disabled', 'disabled').setBusy().fadeTo(0, 0.4); return $(this); }
	$.fn.matchHeight = function() { var maxH = 0; $(this).each(function() { var h = $(this).height(); if (h > maxH) maxH = h; }).height(maxH); }
	$.fn.fitText = function(e) {  var t = $(this); t.html('<span>' + t.text() + '</span>'); var s = t.find('span'); var oS = 4; s.css('font-size', oS).css('white-space', 'nowrap'); var sL = s.text().length, nS = Math.floor((t.width() / sL) * (oS / (s.width() / sL))); s.css('font-size', nS); var tH = t.height(), sH = s.height(); if (sH > tH) s.css('font-size', Math.floor(nS * (tH / sH))); };
	$.selectAll = function(id) { var t = $('#' + id); if (t) { t.focus().select(); } }
	$.rand = function(min,max) { return Math.floor(Math.random() * (max - min + 1) + min); }
	$.preloadImages = function(urls) { var i=0,x,y,z=[]; while(x = arguments[i++]) { y = document.createElement('img'); y.src = x; z.push(y); } }

	$.fn.appendURLContents = function(url) {
		var x = $(this);
		x.val(
			x.val() +
			$.ajax({
				url: url,
				async: false
			}).responseText
		);
	}

	$.getCookie = function(name) {
		var x = document.cookie.split(';'), y;
		for (s in x) {
			y = x[s].split('=');
			if ($.trim(y[0]) == name)
				return unescape(y[1]);
		}
		return null;
	}

	$.setCookie = function(name, value, duration) {
		if (!duration) duration = 31536000;
		var date = new Date();
		date.setTime(date.getTime() + duration);
		var expires = date.toGMTString();
		document.cookie = name + '=' + value + '; expires=' + expires + '; path=/';
	}

	$.removeCookie = function(name) {
		document.cookie = name + '=' + '; expires=Thu, 1 Jan 1970 12:00:00 UTC; path=/';
	}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Widgets
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	$(function() {

		/*** Misc ***/

			$('.selectOnClick').click(function(e) { $(this).select(); });

			$('.disableOnClick').click(function(e) {
				var t = $(this);
				if (t.attr('_af_disabled') == 'disabled') {
					e.preventDefault(); e.stopPropagation(); 
					return false;
				}
				else
				{
					if (t.is('input:submit'))
						t.closest('form').submit(function() { t.disableMe(); });
					else
						t.disableMe();
					return true; 
				}
			});

		/*** WebWidget_SimpleHideableArea ***/

			$.fn.simpleHideableArea = function(startHidden, type) {
				var x = $(this);
				var id = x.attr('id'), className = x.attr('class');
				x.attr('id', id + '_old');
				var _outer = $('<div id="' + id + '_af_simpleHideableArea" class="' + className + '"></div>').insertBefore(x);
				var _heading = x.find('.sha_title').detach();
				var _content = $('<div class="sha_content"></div>').appendTo(_outer);
				var wait = false;
				switch (type) {
					case 2:
						_content._af_loadurl = x.text();
						break;
					default:
						_content.html(x.html());
						break;
				}
				_heading.prependTo(_outer).click(function() {
					if (_content._af_loadurl) {
						if (wait == false) {
							_heading.setBusy();
							_content.hide();
							wait = true;
							$.get(_content._af_loadurl, function(data) {
								_content.html(data);
								_content._af_loadurl = null;
								_content.show();
								wait = false;
								_heading.unsetBusy();
							});
						}
					}
					else
						_content.toggle();
				}).disableSelection();
				x.remove();
				if (startHidden)
					_content.hide();
				return;
			}

		/*** WebWidget_HideableArea ***/

			$.fn.hideableArea = function(startHidden, type) {
				var x = $(this);
				var id = x.attr('id'), className = x.attr('class');
				x.attr('id', id + '_old');
				var _outer = $('<div id="' + id + '_af_hideableArea" class="' + className + '"></div>').insertBefore(x);
				var _heading = x.find('> h3').detach();
				var _message = x.find('> h4').detach().appendTo(_outer);
				var _content = $('<div class="content">' + x.html() + '</div>').appendTo(_outer);
				_heading.attr('class', 'actionButton').html('<span></span> ' + _heading.html()).prependTo(_outer).click(function() {
					_content.toggle();
					_heading.find('> span').html( (_content.css('display') == 'none') ? 'Show' : 'Hide' );
				}).disableSelection();
				x.remove();
				if (startHidden) {
					_heading.find('> span').html('Show');
					_content.hide();
				}
				else
					_heading.find('> span').html('Hide');				
			}

		/*** WebWidget_TabbedArea ***/

			$.fn.tabbedArea = function(initialTabPos) {
				var x = $(this);
				var id = x.attr('id'), className = x.attr('class');
				var _outer = $('<div id="' + id + '_af_tabbedArea" class="' + className + '"><ul class="tabs"></ul><ul class="content"></ul></div>').insertBefore(x);
				var _tabs = _outer.find('> .tabs');
				var _content = _outer.find('> .content');
				var _firstTab = null, _activeTab = null, n = 0;
				if (!initialTabPos)
					initialTabPos = 0;
				$(this)
					.find('> li')
						.each(function() {
							var x = $(this);
							var y = x.find('> h2');
							var title = y.html();
							y.remove();
							var content = x.html();
							var tc = $('<li>' + content + '</li>').appendTo(_content);
							var tt = $('<li class="taboff">' + title + '</li>').appendTo(_tabs);
							tt.click(function() {
								if (_activeTab != null)
									_activeTab.removeClass('tabon').addClass('taboff');
								_activeTab = $(this).removeClass('taboff').addClass('tabon');
								_content.find('> li').hide();
								tc.show();
							});
							tc.hide();
							if (_firstTab == null && n == initialTabPos)
								_firstTab = tt;
							n++;
						});
				x.remove();
				if (_firstTab != null)
					_firstTab.trigger('click');
			}

		/*** WebWidget_Popup ***/

			$.fn.windowedPopup = function(id, url, width, height) {
				var x = $(this);
				x.click(function(e) {
					var left, top;
					e.preventDefault();

					if (height > screen.height)
					{
						height = screen.height;
						top = 0;
					}
					else
						top = (screen.height - height) / 2;
					
					left = (screen.width - width) / 2;
					
					var features = 'location=1,resizable=1,scrollbars=1,status=0,toolbar=0,menubar=0,directories=0,width=' + width + ',height=' + height + ',left=' + left + ',top=' + top;
					var w = window.open(url, id, features);
					w.focus();
				});
			}

	});
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Legacy Functions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	function af_joinQueryString(qsa)
	{
		var a = Array();
		var s = '';

		for (var i in qsa)
		{
			a.push(i + '=' + qsa[i]);
		}

		s = a.join('&');

		return s;
	}

	function af_splitQueryString(qs)
	{
		var a = qs.split('&');
		var b;
		var c = Array();
		var i;
		
		for(i=0;i < a.length;i++)
		{
			b = a[i].split('=');
			if (b[0] && b[1])
				c[ b[0] ] = b[1];
		}
		
		return c;
	}

	function af_reload()
	{
		location.reload(true);
	}

	function af_redirectAndReplace(u)
	{
		self.parent.window.location.replace(u);
	}

	function af_getPref(title, key)
	{
		var cookie_name = title + '_prefs';
		s = af_getCookie(cookie_name);

		if (s == null)
			return null;

		prefs = af_splitQueryString(s);
		
		return prefs[key];
	}

	function af_setPref(title, key, value, reload)
	{
		var cookie_name = title + '_prefs';
		var prefs, s, a;

		s = af_getCookie(cookie_name);

		if (s == null)
		{
			a = Array();
			a[key] = value;
			s = af_joinQueryString(a);
		}
		else
		{
			prefs = af_splitQueryString(s);
			
			if (value == '')
				delete prefs[key];
			else
				prefs[key] = value;	

			s = af_joinQueryString(prefs);
		}

		af_setCookie(cookie_name, s, 365);
		
		if (reload == true)
			window.location.reload();
	}

	function af_clearPref(title, key, reload)
	{
		af_setPref(title, key, '', reload);
	}

	function af_setCookie(name,value,days) {
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	}

	function af_getCookie(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0)
			{
				value = unescape(c.substring(nameEQ.length,c.length));
				
				return value;
			}
		}
		return null;
	}
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Legacy Widgets
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/** WebWidget_Form **/

		$(function() {

			$('.checkboxLabel').each(function() {
				var t = $(this), x = t.prev('.checkboxButton'), b = x.find('input');
				t
					.disableSelection()
					.css('cursor', 'pointer')
					.click(function() {
						if (b)
							b.trigger('click');
					});
			});

			$('.radioLabel').each(function() {
				var t = $(this), x = t.prev('.radioButton'), b = x.find('input.radio');
				t
					.disableSelection()
					.css('cursor', 'pointer')
					.click(function() {
						if (b)
							b.attr('checked', 1).trigger('click');
					});
			});
		
		});
		
		function af_WebWidget_Form_TableContainer(tableId,controlFieldName,min,max,columns,orderable)
		{
			this.instanceName = tableId;
			this.table = document.getElementById(tableId);
			this.controlField = document.getElementById(controlFieldName);
			this.columns = columns;
			this.columnsLength = 0;
			
			for (x in columns)
				this.columnsLength++;
			
			this.min = min;
			this.max = max;
			this.orderable = orderable;
			
			this.txt_actionsColumn = '<input type="button" class="button actionButton" value="&times;" onclick="' + this.instanceName + '.deleteRow(this);">';
			
			if (this.orderable == true)
			{
				this.txt_actionsColumn += '<input type="button" class="button actionButton" value="&uArr;" onclick="' + this.instanceName + '.moveRowUp(this);">' +
				'<input type="button" class="button actionButton" value="&dArr;" onclick="' + this.instanceName + '.moveRowDown(this);">';
			}
			
			this.txt_idRegExpSuffix = '\_\%ID\%';
			this.txt_classRow1 = 'row1';
			this.txt_classRow2 = 'row2';
			this.txt_classEmptyRow = 'rowEmpty';
			this.emptyRowIndex = -1;
		}

		af_WebWidget_Form_TableContainer.prototype =
		{
			addEmptyRow: function()
			{
				tr = this.table.insertRow(this.table.rows.length);

				tr.className = this.txt_classEmptyRow;
				
				td = tr.insertCell(tr.cells.length);
				td.innerHTML = this.txt_actionsColumn;
				td.colSpan = this.columnsLength + 1;
				td.innerHTML = 'No rows added yet. Click on <strong>Add Row</strong> to add one.';

				this.emptyRowIndex = tr.rowIndex;

				return tr;
			},

			swapRows: function(x,y)
			{
				for(k in this.columns)
				{
					eX = document.getElementById(k + '_' + x);
					eY = document.getElementById(k + '_' + y);
					
					if (eX.type == "checkbox" && eY.type == "checkbox")
					{
						tmp = eX.checked;
						eX.checked = eY.checked;
						eY.checked = tmp;
					}
					else
					{
						tmp = eX.value;
						eX.value = eY.value;
						eY.value = tmp;
					}
				}
				
				return true;
			},

			moveRowUp: function(t)
			{
				row = t.parentNode.parentNode;
				x = row.rowIndex;

				if (x < 2)
					return false;

				return this.swapRows(x, x - 1);
			},

			moveRowDown: function(t)
			{
				n = parseInt(this.controlField.value);
				row = t.parentNode.parentNode;
				x = row.rowIndex;
				
				if (x >= n)
					return false;
					
				return this.swapRows(x, x + 1);
			},

			addRow: function(id)
			{
				n = parseInt(this.controlField.value);

				if (n >= this.max)
				{
					alert('You may only have up to ' + this.max + ' rows in this table.');
					return false;
				}

				if (this.getCount() == 0 && this.emptyRowIndex != -1)
				{
					this.table.deleteRow(this.emptyRowIndex);
					this.emptyRowIndex = -1;
				}

				this.incCount();
				n = parseInt(this.controlField.value);

				tr = this.table.insertRow(this.table.rows.length);

				if (n % 2 == 0)
					tr.className = this.txt_classRow2;
				else
					tr.className = this.txt_classRow1;
				
				td = tr.insertCell(tr.cells.length);
				td.innerHTML = this.txt_actionsColumn;
				td.className = 'actions';

				for(k in this.columns)
				{		
					td = tr.insertCell(tr.cells.length);
					rx = new RegExp(k + this.txt_idRegExpSuffix, 'g');
					c = this.columns[k];
					td.innerHTML = c.replace(rx, k + '_' + n);
					
					if (td.innerHTML.indexOf('type="hidden"') >= 0
					||	td.innerHTML.indexOf('type=hidden') >= 0)
						td.className = 'hidden';
				}

				return tr;
			},

			deleteRow: function(t)
			{
				n = parseInt(this.controlField.value);

				if (n <= this.min)
				{
					alert('You must have at least ' + this.min + ' rows in this table.');
					return false;
				}

				row = t.parentNode.parentNode;
				
				if (!row)
					return false;
				
				start = row.rowIndex;
				this.table.deleteRow(row.rowIndex);
				this.decCount();
				
				this.shiftRowsUp(start + 1);

				if (this.getCount() == 0)
					this.addEmptyRow();
				
				return true;
			},
			
			getCount: function()
			{
				return parseInt(this.controlField.value);
			},
			
			decCount: function()
			{
				this.controlField.value = parseInt(this.controlField.value) - 1;
				
				return true;
			},
			
			incCount: function()
			{
				this.controlField.value = parseInt(this.controlField.value) + 1;

				return true;
			},
			
			shiftRowsUp: function(start)
			{
				oldCount = parseInt(this.controlField.value) + 1;
			
				if (start > oldCount)
					return;
				
				for(i=start; i <= oldCount;i++)
				{	
					for(k in this.columns)
					{
						e = document.getElementById(k + '_' + i);
						
						if (e == null)
							continue;
						
						newId = k + '_' + (i - 1);
						e.id = e.name = newId;
					}
					
					tr = this.table.rows[i - 1];
					
					if ((i - 1) % 2 == 0)
						tr.className = this.txt_classRow2;
					else
						tr.className = this.txt_classRow1;
				}

				return true;
			}
		}

		function af_WebWidget_Form_MSHandler_Target(mId, operator, value)
		{
			this.mId = mId;
			this.operator = operator;
			this.value = value;
		}

		af_WebWidget_Form_MSHandler_Target.prototype = {

			evaluate: function()
			{
				// get the field identified by mId
				// evaluate its current value against value using operator
				// return result
				
				// 1 - equal
				// 2 - notequal
				// 3 - greater than
				// 4 - less than
				
				var i, v, vv, value, operator, f, result = true;
				
				value = $('#' + this.mId).val();
				
				// Checkbox check
					if ($('#' + this.mId).is(':checkbox'))
					{
						f = $('input:checkbox[name=' + this.mId + ']:checked');
						
						if (f.length)
							value = f.val();
						else
							return false;
					}
				
				// Radio check
					if (value == null)
					{
						f = $('input:radio[name=' + this.mId + ']:checked');
						
						if (f.length)
							value = f.val();
						else
							return false;
					}
				
				if (this.value instanceof Array)
					vv = this.value;
				else
					vv = new Array(this.value);

				for (i in vv)
				{
					v = vv[i];

					operator = parseInt(this.operator);
					
					switch(operator)
					{
						case 1: // equal (OR)
							result = (value == v);
							
							if (result == true)
								return true;
							
							break;
						
						case 2: // not equal (AND)
							result = result && (value != v);
							break;
							
						case 3: // greater than (AND)
							result = result && (value > v);
							break;
							
						case 4: // less than (AND)
							result = result && (value < v);
							break;
							
						default:
							return false;
					}
				}
				
				return result;
			}

		}

		function af_WebWidget_Form_MSHandler(instanceName)
		{
			this.instanceName = instanceName;
			this.targets = new Array();
			this.deps = new Array();
			
		//	this.fot = new Array();
		}

		af_WebWidget_Form_MSHandler.prototype = {

			addTarget: function(targetId, mId, operator, value)
			{
				// create the target and add it to the target list
				x = new af_WebWidget_Form_MSHandler_Target(mId, operator, value);
				this.targets[targetId] = x;

				// add the targetId to the dep's list of targets
				if (this.deps[mId] == null)
					this.deps[mId] = new Array();

				this.deps[mId].push(targetId);
				
				return true;
			},

			checkM: function(mId)
			{
				// if this dep doesn't exist, bail
				if (this.deps[mId] == null || this.deps[mId].length == 0)
					return false;

				// step through targets for this dep
				for (i=0;this.deps[mId][i];i++)
				{
				
					targetId = this.deps[mId][i];
					target = this.targets[targetId];
					
					if (target == null)
						continue;

					if (target.evaluate() == false)
						this.hideTarget(targetId);
					else
						this.showTarget(targetId);
				}
				
				return true;
			},
			
			setFormRowClass: function(e, className)
			{
				e.className = className;	
				return true;
			},

			hideTarget: function(targetId)
			{
				//this.setFormRowClass(targetId, 'hidden');

				var e = document.getElementById('row_' + targetId);

				$(e).removeClass('visible').addClass('hidden');
				this.setDisabledState(e, true);
			},
			
			showTarget: function(targetId)
			{
				var e = document.getElementById('row_' + targetId);

				$(e).removeClass('hidden').addClass('visible');
				this.setDisabledState(e, false);
			},
			
			setDisabledState: function(e, state)
			{
				var l = e.childNodes.length;
				var i,x;
			
				for (i=0;i < l;i++)
				{
					x = e.childNodes[i];
					
					if (x.nodeName == "INPUT"
					||  x.nodeName == "SELECT"
					||  x.nodeName == "TEXTAREA")
						x.disabled = state;
					else
						this.setDisabledState(x, state);
				}
				
				return true;
			}
		}
