/// @file utilities.js
/// @brief
///
/// @author Ronny Sherer
/// @see
///

var isIE = $.browser.msie;
var isIE6 = $.browser.msie && $.browser.version < 7;

function AssignCookie( c_name, value, expireminutes )
{
	if( expireminutes == null )
	{
		document.cookie = c_name + "=" + escape(value) + "";
	}
	else
	{
		var expiry = new Date();
		expiry.setTime(expiry.getTime()+(expireminutes*60000));
		document.cookie = c_name + "=" + escape(value) + ";expires=" + expiry.toGMTString();
	}
}

function GetCookie( cookieName )
{
	var results = document.cookie.match( '(^|;) ?' + cookieName + '=([^;]*)(;|$)' );
	return ( results ) ? unescape( results[2] ) : null;
}

function FlashPlayerVersion()
{
	if ((navigator.plugins != null && navigator.plugins.length > 0) &&
		(navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]))
	{
		var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
		var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
		var descArray = flashDescription.split(" ");
		var tempArrayMajor = descArray[2].split(".");
		return tempArrayMajor[0];
	}

	return 0;
}

var HiddenFlashesStack = 0;

function HideFlashes()
{
	if (typeof isLinux === 'undefined')
	{
		alert('MUST define isLinux');
		return;
	}
    if (!isLinux || FlashPlayerVersion() != 9)
		return;

	if (HiddenFlashesStack++ > 0)
		return;

	var objects = document.getElementsByTagName('object');
	for (var i = 0; i < objects.length; i++)
	{
		if (typeof objects[i].play !== 'function')
			objects[i].style.visibility = 'hidden';
	}
}

function ShowFlashes()
{
	if (typeof isLinux === 'undefined' || !isLinux || FlashPlayerVersion() != 9)
		return;

	if (HiddenFlashesStack > 0)
	{
		HiddenFlashesStack--;
		if (HiddenFlashesStack > 0)
			return;
	}

	var objects = document.getElementsByTagName('object');
	for (var i = 0; i < objects.length; i++)
	{
		if (typeof objects[i].play !== 'function')
			objects[i].style.visibility = 'visible';
	}
}

/////////////////////////////////////////////////////////////////////
var WholePreview  = null;
var PreviewHeader = null;
var previewFrame  = null;
var FlashDiv = null;
var ScrollBarWidth = 0;

var isSitePreviewLoaded = false;
var isAnimationLoaded = false;

$(document).ready(
	function()
	{
		WholePreview  = $('#WholePreview');
		if (WholePreview.length == 0)
		{
			WholePreview = null;
			return;
		}
		PreviewHeader = $('#PreviewHeader');
		previewFrame  = $('#previewFrame');
		if (previewFrame)
			previewFrame.load( function() { OnFrameLoaded() } );

		FlashDiv = $('#FlashDiv');

		$(document).keydown(function(e)
		{
			var code = (e.keyCode ? e.keyCode : e.which);
			if ((code == 27 || code == 8) && WholePreview.is(':visible'))
			{
				e.preventDefault();
				e.stopPropagation();
				ClosePreview();
				return false;
			}
		});
	}
);

function OnFrameLoaded()
{
	isSitePreviewLoaded = true;
	OnResizeSitePreview();
}

function RebuildPreview(Template)
{
	if (Template)
		document.RebuildPreview.Template.value = Template;
	document.RebuildPreview.submit();
}
/////////////////////////////////////////////////////////////////////

var HiddenSelectsStack = 0;

function HideSelects()
{
	if (!isIE6)
		return;

	if (HiddenSelectsStack++ > 0)
		return;

	$('select').each( function () { this.style.visibility = 'hidden'; });
}

function ShowSelects()
{
	if (!isIE6)
		return;

	if (HiddenSelectsStack > 0)
	{
		HiddenSelectsStack--;
		if (HiddenSelectsStack > 0)
			return;
	}

	$('select').each( function () { this.style.visibility = 'visible'; });
}

	// public method for url encoding
function EncodeToUTF8(string)
{
	string = string.replace(/\r\n/g,"\n");
	var utftext = "";

	for (var n = 0; n < string.length; n++)
	{
		var c = string.charCodeAt(n);
		if (c < 128)
		{
			utftext += String.fromCharCode(c);
		}
		else if((c > 127) && (c < 2048))
		{
			utftext += String.fromCharCode((c >> 6) | 192);
			utftext += String.fromCharCode((c & 63) | 128);
		}
		else
		{
			utftext += String.fromCharCode((c >> 12) | 224);
			utftext += String.fromCharCode(((c >> 6) & 63) | 128);
			utftext += String.fromCharCode((c & 63) | 128);
		}

	}
	return escape( utftext );
}

	// public method for url decoding
function DecodeFromUTF8(utftext)
{
	var string = "";
	var i  = 0;

	while ( i < utftext.length )
	{
		var c = utftext.charCodeAt(i);

		if (c < 128)
		{
			string += String.fromCharCode(c);
			i++;
		}
		else if ((c > 191) && (c < 224))
		{
			var c2 = utftext.charCodeAt(i+1);
			string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
			i += 2;
		}
		else
		{
			var c2 = utftext.charCodeAt(i+1);
			var c3 = utftext.charCodeAt(i+2);
			string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
			i += 3;
		}
	}

	return string;
}

function SetCookieHelper(c_name,value,expiredays)
{
	var exdate=new Date();
	exdate.setDate(exdate.getDate()+expiredays);
	document.cookie= c_name+ "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}

function ValidateEmail(str)
{
	var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
	return emailPattern.test(str);
}

function FindPosition(obj)
{
	var pos = { x:0, y:0 };
	if (obj.offsetParent)
		while (1)
		{
			pos.x += obj.offsetLeft;
			pos.y += obj.offsetTop;
			if (!obj.offsetParent)
				break;
			obj = obj.offsetParent;
		}
	else
	{
		if (obj.x)
			pos.x += obj.x;
		if (obj.y)
			pos.y += obj.y;
	}
	return pos;
}

function addEvent(evType, fn, obj, useCapture)
{
	if (!obj)
		obj = window;

	if (obj.addEventListener)
	{
		obj.addEventListener(evType, fn, useCapture);
		return true;
	}
	else if (obj.attachEvent)
	{
		var r = obj.attachEvent("on"+evType, fn);
		return r;
	}
	else
	{
		alert("Handler could not be attached");
	}
}

function removeEvent(evType, fn, obj)
{
	if (!obj)
		obj = window;

	if (obj.removeEventListener)
	{
		obj.removeEventListener(evType, fn, false);
		return true;
	}
	else if (obj.detachEvent)
	{
		var r = obj.detachEvent("on"+evType, fn);
		return r;
	}
	else
	{
		alert("Handler could not be attached");
	}
}

// Browser Window Size and Position
// copyright Stephen Chapman, 3rd Jan 2005, 8th Dec 2005
// you may copy these functions but please keep the copyright notice as well
function pageWidth()
{
	return window.innerWidth != null ?
		window.innerWidth :
		document.documentElement && document.documentElement.clientWidth ?
			document.documentElement.clientWidth :
			document.body != null ?
				document.body.clientWidth :
				null;
}

function pageHeight()
{
	return window.innerHeight != null ?
		window.innerHeight :
		document.documentElement && document.documentElement.clientHeight ?
			document.documentElement.clientHeight :
			document.body != null ?
				document.body.clientHeight :
				null;
}

function posLeft()
{
	return !isIE ?
		window.pageXOffset :
		document.documentElement && document.documentElement.scrollLeft ?
			document.documentElement.scrollLeft :
			document.body.scrollLeft ?
				document.body.scrollLeft : 0;
}

function posTop()
{
	return !isIE ?
		window.pageYOffset :
		document.documentElement && document.documentElement.scrollTop ?
			document.documentElement.scrollTop :
			document.body.scrollTop ?
				document.body.scrollTop : 0;
}

function posRight()
{
	return posLeft()+pageWidth();
}

function posBottom()
{
	return posTop()+pageHeight();
}

String.prototype.toInt = function()
{
	return parseInt(this.replace('px', ''));
};

if (!Array.prototype.indexOf)
{
	Array.prototype.indexOf = function(item, from)
	{
		var len = this.length;

		from = (typeof from != 'number') ? 0 : ( (from < 0) ? Math.ceil(from) : Math.floor(from) );
		if (from < 0)
			from += len;

		for (; from < len; from++)
			if (from in this && this[from] === item)
				return from;

		return -1;
	};
}
function toggleCheckboxes(checkAllObj, ChecksClassName)
{
	var checkedAllFormCheckBoxes = $('#'+checkAllObj.id).attr('checked');

	var selector = '.' + ChecksClassName + ':checkbox';
	$(selector).each(function () { this.checked = checkedAllFormCheckBoxes; });

	UpdateSelectAll('toggleCheckboxes', ChecksClassName);
}

function AreAllCheckboxesChecked(className)
{
	var selector = '.' + className + ':checkbox';
	var BoxesTotalCount	= $(selector).size();
	var BoxesCheckedCount	= $(selector+"[checked]").size();

	return (BoxesTotalCount == BoxesCheckedCount);
}

function UpdateSelectAll(SelectAllID, ChecksClassName)
{
	$('#'+SelectAllID).attr('checked', AreAllCheckboxesChecked(ChecksClassName) );
}



function LimitLineLength(ID,	///< Id of the element to be limited.
						height,	///< Maximum height occupied by the element.
						ignoreTooltip)
{
	var obj;
	if (typeof ID == 'string')
	{
		obj = $('#'+ID);
	}
	else
	{
		obj = ID;
		ID = obj.attr('id');
	}
	if (height < obj.height())
	{
		var tooltipText = obj.html();
		var str = tooltipText.substr(0,tooltipText.length-2);

		// / Shorten the string until it fits onle line.
		do
		{
			str = str.substr(0,str.length-1);
			obj.html(str+' ...');
		}
		while (height < obj.height() && str.length > 5);

		if (str.length == 5)
		{
			alert('Wrong height at: LimitLineLength() -> #'+ID);
			return;
		}

		/// If there is a space in one of the last 15 characters, truncate to it.
		var len = str.length-15;
		for (i=str.length-1; i>len; i--)
		{
			if (str[i] == ' ')
			{
				str = str.substr(0,i);
				break;
			}
		}

		if (typeof ignoreTooltip == 'undefined' || ignoreTooltip != true)
		{
			// / Put the truncated string and the tooltip, back to the element.
			var tooltipObjID = ID+'Tooltip';
			obj.html(str+' ...'+'<div id="'+tooltipObjID+'" style="width:'+obj.width()+'px;" class="GlobalToolTip">'+tooltipText+'</div>');

			// / Make the tooltip show when hovering.
			var tooltipObj = $('#'+tooltipObjID);
			obj.hover(
					function ()
					{
						tooltipObj.css({'display' : 'block', 'top' : $(this).position().top+'px'});
					},
					function ()
					{
						tooltipObj.css({'display' : 'none'});
					});
		}
	}
}

function LogoutUser()
{
	Logout();

	$("#LoggedInAs").hide();
	$("#LoggedOut").show();
}

function DisableObject(ID, margin)
{
	var ID_DISABLER = ID+'_DISABLER';
	var Disabler = $('#'+ID_DISABLER);
	var obj = $('#'+ID);
	if (Disabler.length)
	{
		Disabler.show();
	}
	else
	{
		if (typeof margin == 'undefined')
			margin = 'margin:0 auto;';
		obj.wrap('<div id="WRAPPER_'+ID_DISABLER+'" style="position:relative;'+margin+'"></div>').append('<div id="'+ID_DISABLER+'" class="Disabler"></div>');
		Disabler = $('#'+ID_DISABLER);
	}
	var objColor = obj.css('color');
	obj.bind('click', function() { return false; })
		.hover(	function() { $(this).css({'color': objColor});});

	Disabler.css('margin', 0).width( obj.outerWidth(true) ).height( obj.outerHeight(true) );
	$('#WRAPPER_'+ID_DISABLER).width( obj.outerWidth(true) );
}

function EnableObject(ID)
{
	var ID_DISABLER = ID+'_DISABLER';
	var Disabler = $('#'+ID_DISABLER);
	var obj = $('#'+ID);
	if (Disabler.length)
	{
		Disabler.hide();
	}
	obj.unbind('click').hover( function() { $(this).css({'color': ''});});
}

function ScrollTo(diff, duration, func)
{
	if (typeof diff == 'string' || typeof diff == 'object')
	{
		if (typeof diff == 'string')
			diff = $(diff);
		diff = diff.position().top;
	}
	if (duration == undefined || duration < 0)
		duration = 500;
	$('html').animate({scrollTop: diff}, duration, func);
}

function consoleIt(func, msg)
{
	// if console is not defined, e.g., Firebug console is not enabled or Non-Firefox browser
	if (typeof console != 'undefined' && typeof eval('console.'+func) != 'undefined')
		eval('console.'+func)(msg);
}

$(document).ready(
	function()
	{

		//back to top scroll function. Any link with a hash (#) will scroll to that id on the page
		$('a[href*=#]:not([rel])').click(
			function()
			{
				if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') &&
					location.hostname == this.hostname)
				{
					var targetOffset = 0;
					var Anchor = jQuery.trim(this.hash).replace(/^#/,''), $target;
					if (Anchor != '#' && Anchor != '')
					{
						var $target = $(this.hash);
						$target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');
						if ($target.length)
							targetOffset = $target.offset().top;
					}
					if (typeof HrefBeforeScroll != 'undefined')
						HrefBeforeScroll(Anchor);
					$('html').animate({scrollTop: targetOffset}, 500,
						function()
						{
							if (typeof HrefAfterScroll != 'undefined')
								HrefAfterScroll(Anchor);
						});
					return false;
				}
			}
		);
		var originalVal = jQuery.fn.val;
		jQuery.fn.val = function(value)
		{
			var tagName = ((typeof this.get == 'undefined') ? this.tagName : (this.length ?
				((typeof this.get(0).tagName == 'string') ? this.get(0).tagName : '') : '')).toUpperCase();
			if (this.hasClass('HypertextEditor'))
			{
				var id = this.get(0).id;
				if (typeof value == 'undefined')	// Return the value
				{
					return getEditorContent(id);
				}
				else	// Set the value
				{
					return setEditorContent(id, value);
				}
			}
			else if (tagName == 'IMG')
			{
				if (typeof value == 'undefined')	// Return the value
				{
					return this.attr('src');
				}
				else	// Set the value
				{
					return this.attr('src', value);
				}
			}
			else
				return originalVal.apply(this, arguments);
		};
	}
);

function VerifySaveOnExit(e, IsChangedFunc, message)
{
	if (typeof IsChangedFunc != 'function' || !IsChangedFunc())
		return;

	if (typeof e == 'undefined')
		e = window.event;
	if (e)
	{
		e.returnValue = message;
		if (typeof e.preventDefault != 'undefined')
			e.preventDefault();
	}

	return message;
}
/////////////////////////////////////////////////////////////////////////////
function DisplayBlockingSuccess(selector, message)
{
	DisplayBlockingMessage(selector, message, true);
}

function DisplayBlockingFailure(selector, message)
{
	DisplayBlockingMessage(selector, message, false);
}

function DisplayBlockingMessage(selector, message, isOk)
{
	var sGif = isOk ? 'v2.gif' : 'x.gif';
	var sClass = isOk ? 'OkMsg' : 'FailedMsg';
	message = '<img src="'+g_HomePathHttp+'/images/'+sGif+'"/> <span class="'+sClass+'"> '+message+'</span>';
	$(selector).block(
		{	timeout: 3000, message: message,
			overlayCSS:{backgroundColor: 'white', opacity: 1},
			css: {	top: '50px', border: 'none', backgroundColor: 'transparent',
					lineHeight: '25px', padding: '10px 20px', width: '' },
			fadeIn:  100, fadeOut: 1000});
}

function WaitForUpdate(selector, message, topPos, bottomPos)
{
	var blockOptions = { message: '<h2>'+message+'</h2><img src="' + HomePath + '/images/loadingSmall.gif"/>',
				centerY: false, baseZ: 7000,
				css: { border: 'none', backgroundColor: 'transparent', padding: '10px 20px', width: '' },
				overlayCSS:  { backgroundColor: 'white', opacity: 1}
			};
	if (topPos == undefined)
		topPos = '';
	if (bottomPos == undefined)
		bottomPos = '';

	if (topPos == '' && bottomPos == '')
		blockOptions.css.top = '50px';
	else if (topPos != '')
		blockOptions.css.top = topPos;
	else if (bottomPos != '')
	{
		blockOptions.css.bottom = bottomPos;
		blockOptions.css.top = 'auto';
	}

	$(selector).block(blockOptions);
}

function FinishedUpdate(selector)
{
	$(selector).unblock();
}

var initializedDialogs = [];
function OpenDialog(dialogSelector, options, width, height, init)
{
	if (width)
		options.width = width;
	else if (options.width)
		width = options.width;
	if (height)
		options.height = height;
	else if (options.height)
		height = options.height;
	if (typeof options != 'object')
		options = new Object();

	if (typeof initializedDialogs[dialogSelector] != 'undefined')
	{
		if (window.top != window)
		{
			var top = (typeof options.top != 'undefined') ? options.top : getDialogTop(options.height);
			options.position = [($(window).width()-options.width)/2,top];
			$(dialogSelector).dialog('option', 'position', options.position);
		}
		$(dialogSelector).dialog('open');
		return;
	}
	initializedDialogs[dialogSelector] = true;

	if (typeof options.resizable == 'undefined')
		options.resizable = false;
	options.modal = true;
	options.autoOpen = true;

	if (window.top != window)
	{
		var top = (typeof options.top != 'undefined') ? options.top : getDialogTop(options.height);
		options.position = [($(window).width()-width)/2, top];
	}
	else
		options.position = 'center';

	if (typeof init == 'function')
		options = init(options);

	$(dialogSelector).dialog(options);
}

function getDialogButton( jqUIdialog, button_names )
{
	if (typeof button_names == 'string')
		button_names = [button_names];
	var buttons = jqUIdialog.parent().find('.ui-dialog-buttonpane button');
	for (var i = 0; i < buttons.length; i++)
	{
		var jButton = $( buttons[i] );
		for (var j = 0; j < button_names.length; j++)
			if ( jButton.text() == button_names[j] )
				return jButton;
	}

	return null;
}

function enableDialogButton( jqUIdialog, button_names, enable )
{
	var button = getDialogButton( jqUIdialog, button_names );
	if (button == null)
		alert('button not found: '+button_names);
	else
	{
		if (enable)
			button.removeAttr('disabled').removeClass( 'ui-state-disabled' );
		else
			button.attr('disabled', 'disabled').addClass( 'ui-state-disabled' );
	}
}

function setDialogButtonText(btn, str)
{
	btn.html("<span class='ui-button-text'>"+str+"</span>");
}

function setDialogButtonTranslation(jqUIdialog, str, translation)
{
	var btn = getDialogButton( jqUIdialog, str );
	if (btn && btn.length)
		btn.html("<span class='ui-button-text'>"+translation+"</span>");
}

function getWindowCenter()
{
	var windowTopDiff = 0;
	var container = $(window.document).find('#cboxContent');
	if (container.length > 0)
		windowTopDiff = $(window).scrollTop() - container.offset().top;

	return windowTopDiff + $(window).height()/2;
}

function getDialogTop(height)
{
	if (typeof height != 'number')
		height = 100;
	var center = window.top.getWindowCenter();
	var top = center - height/2;
	if (top < 10)
		top = 10;
	else if (top+height > $('body').height()-5)
	{
		top -= (top+height - $('body').height()+5);
		if (top < 0)
			top = 0;
	}
	return top;
}

////////////////////////////////////////////////////////////////////////////

function SetRadioButtonValue(name, value)
{
	var radio = document.getElementsByName(name);

	for (var ii = 0; ii < radio.length; ii++)
		if (radio[ii].value == value)
			$(radio[ii]).attr('checked', true);
		else
			$(radio[ii]).removeAttr('checked');
}

function GetRadioButtonValue(name)
{
	var radio = document.getElementsByName(name);

	for (var ii = 0; ii < radio.length; ii++)
		if (radio[ii].checked)
			return radio[ii].value;
}

function GetInputValue(name)
{
	var inputs = document.getElementsByName(name);
	var str = "";

	for (var ii = 0; ii < inputs.length; ii++)
		str += jQuery.trim(inputs[ii].value);

	return str;
}

function GetTextareaValue(name)
{
	var textareas = document.getElementsByName(name);
	var str = "";

	for (var ii = 0; ii < textareas.length; ii++)
		str += textareas[ii].value;

	return str;
}

/////////////////////////////////////////////////////////////
//
// extend() merges recursively any number of objects (or arrays).
// The difference from jQuery extend, is that our accepts unlimited number of
// arguments and more important it is recursive.
//
function extend()  /* any number of arguments*/
{
	var merged = {};
	for (var i=0; i<arguments.length; i++)
	{
		var obj = arguments[i];
		for (var property in obj)
		{
			var prop = obj[property];
			var mergedProp = merged[property];
			merged[property] = (typeof prop == 'object' && typeof mergedProp == 'object') ? extend(mergedProp, prop) : prop;
		}
	}
	return merged;
}
