
var html_helper = new HTMLHelper();

function HTMLHelper()
{
	// Our elements.
	this.BACKGROUND_DIV 	= "overlayblackout";
	this.FOREGROUND_DIV 	= "popin";
	this.HELPER_INPUT 		= "popin_value";
	this.HELPER_LINK 		= "popin_enter";
	this.HELPER_TEXT		= "popin_prompt";
	this.HELPER_BOTTOM  = "popin_bottom";

	// Transitions go here.
	this.EFFECTS_IN = 0.05;
	this.EFFECTS_OUT = 0.15;

	// The different types of HTML we'll help with
	this.TYPE_LINK				= 1;
	this.TYPE_EMAIL				= 2;
	this.TYPE_BOLD				= 3;
	this.TYPE_ITALIC			= 4;
	this.TYPE_UNDERLINED	= 5;
	this.TYPE_EMBED				= 6;

	var textarea_element;
	var stored_selection = "";
	var stored_link = "";

	var ourbody, pbackground;

	function InitKeyHandler(cb)
	{
		GetElement(html_helper.HELPER_INPUT).onkeypress = GetKey;

		function GetKey(event)
		{
			var e = event || window.event;
			var code = e.charCode || e.keyCode;

			if(code == 13)
			{
				eval(cb);
			}
		}
	}

	this.Launch = function(html_type, telement)
	{
		textarea_element = telement;

		// Set up our background and append it to the body.
		ourbody = document.getElementsByTagName("body").item(0);
		pbackground = document.createElement("div");
		pbackground.setAttribute("id", html_helper.BACKGROUND_DIV);
		pbackground.style.display = 'none';
		pbackground.onclick = function() { html_helper.Cancel(); }
		ourbody.appendChild(pbackground);

		// Let's set up the positioning of the background and the prompt,
		// prior to doing anything else.
		GetElement(html_helper.BACKGROUND_DIV).style.top = 0 + "px";
		GetElement(html_helper.BACKGROUND_DIV).style.left = 0 + "px";
		GetElement(html_helper.BACKGROUND_DIV).style.width = ScrollDimensionsInfo()[0] + "px"; //"800px"; //dimensions[0] + "px";
		GetElement(html_helper.BACKGROUND_DIV).style.height = ScrollDimensionsInfo()[1] + "px"; //"600px"; //dimensions[1] + "px";
		GetElement(html_helper.BACKGROUND_DIV).style.zIndex = 20;

		GetPopup().style.top = (Math.round(GetPageScrollPos()+(InnerDimensionsInfo()[1]/3))) + "px";
		GetPopup().style.left = ((InnerDimensionsInfo()[0]-500)/2) + "px";
		GetPopup().zIndex = 99;

		switch(html_type)
		{
			case this.TYPE_LINK:
				GetLinkURL();
				break;

			case this.TYPE_EMAIL:
				GetEmailAddress();
				break;

			case this.TYPE_BOLD:
				LaunchSimpleHelper('Bold', '<strong>', '</strong>');
				break;

			case this.TYPE_ITALIC:
				LaunchSimpleHelper('Italic', '<em>', '</em>');
				break;

			case this.TYPE_UNDERLINED:
				LaunchSimpleHelper('Underlined', '<ins>', '</ins>');
				break;

			case this.TYPE_EMBED:
				launchEmbedHelper();
				break;

			default:
				alert("Blah");
				break;
		}
	}

	this.Cancel = function()
	{
		// Clear out any stored selections.
		stored_selection = "";
		stored_link = "";

		// We don't want this value lingering.
		this.ClearValueField();

		// Get rid of our prompt.
		GetElement(html_helper.BACKGROUND_DIV).style.display = "none";
		GetPopup().style.display = "none";

		// Show the select boxes again.
		ShowSelects();

		// Return focus to our textarea.
		GetElement(textarea_element).focus();
	}

	function GetLinkURL()
	{
		// We're carrying these values around. Better keep track of them.
		tarea = new TextareaManipulation();
		tarea.GetSelection(textarea_element);
		stored_selection = tarea.GetText();

		GetElement(html_helper.HELPER_TEXT).innerHTML = "Enter the URL you'd like to link to";
		GetElement(html_helper.HELPER_LINK).href = "javascript:html_helper.ReceiveLinkURL();";
		InitKeyHandler("html_helper.ReceiveLinkURL();");
		ShowPrompt();
	}

	this.ReceiveLinkURL = function()
	{
		stored_link = GetElement(html_helper.HELPER_INPUT).value;

		if(stored_link == "")
		{
			// We clear out values and try again, until the user enters a link
			// (or clicks cancel).
			this.Cancel();
			GetLinkURL();
		} else
		{
			if(stored_selection != "")
			{
				// We have a selection from which to wrap this URL around.
				tarea.Insert("<a href=\"" + DoGoodLink(stored_link) + "\">" + stored_selection + "</a>");
				this.Cancel();
			} else
			{
				GetElement(html_helper.HELPER_TEXT).innerHTML = "Enter a label (or leave blank)";
				GetElement(html_helper.HELPER_LINK).href = "javascript:html_helper.ReceiveLinkText();";
				GetElement(html_helper.HELPER_INPUT).value = "";
				InitKeyHandler("html_helper.ReceiveLinkText();");
				ShowPrompt();
			}
		}
	}

	function DoGoodLink(link)
	{
		// Check that we're starting with the correct protocol.
		var expr = /^(((https?|ftp):\/\/)|aim:goim|skype|\/)/i;

		if(!(expr.exec(link)))
		{
			link = "http://" + link;
		}

		return(link);
	}

	this.ReceiveLinkText = function()
	{
		var ins_text;
		if(document.getElementById(html_helper.HELPER_INPUT).value.length == 0)
		{
			ins_text = stored_link;
		} else
		{
			ins_text = document.getElementById(html_helper.HELPER_INPUT).value;
		}

		GetElement(textarea_element).value = GetElement(textarea_element).value + "<a href=\"" + DoGoodLink(stored_link) + "\">" + ins_text + "</a>";
		this.Cancel();
	}

	function GetEmailAddress()
	{
		// We're carrying these values around. Better keep track of them.
		tarea = new TextareaManipulation();
		tarea.GetSelection(textarea_element);
		stored_selection = tarea.GetText();

		GetElement(html_helper.HELPER_TEXT).innerHTML = "Enter the e-mail address you'd like to link to";
		GetElement(html_helper.HELPER_LINK).href = "javascript:html_helper.ReceiveEmailAddress();";
		InitKeyHandler("html_helper.ReceiveEmailAddress();");
		ShowPrompt();
	}

	this.ReceiveEmailAddress = function()
	{
		stored_link = GetElement(html_helper.HELPER_INPUT).value;

		if(stored_link == "")
		{
			// Again, if this is blank, we don't want to continue.
			this.Cancel();
			GetEmailAddress();
		} else
		{
			if(!(IsGoodEmail(stored_link)))
			{
				alert("Invalid e-mail address!");
				this.Cancel();
			} else
			{
				if(stored_selection != "")
				{
					// We have a selection from which to wrap this URL around.
					tarea.Insert("<a href=\"mailto:" + stored_link + "\">" + stored_selection + "</a>");
					this.Cancel();
				} else
				{
					GetElement(html_helper.HELPER_TEXT).innerHTML = "Enter a label (or leave blank)";
					GetElement(html_helper.HELPER_LINK).href = "javascript:html_helper.ReceiveEmailText();";
					GetElement(html_helper.HELPER_INPUT).value = "";
					InitKeyHandler("html_helper.ReceiveEmailText();");
					ShowPrompt();
				}
			}
		}
	}

	this.ReceiveEmailText = function()
	{
		var ins_text;
		if(document.getElementById(html_helper.HELPER_INPUT).value.length == 0)
		{
			ins_text = stored_link;
		} else
		{
			ins_text = document.getElementById(html_helper.HELPER_INPUT).value;
		}

		GetElement(textarea_element).value = GetElement(textarea_element).value + "<a href=\"mailto:" + stored_link + "\">" + ins_text + "</a>";
		this.Cancel();
	}

	function IsGoodEmail(email)
	{
		var our_good_chars = /[^a-z0-9\-_\.]/ig;
		var our_parts = email.split('@');

		if(our_parts.length < 2)
		{
			return(false);
		} else
		if((our_good_chars.exec(our_parts[0])) || (our_good_chars.exec(our_parts[1])))
		{
			return(false);
		} else
		{
			var our_domain_parts = our_parts[1].split(".");
			if(our_domain_parts.length < 2)
			{
				return(false);
			}
		}

		return(true);
	}

	function launchEmbedHelper() {
		$(html_helper.HELPER_TEXT).innerHTML = 'Paste the embed code from the site';
		$(html_helper.HELPER_LINK).href = 'javascript:html_helper.receiveEmbed();';
		$(html_helper.HELPER_BOTTOM).innerHTML =
			'<p class="large last"><em>Currently allowing embed tags from the following sites:</em></p>'
			+ '<p class="large last"><strong>YouTube</strong>, <strong>Revver</strong>, <strong>Vimeo</strong>, and <strong>GameTrailers</strong>.</p>'
		;
		InitKeyHandler('html_helper.receiveEmbed();');
		ShowPrompt();
	}

	this.receiveEmbed = function () {
		var embed_text = $(html_helper.HELPER_INPUT).value;
		if (embed_text.length !== 0) {
			new ContentEmbedder(embed_text, textarea_element);
		}

		this.Cancel();
	}

	function LaunchSimpleHelper(keyword, open, close)
	{
		tarea = new TextareaManipulation();
		tarea.GetSelection(textarea_element);
		var our_selection = tarea.GetText();

		if(our_selection != "")
		{
			// The user selected some text. Now we have to wrap that text in our tags.
			tarea.Insert(open + our_selection + close);
		} else
		{
			// We have to manually get something back from the user.
			GetElement(html_helper.HELPER_TEXT).innerHTML = "Enter Text You'd Like To Appear in " + keyword;
			GetElement(html_helper.HELPER_LINK).href = "javascript:html_helper.ReceiveSimple('" + open + "', '" + close + "');";
			InitKeyHandler("html_helper.ReceiveSimple('" + open + "', '" + close + "');");
			ShowPrompt();
		}
	}


	this.ReceiveSimple = function(open, close)
	{
		// Set the value we got, if we got any.
		this.RetrieveInput(GetElement(html_helper.HELPER_INPUT).value, open, close);

		// We are going to get the cursor position here.
		var tarea = new TextareaManipulation();
		tarea.GetVariables(textarea_element);
		tarea.ResetCursor(GetElement(textarea_element).value.length);

		// Close the dialogue box.
		this.Cancel();
	}

	this.RetrieveInput = function(text, open, close)
	{
		if(text.length > 0)
		{
			GetElement(textarea_element).value = GetElement(textarea_element).value + open + text + close;
		}
	}

	this.ClearValueField = function()
	{
		GetElement(html_helper.HELPER_INPUT).value = "";
	}

	function GetElement(id)
	{
		return(document.getElementById(id));
	}

	function ShowPrompt()
	{
		HideSelects();
		GetElement(html_helper.BACKGROUND_DIV).style.display = "block";
		GetPopup().style.display = "block";
		GetElement(html_helper.HELPER_INPUT).focus();
	}

	function GetPopup()
	{
		return(GetElement(html_helper.FOREGROUND_DIV));
	}

	// Browser related functions.
	function InnerDimensionsInfo()
	{
		var dimensions = new Array(2);

		if(self.innerWidth)
		{
			dimensions[0] = self.innerWidth;
			dimensions[1] = self.innerHeight;
		} else
		if(document.documentElement && document.documentElement.clientWidth)
		{
			dimensions[0] = document.documentElement.clientWidth;
			dimensions[1] = document.documentElement.clientHeight;
		} else
		if(document.body)
		{
			dimensions[0] = document.body.clientWidth;
			dimensions[1] = document.body.clientHeight;
		}

		return(dimensions);
	}

	function ScrollDimensionsInfo()
	{
		var dimensions = new Array(2);

		if(window.innerHeight && window.scrollMaxY)
		{
			dimensions[0] = document.body.scrollWidth;
			dimensions[1] = window.innerHeight + window.scrollMaxY;
		} else
		if(document.body.scrollHeight > document.body.offsetHeight)
		{
			dimensions[0] = document.body.scrollWidth;
			dimensions[1] = document.body.scrollHeight;
		} else
		{
			dimensions[0] = document.body.offsetWidth;
			dimensions[1] = document.body.offsetHeight;
		}

		return(dimensions);
	}

	function GetPageScrollPos()
	{
		var offset;

		if(self.pageYOffset)
		{
			offset = self.pageYOffset;
		} else
		if((document.documentElement) && (document.documentElement.scrollTop))
		{
			offset = document.documentElement.scrollTop;
		} else
		if(document.body)
		{
			offset = document.body.scrollTop;
		}

		return(offset);
	}

	function ShowSelects()
	{
		var selects = document.getElementsByTagName("select");
		for(var i = 0; i != selects.length; i++)
		{
			selects[i].style.visibility = "visible";
		}
	}

	function HideSelects()
	{
		var selects = document.getElementsByTagName("select");
		for(var i = 0; i != selects.length; i++)
		{
			selects[i].style.visibility = "hidden";
		}
	}

	// Our text field specific stuff.
	function TextareaManipulation()
	{
		var start_position = null, end_position = null, full_length = null, selection_text = null;
		var our_element;

		this.GetSelection = function(element)
		{
			our_element = document.getElementById(element);

			if((document.selection) && (document.selection.createRange) && (document.selection.createRange().parentElement))
			{
				our_element.focus();

				var original = our_element.value.replace(/\r\n/g, "\n");
				var therange = document.selection.createRange();

				var separator = Math.round(Math.random()*100*new Date()).toString(); //'#$%^%$#';

				selection_text = therange.text;
				therange.text = separator;
				var eitheror = our_element.value.split(separator);

				start_position = eitheror[0].length;
				therange.moveStart("character", -separator.length);

				therange.text = selection_text;

				end_position = our_element.value.length-eitheror[1].length;
			} else
			if(our_element.selectionStart >= 0)
			{
				start_position = our_element.selectionStart;
				end_position = our_element.selectionEnd;
				selection_text = (our_element.value.substr(start_position, end_position-start_position));
			}
		}

		this.GetText = function()
		{
			return(selection_text);
		}

		this.Insert = function(text)
		{
			our_element.value = our_element.value.substr(0, start_position) + text + our_element.value.substr(end_position, our_element.value.length);

			this.ResetCursor(start_position+text.length);
		}

		this.GetVariables = function(element)
		{
			our_element = element;
		}

		this.ResetCursor = function(position)
		{
			if(our_element.selectionStart)
			{
				our_element.focus();
				our_element.setSelectionRange(position, position);
			} else
			if(our_element.createTextRange)
			{
				var range = our_element.createTextRange();
				range.move('character', position);
				range.select();
			}
		}
	}
}
