// Define a global namespace object
var FA = window.FA || {};

/********************************************************************
 Customization
*********************************************************************/
$.fn.isVisible = function() {return this.css('display') != 'none';}

jQuery.fn.extend({
	//---------------------------------------------------------------
	displayBox : function() {
		FA.DisplayBox.display($(this))
	},

	//---------------------------------------------------------------
	pulsate : function(speed, callback) {
		// Use FadeTo to avoid the 'display:none' of FadeOut
		return $(this).fadeTo(speed, 0.01, function(){$(this).fadeTo(speed, 1.0, callback)});
	},

	//---------------------------------------------------------------
	scrollTo : function(speed, easing) {
		return this.each(function() {
			var targetOffset = $(this).offset().top;
			$('html,body').animate({scrollTop: targetOffset}, speed, easing);
		});
	}
});

/********************************************************************
 Class: Page
*********************************************************************/
FA.Page = function()
{
	return {
		//---------------------------------------------------------------
		init : function(e)
		{
			// Add 'target=_blank' attribute to associated <a> elements
 			$('a.targetBlank').each(function(){this.target = "_blank";});

			// Add 'expand' button to associated textareas
			$('textarea.expand').each(function(){FA.TextareaExpander.setup(this);});

			// Add 'bbCode' buttons to associated textareas
			$('textarea.bbCodeSetup').each(function(){FA.BBCode.setup(this);});
		}
	}
}();

/********************************************************************
 Class: Utility
*********************************************************************/
FA.Util = function()
{
	return {
		//---------------------------------------------------------------
		trim : function(value) {
			return value.replace(/^\s+|\s+$/g, '');
		},
		lTrim : function(value) {
			return value.replace(/^\s+/, '');
		},
		rTrim : function(value) {
			return value.replace(/\s+$/, '');
		}
	}
}();

/********************************************************************
 Class: Form
*********************************************************************/
FA.Form = function()
{
	var _isValid;
	var _isFocusSet;

	return {
		//---------------------------------------------------------------
		init : function()
		{
			FA.Form.isValid(true);
			_isFocusSet = false;
		},

		//---------------------------------------------------------------
		validateForm : function(ignoreTransition)
		{
			FA.Form.init();

			var list = $('p.validation');
			for (var i=0, len=list.length; i<len; ++i)
			{
				var id = list[i].id.replace('v-', '');
				if(id != list[i].id) {
					FA.Form.isPresent(id);
				}
			}

			if(FA.Form.isValid() && !ignoreTransition) {
				$('#submitButtons').hide();
				$('#submitMessage').show();
			}

			return FA.Form.isValid();
		},

		//---------------------------------------------------------------
		isPresent : function(inputId)
		{
			var input = $('#' + inputId);
			var message = $('#v-' + inputId);

			// Check if the value of the input is empty
			if($.trim(input.val()) == '')
			{
				FA.Form.isValid(false);

				// Add 'required' class to input and display validation message
				input.addClass('required');
				message.fadeIn();

				// Set focus to the first input
				if(!_isFocusSet) {
					input.focus();
					_isFocusSet = true;
				}
			}
			else
			{
				// Clear class and hide validation message
				input.removeClass('required');
				message.hide();
			}
		},

		//---------------------------------------------------------------
		isValid : function(value)
		{
			if(typeof value != 'undefined') {_isValid = value;}
			return _isValid;
		}
	}
}();

/********************************************************************
 Class: Async
*********************************************************************/
FA.Async = function()
{
	return {
		rootUrl : '/library/php/async',

		//---------------------------------------------------------------
		getGlobalVar : function(xmlDoc, attribute)
		{
			var global = xmlDoc.getElementsByTagName('global');

			return global.length > 0
				? global[0].getAttribute(attribute)
				: '';
		},

		//---------------------------------------------------------------
		getObjectVar : function(xmlDoc, object, attribute)
		{
			var object = xmlDoc.getElementsByTagName(object);

			return object.length > 0
				? object[0].getElementsByTagName(attribute)[0].firstChild.nodeValue
				: '';
		},

		//---------------------------------------------------------------
		getContentEncoded : function(xmlDoc, tagName)
		{
			var value = '';

			var content = xmlDoc.getElementsByTagName(tagName);
			if(content.length > 0)
			{
				value = FA.Util.isDefined(content[0].textContent)
					? content[0].textContent
					: content[0].text;
			}

			return value;
		}
	}
}();

/********************************************************************
 Class: DisplayBox
 Adapted from http://malsup.com/jquery/block/
*********************************************************************/
FA.DisplayBox = function()
{
	var _width = null;
	var _height = null;

	//---------------------------------------------------------------
	function handler(e)
	{
		if((e.keyCode && e.keyCode == 27) || (e.type == 'click' && $(e.target).parents('div#displayBoxWrap').length == 0))
		{
			FA.DisplayBox.remove(e)
		}
		return true;
	}

	return {
		//---------------------------------------------------------------
		display : function(el)
		{
			_width = _width || el.width() + 10;
			_height = _height || el.height() + 10;

			var winWidth = window.innerWidth || document.body.clientWidth;
			var winHeight = window.innerHeight || document.body.clientHeight;

			var l = parseInt((winWidth - _width) / 2) + 'px';
			var t = parseInt((winHeight - _height) / 2) + 'px';

			var overlay = $('<div id="displayBoxOverlay"></div>');
			overlay.css({backgroundColor: '#FFF', opacity: '0.6', 'z-index': 1000, position: 'fixed', top: 0, left: 0, width: '100%', height: '100%'});

			var box = $('<div id="displayBoxWrap"></div>');
			box.css({width: _width, height: _height, left: l, top: t, 'z-index': 1001, position: 'fixed'});

			$([overlay[0], box[0]]).appendTo('body');
			box.append(el.show());

			$().bind('click', handler).bind('keypress', handler);
		},

		//---------------------------------------------------------------
		remove : function()
		{
			$().unbind('click',handler).unbind('keypress', handler);
			$('#displayBoxOverlay').fadeOut();
			$('#displayBoxWrap').fadeOut();
		}
	}
}();

/********************************************************************
 Class: TextareaExpander
*********************************************************************/
FA.TextareaExpander = function()
{
	var _minIcon = 'http://www.aminus3.com/library/img/misc/button_minimize.gif';
	var _maxIcon = 'http://www.aminus3.com/library/img/misc/button_maximize.gif';
	var _multiplier = 4;

	return {
		//---------------------------------------------------------------
		setup : function(textarea)
		{
			// Define custom attribute (default number of rows)
			$(textarea).attr('defaultRows', textarea.rows);

			// Create link and insert after textarea
			var expandLink = $('<a />')
				.attr({href: '#', title: "Maximize/minimize the size of the text box", tabindex: -1})
				.addClass('img')
				.insertAfter($(textarea));

			// Create image and append to link
			var expandImg = $('<img />')
				.attr({id: 'button_' + textarea.id, alt: "Maximize/minimize", src: _maxIcon, width: 9, height: 9, tabindex: -1})
				.addClass('expandButton').bind('click', FA.TextareaExpander.apply)
				.appendTo(expandLink);
		},

		//---------------------------------------------------------------
		apply : function(e)
		{
			e.preventDefault();

			var textarea = $(this).parent().prev('textarea.expand');

			if(textarea.attr('rows') == textarea.attr('defaultRows')) {
				textarea.attr('rows', textarea.attr('rows') * _multiplier);
				$(this).attr('src', _minIcon);
			}
			else {
				textarea.attr('rows', textarea.attr('defaultRows'));
				$(this).attr('src', _maxIcon);
			}
		}
	}
}();

/********************************************************************
 Class : BBCode
*********************************************************************/
FA.BBCode = function()
{
	var _buttonName = 'bbButton';
	var _messageName = 'bbMessage';
	var _tagList = {
		a : Array('clear', '', '', 'bbClear', "Close all open bbCode tags"),
		b : Array('b', '[b]', '[/b]', 'bbBold', "Format selected text with bold - [b]text[/b]"),
		i : Array('i', '[i]', '[/i]', 'bbItalic', "Format selected text with italic - [i]text[/i]"),
		u : Array('u', '[u]', '[/u]', 'bbUnderline', "Format selected text with underline - [u]text[/u]"),
		l : Array('l', '[list]', '[/list]', 'bbList', "Format selected lines as a list - [list]text[/list]"),
		o : Array('o', '[list=]', '[/list]', 'bbOrderedList', "Format selected lines as an ordered list - [list=]text[/list]"),
		h : Array('light', '[h]', '[/h]', 'bbLight', "Format selected text with light-color - [h]text[/h]"),
		c : Array('code', '[code]', '[/code]', 'bbCode', "Format selected text as code - [code]text[/code]"),
		q : Array('quote', '[quote]', '[/quote]', 'bbQuote', "Format selected text as quoted - [quote]text[/quote]"),
		w : Array('url', '[url=http]', '[/url]', 'bbUrl', "Create link to url - [url=http://www.website.com/]text[/url]")
	};

	//---------------------------------------------------------------
	function buildButton(elem, key)
	{
		var tagDetails = _tagList[key];

		var codeButton = document.createElement('input');
		codeButton.id = _buttonName + key;
		codeButton.type = 'button';
		codeButton.href = '#';
		codeButton.value = tagDetails[0];
		codeButton.title = tagDetails[4];
		codeButton.attrKey = key;
		codeButton.attrTargetId = elem.id;
		$(codeButton).addClass('bbCode '+ tagDetails[3]);
		$(codeButton).bind('click', FA.BBCode.applyStyle);

		return codeButton;
	}

	//---------------------------------------------------------------
	function ieFormatSelection(textSelected, openTag, closeTag)
	{
		// Remove extra spaces (and re-add later)
		var spaceL = textSelected.length != FA.Util.lTrim(textSelected).length ? ' ' : '';
		var spaceR = textSelected.length != FA.Util.rTrim(textSelected).length ? ' ' : '';
		textSelected = FA.Util.trim(textSelected);

		// Add tags around selection
		return spaceL + openTag + textSelected + closeTag + spaceR;
	}

	//---------------------------------------------------------------
	function mozFormatSelection(textArea, openTag, closeTag)
	{
		// Get text selection start and end positions
		var selStart = textArea.selectionStart;
		var selEnd = textArea.selectionEnd;
		if(selEnd == 1) selEnd = textArea.textLength;

		var textPrepend = textArea.value.substring(0,selStart);
		var textSelected = textArea.value.substring(selStart, selEnd)
		var textAppend = textArea.value.substring(selEnd, textArea.textLength);

		// Remove extra spaces (and re-add later)
		var spaceL = textSelected.length != FA.Util.lTrim(textSelected).length ? ' ' : '';
		var spaceR = textSelected.length != FA.Util.rTrim(textSelected).length ? ' ' : '';
		textSelected = FA.Util.trim(textSelected);

		return textPrepend + spaceL + openTag + textSelected + closeTag + spaceR + textAppend;
	}

	return {
		//---------------------------------------------------------------
		setup : function(elem)
		{
			var wrapper = document.createElement('div');

			wrapper.appendChild(buildButton(elem, 'b'));
			wrapper.appendChild(buildButton(elem, 'i'));
			wrapper.appendChild(buildButton(elem, 'h'));
			wrapper.appendChild(buildButton(elem, 'w'));

			var message = document.createElement('p');
			message.id = _messageName;
			message.innerHTML = "Select the text you wish to format then click the button to apply formatting.";
			message.style.display = "none";
			$(message).addClass('validation');
			wrapper.appendChild(message);

			elem.parentNode.appendChild(wrapper);
		},

		//---------------------------------------------------------------
		applyStyle : function(e)
		{
			e.preventDefault();
			e.stopPropagation();

			var codeButton = e.target;
			var tagDetails = _tagList[codeButton.attrKey];
			var textArea = $('#' + codeButton.attrTargetId)[0];
			var message = $('#' + _messageName);

			textArea.focus();

			if($.browser.msie)
			{
				var textSelected = document.selection.createRange().text;
				if(textSelected) {
					message.hide();
					document.selection.createRange().text = ieFormatSelection(textSelected, tagDetails[1], tagDetails[2]);
					return;
				}
			}
			else if(textArea.selectionEnd && textArea.selectionEnd - textArea.selectionStart > 0)
			{
				message.hide();
				textArea.value = mozFormatSelection(textArea, tagDetails[1], tagDetails[2]);
				return;
			}

			message.fadeIn();
		}
	}
}();
