﻿/// <reference path="jquery-1.4.4.js"/>
/// <reference path="jquery-ui-1.8.4.custom.min.js"/>
/// <reference path="jquery.a-tools-1.5.2.js"/>
/// <reference path="ProxiteamGenericScripts.js"/>
/// <reference path="BbCodeScripts.js"/>

Proxiteam.Forum = {};

(function()
{
	var replyTextboxId = "Body";

	Proxiteam.Forum.HookUpPostQuoteIcon = function (iconId, ajaxRequestUrl)
	{
		/// <summary>
		/// Sets up a Post's quote icon so that it ajax grabs the post's contents
		/// inside a quote tag to put in the reply textbox
		/// </summary>
		/// <param name="iconId" type="String">The icon's HTML ID</param>
		/// <param name="ajaxRequestUrl" type="String">The URL to call via Ajax to get quote</param>

		$("#" + iconId).click(function() { OnIconClicked(ajaxRequestUrl) });
	};

	function OnIconClicked(ajaxRequestUrl)
	{
		var replyTextbox = $("#" + replyTextboxId);
		if (replyTextbox.val() != "")
		{
			var reply = confirm("The reply textbox already contains some text.\r\nDo you want to remove that text and replace it with the quote?");
			if (reply == false)
				return;
		}

		$.ajax({
			url: ajaxRequestUrl,
			type: "POST",
			success: OnAjaxSuccess,
			error: Proxiteam.Util.Ajax.OnAjaxError,
			dataType: "json"
		});
	}

	function OnAjaxSuccess(data, request, textStatus)
	{
		var replyTextbox = $("#" + replyTextboxId);
		replyTextbox.val(data);
		replyTextbox.change();
	}

})();


(function() 
{
	var initialised = false;
	var bbCodeRenderAjaxUrl;
	var previewDiv = null;
	var previewDivId = "PostPreview";
	var appendPreviewDivToId = "ReplyForm";
	var replyTextbox = null;
	var replyTextboxId = "Body";
	var lastKeyDownTime = null;
	var replyTextboxValAtLastRefresh = null;
	var lastPreviewRefreshTime = null;
	var refreshPreviewIntervalTime = 1000;
	var refreshPreviewIntervalId = null;
	var whileTypingTimeSpan = 1000;
	var refreshAtLeastEveryTimeSpan = 5000;
	var ajaxInProgress = false;

	Proxiteam.Forum.InitialiseReplyTextBoxPreview = function (bbCodeRenderUrl)
	{
		/// <summary>
		/// Configures the Reply textbox so when changed a preview of the typed content is rendered
		/// </summary>
		/// <param name="bbCodeRenderUrl" type="String">The URL to call via Ajax to get BBCode rendered</param>

		if (initialised)
		{
			$.error("Do not call InitialiseReplyTextBoxPreview more than once");
			return;
		}

		replyTextbox = $("#" + replyTextboxId);
		bbCodeRenderAjaxUrl = bbCodeRenderUrl;
		
		replyTextbox.resizable({
			minWidth: 650, //If changing sizes remember to also change in CSS
			maxWidth: 650,
			minHeight: 200,
			handles: 's'
		});

		replyTextbox.focus(OnTextboxGainFocus);
		replyTextbox.blur(OnTextboxLoseFocus);
		replyTextbox.change(OnTextboxChanged);
		replyTextbox.keydown(function() { OnTextboxKeyDown(bbCodeRenderAjaxUrl) });

		if (replyTextbox.val() != "")
			RefreshPreview(true);

		initialised = true;
	};


	function OnTextboxKeyDown()
	{
		lastKeyDownTime = new Date();
	}

	function OnTextboxGainFocus()
	{
		if (refreshPreviewIntervalId == null)
			refreshPreviewIntervalId = setInterval(function() { RefreshPreview(false) }, refreshPreviewIntervalTime);
	}

	function OnTextboxLoseFocus()
	{
		if (refreshPreviewIntervalId != null)
		{
			clearInterval(refreshPreviewIntervalId);
			refreshPreviewIntervalId = null;
		}
	}

	function OnTextboxChanged()
	{
		RefreshPreview(true);
	}

	function RefreshPreview(force)
	{
		//Nothing has changed, don't refresh
		if (replyTextbox.val() == replyTextboxValAtLastRefresh)
			return;
		
		var nowTime = new Date();

		if (force == false)
		{
			//Don't refresh if it hasn't been whileTypingTimeSpan since the last keydown
			//however, do refresh if it has been over 5 seconds
			var timeSinceLastKeyDown = nowTime - lastKeyDownTime;
			var timeSinceLastRefresh = nowTime - lastPreviewRefreshTime;
			if (timeSinceLastKeyDown < whileTypingTimeSpan && 
			    timeSinceLastRefresh < refreshAtLeastEveryTimeSpan)
				return;
		}
		
		//If the reply is empty, don't show the preview div
		if (replyTextbox.val() == "")
		{
			replyTextboxValAtLastRefresh = replyTextbox.val();
			lastPreviewRefreshTime = new Date();
			if (previewDiv != null)
			{
				previewDiv.remove();
				previewDiv = null;
			}
			return;
		}

		//Don't run another AJAX request if one is already going
		if (ajaxInProgress)
			return;

		var replyBbCode = replyTextbox.val();

		$.ajax({
			url: bbCodeRenderAjaxUrl,
			type: "POST",
			complete: OnAjaxComplete,
			success: function(data, request, textStatus) { OnAjaxSuccess(data, request, textStatus, replyBbCode); },
			error: Proxiteam.Util.Ajax.OnAjaxError,
			dataType: "html",
			data: { bbCode: replyBbCode }
		});
		ajaxInProgress = true;
	}

	function OnAjaxSuccess(data, request, textStatus, replyTextboxVal)
	{
		if (previewDiv == null)
		{
			previewDiv = $("<div/>")
				.attr("id", previewDivId)
				.appendTo("#" + appendPreviewDivToId);

			$("<p/>")
				.text("Post Preview")
				.attr("id", "PostPreviewTitle")
				.appendTo(previewDiv);

			$("<div/>")
				.addClass("PostText")
				.appendTo(previewDiv);
		}

		var div = $("div", previewDiv).html(data);
		Proxiteam.BbCode.InitialiseBbCodes(div, true);

		replyTextboxValAtLastRefresh = replyTextboxVal;
		lastPreviewRefreshTime = new Date();
	}


	function OnAjaxComplete()
	{
		ajaxInProgress = false;
	}

})();


(function()
{
	var replyTextbox;
	var replyTextboxId = "Body";
	var buttonsDiv;
	var buttonsDivId = "BbCodeButtons";
	var buttonsRowClass = "BbCodeButtonsRow";
	var moreLinkId = "BbCodeMoreLink";
	var descriptionP;
	var descriptionPId = "BbCodeButtonDescription";

	Proxiteam.Forum.InitialiseReplyTextBoxBbCodeButtons = function (insertBefore)
	{
		/// <summary>
		/// Creates the BBCode editor buttons for the Reply textbox
		/// </summary>
		/// <param name="insertBefore" type="jQuery">The element to insert the BBCode buttons before</param>
		replyTextbox = $("#" + replyTextboxId);
		
		buttonsDiv = $("<div/>")
			.attr("id", buttonsDivId)
			.insertBefore(insertBefore);

		var numRows = 0;
		$.each(buttons, function()
		{
			if (this.rowNum > numRows)
				numRows = this.rowNum;
		});
		numRows++;

		for (var i = 0; i < numRows; i++)
		{
			$("<div/>")
				.addClass(buttonsRowClass)
				.appendTo(buttonsDiv);
		}

		$.each(buttons, function()
		{
			this.creatorFunc(this);
		});

		if (numRows > 1)
		{
			$("<a/>")
				.attr("id", moreLinkId)
				.attr("href", "")
				.text("more...")
				.click(OnMoreLinkClicked)
				.appendTo(buttonsDiv.children().get(0));

			buttonsDiv.children().not(":first").hide();
		}

		descriptionP = $("<p/>")
			.attr("id", descriptionPId)
			.appendTo(buttonsDiv);
	}

	function OnButtonHoverOver(buttonData)
	{
		descriptionP.text(buttonData.description);
	}


	function OnButtonCeaseHoverOver()
	{
		descriptionP.text("");
	}

	function OnMoreLinkClicked()
	{
		buttonsDiv.children().not(":first").show();
		$("#" + moreLinkId).remove();
		return false;
	}

	function CreateButton(buttonData)
	{
		$("<input/>")
			.val(buttonData.name)
			.attr("id", buttonData.id)
			.attr("type", "button")
			.click(function() { return buttonData.renderFunc(buttonData); })
			.hover(function() { OnButtonHoverOver(buttonData); }, OnButtonCeaseHoverOver)
			.appendTo(buttonsDiv.children().get(buttonData.rowNum));
	}

	function SimpleTagRender(buttonData)
	{
		return SimpleTagRenderUnwrapped(buttonData.openTag, buttonData.closeTag);
	}


	function SimpleTagRenderUnwrapped(openTag, closeTag)
	{
		var selectionInfo = replyTextbox.getSelection();
		if (selectionInfo.length == 0)
		{
			replyTextbox.insertAtCaretPos(openTag + closeTag);
			selectionInfo = replyTextbox.getSelection();
			replyTextbox.setCaretPos(selectionInfo.start - closeTag.length + 1);
		}
		else
		{
			text = replyTextbox.val();
			text = text.insert(openTag, selectionInfo.start);
			text = text.insert(closeTag, selectionInfo.end + openTag.length);
			replyTextbox.val(text);
			replyTextbox.setCaretPos(selectionInfo.end + openTag.length + closeTag.length + 1);
		}

		replyTextbox.focus();
		return false; //So the button doesn't submit the form
	}


	function CreateColour(buttonData)
	{
		select = $("<select/>")
			.attr("id", buttonData.id)
			.change(function() { return ColourRender(buttonData); })
			.hover(function() { OnButtonHoverOver(buttonData); }, OnButtonCeaseHoverOver)
			.appendTo(buttonsDiv.children().get(buttonData.rowNum));

		option = $("<option/>")
				.text(buttonData.name)
				.val("")
				.css("text-align", "center")
				.appendTo(select);

		for (name in buttonData.colours)
		{
			option = $("<option/>")
				.val(name)
				.appendTo(select);

			if ($.browser.mozilla)
			{
				//Only firefox support this
				$("<div/>")
					.css("margin-left", "auto")
					.css("margin-right", "auto")
					.css("width", "10px")
					.css("height", "10px")
					.css("border", "1px solid black")
					.css("background-color", buttonData.colours[name])
					.appendTo(option);
			}
			else
			{
				option
					.css("background-color", buttonData.colours[name]);
			}
		}
	}

	function ColourRender(buttonData)
	{
		dropdown = $("#" + buttonData.id);
		colour = dropdown.val();
		if (colour == "")
			return false;

		SimpleTagRenderUnwrapped("[colour=" + buttonData.colours[colour] + "]", "[/colour]");
		dropdown.val("");
		return false;
	}


	function CreateSize(buttonData)
	{
		select = $("<select/>")
			.attr("id", buttonData.id)
			.change(function() { return SizeRender(buttonData); })
			.hover(function() { OnButtonHoverOver(buttonData); }, OnButtonCeaseHoverOver)
			.appendTo(buttonsDiv.children().get(buttonData.rowNum));

		option = $("<option/>")
				.val("")
				.text(buttonData.name)
				.appendTo(select);

		for (name in buttonData.sizes)
		{
			$("<option/>")
				.val(name)
				.text(name)
				.appendTo(select);
		}
	}

	function SizeRender(buttonData)
	{
		dropdown = $("#" + buttonData.id);
		size = dropdown.val();
		if (size == "")
			return false;

		SimpleTagRenderUnwrapped("[size=" + buttonData.sizes[size] + "]", "[/size]");
		dropdown.val("");
		return false;
	}

	var buttons = {
		bold : {
			name: "B", 
			description: "Bold. Example: [b]Bolded text[/b]",
			openTag: "[b]",
			closeTag: "[/b]",
			id: "BoldBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		}, 
		italics : {
			name: "i",
			description: "Italics. Example: [i]Italicised text[/i]",
			openTag: "[i]",
			closeTag: "[/i]",
			id: "ItalicsBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		}, 
		underline : {
			name: "U",
			description: "Underline. Example: [u]Underlined text[/u]",
			openTag: "[u]",
			closeTag: "[/u]",
			id: "UnderlineBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		url : {
			name: "url",
			description: "Hyperlink. Example: [url]http://proxiteam.net[/url] [url=http://proxiteam.net]Proxiteam[/url]",
			openTag: "[url]",
			closeTag: "[/url]",
			id: "UrlBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		quote : {
			name: "quote",
			description: "Quoted text. Example: [quote]Quoted text[/quote], [quote=\"Name of Quote Author\"]Quoted text[/quote]",
			openTag: "[quote]",
			closeTag: "[/quote]",
			id: "QuoteBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		spoiler : {
			name: "spoiler",
			description: "Hides the contents of the tag. Example: [spoiler]Vader is Luke's father[/spoiler], [spoiler=GSL 3 Results]oGsMC wins[/spoiler]",
			openTag: "[spoiler]",
			closeTag: "[/spoiler]",
			id: "SpoilerBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		list : {
			name: "list",
			description: "An unordered or ordered list. Unordered example: [list][*]Marines [*]Marauders[/list]. Ordered example: [list=o][*]1st [*]2nd[/list]",
			openTag: "[list]",
			closeTag: "[/list]",
			id: "ListBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		bullet : {
			name: "•",
			description: "A bullet point or an ordered point inside a list. Must be inside a [list] tag.",
			openTag: "[*]",
			closeTag: "",
			id: "BulletBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		image : {
			name: "img",
			description: "Inserts an image. Example: [img=320,240]http://mysite.com/myimage.jpg[/img]",
			openTag: "[img=width,height]",
			closeTag: "[/img]",
			id: "ImageBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		flash : {
			name: "flash",
			description: "Inserts a Flash control. Example: [flash=320,240]http://www.youtube.com/v/owGykVbfgUE[/flash]",
			openTag: "[flash=width,height]",
			closeTag: "[/flash]",
			id: "FlashBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		centreAlign : {
			name: "",
			description: "Centre-aligns content. [centre]Centred text[/centre] [center]You can even spell \"center\" incorrectly![/center]",
			openTag: "[centre]",
			closeTag: "[/centre]",
			id: "CentreAlignBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		rightAlign : {
			name: "",
			description: "Right-aligns content. [right]Right-aligned text[/right]",
			openTag: "[right]",
			closeTag: "[/right]",
			id: "RightAlignBbCodeButton",
			rowNum: 0,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		colour : {
			name: "Colour",
			description: "Colours text. [colour=red]Red text[/colour] [color=#00FF00]You can spell \"color\" incorrectly, if you like.[/color]",
			id: "ColourBbCodeDropdown",
			rowNum: 0,
			creatorFunc: CreateColour,
			colours: { "Dark Red": "#C00000", "Red": "Red", "Orange": "Orange", "Yellow": "Yellow", 
			          "Light Green": "#92D050", "Green": "#00B050", "Light Blue": "#00B0F0", "Blue": "#0070C0", 
					  "Dark Blue": "#002060", "Purple": "#7030A0", "White": "White", "Black": "Black" }
		},
		textSize : {
			name: "Size",
			description: "Sets the font size via a percentage from the norm. [size=200]200% larger text[/right] [size=50]Half-size text[/size]",
			id: "TextSizeBbCodeDropdown",
			rowNum: 0,
			creatorFunc: CreateSize,
			sizes: { Tiny: "70", Small: "85", Large: "150", Huge: "200" }
		},
		strikethrough : {
			name: "S",
			description: "Strikethrough. Example: [s]Struckthrough text[/s]",
			openTag: "[s]",
			closeTag: "[/s]",
			id: "StrikethroughBbCodeButton",
			rowNum: 1,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		code : {
			name: "code",
			description: "Programming code (uses a fixed width font). Example: [code]public interface ITank { void FireCannon(); }[/code]",
			openTag: "[code]",
			closeTag: "[/code]",
			id: "CodeBbCodeButton",
			rowNum: 1,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		},
		escape : {
			name: "esc",
			description: "Escapes BBCode; BBCode inside these tags is not rendered. Example: [esc][b]This text is not bold[/b][/esc]",
			openTag: "[esc]",
			closeTag: "[/esc]",
			id: "EscapeBbCodeButton",
			rowNum: 1,
			creatorFunc: CreateButton,
			renderFunc: SimpleTagRender
		}
	};

})();
