/******************
 *	AJAX MANAGER
 ******************/

function AjaxManager(myself, element)
{
	this.eventManager = new EventManager();
	this._isRequestComplete = false;
	this._isFadeComplete = false;
	this._tempArgs = {};
	this._element = element;
	this._myself = myself;
	this._isRequestPending = false;
}

AjaxManager.prototype.getEventManager = function()
{
	return this.eventManager;
}

AjaxManager.prototype.isRequestComplete = function()
{
	return this._isRequestComplete;
}

AjaxManager.prototype.performRequest = function(url, postBody)
{
	var obj = this;
	
	if(postBody == undefined)
		postBody = "";
	
	new Ajax.Request(this._myself + url, {
		method:"post",
		postBody: postBody,//Form.serialize( document.sendWhisper ),
		onSuccess:function(transport)
		{
			obj.eventManager.dispatchEvent(REQUEST_SUCCESS, {response:transport.responseText, responseJSON:transport.responseJSON});
			//eval(transport.responseText);
		}
	});
}

AjaxManager.prototype.request = function(url, postBody)
{
	this.eventManager.addListener(REQUEST_SUCCESS, this.onRequestSuccess, this, false);
	this.performRequest(url, postBody);
	
	if(eventManagers[this._element] == undefined)
		eventManagers[this._element] = new EventManager();
		
	eventManagers[this._element].addListener(FADE_FINISHED, this.onFadeFinished, this, false);
	Effect.Fade(this._element, {duration:0.5});
	
	this._isRequestPending = true;
}

AjaxManager.prototype.onRequestSuccess = function(args)
{
	this._tempArgs = args;
	this._isRequestComplete = true;
	
	if(this._isFadeComplete)
		this.showResponse(args);
		
	this._isRequestPending = false;
}
	
AjaxManager.prototype.onFadeFinished = function()
{
	this._isFadeComplete = true;
	this._fadeHandle = null;
	
	if(this._isRequestComplete)
		this.showResponse(this._tempArgs);
}
	
AjaxManager.prototype.showResponse = function(args)
{
	this._isFadeComplete = false;
	this._isRequestComplete = false;
	
	$(this._element).innerHTML = args["response"];
	Effect.Appear(this._element, {duration:0.5});
	
}


/**************
 * 	CHECKBOX
 **************/

var checkboxLists = [];

function initCheckboxList(id, count, initialValue)
{
	checkboxLists[id] = [];
	
	for(i = 0; i < count + 1; i++)
		checkboxLists[id][i] = initialValue;
}

function toggleCheckbox(id, index, isListManager)
{
	if(checkboxLists[id] == undefined)
		initCheckboxList(id, 1, $("input_" + id + "_" + index).defaultChecked);
	
	if(checkboxLists[id][index] == "true" || checkboxLists[id][index] == true)
		changeCheckboxState(id, index, false);
	else
		changeCheckboxState(id, index, true);
	
	if(isListManager)
		for(i = 1; i < checkboxLists[id].length; i++){
			//some checkboxes has value set to -1, that means that they are uncheckable 
			// for example we can not check to delete unread mail from admin in inbox 
			if($("input_" + id + "_" + i).value != '-1')
				changeCheckboxState(id, i, $("input_" + id + "_" + index).checked);
			
		}
			
	if(index != "0")
	{
		for(i = 1; i < checkboxLists[id].length; i++)
			if(checkboxLists[id][i] == "false")
			{
				changeCheckboxState(id, 0, false);
				return;
			}
				
		changeCheckboxState(id, 0, true);
	}
}

function changeCheckboxState(id, index, isSelected)
{
	if(isSelected)
	{
		swapClass("checkbox_" + id + "_" + index, "checkbox_on margin_auto float_none");
		checkboxLists[id][index] = "true";
		$("input_" + id + "_" + index).checked = true;
	}
	else
	{
		swapClass("checkbox_" + id + "_" + index, "checkbox_off margin_auto float_none");
		checkboxLists[id][index] = "false";
		$("input_" + id + "_" + index).checked = false;
	}
}

/************
 *	EVENTS
 ************/

var FADE_FINISHED = "fade_finished";
var APPEAR_FINISHED = "appear_finished";
var REQUEST_SUCCESS = "request_success";
var UPLOAD_FINISHED = "upload_finished";

/*******************
 *	EVENT MANAGER
 *******************/

var eventManagers = [];

function EventManager()
{
	this._listeners = new Object();
}

EventManager.prototype.addListener = function(event, method, object, isPermament)
{
	if(this._listeners[event] == undefined)
		this._listeners[event] = [];
	
	this._listeners[event].push({method:method, object:object, isPermament:isPermament});
}

EventManager.prototype.dispatchEvent = function(event, args)
{
	var toRemove = [];
	var item = new Object();
	
	if(this._listeners[event] != undefined)
	{
		for(iterator = 0; iterator < this._listeners[event].length; iterator++)
		{
			item = this._listeners[event][iterator];
			
			item["method"].call(item["object"], args);
		}
		
		this._listeners[event] = this._listeners[event].filter(isPermament);
	}
}

function isPermament(element, index, array)
{
	return (element["isPermament"] == true);
}

/***************
 *	MAIN MENU
 ***************/

var _lastHighlighted = 1;
var obj = this;
var fadeFinished = true;

eventManagers["subMenuContainer"] = new EventManager("subMenuContainer");

eventManagers["subMenuContainer"].addListener(FADE_FINISHED, onFadeFinished, this, true);
eventManagers["subMenuContainer"].addListener(APPEAR_FINISHED, onAppearFinished, this, true);

function mainMenuHighlightButton(id)
{
	swapClass("headerTabLeft_" + id, "headerTabLeftHighlight");
	swapClass("headerTabRight_" + id, "headerTabRightHighlight");
	swapClass("headerTabCenter_" + id, "headerTabCenterHighlight");
	swapClass("headerTabTitle_" + id, "headerTabTitleHighlight");
	
	if(_lastHighlighted != id)
	{
		mainMenuUnhighlightButton(_lastHighlighted);
		
		if(fadeFinished)
			fade = new Effect.Fade("subMenuContainer", {duration:0.1});
			
		fadeFinished = false;
	}
		
	_lastHighlighted = id;
}

function mainMenuUnhighlightButton(id)
{
	swapClass("headerTabLeft_" + id, "headerTabLeft");
	swapClass("headerTabRight_" + id, "headerTabRight");
	swapClass("headerTabCenter_" + id, "headerTabCenter");
	swapClass("headerTabTitle_" + id, "headerTabTitle");
}

function onFadeFinished()
{
	fadeFinished = true;
	generateSubMenu(_lastHighlighted);
	Effect.Appear("subMenuContainer", {duration:0.1});
}

function onAppearFinished()
{
	
}

function mainMenuSelectFirstSubItem(id)
{
	window.location = /*"index.cfm?fuseaction=" + */subItems[id][1]["fuseaction"];
}

/**************
 *	SUB MENU
 **************/

var subItems = new Array();

function addSubItem(mainId, subId, textId, fuseaction)
{
	if(subItems[mainId] == undefined)
		subItems[mainId] = new Array();
	subItems[mainId][subId] = new Array();
	subItems[mainId][subId]['textId'] = textId;
	subItems[mainId][subId]['fuseaction'] = fuseaction;
}

function generateSubMenu(id)
{
	mainMenuItemWidth = 988 / totalMainMenuItems; // the width of single Main Menu item
	subMenuItemWidth = 100; // the width of single Sub Menu item
	subLength = subItems[id].length; // number of sub items in current main menu item
	
	buttons = "<ul id='subMenuList' class='menu' >";
	
	for(var i = 1; i < subItems[id].length; i++)
	{
		buttons += "<li><div id='subItem_" + i + "' class='relative2' style='margin-left:10px; margin-right:10px; display:inline; float:left; font-weight:bold; margin-top:4px;'><a href='" + subItems[id][i]['fuseaction'] + "'>" + subItems[id][i]['textId'] + "</a></div></li>";
	}
	
	buttons += "</ul>";
	
	$("subMenuContainer").innerHTML = buttons;
	
	$("subMenuContainer").style.display = "block";
	subMenuWidth = $("subMenuContainer").offsetWidth;
	$("subMenuContainer").style.display = "none";
	
	left = Math.floor( (id - 1) * mainMenuItemWidth - (subMenuWidth / 2) + (mainMenuItemWidth / 2));
	
	if(left < 0)
		left = 0; // the menu is aligned to the left side when possible
	else if(left > 988 - subMenuWidth)
		left = 988 - subMenuWidth; // the menu is aligned to the right
	
	$("subMenuContainer").style.left = left + "px";
}

/*********************
 *	TOOLTIP MANAGER
 *********************/

var IE = false;

if (navigator.appName == "Microsoft Internet Explorer")
{
	IE = true;
}

document.onmousemove = getMouseCoords;
mouseX = 0;
mouseY = 0;
windowHeight = 0;
scrollOffset = 0;

function getMouseCoords(mouse)
{
	mouseX = IE ? event.clientX : mouse.pageX;
	mouseY = IE ? event.clientY : mouse.pageY;
	
	windowHeight = IE ? document.documentElement.clientHeight : window.innerHeight;
	windowWidth = IE ? document.documentElement.clientWidth : window.innerWidth;
	//scrollOffset = IE ? document.documentElement.scrollTop : document.body.scrollTop;
	
	scrollOffset = document.documentElement.scrollTop + document.body.scrollTop;
	scrollPosition = IE ? document.documentElement.scrollTop : 0;
}

function ToolTipManager(myself)
{
	this._toolTips = [];
	this._ajaxManager = new Object();
	this._myself = myself;
}

ToolTipManager.prototype.attachElement = function(id)
{
	newToolTip = $(id);
	newToolTip.parentNode.removeChild(newToolTip);
	newToolTip.style.display = 'block';
	
	this._toolTips.push({id:id, toolTip:newToolTip, args:{}});
}

ToolTipManager.prototype.showToolTip = function(id, referer, type, args)
{
	thisObj = this;

	if($(id) == undefined)
	{
		this.getToolTipById(id).referer = referer;
		
		this.getToolTipById(id).toolTip.style.display = "none";
		$("toolTipContainer").appendChild(this.getToolTipById(id).toolTip);
		
		this.getToolTipById(id).args = args;

		switch(args.type)
		{
			case "profilePhoto":
				$("profilePhotoToolTipImage").src = args.photoPath;
				$("profilePhotoToolTipStatus").innerHTML = args.status;
				break;
			case "text":
				$("textToolTip").innerHTML = args.text;
				break;
			case "whisper":
				//document.forms["whisperForm"].userId.value = args.userId;
				this.hideToolTip("confirmationToolTip");
				initWhisperToolTip();
				break;
			case "confirmation":
				this.hideToolTip("whisperToolTip");
				initConfirmationToolTip();
				break;
		}
		
		switch(type)
		{
			case "DRAGGABLE": // used for tooltips that will follow mouse cursor
				$(referer).onmousemove = function()
				{
					thisObj.updateToolTips(referer);
				}
				
				$(referer).onmouseout = function()
				{
					thisObj.hideToolTips(referer);
				}
				
				this.updateToolTips(referer);
				break;
			case "RELATIVE": // relative to the element that dispatches the event
				args.x = args.x == undefined ? 0 : args.x;
				args.y = args.y == undefined ? 0 : args.y;
				
				this.getToolTipById(id).toolTip.style.top = args.y + $(referer).cumulativeOffset(referer).top + "px";
				this.getToolTipById(id).toolTip.style.left = args.x + $(referer).cumulativeOffset(referer).left + "px";
				break;
			case "FIXED": // placed on fixed coordinates
				args.x = args.x == undefined ? 0 : args.x;
				args.y = args.y == undefined ? 0 : args.y;
				
				if(args.centered)
					this.getToolTipById(id).toolTip.style.margin = "auto";
				else
					this.getToolTipById(id).toolTip.style.left = args.x + "px";
				
				this.getToolTipById(id).toolTip.style.top = args.y + "px";
				break;
			case "STATIC":
				this.getToolTipById(id).toolTip.style.position = "fixed";
				break;
		}
		
		this.getToolTipById(id).toolTip.style.display = "block";
		this.getToolTipById(id).toolTip.style.opacity = 1.0;
	}
	else
	{
		if(args.am != undefined && args.am._isRequestPending == false)
		{
			if(_fadeHandle != undefined)
			{
				_fadeHandle.cancel();
			}
			
			this.hideToolTip(id);
			this.showToolTip(id, referer, type, args);
		}
	}
}

ToolTipManager.prototype.getToolTipById = function(id)
{
	returns = null;
	
	this._toolTips.each(function(item)
	{
		if(item.id == id)
		{
			returns = item;
		}
	});
	
	return returns;
}

ToolTipManager.prototype.exists = function(id)
{
	var returnedValue = false;
	
	this._toolTips.each(function(item)
	{
		if(item.id == id && $(id) != undefined)
			returnedValue = true;
	});
	
	return returnedValue;
}

ToolTipManager.prototype.hideToolTip = function(id)
{
	if(this.exists(id))
	{
		$("toolTipContainer").removeChild($(id));
	}
}

ToolTipManager.prototype.hideToolTips = function(referer)
{
	this._toolTips.each(function(item, index)
	{
		switch(item.args.type)
		{
			case "profilePhoto":
				$("profilePhotoToolTipImage").src = "images/blank.gif";
				break;
		}
		
		if (item.referer == referer)
		{
			$("toolTipContainer").removeChild($(item.id));
			//item = null;
		}
	});
	
	//this._toolTips = this._toolTips.filter(isNull);
}

ToolTipManager.prototype.updateToolTips = function(referer)
{
	this._toolTips.each(function(item, index)
	{
		if (item.referer == referer)
		{
			element = $(item.id);
			
			if(element != undefined)
			{
				//elementBottom = mouseY - 32 + element.offsetHeight + scrollOffset;
				//elementTop = mouseY - 32 + scrollOffset;
				//correctionX = (mouseX + 16 + element.offsetWidth)0;
				//correctionY = 0;
				
				// TODO: finish correction when bottom of the tooltip hides under the bottom browser border
				//if(elementBottom > windowHeight + scrollOffset)
				//	correctionY = elementBottom - (windowHeight + scrollOffset);
				
				//element.style.left = String(mouseX + 16 + "px");
				//element.style.top = String(elementTop - correctionY + "px");
				
				elementBottom = mouseY - 32 + element.offsetHeight + scrollPosition;
				elementTop = mouseY + scrollPosition;
				
				correctionY = 0;

				if(windowWidth < mouseX + 300)
					{
						if(element.offsetWidth == 0)
							{
								correctionX = 150;
							}
						else
							{
								correctionX = element.offsetWidth + 32;
							}
						
					}
				else
					{
						correctionX = 0;
					}

				
				if(windowHeight > mouseY - scrollOffset + scrollPosition + 300)
					{
						correctionY = 0;
					}
				else
					{
						if(element.offsetHeight == 0)
							{
								correctionY = - 160 + 16;
							}
						else
							{
								correctionY = - element.offsetHeight + 16;
							}
					}

				element.style.left = String(mouseX + 16 - correctionX + "px");
				element.style.top = String(elementTop + correctionY + "px");
			}
		}
	});
}

function isNull(element, index, array)
{
	return (element == null);
}

/***********
 *	UTILS
 ***********/

function countChars(infoHolder, textHolder, max, label)
{
	var length = textHolder.value.length;
		
	if(length <= max)
		fullText = textHolder.value;
	else
		textHolder.value = fullText;
		
		infoHolder.innerHTML = "(" + label + ": " + (max - fullText.length) + ")";
}

function highlightByClass(el, hlClass, unHlClass)
{
	$(el).onmouseover = function()
	{
		swapClass(el, hlClass);
	}
	
	$(el).onmouseout = function()
	{
		swapClass(el, unHlClass);
	}
}

/*function highlightByImage(el, img1, img2)
{
	$(el).onmouseover = function()
	{
		$(el).src = img1;
	}
	
	$(el).onmouseout = function()
	{
		$(el).src = img2;
	}
}*/

function swapClass(elem, newClass)
{
	$(elem).setAttribute('class', newClass);
	$(elem).setAttribute('className', newClass);
}

function setOpacity(element, value)
{
	$(element).setStyle({opacity:value});
}