/* 
Constants to determine browser type / version
*/
var isOpera = navigator.userAgent.indexOf('Opera') > -1;
var isIE = navigator.userAgent.indexOf('MSIE') > 1 && !isOpera;
var isMoz = navigator.userAgent.indexOf('Mozilla/5.') == 0 && !isOpera;
var isMac = (navigator.appVersion.indexOf("Mac")!=-1) ? true : false;
var NS4 = (document.layers) ? true : false;
var IE4plus = (document.all) ? true : false;
var IE4 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 4.")!=-1)) ? true : false;
var IE5 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 5.")!=-1)) ? true : false;
var IE6 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 6.")!=-1)) ? true : false;
var IE7 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 7.")!=-1)) ? true : false;
var ver4 = (NS4 || IE4plus) ? true : false;
var NS6 = (!document.layers) && (navigator.userAgent.indexOf('Netscape')!=-1);
var isGecko = /gecko/i.test(navigator.userAgent); //added by dan-el
var docTitle = null;

/* 
Constants that enables/disables specific G2Page features
*/
var ENABLE_PROFILER = false;
var ENABLE_CLIENT_VALIDATION = true;
var ENABLE_POSTDATA_ONDEMAND = true;
var ENABLE_FAKE_POSTBACKS = false;
var NOTIFY_SERVER_HISTORY_CHANGE = false;
var CALLBACK_TIMEOUT = 5000; // the maximum time we will wait for a postback to return from server
// to enable this add in G2Page.PreRender:	TryRegisterG2ClientScriptFile("dhtmlHistory.js");

/*
Global window vars
*/
timings = [];
G2UseSyncCallbacks = false;
G2PartialPostDataElementIds = new Object();
G2InputChangedObservers = new Array();
var mainAdminTabControl = null;
G2AdminInputChangedObservers = new Object();
G2_EvalCache = {};

// a safty net for multiple post back all in the dame time.
var waitForCallback = null;


/*
Static methods that allows declaring various JS structures
*/


/*
G2_DeclareFunctions
Desc:
Methods declared with this function can be profiled
Usage:
regex to find function ggg(a, b, c)
function {.*}\({.*}\)
\1 : function(\2)
*/
G2_DeclareFunctions = function(json)
{
	1;
	for(var memberName in json)
	{
		var member = json[memberName];
		if(typeof(member)=="function")
		{
			member.name = memberName;
			eval(memberName+"=member;");
			if(ENABLE_PROFILER)
				Profiler.profile(member);
		}
	}
}

/*
G2_DeclareUtilInstance
Desc:
Allows declaring a static like instance in JS. Examples are: G2PopupManager, G2FrameManager, G2DOM
*/
G2_DeclareUtilInstance = function(instance)
{
	for(var memberName in instance)
	{
		var member = instance[memberName];
		if(typeof(member)=="function")
		{
			member.name = memberName;
			if(ENABLE_PROFILER)
				Profiler.profileUtilInstanceFunction(instance, member);
		}
	}
}

ImportInto = function(target, source)
{
	for(var memberName in source)
	{
		var member = source[memberName];
		target[memberName] = member;
		if(typeof(member)=="function")
		{
			member.name = memberName;
		}
	}
	if(source.toString!=Object.prototype.toString)
	{
		var member = source.toString;
		if(typeof(member)=="function")
			member.name = "toString";
		target.toString = member;
	}
}

G2_DeclareClass = function(type, name, baseType, json)
{
	type.name = name;
	if(baseType!=null)
		ImportInto(type.prototype, baseType.prototype);
	ImportInto(type.prototype, json);
	if(ENABLE_PROFILER)
	{
		for(var p in json)
		{
			var func = json[p];
			if(typeof(func)=="function")
				Profiler.profileTypeFunction(type, json[p]);
		}
	}

}

if(ENABLE_PROFILER)
{
	var Profiler = 
	{
		_pFuncs: [],
		profileUtilInstanceFunction : function(instance, func)
		{
			var pFunc = this._createProfilerFunction(func);
			if(pFunc==null)
				return;//cannot profile function
			instance[func.name] = pFunc;
		},
		profileTypeFunction : function(type, func)
		{
			var pFunc = this._createProfilerFunction(func);
			if(pFunc==null)
				return;//cannot profile function
			type.prototype[func.name] = pFunc;
		},
		profile : function(func)
		{
			var pFunc = this._createProfilerFunction(func);
			eval(func.name+"=pFunc;");
		},
		_createProfilerFunction : function(func)
		{
			if(func.name==null)
				return; //cannot profile function without a name
			var pFunc = function()
			{
				var pCallee = arguments.callee;
				pCallee.totalCalls++;
				var startInvoke = new Date().getTime();
				var result = pCallee.realFunc.apply(this, arguments);
				var endInvoke = new Date().getTime();
				var timeInvoke = endInvoke-startInvoke;
				pCallee.totalWithChildren += timeInvoke;
				var pCaller = pCallee.caller;
				var x = 0;
				while(pCaller!=null && pCaller.totalOfChildren==undefined && pCaller!=pCallee && x<5)
				{
					pCaller = pCaller.caller;
					x++;
				}
				if(pCaller!=null && pCaller.totalOfChildren!=undefined && pCaller!=pCallee)
				{
					pCaller.totalOfChildren+=timeInvoke;
				}
				return result;
			}
			pFunc.realFunc = func;
			pFunc.totalWithoutChildren = 0;
			pFunc.totalOfChildren = 0;
			pFunc.totalWithChildren = 0;
			pFunc.totalCalls = 0;
//			pFunc.totalOfChildrenWithProfiler = 0; //
			pFunc.name = func.name;
			this._pFuncs.push(pFunc);
			return pFunc;
		},
		clearData : function()
		{
			for(var i=0;i<this._pFuncs.length;i++)
			{
				var pFunc = this._pFuncs[i];
				pFunc.totalWithoutChildren = 0;
				pFunc.totalOfChildren = 0;
				pFunc.totalWithChildren = 0;
				pFunc.totalCalls = 0;
			}
		},
		takeSnapshot : function(sortBy)
		{
			if(sortBy==null)
				sortBy="totalCalls";
			var desc = sortBy!="name" ? -1 : 1;
			var arr = [];
			for(var i=0;i<this._pFuncs.length;i++)
			{
				var pFunc = this._pFuncs[i];
				pFunc.totalWithoutChildren = pFunc.totalWithChildren-pFunc.totalOfChildren;
				if(pFunc.totalCalls>0)
					arr.push(pFunc);
			}
			var array = arr.sort(function(x, y)
			{
				var valueX = x[sortBy];
				var valueY = y[sortBy];
				if(valueX==null || valueY==null)
				{
					if(valueX==valueY)
						return 0;
					return valueX==null ? 1*desc : -1*desc;
				}
				if(typeof(valueX)=="string" && typeof(valueY)=="string")
					return valueX.localeCompare(valueY)*desc;
				return (valueX.valueOf()-valueY.valueOf())*desc;
			});
			return array;
		},
		createDebugDiv : function()
		{
			if(Profiler.debugWindow==null)
			{
				if(window.opener!=null && window.opener.Profiler.debugWindow!=null)
				{
					Profiler.debugWindow = window.opener.Profiler.debugWindow;
				}
				else
				{
					var debugWindow = window.open(G2_MapPath('~/Client/Scripts/profiler.htm'), "debugWindow");
					Profiler.debugWindow = debugWindow;
				}
//				Profiler.debugWindow.registerWindow(window);
			}
		}
	}
	
}

/* 
Language extenstions
*/

String.prototype.endsWith = function String$endsWith(suffix) 
{
	return (this.substr(this.length - suffix.length) === suffix);
}

String.prototype.startsWith = function String$startsWith(prefix) 
{
  return (this.substr(0, prefix.length) === prefix);
}
String.prototype.contains = function(s)
{
	return this.indexOf(s)!=-1;
}


/* 
ASP.NET JS overrides
*/

if(typeof(WebForm_DoCallback)=="function")
{
	AspNet_WebForm_DoCallback = WebForm_DoCallback;
	AspNet_WebForm_CallbackComplete_Sync = WebForm_CallbackComplete;
}
window.net__doPostBack = window.__doPostBack;

window.__doPostBack = function(eventTarget, eventArgument,forcesilent) 
{
	// check lock to prevent multuple postbacks all in the same time
	if(waitForCallback)
	{
		// if we pass the the timeout value go on
		if(new Date() - waitForCallback <= CALLBACK_TIMEOUT)
		{
			// try again in 0.5 seconds
			window.setTimeout(function () { __doPostBack(eventTarget, eventArgument, forcesilent); }, 500);
			return;
		}
	}
	// lock this code
	waitForCallback = new Date();

  if (theForm==null || theForm.__EVENTTARGET == null) //This is sometimes caused when posting back from a popup that's closed.
		return;

	if (forcesilent == null)
		forcesilent = false;
	//Validation
	var targetEl = null;
	if(typeof(eventTarget)=="object")
	{
		targetEl = eventTarget;
		eventTarget = eventTarget.id;//String.Replace(eventTarget.id, "_", "$");
	}
	else
	{
		targetEl = G2_GetEventTargetElement(eventTarget);
	}
  if(targetEl!=null)
  {
		// 'CancelPostBackOnDisabled' attribute was added for canceling post back in case of disabled linkButton.
		// Any one can add this attribute in order to cancel postBack if the control is disabled.
		if (targetEl.cancelPostBackOnDisabled && targetEl.isDisabled)
			return;
			
		if (document.isPostingFromAClosedPopup) //Handle 'error 84' in IE when trying to postback from a closed popup.
			return;
    if(ENABLE_CLIENT_VALIDATION && (G2DOM.G2GetAttribute(targetEl,"causesvalidation")=="true" || (window.validateAll == "true" && G2DOM.G2GetAttribute(targetEl,"ignorevalidation") != "true"))) 
    {
      if(typeof(G2Validation_PerformValidation)=="function" && G2Validation_PerformValidation(targetEl)==false) 
        return;
      if(targetEl.onvalidatedclientclick!=null)
      {
     		var func = new Function(targetEl.onvalidatedclientclick);
				var res = func.call(targetEl);
				if (res == false)
					return;
      }
      if(targetEl.onbeforepostback!=null)
        window[targetEl.onbeforepostback](eventTarget, eventArgument);
    }
  }
  else
  {
    Debug.writeln("Could not find element " + eventTarget);
  }
  
 	if (theForm.onsubmit && (theForm.onsubmit() == false))
    return false;

  //Disable tooltips during silent postbacks.
  G2PopupManager.disableTooltips();
  //Display the processing image
  if (targetEl != null)
  {
    if (G2DOM.G2GetAttribute(targetEl,"showprocessingimage")=="true")
    {
      ShowProcessingImage(targetEl);
    }
    if (G2DOM.G2GetAttribute(targetEl,"showdisabler")=="true")
    {
      G2_ShowDisabler(true); 
    }
  }
  else
  {
    Debug.writeln("Could not find element " + eventTarget);
  }
  
  if(window.OnBeforePostbackClientFunction!=null)
  {
     window[window.OnBeforePostbackClientFunction]({eventTarget:eventTarget, eventArgument:eventArgument});
  }
  var doClassicPostBack = !G2IsSilent(eventTarget, eventArgument, targetEl) && !forcesilent;
  if(doClassicPostBack && !ENABLE_FAKE_POSTBACKS)
  {
 		for(var id in G2PartialPostDataElementIds)
		{
		  var element = G2PartialPostDataElementIds[id];
		  if(element==null || element.parentElement==null)
		  {
			  element = document.getElementById(id);
			}
			//isValueDirty might not be declared because it might've been updated dynamically, and lazy initialized.
			if(element!=null && typeof(element.isValueDirty)=="function" && !element.isValueDirty())
			{
				element.disabled = true;
			}
		}
 		for(var id in G2_PreventPostElementIds)
		{
			var element = document.getElementById(id);
			if(element!=null)
				element.disabled = true;
		}
		//we do not use the real __doPostback because it checks onsubmit again.
		theForm.__EVENTTARGET.value = eventTarget;
		theForm.__EVENTARGUMENT.value = eventArgument
		theForm.submit();

//		window.net__doPostBack(eventTarget, eventArgument);
		return;
  }
	var arg;
	if(ENABLE_FAKE_POSTBACKS && doClassicPostBack)
	{
		arg = "FakePostBack";
	}
	else
		arg = "SilentPostBack";
//		
  theForm.__EVENTTARGET.value = eventTarget;
  theForm.__EVENTARGUMENT.value = eventArgument;
	var arg = arg+"|" + eventTarget + "|" + eventArgument;
	G2_DoCallback('__Page', arg ,G2CallbackManager_HandleResult,{eventTarget:eventTarget,eventArgument:eventArgument},G2_OnCallbackError,false, false);
}

function WebForm_FireDefaultButton(event, target)
{
    if (event.keyCode == 13 && !(event.srcElement && (event.srcElement.tagName.toLowerCase() == "textarea"))) 
    {
			var defaultButton;
			if (__nonMSDOMBrowser) 
			{
				defaultButton = document.getElementById(target);
			}
    else 
    {
      defaultButton = document.all[target];
    }
    if (defaultButton && typeof(defaultButton.click) != "undefined") 
    {
			//added by dan-el - causes any other focused element to blur and fire the onchange event, #7457
			try
			{
				defaultButton.focus(); 
			}
			catch(err)
			{
				event.srcElement.blur();
			}
			defaultButton.click();
      event.cancelBubble = true;
      if (event.stopPropagation) 
				event.stopPropagation();
      return false;
    }
  }
  return true;
}
G2_onHistoryChange = function(newLocation, historyData)
{
	__doPostBack("__Page", "HistoryChange|"+newLocation, true);
}

/* 
G2 General Library Util Instance
*/

G2 = 
{
	AppendQueryString : function(url, qs)
	{
		if(url.search(/\?/)!=-1)
			return url+"&"+qs;
		return url+"?"+qs;
	},
	ArgumentsFrom : function(args, index)
	{
		var arr = [];
		for(var i=index;i<args.length;i++)
		{
			arr.push(args[i] || null);
		}
		return arr;
	},
	GetRelativeMouseX : function(e, relativeElement)
	{
		return e.clientX-G2_GetX(relativeElement)+relativeElement.scrollLeft;
	},
	GetRelativeMouseY : function(e, relativeElement)
	{
		return e.clientY-G2_GetY(relativeElement)+relativeElement.scrollTop;
	},
	Delegates : {},
	GetDelegate : function(target, func)
	{
		if(target==null)
			return func;
		if(typeof(func)=="string")
			func = target[func];
		var key = this.GetHashKey(func)+"$$"+this.GetHashKey(target);
		var delegate = this.Delegates[key];
		if(delegate==null)
		{
			delegate = function()
			{
				return arguments.callee.func.apply(arguments.callee.target, arguments);
			};
			delegate.func = func;
			delegate.target = target;
			delegate.isDelegate = true;
			this.Delegates[key] = delegate;
		}
		return delegate;
	},

	_hashIndex : 1,
	GetHashKey : function(obj)
	{
		if(obj===undefined)
			return "undefined";
		if(obj===null)
			return "null";
		var typeOf = typeof(obj);
		if(typeOf=="object" || typeOf=="function")
		{
			if(obj._hashKey==null)
			{
				obj._hashKey = typeOf+"$"+this._hashIndex;
				this._hashIndex++;
			}
			return obj._hashKey;
		}
		return obj.valueOf().toString();
	},
	historyIndex : 0,
	// check if any control was registered due to a change.
	ChangesWasMadeToControls : function()
	{
		if (this.changedInputs)
		{
			var i=0;
			for (var j in this.changedInputs)
				i++;
			if (i == 0)
				return false;
		}		
		return true
	},

	notifyInputPropertyChanged : function(e)
	{
	1;//value for textboxes, checked for checkboxes, selectedIndex for combos
		if(e.propertyName=="value" || e.propertyName=="checked" || e.propertyName=="selectedIndex") //checked is for checkbox and radiobutton
			this.notifyInputChanged(e.srcElement);
	},
	changedInputs : new Object(),
	notifyInputChangedFF_Watch : function(inputId, oldVal, newVal)
	{
		G2.notifyInputChanged(this);
		return newVal;
	},
	notifyInputChangedFF_Event : function(evnt)
	{
		G2.notifyInputChanged(evnt.target);
	},
	RegisterPropertyChangeWatch : function(elementID)
	{
		if (isMoz)
		{
			var e = document.getElementById(elementID);
			e.watch("value",this.notifyInputChangedFF_Watch	);
			e.watch("checked",this.notifyInputChangedFF_Watch);
			e.watch("selectedIndex",this.notifyInputChangedFF_Watch);
			e.addEventListener("change",this.notifyInputChangedFF_Event,false);
		}
	},	
	RegisterPropertyChangeWatchWithHandler : function(elementID,handler)
	{
		if (isMoz)
		{
			var e = document.getElementById(elementID);
			var watchHandler = function(){handler(this);};
			e.watch("value",watchHandler);
			e.watch("checked",watchHandler);
			e.watch("selectedIndex",watchHandler);
			var eventHandler = function(evnt){handler(evnt.target);};
			e.addEventListener("change",eventHandler,false);
		}
	},	
	notifyInputChanged : function(input)
	{
	   if(input.isInitializing)
	    return;
		this.changedInputs[input.id] = input;
		if(input.notifyobserver == null || input.notifyobserver == "true")		
			this.fireNotifyInputChangedEvent();
	},
	undoNotifyInputChanged : function(input)
	{
		if(this.changedInputs[input.id] != null)
		{
			delete this.changedInputs[input.id];
		}
	},	
	notifyCheckBoxPropertyChange : function(e)
	{
		if(e.propertyName=="value" || e.propertyName=="checked")
		{
			var checkbox = e.srcElement;
			this.notifyInputChanged(checkbox);
			if(typeof(checkbox.g2PerformUndo)=="undefined")
			{
				checkbox.originalValue = !checkbox.checked; //the value before the click
				checkbox.g2PerformUndo = G2.CheckBox_PerformUndo;
				checkbox.g2SetOriginalValue = G2.CheckBox_SetOriginalValue;
				checkbox.g2IsDirty = G2.CheckBox_IsDirty;
			}
		}
	},
	notifyCheckBoxClicked : function(checkbox)
	{
		this.notifyInputChanged(checkbox);
		if(typeof(checkbox.g2PerformUndo)=="undefined")
		{
			checkbox.originalValue = !checkbox.checked; //the value before the click
			checkbox.g2PerformUndo = G2.CheckBox_PerformUndo;
			checkbox.g2SetOriginalValue = G2.CheckBox_SetOriginalValue;
			checkbox.g2IsDirty = G2.CheckBox_IsDirty;
		}
	},
	CheckBox_PerformUndo : function(checkbox)
	{
		checkbox = checkbox || this;
		checkbox.checked = checkbox.originalValue;
	},
	CheckBox_SetOriginalValue : function(checkbox)
	{
		checkbox = checkbox || this;
		checkbox.originalValue = checkbox.checked;
	},
	CheckBox_IsDirty : function(checkbox)
	{
		checkbox = checkbox || this;
		return checkbox.checked != checkbox.originalValue;
	},
	getAdminToolsActiveTabId : function ()
	{
		if (mainAdminTabControl == null)
			mainAdminTabControl = $('adminTabControlDiv').firstChild;
		if (mainAdminTabControl.ActiveTab) //already initialized
			return mainAdminTabControl.ActiveTab.id;
		else //not yet initialized
			return mainAdminTabControl.activetabid;
	},
	getAdminToolsObserversInTab : function(tabId)
	{
		if (typeof(tabId) == 'undefined')
			tabId = this.getAdminToolsActiveTabId();
		if (typeof (G2AdminInputChangedObservers[tabId]) == 'undefined')
			G2AdminInputChangedObservers[tabId] = new Object();
		return G2AdminInputChangedObservers[tabId]; 
	},
	attachObserver : function (id, tabId)
	{		
		var observers = this.getAdminToolsObserversInTab(tabId);
		if (observers[id] == true) //Change by Adi Eduard
		  return;
		observers[id] = false; 
	},
	detachObserver : function (id, tabId)
	{		
		var observers = this.getAdminToolsObserversInTab(tabId);
		delete observers[id];
	},
	fireNotifyInputChangedEvent : function (tabId)
	{
	  if (window.IsAdminToolsMainPage != true) //this feature works only in the admin tools
			return; 
		var observers = this.getAdminToolsObserversInTab(tabId);
		for(var obs in observers)
		{
			observers[obs] = true;
		}
	},
	setObjectChanged : function (id, tabId)
	{
		var observers = this.getAdminToolsObserversInTab(tabId);
		observers[id] = true;
	},
	setObjectUnchanged : function (id, tabId)
	{
		var observers = this.getAdminToolsObserversInTab(tabId);
		(observers[id] != null)
			observers[id] = false;
	},
	IsObjectChanged : function (id, tabId)
	{
			var observers = this.getAdminToolsObserversInTab(tabId);
			return observers[id] == true;
	},
	AreThereAnyChanges : function ()
	{
		var allObservers = G2AdminInputChangedObservers;
		for (var tab in allObservers)
		{
			tabObservers = allObservers[tab];
			for (var obsId in tabObservers)
			{
				if (tabObservers[obsId] == true)
					return true;
			}
		}
		return false;
	}
	
};
G2_DeclareUtilInstance(G2);

G2_DeclareFunctions(
{
	G2InitParentControl : function(sender, e)
	{
		if(sender.g2HasInitedParentControl)
			return;
		sender.g2HasInitedParentControl = true;
		var control = sender;
		var controlType;
		while(control!=null)
		{
			controlType = G2DOM.G2GetAttribute(control, "g2control")
			if(controlType!=null)
				break;
			control = control.parentElement;
		}
		if(control.g2IsInited)
			return;
		if(control.isDisabled)
			return;
		window[controlType+"_Init"](control, e);
		if(!control.g2IsInited)
			control.g2IsInited = true;
	},
	G2_VerifyControlInitialized : function(control, e)
	{
		if(control.g2IsInited)
			return;
		var controlType = G2DOM.G2GetAttribute(control, "g2control");
		if(controlType==null)
			return;
		window[controlType+"_Init"](control, e);
		if(!control.g2IsInited)
			control.g2IsInited = true;
	},

	G2_DoCallback : function(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync, classicPostback)
	{
	  G2_OnBeforeCallback();
	  WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync, classicPostback);
	},
	G2_OnBeforeCallback : function()
	{
		document.body.style.cursor="wait";
	},

	G2_OnCallbackError : function(result, context)
	{
		var err = "Callback Error: "+result;
		alert(err);
		
		G2_OnCallbackFinally(result, context);
	},

	G2_OnCallbackFinally : function(result, context)
	{
 		document.body.style.cursor = "";
 		//Close and reebable tooltips (disabled during silent postbacks)
 		G2PopupManager.enableTooltips();
 		G2PopupManager.closeAllTooltips();
	},
	//taken from aspnet scripts - performed MAJOR optimizations (removed the foreach loop)
	G2_InitCallback : function() 
	{
 		var context = {postData:new Array(), postCollection:new Array()};
		G2_InitCallbackRecursive(context);
		return context;
//		__theFormPostData =context.postData.join("");
//		__theFormPostCollection = context.postCollection;
	},


	G2CallbackManager_HandleResult : function(result, aspNetContext)
	{
		// unlock dopostback
		waitForCallback = null;
		
		var r = result.split("%||%");
		var context = {resultArray:r, aspNetContext:aspNetContext};
//		//moved to start by dan-el  
//		var viewState = r[4];
//		G2CallbackManager_UpdateViewState(viewState);
		//Handle hidden fields


		var scriptIncludes = r[1].split("||||");
		var srcArray = new Array();
		for(var i=0; i<scriptIncludes.length; i++)
		{
			var src = scriptIncludes[i];
			if(src==null || src=="")
				continue;
			srcArray.push(src);
		}
		G2_RegisterScripts(srcArray, function(){G2_HandleCallbackResultPhase2(result, context);});
		
		
		
	},

	
	G2_HandleCallbackResult_UpdateDomElements : function(htmlData)
	{
		for(var i=0; i<htmlData.length; i++)
		{
			if(htmlData[i]=="" || htmlData[i]==null)
				break;
			var element=document.getElementById(htmlData[i]);
			i++;
			var newHtml = htmlData[i];
			if (element != null)
			{
				var controlElement = element;
				if(element.getcontrolelement!=null)
				{
					controlElement = G2_Eval(element.getcontrolelement, element);
					if(controlElement==null)
					{
						G2_Warn("G2_HandleCallbackResult_UpdateDomElements", "controlElement wasn't found for element "+element.id);
						continue;
					}
				}
				G2DOM.G2ReplaceOuterHTML(controlElement,newHtml);
			}
		}
	},
	
	G2_Eval : function(code, target)
	{
		var cache = G2_EvalCache;
		var func = cache[code];
		if(func==null)
		{
			func = new Function(code);
			cache[code] = func;
		}
		return func.call(target);
	},
	StartTiming : function()
	{
		timings.push(new Date().getTime());
	},
	EndTiming : function(name)
	{
		name = name || arguments.callee.caller.name;
		var end = new Date().getTime();
		var start = timings.pop();
		var span= end-start;
//		if(span>500)
//			alert(name+" took "+span+"ms!");
	},
	
	G2_HandleCallbackResult_AddRepeaterElement: function(htmlData)
	{
		for(var i=0; i<htmlData.length; i++)
		{
			if(htmlData[i]=="" || htmlData[i]==null)
				break;
			var element=document.getElementById(htmlData[i]);
			i++;
			if(element != null)
			{
				var tbody = element.firstChild.tBodies[0];
				var newElement = G2DOM.G2CreateElementFromHtml(htmlData[i]);
				tbody.appendChild(newElement);
			}
		}		
	},
	
	G2_HandleCallbackResult_RemoveElement: function(itemsToRemove)
	{
		for(var i=0; i<itemsToRemove.length; i++)
		{
			if(itemsToRemove[i]=="" || itemsToRemove[i]==null)
				break;
			var element = document.getElementById(itemsToRemove[i]);			
			if(element != null)
			{
				element.removeNode(true)				
			}
		}		
	},
	
	G2_HandleCallbackResult_UpdateHiddenFields : function(hfHtml)
	{
		var div=document.createElement("DIV");
		div.innerHTML = hfHtml;
		var divChildren = div.children;
		var addElements = new Array();
		for(var i=0;i<divChildren.length; i++)
		{
			var hf = divChildren[i];
			var curHf = document.getElementById(hf.id);
			if(curHf!=null)
				curHf.value = hf.value;
			else
				addElements.push(hf); //we don't appendChild now because the length will change.
		}
		for(var i=0;i<addElements.length;i++)
		{
			document.forms[0].appendChild(addElements[i]);
		}
	},
	G2_HandleCallbackResult_UpdateActiveElement : function(activeElementID, prevActiveElement)
	{
		var el = document.getElementById(activeElementID);
		if(el!=null && el.tagName!="A" && prevActiveElement!=el)
		{
			var f = function()
			{	
				//the following line handles focusing an element that was replaced during a callback
				if(el.parentElement==null) //Element is detached from the dom
					el = document.getElementById(el.id);//Find the new element in the dom
				try
				{
				  el.isFocusingAfterPostback = true;//Indicate to the element that this is autofocus 
					el.focus(); //This may fail if the control is hidden etc.
				} 
				catch(e)
				{
				}
			}
			window.setTimeout(f, 50);
		}
	},
	G2_HandleCallbackResult_EvalStartupStatements : function(scriptData)
	{
		StartTiming();
		eval(scriptData);
		EndTiming();
	},
	G2_ReplaceCssClass : function(element, addCss, removeCss, inverse)
	{
		if(inverse)
		{
			var temp = removeCss;
			removeCss = addCss;
			addCss = temp;
		}
		var classes = G2_ParseCssClasses(element);
		classes.remove(removeCss);
		classes.add(addCss);
		G2_SetCssClasses(element, classes);

  },
	G2_RemoveCssClass : function(element, className)
	{
		var index = G2_FindWholeWord(element.className, className);
		if(index!=-1)
		{
			var begin = element.className.substr(0, index-1);
			var end = element.className.substr(index+className.length+1);
			if(begin!="" && end!="")
				element.className = begin+" "+end;
			else
				element.className = begin+end;
		}
  },
	G2_ParseCssClasses : function(element)
	{
		var list = element.className.split(/ /g);
		var obj = new ListSet();
		if(list.length==1 && list[0]=="")
		{
		}
		else
		{
			obj.addRange(list);
		}
		return obj;
  },
	G2_SetCssClasses : function(element, listset)
	{
		element.className = listset.toString(" ");
  },

	G2_AddCssClass : function(element, className)
	{
    if (!G2_ContainsCssClass(element, className)) 
    {
      if (element.className === '') 
      {
        element.className = className;
      }
      else 
      {
        element.className += ' ' + className;
      }
    }
  },
	G2_ContainsCssClass : function(element, className)
	{
		return G2_FindWholeWord(element.className, className)!=-1;
	},
	G2_FindWholeWord : function(text, word, seperator)
	{
		if(seperator==null)
			seperator = " ";
		if(word==null || word=="" || word.indexOf(seperator)!=-1)
			throw new Error("error in word: "+word);
		if(text=="")
			return -1;
		var x = 0;
		for(var i=0;i<text.length;i++)
		{
			if(text.charAt(i)==seperator)
			{
				if(x==word.length)
					return i-x;
				x=0;
			}
			else if(text.charAt(i)==word.charAt(x))
				x++;
			else
				x=0;
		}
		if(x==word.length)
			return i-x;
		return -1;
  },

	G2_HandleCallbackResultPhase2 : function(result, context)
	{	
		var resultArray = context.resultArray;

		//Handle html repeater data
		var htmlRepeaterData = resultArray[5].split("||||");
		G2_HandleCallbackResult_AddRepeaterElement(htmlRepeaterData);
				
		//Handle removing items
		var itemsToRemove = resultArray[6].split("||||");
		G2_HandleCallbackResult_RemoveElement(itemsToRemove);
		
		//Handle html data
		var htmlData = resultArray[0].split("||||");
		var activeElementID = null;
		var activeElement = document.activeElement;
		if(activeElement && !String.IsNullOrEmpty(activeElement.id))
		{
			activeElementID = activeElement.id;
		}
		G2_HandleCallbackResult_UpdateDomElements(htmlData);				
		
		//aspnet holds a strong reference to the form element, (in a variable named theForm)
		//which might be updated dynamically, so we update that reference
		if(theForm.parentElement==null) 
			theForm = document.forms[0];
		var hfHtml = resultArray[2];
		if(hfHtml!=null && hfHtml!="")
		{
			G2_HandleCallbackResult_UpdateHiddenFields(hfHtml);
		}

		if(activeElementID!=null)
		{
			G2_HandleCallbackResult_UpdateActiveElement(activeElementID, activeElement);
		}
			
		//Handle scripts
		var scriptData = resultArray[3];
		if(scriptData!=null && scriptData!="")
		{
			G2_HandleCallbackResult_EvalStartupStatements(scriptData);
		}
		
 	  //Handle the processing image - AFTER the startup statements (since we might navigate, and in that case we don't want to hide the image)
		HideProcessingImage();
		
		G2_ShowDisabler(false);
		
		//Handle last scripts
		var lastScriptData = resultArray[4];
		if(lastScriptData!=null && lastScriptData!="")
		{
			window.setTimeout(function(){	G2_HandleCallbackResult_EvalStartupStatements(lastScriptData); }, 10);
		}
		
		if(window.OnAfterCallbackClientFunction!=null)
		{
			window[window.OnAfterCallbackClientFunction]();
		}
		
		
		if(NOTIFY_SERVER_HISTORY_CHANGE)
		{
			if(context.aspNetContext.eventTarget=="__Page" && context.aspNetContext.eventArgument.startsWith("HistoryChange"))
			{
			}
			else
			{
				G2.historyIndex++;
				dhtmlHistory.add(G2.historyIndex.toString(), "Hello World " + "Data")
			}
		}
		G2_OnCallbackFinally(result, context);

		//event validation - doesn't work
	//  var eventValidationFieldValue = r[3];
	//  var eventValidationField = document.getElementById("__EVENTVALIDATION");
	//  eventValidationField.value = eventValidationFieldValue;
	},



	G2CallbackManager_UpdateViewState : function(viewState)
	{
		var div = document.createElement("div");
		div.innerHTML = viewState;
		document.getElementById("__VIEWSTATE").value =div.firstChild.value;
	},


	G2_InitCallbackAddField : function(name, value, context) 
	{
	//	WebForm_InitCallbackAddField(name, value);
//			var nameValue = new Object();
//			nameValue.name = name;
//			nameValue.value = value;
//			context.postCollection.push(nameValue);
			context.postData.push(name);
			context.postData.push("=");
			context.postData.push(WebForm_EncodeCallback(value));
			context.postData.push("&");
	},

	EnableSupportForPartialPostData : function(element)
	{
		element.isValueDirty = EnableSupportForPartialPostData_IsValueDirty;
		element.setValueAsNotDirty = EnableSupportForPartialPostData_SetValueAsNotDirty;
		element._originalValue = element.value;
		G2PartialPostDataElementIds[element.id] = element;
		if(ENABLE_POSTDATA_ONDEMAND)
		{
			if (isIE)
			{
				if((element.tagName=="INPUT" && element.type=="text") || element.tagName=="SELECT" || element.tagName=="TEXTAREA")
				{
					G2_AttachEvent(element, "onchange", function()
					{
						G2.notifyInputChanged(this);
					});
				}
				else
				{
					G2_AttachEvent(element, "onpropertychange", function()
					{
						if(event.propertyName=="value")
							G2.notifyInputChanged(this);
					});
				}
			} 
			else if (isMoz)
			{
				G2.RegisterPropertyChangeWatch(element.id);
			}
		}
	},
	
	EnableSupportForPartialPostData_SetValueAsNotDirty : function()
	{
		this._originalValue = this.value;
	},
	
	EnableSupportForPartialPostData_IsValueDirty : function()
	{
		return !(this.value===this._originalValue);
	},
	G2_InitCallbackByIds : function(ids, context)
	{
		for(var i=0;i<ids.length;i++)
		{
			var element = $(ids[i]);
			if(element!=null)
			{
				G2_InitCallbackForElement(element, context);
			}
			else if(ids[i]=="__WINDOWID" && window.location.href.search("WindowID")==-1)
			{
				throw new Error("window id not found");
			}
		}
	},

	G2_InitCallbackRecursive : function(context)
	{
		if(ENABLE_POSTDATA_ONDEMAND)
		{
			G2_InitCallbackAddField("__PARTIALPOSTDATA", "true", context);
			G2_InitCallbackByIds(["__EVENTTARGET", "__EVENTARGUMENT",  "__EVENTVALIDATION", "__VIEWSTATE", "__WINDOWID"], context);
			var inputsToRemove = new Object();
			for(var id in G2.changedInputs)
			{
				var element = $(id)
				if (element) //the element may be detached from the DOM
				{
					G2_InitCallbackForElement(element, context);
					inputsToRemove[id] = id;
				}
			}
			for (var id in inputsToRemove)//remove sent inputs
			{
				delete G2.changedInputs[id];
			}
		}
		else
			G2_PerformRecursiveActionOnElement(theForm, G2_InitCallbackForElement, context);
	},

	G2_InitCallbackForElement : function(element, context)
	{
		if(element.doesNotContainInputs)
			return false;
		if(G2_PreventPostElementIds[element.id]==true)
			return false;
		var tagName = element.tagName.toLowerCase();
		if (tagName == "input") 
		{
			var type = element.type;
			if ((type == "text" || type == "hidden" || type == "password" ||
					((type == "checkbox" || type == "radio"))) && // && element.checked
					(element.id != "__EVENTVALIDATION")) 
			{
				var name = element.name;
				var value = element.value;
				if(type == "checkbox")
				{
					if(ENABLE_POSTDATA_ONDEMAND)
					{
						value = element.checked ? "on" : "off";
					}
					else if(!element.checked)
						return false;
				}
				else if(type == "radio")
				{
					if(ENABLE_POSTDATA_ONDEMAND)
					{
						if(type == "radio" && element.g2rb=="true")
						{
							name = element.id;
						  value = element.checked ? "on" : "off";
						}
						else
					  {
					    G2_InitCallbackAddField(name, value, context);
					    return false;
					  }
					}
					else if(!element.checked)
						return false;
				}

				if(typeof(element.isValueDirty)=="function")
				{
					if(element.isValueDirty())
					{
						element.setValueAsNotDirty();
					}
					else
						return false;
				}
				G2_InitCallbackAddField(name, value, context);
				return false;
			}
		}
		else if (tagName == "select") 
		{
			var selectCount = element.options.length;
			var selCount = 0;
			for (var j = 0; j < selectCount; j++) 
			{
				var selectChild = element.options[j];
				if (selectChild.selected == true) 
				{
					selCount++;
					G2_InitCallbackAddField(element.name, selectChild.value, context);
					if(!element.multiple)
						return false;
				}
			}
			//We send null value to the ListBox
			if(selCount==0 && element.multiple)
				G2_InitCallbackAddField(element.name, "__NULL__", context);
		}
		else if (tagName == "textarea") 
		{
			G2_InitCallbackAddField(element.name, element.value, context);
			return false;
		}
		return true;
	},





	G2_GetEventTargetID : function(eventTarget) 
	{
		var realId;
		if(eventTarget.indexOf("$")>-1)
			realId = eventTarget.replace(/\$/g, '_');
		else if(eventTarget.indexOf(":")>-1)
			realId = eventTarget.replace(/:/g, '_');
		else
			realId = eventTarget;
		return realId; 
	},

	G2_GetEventTargetElement : function(eventTarget)
	{
		var el = $(eventTarget);
		if(el==null)
		{
			if(eventTarget.indexOf("$")>-1)
				eventTarget = eventTarget.replace(/\$/g, '_');
			else if(eventTarget.indexOf(":")>-1)
				eventTarget = eventTarget.replace(/:/g, '_');
			else
				return null;
			el = $(eventTarget);
		}
		return el;
	},


	G2_RefreshElement : function(element)
	{
		element.outerHTML = element.outerHTML;
	},

	G2IsSilent : function(eventTarget, eventArgument, eventTargetElement) 
	{
		if(window.silentPostbacks==true)
			return true;
		if (window.DisableSilentPostBack==true)
			return false;
		if(eventTargetElement!=null && eventTargetElement.getAttribute("silentpostback")=="true")
			return true;
		return false;
		var targets = window.silentPostbacksTargets;
		if(targets==null)
			return false;
		var val = targets[eventTarget];
		//TODO: find what causes this
		if(val==null && eventTarget.indexOf("$")>-1)
		{
			eventTarget = eventTarget.replace(/\$/g, '_');
			val = targets[eventTarget];
		}
		if(val==null && eventTarget.indexOf(":")>-1)
		{
			eventTarget = eventTarget.replace(/:/g, '_');
			val = targets[eventTarget];
		}
		if(val==null)
			return false;
		if(!String.IsNullOrEmpty(eventArgument) && val.args!=null)
		{
			var childValue = val.args[eventArgument];
			if(childValue!=null)
				return childValue;
		}
		return val.silent;
	},

	G2SetSilentPostBacks : function(json) 
	{
		if(window.silentPostbacksTargets==null)
		{
			window.silentPostbacksTargets = json;
		}
		else
		{
			for(var p in json)
			{
				window.silentPostbacksTargets[p] = json[p];
			}
		}
	},


	G2SetSilentPostBacksAll : function(isSilent)
	{
		window.silentPostbacks = isSilent;
	},

	//*****************************************************************
	//*                      G2ScriptManager                          *
	//*****************************************************************
	G2_GetRegisteredScripts : function()
	{
		if(_registeredScripts==null)
		{
			var elements = document.getElementsByTagName("script");
			_registeredScripts = new Object();
			for(var i=0;i<elements.length;i++)
			{
				var element = elements[i];
				if(element.src!="")
					_registeredScripts[element.src] = true;
			}
		}
		return _registeredScripts;
	},

	G2_IsScriptRegistered : function(src)
	{
		return G2_GetRegisteredScripts()[src]==true;
	},

	G2_GetUnregisteredScripts : function(srcArray)
	{
		if(srcArray==null)
			return null;
		var sources = new Array();
		for(var i=0;i<srcArray.length;i++)
		{
			var src = srcArray[i];
			if(!G2_IsScriptRegistered(src))
			{
				sources.push(src);
			}
		}
		return sources;
	},
	//
	// Gets an array of src strings, and loads these scripts. returns a callback when all scripts are loaded
	//
	G2_RegisterScripts : function(srcArray, loadCompletedCallback)
	{
		var sources = G2_GetUnregisteredScripts(srcArray);
		if(sources!=null && sources.length>0)
		{
			var context = {total:sources.length, loadCompletedCallback:loadCompletedCallback, sources:sources};
			for(var i=0;i<sources.length;i++)
			{
				var src = sources[i];
//				didNothing = false;
				var element = document.createElement("SCRIPT");
				element.src = src;
				element.setAttribute("type","text/javascript"); //Check if really needed
				document.body.appendChild(element); //TODO: this is a problem - the included file takes time to load 
				
				if(loadCompletedCallback!=null)
				{
					G2_AttachEvent(element, isIE ? "onreadystatechange" : "onload", function(e){G2_WaitForScripts(e ? e : event,context);}	);
				}
			}
		}
		else if(loadCompletedCallback!=null)
		{
			loadCompletedCallback();
		}
	},
	//*****************************************************************
	//*               End of G2ScriptManager                          *
	//*****************************************************************

	G2_WaitForScripts : function(event,context)
	{
		var element = G2Event.element(event);
		if(element.readyState=="loaded" || element.readyState=="complete" || isMoz)
		{
			context.total--;
			//clean up
			G2_DetachEvent(element, isIE ? "onreadystatechange" : "onload", G2_WaitForScripts);
			//end 
			_registeredScripts[element.src] = true;
			if(context.total==0)
			{
				context.loadCompletedCallback();
			}
		}
	},
	
	G2_CreateXmlHttp : function()
	{
		var xmlRequest,e;
		try 
		{
			xmlRequest = new XMLHttpRequest();
		}
		catch(e) 
		{
			try 
			{
				xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e) {
			}
		}
		var setRequestHeaderMethodExists = true;
		try 
		{
			setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);
		}
		catch(e) {}
		if(!setRequestHeaderMethodExists)
			return null;
		return xmlRequest;
	},

	WebForm_DoCallback : function (eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync, classicPostback, g2context) 
	{
		if(g2context==null) //this may happen when calling DoCallback directly (when using ClientScript.GetCallbackReference
		{
			g2context = G2_InitCallback();
		}

		g2context.postData.push("__CALLBACKID=");
		g2context.postData.push(WebForm_EncodeCallback(eventTarget));
		g2context.postData.push("&__CALLBACKPARAM=");
		g2context.postData.push(WebForm_EncodeCallback(eventArgument));
		if (theForm["__EVENTVALIDATION"]) 
		{
			g2context.postData.push("&__EVENTVALIDATION=");
			g2context.postData.push(WebForm_EncodeCallback(theForm["__EVENTVALIDATION"].value));
		}
		var postData = g2context.postData.join("");
		var xmlRequest = G2_CreateXmlHttp();
		
		var callback = new Object();
		callback.eventCallback = eventCallback;
		callback.context = context;
		callback.errorCallback = errorCallback;
		callback.async = useAsync;
		var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);
		if (!useAsync) 
		{
				if (__synchronousCallBackIndex != -1) {
						__pendingCallbacks[__synchronousCallBackIndex] = null;
				}
				__synchronousCallBackIndex = callbackIndex;
		}
		if (xmlRequest!=null) 
		{
			if(!G2UseSyncCallbacks)
				xmlRequest.onreadystatechange = WebForm_CallbackComplete;
			callback.xmlRequest = xmlRequest;
			xmlRequest.open("POST", theForm.action, !G2UseSyncCallbacks); //was hardcoded true - modified by Alon to force sync. calls to allow popups to be opened.
			xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			xmlRequest.send(postData);
			if(G2UseSyncCallbacks)
				WebForm_CallbackComplete();
			return;
		}
		WebForm_DoCallback_WithIFrame();
	},
	//this code exists in asp.net callbacks code - and used when browser doesn't support xmlhttp.
	//removed for now.
	WebForm_DoCallback_WithIFrame : function()
	{
		throw new Error("not implemented");
	},


	WebForm_CallbackComplete : function() 
	{
			for (var i = 0; i < __pendingCallbacks.length; i++) 
			{
					callbackObject = __pendingCallbacks[i];
					if (callbackObject && callbackObject.xmlRequest && (callbackObject.xmlRequest.readyState == 4)) 
					{
							WebForm_ExecuteCallback(callbackObject);
							//TODO: HACK: added by dan-el - when closing popups the item is not there. probably related to registration to callbackreference
							if(__pendingCallbacks[i]!=null) 
							{
								if (!__pendingCallbacks[i].async) 
								{
										__synchronousCallBackIndex = -1;
								}
							}
							__pendingCallbacks[i] = null;
							var callbackFrameID = "__CALLBACKFRAME" + i;
							var xmlRequestFrame = document.getElementById(callbackFrameID);
							if (xmlRequestFrame) 
							{
									xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
							}
					}
			}
	},

	WebForm_ExecuteCallback : function(callbackObject) 
	{
		var response = callbackObject.xmlRequest.responseText;
		if (response.charAt(0) == "s") 
		{
			if ((typeof(callbackObject.eventCallback) != "undefined") && (callbackObject.eventCallback != null)) 
			{
				callbackObject.eventCallback(response.substring(1), callbackObject.context);
			}
		}
		else if (response.charAt(0) == "e") 
		{
			if ((typeof(callbackObject.errorCallback) != "undefined") && (callbackObject.errorCallback != null)) 
			{
				callbackObject.errorCallback(response.substring(1), callbackObject.context);
			}
		}
		else 
		{
			var separatorIndex = response.indexOf("|");
			if (separatorIndex != -1) 
			{
				var validationFieldLength = parseInt(response.substring(0, separatorIndex));
				if (!isNaN(validationFieldLength)) 
				{
					var validationField = response.substring(separatorIndex + 1, separatorIndex + validationFieldLength + 1);
					if (validationField != "") 
					{
						var validationFieldElement = theForm["__EVENTVALIDATION"];
						if (!validationFieldElement) 
						{
							validationFieldElement = document.createElement("INPUT");
							validationFieldElement.type = "hidden";
							validationFieldElement.name = "__EVENTVALIDATION";
							theForm.appendChild(validationFieldElement);
						}
						validationFieldElement.value = validationField;
					}
					if ((typeof(callbackObject.eventCallback) != "undefined") && (callbackObject.eventCallback != null)) 
					{
						callbackObject.eventCallback(response.substring(separatorIndex + validationFieldLength + 1), callbackObject.context);
					}
				}
			}
			else
			{
				var location = callbackObject.xmlRequest.getResponseHeader("location"); //if Response.RedirectLocation is used
				if(location!=null && location!="")
				{
					G2_Navigate(location);
				}
				else
				{
   				callbackObject.errorCallback(response, callbackObject.context);
   			}
			}
		}
	},

	G2_UseSyncCallbacks : function()
	{
		G2UseSyncCallbacks = true;
//		WebForm_DoCallback = WebForm_DoCallback_Sync;
//		WebForm_CallbackComplete = WebForm_CallbackComplete_Sync;
	},


	//
	//recursivle iterates on all child elements of a certain element,
	//and calls the specified action with the element and context, action(element, context)
	//if the action returns false, it will stop the recursive operation inside that element
	//
	G2_PerformRecursiveActionOnElement : function(element, action, context)
	{
		_G2_PerformRecursiveActionOnElement(element, action, context);
	},
	_G2_PerformRecursiveActionOnElement : function(element, action, context)
	{
		if(element.nodeType!=1) //textnode
			return;

		var result = action(element, context);
		if(result==false)
			return;
		var child = element.firstChild;
		while(child!=null)
		{
			_G2_PerformRecursiveActionOnElement(child, action, context);
			child = child.nextSibling;
		}
	},


	G2_SetFocus : function(elementId)
	{
		if(G2_SetFocus_ThreadId!=null)
		{
			window.clearTimeout(G2_SetFocus_ThreadId);
			G2_SetFocus_ThreadId = null;
		}
		G2_SetFocus_ThreadId = window.setTimeout(
			function()
			{
				G2_SetFocus_ThreadId = null;
				var success = G2_AutoFocus(elementId);
				if(success) //case 8578 - sometimes after the successful focus, the body is somehow focused. this hack fixes it.
				{
					if(document.activeElement==null || document.activeElement.id!=elementId)
					{
						success = G2_AutoFocus(elementId);
					}
				}
			}, 50);
	},


	///
	/// Finds a server control by server ID (using id.contains(id))
	///
	G2_FindServerControl : function(fromElement, id)
	{
		return _G2_FindServerControl(fromElement, id);
	},
	_G2_FindServerControl : function(fromElement, id)
	{
		if(fromElement.id!=null && fromElement.id.endsWith(id))
			return fromElement;

		if(fromElement.doesNotContainInputs || fromElement.tagName=="SELECT")
			return null;

		var element = fromElement.firstChild;
		while(element!=null)
		{
			var foundControl = _G2_FindServerControl(element, id)
			if(foundControl!=null)
				return foundControl;
			element = element.nextSibling;
		}
		return null;
	},



	G2ReturnValue : function(value)
	{
		this.value = value;
	},
	
	// Get current page theme
	G2_PageTheme : function()
	{
		return document.getElementById("G2_PageTheme").value;
	},


	G2_MapPath : function(virtualUrl)
	{
		var rootAppPath = document.getElementById("G2_RootAppPath").value;
		var path = virtualUrl.replace("~/", rootAppPath);
		return path;
	},
	G2_IsNavigating : function()
	{
	  return window.top.IsNavigating;
	},
	
	G2_Navigate : function(url, isInternalNavigation, targetFrame, navigateWithForms)
	{
	    var navigationWindow = null;
	    if (isInternalNavigation && isInternalNavigation != 'false')
		{
		      if(targetFrame!="" && targetFrame!=null) //navigate inside a frame
		      {
		        var f = document.getElementById(targetFrame);
		        f.contentWindow.document.location.href = url;
		        return;
		      }
		      else //navigate in this window
		         navigationWindow = window; 
		}
		else //navigate in the topmost window
		{
		      navigationWindow = window.top;
	    }
	    if (navigateWithForms && navigateWithForms != 'false') //naviage throught form submit
	        G2_FormNavigate(navigationWindow, url);
	     else //navigate through url change
	     {
	        navigationWindow.IsNavigating = true;
	        navigationWindow.window.location.href = url;
	        
	     }
	},
	
	G2_FormNavigate : function (windowObj, url)
	{
	    windowObj.IsNavigating = true;
	    var navForm = window.document.createElement("FORM");
	    navForm.method = "get";
	    var urlPair = url.toString().split('?');
	    var navUrl = urlPair[0];
	    if (urlPair.length > 1)
	    {
            var query = urlPair[1];
            queryStringKeys = new Array();	
            queryStringValues = new Array();
	        var pairs = query.split("&");
        	for (var i=0; i < pairs.length; i++)
            {
	            var pos = pairs[i].indexOf('=');
	            if (pos >= 0)
	            {
		            var argname = pairs[i].substring(0,pos);
		            var value = pairs[i].substring(pos+1);
		            var input = window.document.createElement('INPUT');
		            input.name = argname;
		            input.value = value;
		            input.type = 'hidden';
		            input.style.display = 'none';
		            navForm.appendChild(input);
	            }
             }
        }
    	windowObj.document.body.appendChild(navForm);
	    navForm.action = navUrl;
	    navForm.submit();
	},
	
	G2_Warn : function(sender, msg)
	{
		G2_Trace(sender, "************************************");
		G2_Trace(sender, msg);
		G2_Trace(sender, "************************************");
	},

	G2_Trace : function(sender, msg)
	{
		var id = null;
		if(sender!=null)
		{
			id = sender.id!=null ?  sender.id : sender.toString();
		}
		var now = new Date();
		var time = Date_ToString(now, "HH:mm:ss:ff");
		Debug.writeln(time+", "+id+": "+msg);
	},

	//New version by Alon.
	G2_GetData : function(url, callback, errorCallback)
	{
		url = encodeURI(url); //added by dan-el - when url has querystring arguments that contains chinese (for example) - will only work with encoding.
		if (isIE && window.ActiveXObject)
		{
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			if (xmlhttp!=null)
			{
				xmlhttp.onreadystatechange=function()
				{
					var x = xmlhttp.readyState;
					var y = xmlhttp.readyState;
					if(x==y)
					{
					}
					// if xmlhttp shows "loaded"
					if (xmlhttp.readyState==4)
					{
						// if "OK"
						if (xmlhttp.status==200)
						{
							callback(xmlhttp);
						// ...some code here...
						}
						else
						{
							errorCallback(xmlhttp);
						}
					}
				}
				xmlhttp.open("GET",url,true);
				xmlhttp.send(null);
			}
		} 
		else if (window.XMLHttpRequest)
		{
			try
			{
				var xmlhttp=new XMLHttpRequest();
				xmlhttp.open("GET",url,false);
				xmlhttp.send(null);
				callback(xmlhttp);		
			} 
			catch(everything)
			{
			  if (G2_Trace!=null)
			  {
				  G2_Trace("G2_GetData", everything.description);
				}
				errorCallback(xmlhttp);
			}
		} 
		else
		{
			alert("Your browser does not support XMLHTTP.");
		}
	},

	//function G2Page_Wait()
	//{
	//  setTimeout("G2Page_Wait_Timeout();",150);
	//}

	//function G2Page_Wait_Timeout()
	//{
	//  if(!Page_IsValid)
	//   return;
	//  var hf = document.getElementById("G2_WaitingImage");
	//  if(hf.value!="")
	//  {
	//    var img = document.getElementById(hf.value);
	//    img.style.display = "block";
	//    var srcWas = img.src;
	//    img.src = "";
	//    img.src = srcWas;
	//  }
	//}

	G2_IsInPopup : function()
	{
		try
		{
			parentDoc = parent.document;
			return (parentDoc!=null && parentDoc!=document)
		} 
		catch(everything)
		{	
			G2_Trace("IsInPopup", everything.description);
			Debug.writeln("IsInPopup() FAILED");
			return false;
		}  
	},


	//now registered inline from g2page.cs
	//function G2Page_Init()
	//{
	//	G2_AttachEvent(window, "onload", G2Page_OnLoad);
	//}


	//Unless explicitly specified, resizing is DISABLED until page is loaded.
	//When the page is loaded, the auto-size feature is enabled
	G2Page_OnLoad : function()
	{
	//	G2_DetachEvent(window, "onload", G2Page_OnLoad);
		G2_PreventInputPost("G2_OnLoadStatement");
		var s = document.getElementById("G2_OnLoadStatement");
		enableResizing = true;
		if(s!=null)
		{
			eval(s.value);
		}	
		if (G2_IsInPopup())
		{
			G2Dialog_Init();
		}
	},

	G2_FirePopupClosed : function(popupID, popupResult, silent, uniqueId)
	{
		if (uniqueId!=null)
			popupID = popupID + "###"+uniqueId;
		var hf1 = document.getElementById('__PopupWindowID');
		var hf2 = document.getElementById('__PopupResult');
		hf1.value = popupID;
		hf2.value = popupResult;
		G2.notifyInputChanged(hf1);
		G2.notifyInputChanged(hf2);
		__doPostBack('__Page','G2PopupClosed',silent);  
	},

	G2HtmlFrame_Init : function(iframeId, targetElementId, tooltipKey, autoSize)
	{
		if(tooltipKey!=null && tooltipKey!="")
		{
			G2Tooltips[tooltipKey] = iframeId;
		}
		if(targetElementId!="")
		{
			var target = document.getElementById(targetElementId);
			var iframe = document.getElementById(iframeId);
			target._tooltipFrame = iframe;
			iframe.style.position="absolute";
	    
			target.onmouseover=function()
			{
				x = event.clientX + document.body.scrollLeft;
				y = event.clientY + document.body.scrollTop;
				this._tooltipFrame.style.pixelLeft = x;
				this._tooltipFrame.style.pixelTop = y;
				this._tooltipFrame.style.display = "block";
			}
			target.onmouseout=function()
			{
				this._tooltipFrame.style.display = "none";
			}
		}
		
		if(autoSize)
			window.setTimeout(function() { G2FrameManager.registerFrame(iframeId); }, 0);
	},

	G2ShowTooltip : function(target, tooltipKey,event)
	{
		var iframeId = G2Tooltips[tooltipKey];
		var iframe = document.getElementById(iframeId);
		if (!iframe)
			return;
		if (!event)
			event = window.event;
		G2ShowTooltipElement(target, iframe,event);
	},
	
  G2ShowTooltipElement : function(targetElement, tooltipElementOrId,e)
  {
	  if (!e)
		  e = window.event;
  		
	  if(typeof(tooltipElementOrId)=="string")
	   el = document.getElementById(tooltipElementOrId);
	  else
	   el = tooltipElementOrId;
  	 
	  G2PopupManager.showTooltipStart(targetElement, el,e);
  },  

	Date_Parse : function(strDate)
	{
		var date = new Date(strDate);
		if(isNaN(date))
			return null;
		return date;
	},



	//------- G2 Utils -----------------------------------------------------------
	//UNUSED
	G2SyncTables : function(tbl1ID,tbl2ID)
	{
		var table1 = document.getElementById(tbl1ID);
		var table2 = document.getElementById(tbl2ID);

		if(table1==null || table2==null)
			return;
		var tbl1AmoutOfRows= table1.rows.length;
		var tbl2AmoutOfRows= table2.rows.length;
		var minRowSize=0;


		if(tbl1AmoutOfRows>tbl2AmoutOfRows)
			minRowSize= tbl2AmoutOfRows;
		else 
			minRowSize= tbl1AmoutOfRows;
	    
		var i =0;
		var j =0;
		var minColSize=0;
		if(table1.rows[0].cells.length <table2.rows[0].cells.length)
			minColSize=table1.rows[0].cells.length;
		else 
			minColSize=table2.rows[0].cells.length;
	    
		while(i<minRowSize){
				j=0;
				while(j<minColSize){
									if(table1.rows[i].cells[j].style.width<table2.rows[i].cells[j].style.width)
										table1.rows[i].cells[j].style.width=table2.rows[i].cells[j].style.width;
									else
										table2.rows[i].cells[j].style.width=table1.rows[i].cells[j].style.width;
								 j=j+1;
				}
			i=i+1;
		}
	},

	String_ToInt : function(text)
	{
		if(text==null || text.length==0)
			return null;
		text = String_TrimLeft(text, "0");//because of js bug: parseInt('08') returns 0 as a result
		if(text.length==0)
			return 0;
		var x = parseInt(text);
		if(isNaN(x))
			return null;
		return x;
	},

	String_TrimLeft : function(text, trimChar)
	{
		while(text.length>0 && text.charAt(0)==trimChar)
		{
			text = text.substr(1, text.length-1);
		}
		return text;
	},

	Select_FindByValue : function(select, value)
	{
		for(var i=0;i<select.options.length;i++)
		{
			if(select.options[i].value==value)
				return select.options[i];
		}
		return null;
	},

	Select_IndexOfValue : function(select, value)
	{
		for(var i=0;i<select.options.length;i++)
		{
			if(select.options[i].value==value)
				return i;
		}
		return null;
	},
	Select_ContainsValue : function(select, value)
	{
		return Select_IndexOfValue(select, value)!=null;
	},

	//
	// returns the index of the first occurance of a specific item in an array
	//
	Array_IndexOf : function(array, value)
	{
		for(var i=0;i<array.length;i++)
		{
			if(array[i]==value)
				return i;
		}
		return -1;
	},
	G2_findPreviousControl : function(ctrl , tagName)
	{
		while (ctrl!=null && ctrl.tagName!=tagName)
		{
			if (ctrl.previousSibling==null)
				ctrl = ctrl.parentElement;
			else
				ctrl = ctrl.previousSibling;
		}
		return ctrl;

	},

	G2_getDayName : function(year , month , day)
	{
		var dDate = new Date();
		dDate.setFullYear(year,month-1,day);
		return weekDays[dDate.getDay()];
	},


	DateRange_GetDays : function(dateRange, hoursToAdd)
	{
		return DateRange_GetNights(dateRange, hoursToAdd)+1;
	},

	DateRange_GetNights : function(dateRange, hoursToAdd)
	{
		//case 7606: in case of date range over Summertime trnsition (start date in summertime 
		//and end date in regulare time or the other way around)
		dateRange = dateRange + hoursToAdd*1000*60*60;
		return Math.ceil(dateRange/(24*60*60*1000));
	},

	DateRange_GetYears : function(dateRange)
	{
		return dateRange/(365*24*60*60*1000);
	},

	Date_AddHours : function(date,hours) 
	{
		return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours() + hours, date.getMinutes(), date.getSeconds());
	},

	Date_AddDays : function(date,days) 
	{
		return new Date(date.getFullYear(), date.getMonth(), date.getDate()+days, date.getHours(), date.getMinutes(), date.getSeconds());
	},

	Date_SubtractDays : function(date,days) 
	{
		return new Date(date.getFullYear(), date.getMonth(), date.getDate()-days, date.getHours(), date.getMinutes(), date.getSeconds());
	},

	Date_ToDotNetString : function(date) 
	{
		return Date_ToString(date, "MM-dd-yyyy");
	},

	Date_VerifyLeadingZero : function(str)
	{
		if(str.length==1)
			str = "0"+str;
		return str;
	},

	///Parses a string like 'Aug' or '8' or '08' into the month number (not javascript month)
	///and returns it - like 8 in this case
	Date_ParseMonth : function(text)
	{
		var month = Array_IndexOf(Date_ShortMonthNames, text);
		if(month!=-1)
		{
			return month+1;
		}
		
		month = String_ToInt(text);
		return month;
	},

	Number_Extension : function(str)
	{
			var lastDigit = str.charAt(str.length-1);
			var last = parseInt(lastDigit);
			var prev = 0;
			if (str.length >= 2) 
			{
				var prevDigit = str.charAt(str.length-2);
				prev = parseInt(prevDigit);
			}
			
			if (prev != 1) //When the number doesn't end with 11, 12 or 13, the extension is according the last digit
			{
				if (last == 1)
					return "st";
				else if (last == 2)
					return "nd";
				else if (last == 3)
					return "rd";
				else
				 return "th"; // 0, 4, 5, 6, 7, 8 and 9
			}
			else //When the number ends with 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, when the tenth digit is 1
				return "th"; 
			
	},

	Number_Format : function(number, format)
	{
		if(format=="#")
		{
			return number.toString();
		}
		else if(format=="##")
		{
			var s = number.toString();
			while(s.length<2)
			{
				s = "0"+s;
			}
			return s;
		}
		else if(format=="##xx")
		{
			var s = Number_Format(number, "##");
			var ext = Number_Extension(s);
			s += ext;
			return s;
		}
		else if(format=="#xx")
		{
			var s = Number_Format(number, "#");
			var ext = Number_Extension(s);
			s += ext;
			return s;
		}
		throw new Error("number format is not supported");
	},

	//
	// Formats a javascript Date object to string in a manner similar to .net framework.
	// currently supports: day, month, year, hour, minute,
	// seperators: '/', ':'
	//
	Date_ToString : function(date, format) 
	{
		if(date==null)
			return "";
			
		if(format=="H")
		{
			return date.getHours().toString();
		}
		else if(format=="HH")
		{
			return Date_VerifyLeadingZero(date.getHours().toString());
		}
		else if(format=="m")
		{
			return date.getMinutes().toString();
		}
		else if(format=="mm")
		{
			return Date_VerifyLeadingZero(date.getMinutes().toString());
		}
		else if(format=="s")
		{
			return date.getSeconds().toString();
		}
		else if(format=="ss")
		{
			return Date_VerifyLeadingZero(date.getSeconds().toString());
		}
		else if(format=="ff")
		{
			return Date_VerifyLeadingZero(date.getMilliseconds().toString());
		}
		else if(format=="d")
		{
			return date.getDate().toString();
		}
		else if(format=="dxx")
		{
			var day = date.getDate();
			var s = Number_Format(day, "#xx");
			return s;
		}
		else if(format=="dd")
		{
			return Date_VerifyLeadingZero(date.getDate().toString());
		}
		else if(format=="ddxx")
		{
			var day = date.getDate();
			var s = Number_Format(day, "##xx");
			return s;
		}
		else if(format=="M")
		{
			return (date.getMonth()+1).toString();
		}
		else if(format=="MM")
		{
			return Date_VerifyLeadingZero((date.getMonth()+1).toString());
		}
		else if(format=="MMM")
		{
			return Date_ShortMonthNames[date.getMonth()];
		}
		else if(format=="MMMM")
		{
			return Date_MonthNames[date.getMonth()];
		}
		else if(format=="y")
		{
			throw new Error("'y' is not a valid datetime format");
		}
		else if(format=="yy")
		{
			var str = date.getFullYear().toString();
			if(str.length==4)
				str = str.substr(2, 2);
			return str;
		}
		else if(format=="yyyy")
		{
			return date.getFullYear().toString();
		}
		else if(format.search(":")!=-1)
		{
			return _Date_ToString(date, format, ":");
		}
		else if(format.search("/")!=-1)
		{
			return _Date_ToString(date, format, "/");
		}
		else if(format.search("\\\\")!=-1)
		{
			return _Date_ToString(date, format, "\\");
		}
		else if(format.search("-")!=-1)
		{
			return _Date_ToString(date, format, "-");
		}
		else if(format.search(" ")!=-1)
		{
			return _Date_ToString(date, format, " ");
		}
		else if(format.search(".")!=-1)
		{
			return _Date_ToString(date, format, ".");
		}
		else
			throw new Error("date format is not supported");
	},

	//	var myDate = new Object();
	//	myDate.Day = date.getDate();
	//	myDate.Month = date.getMonth()+1;
	//	myDate.Year = date.getFullYear();
	//	myDate.ShortYear = date.getYear();

	//	if(format=="dd/MM/yy")
	//	{
	//		var s = (myDate.Day+"/"+myDate.Month+"/"+myDate.ShortYear);//.getDate()+"-" + date.getMonth()+1)+"-" + date.getFullYear();
	//		return s;
	//	}

	_Date_ToString : function(date, format, seperator)
	{
		var str="";
		var tokens = format.split(seperator);
		for(var i=0;i<tokens.length;i++)
		{
			var token = tokens[i];
			if(token!=null && token.length>0)
				str += Date_ToString(date, token);
			if(i!=tokens.length-1) //if not last, add seperator
				str += seperator;
		}
		return str;
	},


	// -------------------------------------------------------------------
	// autoComplete (text_input, select_input, ["text"|"value"], [true|false])
	//   Use this function when you have a SELECT box of values and a text
	//   input box with a fill-in value. Often, onChange of the SELECT box
	//   will fill in the selected value into the text input (working like
	//   a Windows combo box). Using this function, typing into the text
	//   box will auto-select the best match in the SELECT box and do
	//   auto-complete in supported browsers.
	//   Arguments:
	//      field = text input field object
	//      select = select list object containing valid values
	//      property = either "text" or "value". This chooses which of the
	//                 SELECT properties gets filled into the text box -
	//                 the 'value' or 'text' of the selected option
	//      forcematch = true or false. Set to 'true' to not allow any text
	//                 in the text box that does not match an option. Only
	//                 supported in IE (possible future Netscape).
	// -------------------------------------------------------------------
	G2DropDown_AutoComplete  : function(field, select, property, forcematch) 
	{
		var found = false;
		for (var i = 0; i < select.options.length; i++) {
		if (select.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0) {
			found=true; break;
			}
		}
		if (found) { select.selectedIndex = i; }
		else { select.selectedIndex = -1; }
		if (field.createTextRange) 
		{
			if (forcematch && !found) 
			{
				field.value=field.value.substring(0,field.value.length-1); 
				return;
			}
			var cursorKeys ="8;46;37;38;39;40;33;34;35;36;45;";
			if (cursorKeys.indexOf(event.keyCode+";") == -1) 
			{
				var r1 = field.createTextRange();
				var oldValue = r1.text;
				var newValue = found ? select.options[i][property] : oldValue;
				if (newValue != field.value) 
				{
					field.value = newValue;
					var rNew = field.createTextRange();
					rNew.moveStart('character', oldValue.length) ;
					rNew.select();
				}
			}
		}
	},

	Select_SetValue : function(select, value, suppressOnChangeEvent)
	{
		select.value = value;
		if(!suppressOnChangeEvent)
			G2_FireEvent(select, "onchange");
	},

	String_PadEnd : function(src, count, paddingChar)
	{
		if(paddingChar==null)
			paddingChar=" ";
		var s="";	
		for(var i=0;i<count;i++)
		{
			s+=paddingChar;
		}
		return src+s;
	},


	String_InsertAt : function(src, index, value)
	{
		var s1 = src.substr(0, index);
		var s2 = src.substr(index, src.length-index);
		return s1+value+s2;
	},

	String_RemoveAt : function(src, index)
	{
		var s1 = src.substr(0, index);
		var s2 = src.substr(index+1, src.length-index+1);
		return s1+s2;
	},

	String_RemoveAll : function(src, search)
	{
		var tokens = src.split(search);
		var s = "";
		for(var i=0;i<tokens.length;i++)
		{
			s+=tokens[i];
		}
		return s;
	},
	
	String_StartsWith : function(text, start)
	{
		if(start.length>text.length)
			return false;
		for(var i=0;i<start.length;i++)
		{
			if(start.charAt(i)!=text.charAt(i))
				return false;
		}
		return true;
	},

	G2_CopyArray : function(sourceArray, startIndex)
	{
		if(startIndex==null)
			startIndex = 0;
		var array = new Array();
		array.length = sourceArray.length-startIndex;
		var j=0;
		for (var i=startIndex;i<sourceArray.length;i++)
		{
			array[j] = sourceArray[i];
			j++;
		}
		return array;
	},

	G2_ShowControl : function(control, useVisibility)
	{
		if(useVisibility)
		{
			control.style.visibility = "visible";
		}
		else
		{
			control.style.display = "";//FOLLOWUPDAN-EL

		}
		if(typeof(control.OnShow)!="undefined")
		{
			control.OnShow();
		}
		return true;
	},
	
	G2_IsElementVisible : function(element, checkParents)
  {
	  if(element.style && element.style.display=="none")
		  return false;
	  if(checkParents)
	  {
		  if(element.parentElement!=null)
			  return G2_IsElementVisible(element.parentElement, checkParents);
		  else
		      if (isMoz) //Moz has a parent for the documentElement (html tag)
		          return element instanceof Document;
		      else
			      return element==element.document.documentElement; //only when element reaches to the top doc element we can be (pretty) sure it's visible.
  			
	  }
	  return true;
  },

	G2_HideControl : function(control, useVisibility)
	{
 		if(useVisibility)
		{
			control.style.visibility = "hidden";
		}
		else
		{
			control.style.display = "none";
		}
		if(typeof(control.OnHide)!="undefined")
		{
			control.OnHide();
		}
		return false;
	},
	G2_ToggleElementVisibility : function(element)
	{
		if(element==null)
			return; //TODO: warn
		if(element.style.display=="none")
			G2_ShowControl(element);
		else
			G2_HideControl(element);
	},

	G2_ShowHideControl : function(control, show, useVisibility)
	{
		if(show)
		{
			return G2_ShowControl(control, useVisibility);
		}
		else
		{
			return G2_HideControl(control, useVisibility);
		}
	},

	G2Page_ErrorCallback : function(message)
	{
		alert('An error occurred on the server:\n' + message);
	},

	G2_RecursiveSetPropertyValue : function(rootElement, propertyName, value)
	{
		if(rootElement.nodeName!="#text" && rootElement[propertyName]!=value)
		{
			rootElement[propertyName] = value;
		}
		var rootElementChildren = rootElement.children;
		for(var i=0;i<rootElementChildren.length;i++)
		{
			var child = rootElementChildren[i];
			G2_RecursiveSetPropertyValue(child, propertyName, value);
		}
	},

	//----------------------------------------------------------------------	

	G2_GetY : function(element)
	{
		var y = 0;
		while( element != null ) 
		{
			y += parseInt(element.offsetTop);
			
			// taking into account scrooling with in overflow scroll elements
			if(element.tagName != 'HTML' && element.scrollTop != null)
				y -= element.scrollTop;
			if(element.tagName == 'IFRAME')
				y -= document.documentElement.scrollTop;
			
			element = element.offsetParent;
		}
		return y;
	},

	G2_GetX : function(element)
	{
		var x = 0;
		while( element != null ) 
		{
			x += parseInt(element.offsetLeft);
			element = element.offsetParent;
		}
		return x;
	},

	G2Validator_ValidateElementOnChange : function(element)
	{
		if(element!=null && element.Validators!=null)
		{
			var dummyEvent = new Object();
			dummyEvent.srcElement = element; //IE
			dummyEvent.target = element; //FF
			ValidatorOnChange(dummyEvent);
		}
	},

	//---------------------------------------------

	isFixedPositioned : function(elem)
	{
		while (elem!=null)
		{
			if (elem && elem.style && elem.currentStyle.position == "fixed")
				return true;
			elem = elem.parentElement;
		}
		return false;
	},

  G2_BringToFront : function(elementToFloat)
	{
	  //marked by dan-el elementToFloat.style.zIndex = G2_maxZ++;
	},
	
	G2_FloatElement : function(elementToFloat, positionElement, dir, useFrame,useFixedPositioning)
	{
		//G2_Trace("G2_FloatElement", "start");
		var parent = elementToFloat.parentElement;
		if(parent!=null)
		{
			parent.removeChild(elementToFloat);
		}
		document.body.appendChild(elementToFloat);
		elementToFloat.style.position = useFixedPositioning ? "fixed" : "absolute";
		G2_BringToFront(elementToFloat);
		//this.bringElementToFront(elementToFloat);
		var N=(dir.indexOf("N")>-1);
		var S=(dir.indexOf("S")>-1);
		var E=(dir.indexOf("E")>-1);
		var W=(dir.indexOf("W")>-1);
		if(!N && !S)
			S=true;
		if(!E && !W)
		{
			E=true;
		}
		
		var x = G2_GetX(positionElement);
		var y = G2_GetY(positionElement);

	  
		if (S)
			y += positionElement.offsetHeight;
		if (W)
			x += positionElement.offsetWidth;
		elementToFloat.style.pixelTop = y;
		elementToFloat.style.pixelLeft = x;
	  
		elementToFloat.style.display = "block";
	  
		//iframe is the only one that can hide select tags in IE
		if(useFrame) 
		{
			window.setTimeout(function(){G2_AttachFrame(elementToFloat,useFixedPositioning);}, 0);
		}
 		//G2_Trace("G2_FloatElement", "end");
	},

	G2_HideFloatingElement : function(targetElement)
	{
		G2_DetachFrame(targetElement);
		targetElement.style.display = "none";
	},
	G2_CreateIFrame : function(doc, frameBorder, scrolling)
	{
		doc = doc || document;
		var frame = doc.createElement("IFRAME");
		if(frameBorder==null)
			frameBorder = 0;
		frame.frameBorder = frameBorder.toString();
		if(scrolling!=null)
			frame.scrolling = scrolling ? "yes" : "no";
		
		// validate body exist
		var body = doc.body;
		if(body == null)
		  body = document.body;
		  
		body.appendChild(frame);
		var frameDoc = frame.contentWindow.document;
		frameDoc.open();
		frameDoc.write("<html><body></body></html>");
		frameDoc.close();
		body.removeChild(frame);
		return frame;
	},
	G2_AttachFrame : function(targetElement,useFixedPositioning)
	{
		if(!IE6)
			return;
		//G2_Trace("G2_AttachFrame", "start");

		if(G2_FixFrame==null)
		{
			G2_FixFrame = G2_CreateIFrame(targetElement.document, 0, false);
			G2_FixFrame.setAttribute("id", "fixFrame");
			targetElement.insertAdjacentElement("beforeBegin", G2_FixFrame);
		}
	  
		//TODO: some of the size properties causes performance overhead of about a second
		G2_FixFrame.style.position = useFixedPositioning ? "fixed" : "absolute";
		G2_FixFrame.style.width = targetElement.offsetWidth+"px";
		G2_FixFrame.style.height = targetElement.offsetHeight+"px";
		G2_FixFrame.style.top = G2_GetY(targetElement)+"px";
		G2_FixFrame.style.left = G2_GetX(targetElement)+"px";
		//G2_FixFrame.style.zIndex = targetElement.currentStyle.zIndex - 1;
		G2_FixFrame.style.display = "block";
		targetElement._popupFixFrame = G2_FixFrame;
		targetElement.onresize = function()
		{
			this._popupFixFrame.style.width = this.offsetWidth+"px";
			this._popupFixFrame.style.height = this.offsetHeight+"px";
		}
		targetElement.onmove = function()
		{
			this._popupFixFrame.style.pixelTop = this.offsetTop;
			this._popupFixFrame.style.pixelLeft = this.offsetLeft;
		}
 		//G2_Trace("G2_AttachFrame", "end");
	},
	G2_DetachFrame : function(targetElement)
	{
		if(!IE6)
			return;
		if(targetElement._popupFixFrame==null)
			return;
		targetElement._popupFixFrame.style.display = "none";
		targetElement._popupFixFrame = null;
		//G2_FixFrame.style.display = "none";
		targetElement.onresize = null;
		targetElement.onmove = null;
	},

	//added by rony - for validation control re evaluation.
	G2ReEvaluateValidationControl : function(validationControl) {
			Page_InvalidControlToBeFocused = null;
			if (typeof(Page_Validators) == "undefined") {
					return true;
			}
			validationControl.isvalid = true;
			if (typeof(validationControl.enabled) == "undefined" || validationControl.enabled != false) {
					if (typeof(validationControl.evaluationfunction) == "function") {
							validationControl.isvalid = validationControl.evaluationfunction(validationControl);
							if (!validationControl.isvalid && Page_InvalidControlToBeFocused == null &&
									typeof(validationControl.focusOnError) == "string" && validationControl.focusOnError == "t") {
									ValidatorSetFocus(validationControl, event);
							}
					}
			}
			ValidatorUpdateDisplay(validationControl);
	},

	/*
	resizing the hieght for the outer ifram element from a current page
	*/

	FixOuterIFramHight : function(){
		//FixIFrameHeight(window.frameElement.id);
		var iframe = window.frameElement;
		if (iframe.addEventListener)
		{
			iframe.addEventListener("load", readjustIframe, false);
		}
		else if (iframe.attachEvent)
		{
			iframe.attachEvent("onload", readjustIframe);
		}
		iframe.style.display = "";
	},
	/*
	Resizing IFrame dynamically
	Addaed by Arnon 21.10.06
	*/


	FixIFrameHeight : function(iframeId,doc,dontUseEvents)
	{
		if (doc==null)
			doc = document;			  
			
		if (dontUseEvents==null)
			dontUseEvents = false;

		var iframe = doc.getElementById(iframeId);
		
		if (iframe==null)
			return;
			
		if (iframe.addEventListener)
		{
			iframe.addEventListener("load", readjustIframe, false);
		}
		else if (iframe.attachEvent && !dontUseEvents)
		{
			iframe.attachEvent("onload", readjustIframe);
		} 
		else 
			readjustIframe({currentTarget:iframe});
		iframe.style.display = "";
	},

	readjustIframe : function(loadevt)
	{
		var crossevt=(window.event && window.event.type=="load" )? event : loadevt;
		var iframe=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement;
		if (iframe)
		{
				iframe.style.height=iframe.Document.body.scrollHeight+"px";
				iframe.style.width=iframe.Document.body.scrollWidth+"px";
		}	
	},

	// Set the iframe flash elements transparent
	fixFlashInIframe : function(iframeId)
	{
		var iframe = document.getElementById(iframeId);
		fixFlashForIframe(iframe);
	},
	
	// Set the flash param wmode to transparent
	fixFlashForIframe : function(iframe)
	{
		G2DOM.SetFlashElementsTransparent(iframe);
		
		var iframes = iframe.Document.getElementsByTagName('iframe');
		for (var i = 0; i < iframes.length; i++) 
		{   
			  fixFlashForIframe(iframes[i]);
		}
	},
	
	// Fix the flash on iframe load
	FixIFrameFlash : function(iframeId)
	{
		var iframe = document.getElementById(iframeId);
		var fixFlash = function()
		{
			fixFlashInIframe(iframeId);
		}
		G2_AttachEvent(window, "onload", fixFlash,false);
	},
	
	FixIFrameSize : function(iframeId)
	{
		var iframe = document.getElementById(iframeId);
		iframe.style.border="0px";
		var onloaded = function()
		{
			readjustIframe({currentTarget:iframe});
		}
		if (iframe.addEventListener)
		{
			iframe.addEventListener("load", onloaded, false);
		}
		else if (iframe.attachEvent)
		{
			iframe.attachEvent("onload", onloaded);
		}
			
		iframe.style.display = "";
	},



	readjustIframeSize : function(loadevt)
	{
		var crossevt=(window.event)? event : loadevt;
		var iframe=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement;
		if (iframe)
		{
			iframe.style.height=iframe.document.body.scrollHeight+"px";
		//	iframe.style.width=iframe.document.body.scrollWidth+"px";
			iframe.style.border="0px";
		}	
	},
	///*End of Resizing IFrame dynamically*/

	G2_AmntKeyPress : function()
	{
		var key = window.event.keyCode;
		if ((key < 48 || key > 57) && key != 46 && key != 45)
			window.event.keyCode = 0;
	},

	// TextBox: simulate [Tab] key press when number of characters reach maxLength
	G2_AutoSkip : function(thisEl, force,evnt)
	{
		if (force || (thisEl.value.length == thisEl.maxLength && evnt.keyCode != 9 && evnt.keyCode != 16)) 
		{
			nextEl = G2_GetNextElementToSkip(thisEl);
			if (nextEl != null) 
			{
				try {
					nextEl.focus();
					if (nextEl.select)
						nextEl.select();
				}
				catch (e) {}
			}
		}
	},

	// Get next element in tabIndex/creationOrder
	G2_GetNextElementToSkip : function(thisEl)
	{
		var currTabIndex = thisEl.tabIndex;
		var minDiffFromCurrTabIndex = 32767, minTabIndex = 32767;
		var nextCreateOrderEl = null, nextTabOrderEl = null, minTabOrderEl = null, nextEl = null;
		var getNextCreateOrder = false;
		for (var i = 0; i < thisEl.form.elements.length; i++) 
		{
			var element = thisEl.form.elements[i];
			if (element.type != "hidden" && !element.disabled && element.style.display != "none") 
			{
				if (element == thisEl) 
				{
					getNextCreateOrder = true;
				}
				else if (element.tabIndex >= 0)
				{
					// Find element with next creation order
					if (getNextCreateOrder) {
						nextCreateOrderEl = thisEl.form.elements[i];
						getNextCreateOrder = false;
						if (thisEl.tabIndex == 0)
							break;
					}
					if (element.tabIndex > 0) 
					{
						// Find element with next tabIndex
						var diff = element.tabIndex - currTabIndex;
						if (diff > 0) 
						{
							if (diff < minDiffFromCurrTabIndex) 
							{
								minDiffFromCurrTabIndex = diff;
								nextTabOrderEl = element;
							}
						}
					}
					// Find element with min tabIndex
					if (element.tabIndex < minTabIndex) 
					{
						minTabIndex = element.tabIndex;
						minTabOrderEl = element;
					}
				}
			}
		}
		if (thisEl.tabIndex == 0 && nextCreateOrderEl != null && nextCreateOrderEl.tabIndex == 0)
			nextEl = nextCreateOrderEl;
		else if (nextTabOrderEl != null)
			nextEl = nextTabOrderEl;
		else if (minTabOrderEl != null)
			nextEl = minTabOrderEl;
		else
			nextEl = nextCreateOrderEl;
		return nextEl;
	},

	G2Menu_ChangeMouseOver : function(parent)
	{	
		if (typeof(parent)=="string")
			parent = document.getElementById(parent);
		if (parent==null)
			return;
		var element = parent.firstChild;
		while(element!=null)
		{
			if(element.onmouseover!=null)
			{
				if(element.onmouseover!=null)
				{
					var func = element.onmouseover;
					element.onmouseover = null;	
					G2_AttachEvent(element, "onclick",function(e)
					{
						Menu_HoverStatic(this);
						e.cancelBubble = true;
					});
				}
			}
			if(element.style!=null && element.style.cursor!="hand")
			{
				element.style.cursor = "hand";
			}
			G2Menu_ChangeMouseOver(element);
			element = element.nextSibling;
		}
	},



	G2Menu_ChangeMouseOver_Old : function(targetElement) //new implementation by dan-el
	{
		var curEl = targetElement.firstChild;
		var firstLevelFound = false;
		while(curEl!=null)
		{
			if(!firstLevelFound && curEl.onmouseover!=null)
				firstLevelFound = true;
	      
			if(firstLevelFound)
			{
				curEl.onclick = function()
				{
					Menu_HoverStatic(this);
					event.cancelBubble = true;
					//return false;
				};
				//Yucki!
				var aa = curEl.getElementsByTagName("A");
				var a= null;
				if(aa.length>0)
					a = aa[0];
	      
				var nolink = "javascript:void(0)";
	        
				if(a!=null && a.href!=nolink)
				{
					if(a.href.indexOf("javascript:")>-1)
					{
						a.href = nolink;//Fix for case 4457. (nolink was: #)
					}
					else if(a.href.lastIndexOf("#") == a.href.length-1)
					{
						a.href = nolink; //Fix for case 4457. (nolink was: #)
					}
				}
	      
				curEl.onmouseover=null;
				curEl.ondeactivate = function(){Menu_Unhover(this);};
				curEl.onmouseout = null;
				//alert("before: " + curEl.style.cursor);
				curEl.style.cursor = "hand";
				if(a!=null)//TODO: Bug - Gilad
					a.style.cursor = "hand";
				//alert("after: " + curEl.style.cursor);
			}
			curEl = curEl.nextSibling;
		}
	  
		if(firstLevelFound)
			return true;
	  
		curEl = targetElement.firstChild;
		while(curEl!=null)
		{    
			//if (curEl.onmouseover!=null)
			//{
				G2Menu_ChangeMouseOver(curEl);
				curEl.onmouseover=null;    
			//}
			curEl = curEl.nextSibling;
		}
	},

	G2ConfirmBox_Show : function(text, eventTarget)
	{
		var eventArgument = confirm(text);
		__doPostBack(eventTarget, eventArgument);
	},

	//
	// findRel Usage:
	//
	// findRel( tag , "style.display == 'none'", G2GetParent )
	// This will find the nearest hidden tag in the hierarchy (moving up)
	// third parameter must be a function, like function(t){return t.nextSibling;} 
	findRel : function(node, predicate, nav)
	{
		if (typeof(predicate)=="string")
			eval("var compiledPredicate = function(){ return this."+predicate+";}");
		else
			compiledPredicate = predicate;

		try
		{
			while (node!=null)
			{			
				if (compiledPredicate.call(node))
					return node;
					
				node = nav(node);			
			}
		} 
		catch(e)
		{
		}
		return null;
	},

	$ : function( a )
	{
		return document.getElementById(a);
	},
		
	EventAttr : function(name)
	{
		if (event.srcElement.attributes[name] == null)
		{
			if (event.srcElement.parentElement.attributes[name] == null)
				return "";
				
			return event.srcElement.parentElement.attributes[name].nodeValue;
		}
			
		return event.srcElement.attributes[name].nodeValue;
	},

	G2Page_ShowWaiting : function()
	{
		//alert('waiting');
	},

	G2Page_ShowReady : function()
	{
		//alert('ready');
	},

	/**************************************************************************
	 *
	 * Popups and related functions
	 *
	 **************************************************************************/

	G2PopupWindow_ExtractParameter : function(features, paramname, defaultValue)
	{
		var poz = features.indexOf(paramname);
		if (poz==-1)
			return defaultValue;
		
		var f = features.substring(poz+paramname.length+1);
		poz = f.indexOf(';');
		var poz2 = f.indexOf(',');
		if (poz2!=-1 && poz ==-1)
			poz = poz2;
		if (poz!=-1)
			f = f.substring(0,poz);
		poz = f.indexOf('px');
		if (poz!=-1)
			f = f.substring(0,poz);
		return f;
		
	},

	// Modal Dialog Box  from http://www.eggheadcafe.com/articles/javascript_modal_dialog.asp
	/*
	var ModalDialogWindow;
	var ModalDialogInterval;
	var ModalDialog = new Object;

	ModalDialog.value = '';
	ModalDialog.eventhandler = '';

	function ModalDialogMaintainFocus()
	{
		try
		{
			if (ModalDialogWindow.closed)
			 {
					window.clearInterval(ModalDialogInterval);
					eval(ModalDialog.eventhandler);       
					return;
			 }
			ModalDialogWindow.focus(); 
		}
		catch (everything) {   }
	}

	function ModalDialogRemoveWatch()
	 {
			ModalDialog.value = '';
			ModalDialog.eventhandler = '';
	 }
	*/

	//This method is used to overcome google toolbar's popup blocker
	G2ExecuteSync : function(f)
	{
		var temporaryButton = G2DOM.G2CreateElement("<input type='Button' style='display:none'></input>");
			temporaryButton.id = temporaryButton.uniqueID;
			temporaryButton.onclick = f;
			document.body.appendChild(temporaryButton);
			temporaryButton.click();
			document.body.removeChild(temporaryButton);
	},

	ModalDialogShow : function(url,name,features,w,h,wndargs)
	{
		var me = window;
		var fullPath = G2_MapPath("~/Client/Dialog.aspx");
		if (IE6 && wndargs.title && wndargs.title!="")
		{
		fullPath += "?Title="+encodeURI(wndargs.title);
		wndargs.title=null;
		}
		//The following is a hack to run a function synchronously using a temporary hidden button   
		function ie_f()
		{
				return null!= window.showModalDialog(fullPath,wndargs,features);//{url:url,obj:me,width:w,height:h}, features);
		}
		function moz_f()
		{	
			var t =  window.open(fullPath,"G2POPUP","modal,"+features);//{url:url,obj:me,width:w,height:h}, features);				
			if (t!=null)
			{
				t.dialogArguments = wndargs;
				t.focus();
			}
			return null!=t;
		}
		if (isIE)
			G2ExecuteSync(ie_f);
		else
			moz_f();
	},


  G2_GetWindowId : function()
  {
    var el = document.getElementById('__WindowID');
    if(el==null)
      return null;
    return el.value
  },
  G2_CreateTable : function(rows, cols, onTopWindow, cellPadding, cellSpacing)
  {
    
		if (onTopWindow)
		{ 
			var win = GetTopAvailableWindow();
			var doc = win.document;
		}
		else
			var doc = document;
		
    
		cellPadding = cellPadding || 0;
		cellSpacing = cellSpacing || 0;
		var table = doc.createElement("table");
		table.cellPadding = cellPadding;
		table.cellSpacing = cellSpacing;
		for(var i=0;i<rows;i++)
		{
			var row = table.insertRow();
			for(var j=0;j<cols;j++)
			{
				var cell = row.insertCell();
			}
		}
		return table;
  },
  
	G2PopupWindow_Open : function(url, context, modal, name, features, title, uniqueID)
	{	
		if (features==null && context!=null)
		{
			//var h = document.getElementById(context);
			//if(h!=null)
			features = window[context];//h.value;
		}   
		if (modal==null)
			modal = features.indexOf('modal=0') == -1;
		url = url.replace(/\$quot\$/g,"'");		
							
		if(modal)
		{
			var wid = G2_GetWindowId();
			if(wid!=null)
			{
				if (url.indexOf('?') == -1)
					url += "?IsPopup=True";
				else
					url+="&IsPopup=True";
			}
	  	var h = parseInt(G2PopupWindow_ExtractParameter(features,"dialogHeight",""));
			var w = parseInt(G2PopupWindow_ExtractParameter(features,"dialogWidth",""));
			var minH = parseInt(G2PopupWindow_ExtractParameter(features,"dialogMinHeight","0"));
			var minW = parseInt(G2PopupWindow_ExtractParameter(features,"dialogMinWidth","0"));
			var autoSize = parseInt(G2PopupWindow_ExtractParameter(features,"autoSize","1"));
			var synthetic = G2PopupWindow_ExtractParameter(features,"SyntheticPopup","0");
			var fade = G2PopupWindow_ExtractParameter(features,"FadeSyntheticPopup","0");			
			var horzMargin = parseInt(G2PopupWindow_ExtractParameter(features,"HorizontalMargin","5"));
			var vertMargin = parseInt(G2PopupWindow_ExtractParameter(features,"VerticalMargin","5"));
			var scroll = G2PopupWindow_ExtractParameter(features,"scroll","0");
			var closeBtn = G2PopupWindow_ExtractParameter(features,"closeBtn","0");
			var closeClientFunction = G2PopupWindow_ExtractParameter(features,"OnCloseClientFunction","");
			var me = window;
			
			//If title was specified, but not name - copy title to name
			if (title && title!=null && title!="" && !name && (name==null||name==""))
				name=title;
			
			//If name was specified, but not title, copy name to title
			if (!title && (title==null||title=="") && name && name!=null && name!="")
				title=name;
			if (synthetic!="0")	
			{
				window.setTimeout(function(){		//This causes 'Operation Aborted' when showing popups in full postbacks
				var wnd = SyntheticModalDialogShow(url,name,features,h,w,{url:url,obj:me,width:w,height:h,title:title,autoSize:(autoSize=="1"),vertMargin:vertMargin,horzMargin:horzMargin, scroll : (scroll=="1"),closeBtn : (closeBtn=="1"), fade : (fade=="1"), minH : minH, minW : minW, uniqueID : uniqueID, closeClientFunction:closeClientFunction});
				},0);
			}
			else
			{	
				var wnd = ModalDialogShow(url,name,features,h,w,{url:url,obj:me,width:w,height:h,title:title,autoSize:autoSize});
			}
		}
		else
		{
			//Workaround for bug #3634: 
			// IE popup blocker blocked the popup, because it was not initiated by a user click.		
			
			//Note: The following is a workaround for IE popup blockers. It is not jiffacode.
			var temporaryButton = G2DOM.G2CreateElement("<input type='Button' style='display:none'></input>");
			temporaryButton.id = temporaryButton.uniqueID;
			temporaryButton.onclick = function()
			{
				var wnd = window.open(url, name, features);
				
				if (null == wnd)
				{
					alert('popup blocker detected!');
				} 
				else
				{
					if (features.indexOf('maximized=yes')!=-1)
						{
							wnd.moveTo( 0, 0 );
		
							wnd.resizeTo( screen.availWidth, screen.availHeight );
						}
				}
			}
			document.body.appendChild(temporaryButton);
			temporaryButton.click();
			document.body.removeChild(temporaryButton);
		}
	},

	updatePopupTitle : function(newTitle)
	{
		if (G2_IsInPopup() && window.top.document.popup!=null)
		{
			window.top.document.popup.setTitle(newTitle);
		}	
	},

	CreateModalContainer : function(contentid,h,w,title)
	{
			h = parseInt(h);
			w = parseInt(w);
			var marginHeight = (document.body.clientHeight - h) / 2;
			var marginWidth = (document.body.clientWidth - w) / 2;
			
			var containerTable = document.createElement("Table");
						
			//containerTable.id = id;
			containerTable.style.position="absolute";
			containerTable.style.pixelLeft=0;
			containerTable.style.pixelTop=0;
			containerTable.style.width=document.body.clientWidth+"px";
			containerTable.style.height=document.body.clientHeight+"px";
			G2_BringToFront(containerTable);
			containerTable.style.display="none"
			containerTable.style.background="transparent";
			containerTable.style.border="0px";
			containerTable.cellPadding = "0";
			containerTable.cellSpacing = "0";
			
			

			//Top Row
			var topRow = containerTable.insertRow();
			topRow.style.height=marginHeight+"px";
			var topRowCell = topRow.insertCell();
			topRowCell.colSpan = "3";
			topRowCell.className="MessageBoxContainer";
			topRowCell.innerHTML="<div style='background:#ccccee; width:300px'><b>"+title+"</b></div>";
			topRowCell.style.textAlign="center";
			topRowCell.style.verticalAlign="bottom";
			////////////////////////////////////////////////////////////////////////
			
			
			//Middle Row
			var middleRow = containerTable.insertRow();
			middleRow.style.height=w+"px";
			
			
			//Middle-Left
			var middleLeftCell = middleRow.insertCell();
			middleLeftCell.style.width=marginWidth+"px";
			middleLeftCell.style.height=h+"px";
			middleLeftCell.innerHTML="&nbsp;";
			middleLeftCell.className = "MessageBoxContainer";
			
			//Content cell
			var ContentCell = middleRow.insertCell();
			ContentCell.align="center";
			ContentCell.id = contentid;
			ContentCell.valign="middle";
			ContentCell.id = "modalContent";
			ContentCell.style.backgroundColor="white";
			ContentCell.style.width=w+"px";
			ContentCell.style.height=h+"px";
			
			//Middle-Right
			var middleRightCell = middleRow.insertCell();
			middleRightCell.style.width=marginWidth+"px";
			middleRightCell.style.height=h+"px";
			middleRightCell.innerHTML="&nbsp;";		
			middleRightCell.className = "MessageBoxContainer";
			
			////////////////////////////////////////////////////////////////////////
			//Bottom Row
			var bottomRow = containerTable.insertRow();
			bottomRow.style.height=marginHeight+"px";
			var bottomRowCell = bottomRow.insertCell();
			bottomRowCell.colSpan = "3";
			bottomRowCell.className="MessageBoxContainer";
			bottomRowCell.innerHTML="&nbsp;";
			
			return containerTable;
				
	},


	G2PopupWindow_CloseAndRedirect : function(url)
	{
		var parentWindow = window.opener; 
		G2_ClosePopupWindow();
		//window.close();
		parentWindow.location = url;
	},

	min : function(a,b)
	{
		return (a<b) ? a : b;
	},

	max : function(a,b)
	{
		return (a>b) ? a : b;
	},

	minInt : function(a,b)
	{
		var valA = parseInt(a);
		var valB = parseInt(b);
		
		if (isNaN(valA))
			return valB;
		if (isNaN(valB))
			return valA;
		return min(valA,valB);
	},

	maxInt : function(a,b)
	{
		var valA = parseInt(a);
		var valB = parseInt(b);
		
		if (isNaN(valA))
			return valB;
		if (isNaN(valB))
			return valA;
		return max(valA,valB);
	},

	// Removes leading whitespaces
	LTrim : function( value ) 
	{	
		var re = /\s*((\S+\s*)*)/;
		return value.replace(re, "$1");	
	},

	// Removes ending whitespaces
	RTrim : function( value ) 
	{	
		var re = /((\s*\S+)*)\s*/;
		return value.replace(re, "$1");	
	},

	// Removes leading and ending whitespaces
	trim : function( value ) 
	{	
		if (!value || value==null)
			value = this;
		return LTrim(RTrim(value));	
	},

	//----------------------------------------------------------------
	// Source: http://www.xs4all.nl/~zanstra/logs/jsLog.htm
	//----------------------------------------------------------------

	verifyObjectShown : function(obj)
	{
		var t=1;
		if (!InView(obj,5))
		{
			ScrollIntoView(obj,false,5);
			//obj.scrollIntoView(false); //align to bottom -- don't use unlesss previouse method fails (and it shouldn't)
		}
	},

	InView : function(element,margin) 
	{
		if(!margin) margin=0;
		var Top=GetTop(element), ScrollTop=GetScrollTop();
		return !(Top<ScrollTop+margin||
			Top>ScrollTop+GetWindowHeight()-element.offsetHeight-margin);
	},

	ScrollIntoView : function(element,bAlignTop,margin) 
	{
		if(!margin) margin=0;
		var posY = GetTop(element);
		if(bAlignTop) 
			posY -= margin;
		else 
			posY += element.offsetHeight+margin-GetWindowHeight();
		window.scrollTo(0, posY);
	},
	
	GetTopWindowHeight : function() 
	{
		return window.top.innerHeight ||
			window.top.document.documentElement&&window.top.document.documentElement.clientHeight ||
			window.top.document.body.clientHeight || 0;
	},

	GetWindowHeight : function() 
	{
		return window.innerHeight ||
			document.documentElement&&document.documentElement.clientHeight ||
			document.body.clientHeight || 0;
	},
	GetScrollTop : function() 
	{
		return window.pageYOffset ||
			document.documentElement && document.documentElement.scrollTop ||
			document.body.scrollTop || 0;
	},
	GetTop : function(element) 
	{
		var pos=0;
		do 
		{
			pos += element.offsetTop;
		}
		while(element=element.offsetParent);
		return pos;
	},


	////////////////////////////////////////////////////////////
	//        Range and selection relates functions           //
	////////////////////////////////////////////////////////////


	G2_SetSelectionRange : function(input, selectionStart, selectionEnd) 
	{
		if (input.setSelectionRange) 
		{
			input.focus();
			input.setSelectionRange(selectionStart, selectionEnd);
		}
		else if (input.createTextRange) 
		{
			var range = input.createTextRange();
			range.collapse(true);
			range.moveEnd('character', selectionEnd);
			range.moveStart('character', selectionStart);
			range.select();
		} else Debug.writeln('Cannot set selection');
	},

	G2_GetSelectionStartFromRange : function(range) 
	{
		var range = document.selection.createRange();
		var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
		if (!isCollapsed)
			range.collapse(true);
		var b = range.getBookmark();
		return b.charCodeAt(2) - 2;
	},
	G2_GetSelectionStart : function(input) 
	{
		if (isGecko)
			return input.selectionStart;
		var range = document.selection.createRange();
		var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
		if (!isCollapsed)
			range.collapse(true);
		var b = range.getBookmark();
		return b.charCodeAt(2) - 2;
	},

	G2_GetSelectionEnd : function(input) 
	{
		if (isGecko)
			return input.selectionEnd;
		var range = document.selection.createRange();
		var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
		if (!isCollapsed)
			range.collapse(false);
		var b = range.getBookmark();
		return b.charCodeAt(2) - 2;
	},
	G2_SetCaretPosition : function(input, index)
	{
		G2_SetSelectionRange(input, index, 0);
	},

	G2_GetCaretPosition : function(input)
	{
		var range = input.document.selection.createRange();
		var pos = 0;
		while(range.move("character", -1)!=0)
			pos++;
		return pos;
	},



	Find : function(array, predicate, context)
	{
		for(var i=0;i<array.length;i++)
		{
			var item = array[i];
			if(predicate(item, context))
				return item;
		}
		return null;
	},

	//
	//iterates an array, and performs the specified action with the specified context.
	//
	ForEach : function(array, action, context)
	{
		if(array==null || action==null)
			return;
		for(var i=0;i<array.length;i++)
		{
			action(array[i], context);
		}
	},

	ForEachSibling : function(element, action, context, predicate)
	{
		if(element==null)
			return;
		action(element, context);
		var nextSibling = element.nextSibling;
		if (predicate != null)
		{
		    while (nextSibling != null && !predicate(nextSibling))
		        nextSibling = nextSibling.nextSibling;   
		}
		ForEachSibling(nextSibling, action, context, predicate);
	},

	G2_PlaceElementAbsolutlyBeside : function(element, parentElement , position)
	{ 
		element.style.position = "absolute";
		parentElement.document.body.appendChild(element);
		element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement)+parentElement.scrollWidth;
		if(position == "Left")
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement)-element.scrollWidth;
		
		element.style.pixelTop = (G2_GetAbsoluteTop(parentElement));
		
		// keep element from exiting screen limits
		G2_VerifyAbsoluteElementNotCropped(element);
	},
	G2_PlaceElementAbsolutlyAbove : function(element, parentElement, position, align)
	{
		element.style.position = "absolute";
		parentElement.document.body.appendChild(element);
		
		if(position == "Left")
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement) - element.scrollWidth;
		else
			element.style.pixelLeft = (G2_GetAbsoluteLeft(parentElement));
			
		element.style.pixelTop = G2_GetAbsoluteTop(parentElement)-element.scrollHeight;
		
		// keep element from exiting screen limits
		G2_VerifyAbsoluteElementNotCropped(element);
	},

	G2_PlaceElementAbsolutlyBelow : function(element, parentElement, position)
	{
		element.style.position = "absolute";
		parentElement.document.body.appendChild(element);
		
		if(position == "Left")
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement) - element.scrollWidth;
		else
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement);
			
		element.style.pixelTop = G2_GetAbsoluteTop(parentElement)+parentElement.scrollHeight;
		
		// keep element from exiting screen limits
		G2_VerifyAbsoluteElementNotCropped(element);
	},
	//pos=T,B,R,L
	G2_GetAbsolute : function(element, pos, includeFrames, posInfo)
	{
		if(pos=="t")
			return G2_GetAbsoluteTop(element, includeFrames, posInfo);
		else if(pos=="l")
			return G2_GetAbsoluteLeft(element, includeFrames, posInfo);
		if(pos=="b")
			return G2_GetAbsoluteBottom(element, includeFrames, posInfo);
		else if(pos=="r")
			return G2_GetAbsoluteRight(element, includeFrames, posInfo);
		return null;
	},
	//pos=t,b,r,l
	G2_SetAbsolute : function(element, pos, value, ignoreCurrentTopAndLeft)
	{
		if(value==null)
			return;
		if(pos=="t")
			element.style.pixelTop = value;
		else if(pos=="l")
			element.style.pixelLeft = value;
		else if(pos=="b")
		{
			if(element.style.top=="" || ignoreCurrentTopAndLeft)
				element.style.top = (value-element.offsetHeight)+"px";
			else
				element.style.height=(value - element.style.pixelTop)+"px";
		}
		else if(pos=="r")
		{
			if(element.style.left==""  || ignoreCurrentTopAndLeft)
				element.style.left = (value-element.offsetWidth)+"px";
			else
				element.style.width=(value - element.style.pixelLeft)+"px";
		}
	},
	
	// this method returns true if a change was made, and false otherwise. case 11147
	G2_VerifyAbsoluteElementNotCropped : function(element)
	{
		var result = false;
		var elementOffsetWidth = element.offsetWidth;
		var offsetParent = element.offsetParent;
		if (offsetParent==null)
		  return false;
	  if (isIE)
	    element.style.display = "none";
	  if(element.offsetLeft+elementOffsetWidth>offsetParent.clientWidth)
	  {
		  element.style.pixelLeft-=element.offsetLeft+elementOffsetWidth-offsetParent.clientWidth;
		  result = true;
	  }
	  element.style.display = "";
	  
	   //locate the element in a proper place if it overflow the client screen	height  
	  var scrollTop =  window.top.document.documentElement.scrollTop;
	  var elementOffsetHeight = element.offsetHeight;
		var offsetParent = element.offsetParent;
		if (offsetParent==null)
		 return;
	 	
	 	if(G2_GetAbsoluteTop(element)+elementOffsetHeight > GetTopWindowHeight() + scrollTop)
	 	{
		  element.style.pixelTop -= G2_GetAbsoluteTop(element)+elementOffsetHeight-(GetTopWindowHeight() + scrollTop);
		  result = true;
	  }
	  
	  if(element.style.pixelTop < 0)
			element.style.pixelTop = 0;
			
		return result;
	},
	//places an element near another element - dock = string = "tl:bl,tr:br" etc... tl=TopLeft tl:br,
	G2_PlaceElementAbsolutlyNear : function(element, relativeElement, dock, onTopWindow, appendToElement)
	{
		var parent = onTopWindow ? window.top.document.body : relativeElement.document.body;
		
		if(appendToElement)
			parent = appendToElement;
			
		if(element.parentElement!=parent)
			parent.appendChild(element);
		if (isMoz)
		  element.style.display = "none";
		element.style.position = "absolute";
		var tokens = dock.split(",");
		var settings = {};
		for(var i=0;i<tokens.length;i++)
		{
			var token = tokens[i];
			var miniTokens = token.split(":");
			var relCorner = miniTokens[0];
			var absCorner = miniTokens[1];
			
			var rel1 = relCorner.charAt(0);
			var rel2 = relCorner.charAt(1);
			var abs1 = absCorner.charAt(0);
			var abs2 = absCorner.charAt(1);
			var posInfo = new Object();
			var rel1Val = G2_GetAbsolute(relativeElement, rel1, onTopWindow, posInfo);
			var rel2Val = G2_GetAbsolute(relativeElement, rel2, onTopWindow, posInfo);
			if(posInfo.offsetParent!=null && posInfo.offsetParent.currentStyle!=null)
			{
			  if(posInfo.offsetParent.currentStyle.position=="fixed")
			    element.style.position = "fixed";
			}
			settings[abs1] = rel1Val;
			settings[abs2] = rel2Val;
		}
		if (isMoz)
		  element.style.display = "";
		//the top and left MUST be set before the bottom and right
		G2_SetAbsolute(element, "t", settings["t"]); 
		G2_SetAbsolute(element, "l", settings["l"]); 
		G2_SetAbsolute(element, "b", settings["b"], settings["t"]==null); 
		G2_SetAbsolute(element, "r", settings["r"], settings["l"]==null); 
	},	
	G2_IsAbsolutlyPositioned : function(element)
	{
		if(element==null)
			return false;
		if(element.style.position=="absolute")
			return true;
		return G2_IsAbsolutlyPositioned(element.parentElement);
	},


	G2_GetElement : function(idOrElement)
	{
		if(typeof(idOrElement)=="string")
			return document.getElementById(idOrElement);
		return idOrElement;
	},
	
	G2_GetAbsoluteLeft : function(element, includeFrames, posInfo) 
	{
	  var x = 0;
    var originalElement = element;
    while( element != null ) 
    {
      x += element.offsetLeft;
      //bug in ie - when using 'relative right:50px' the offsetLeft is wrong //TODO: check in firefox  (dan-el)
 			if(element.style.position=="relative" && element.style.right.contains("px") && element.offsetParent!=element.parentElement)
			{
				x-=element.style.pixelRight;
			}
      if(posInfo!=null)
        posInfo.offsetParent = element;
      if (isMoz && element.currentStyle.position=="fixed")
        element = null;
      else
        element = element.offsetParent;
    }
    if (includeFrames && originalElement.document.parentWindow.frameElement!=null)
    {
      var f = originalElement.document.parentWindow.frameElement;
      var fb = 0;
      if(f.frameBorder == "1" || f.frameBorder == "yes")
        fb = 2;
      x += G2_GetAbsoluteLeft(f, includeFrames) + fb;
    }
    return x;
	},

	G2_GetAbsoluteTop : function(element, includeFrames, posInfo) 
	{
	  var y = 0;
    var originalElement = element;
    while( element != null ) 
    {
      y += element.offsetTop;

			// taking into account scrooling with in overflow scroll elements
      if(element.tagName != 'HTML' && element.scrollTop != null)
				y -= element.scrollTop;
			if(element.tagName == 'IFRAME')
				y -= document.documentElement.scrollTop;

      if(posInfo!=null)
        posInfo.offsetParent = element;
      if (isMoz && element.currentStyle.position=="fixed")
        element = null;
      else
        element = element.offsetParent;
    }
    if (includeFrames && originalElement.document.parentWindow.frameElement!=null)
    {
      var f = originalElement.document.parentWindow.frameElement;
      var fb = 0;
      if(f.frameBorder == "1" || f.frameBorder == "yes")
        fb = 2;
      y += G2_GetAbsoluteTop(f, includeFrames) + fb;
    }
    return y;
	},
	G2_GetAbsoluteBottom : function(element, includeFrames) 
	{
		return G2_GetAbsoluteTop(element, includeFrames)+element.offsetHeight;
	},
	G2_GetAbsoluteRight : function(element, includeFrames) 
	{
		return G2_GetAbsoluteLeft(element, includeFrames)+element.offsetWidth;
	},
	isInSyntheticPopup : function()
	{
		return (parent.document.body.closeSyntheticPopup!=null || document.body.closeSyntheticPopup!=null);
	},

	/**
			This method is called by G2Page.CloseWindow()


	**/
	 G2_ClosePopupWindow : function(openerFunctionScript_functionToCall,
										result,
										firePopupClosedOnOpener,
										fireCloseScript_functionToCall,
										fireCloseScript_windowID,
										fireCloseScript_forceSilentPopupClosedOnOpener)
	{
	  // The window parent should register G2PopupWindow2.js in order to 
	  // Get the popup window (the problem happens when the parent window
	  // of the popup is not the same as the window which open the popup)
		if(window.parent!=window && window.parent.G2PopupWindow2!=null)
		{
			var popup = window.parent.G2PopupWindow2.GetCurrentPopup(window);
			if(popup!=null)
			{
				var silent = fireCloseScript_forceSilentPopupClosedOnOpener ? true : null;
				popup.Close(firePopupClosedOnOpener, fireCloseScript_windowID, silent);
				return;
			}
		}
			if (isInSyntheticPopup())
				return G2_CloseSyntheticPopupWindow(openerFunctionScript_functionToCall,
										result,
										firePopupClosedOnOpener,
										fireCloseScript_functionToCall,
										fireCloseScript_windowID,
										fireCloseScript_forceSilentPopupClosedOnOpener);
				
			var op = window.top.opener;    
			if (op == null && window.dialogArguments == null)
			{
					//'Access Denied' detected.
					if (!String.IsNullOrEmpty(result))
							throw "Error - Result cannot be set with SSL Pages. To return a value from a popup to its opener, use the returnValue property on G2Page.";
					window.top.close();
					return;
			}
			else
			{            
					if (op == null)
						op = window.dialogArguments.obj;
						
					if (!String.IsNullOrEmpty(openerFunctionScript_functionToCall))
					{
									var openerFunction = op[openerFunctionScript_functionToCall];
									openerFunction(result);
					}
	        
					if (window.top.dialogArguments)
							window.top.dialogArguments.CloseEventFired = true;
					window.top.close();
	        
					if (firePopupClosedOnOpener)
					{
						try
						{
							var closeCallback = op.G2_FirePopupClosed;
							if (closeCallback!=null)
								closeCallback.call(op,fireCloseScript_windowID,result,fireCloseScript_forceSilentPopupClosedOnOpener);        
						}
						catch(accessDenied)
						{
							//This is a known limitation. SSL pages and non-SSL pages cannot communicate with each other
						}
							
					}       
			}
	},


	G2_FindElementById : function(element, id)
	{
		return _G2_FindElementById(element, id);
	},
	_G2_FindElementById : function(element, id)
	{
		if(element.id==id)
			return element;	
		if(element.doesNotContainInputs || element.tagName=="SELECT")
			return null;

		var child = element.firstChild;
		while(child!=null)
		{
			var el = _G2_FindElementById(child, id);
			if(el!=null)
				return el;
			child = child.nextSibling;
		}
		return null;
	},

	G2_FindParentElementByG2Tag : function(element, g2tag)
	{
		return _G2_FindParentElementByG2Tag(element, g2tag);
	},
	_G2_FindParentElementByG2Tag : function(element, g2tag)
	{
		if(element==null)
			return null;
		if(G2DOM.G2GetAttribute(element,'g2tag')==g2tag)
			return element;
		return _G2_FindParentElementByG2Tag(element.parentElement, g2tag);
	},

	G2_FindElementByTagName : function(element, tagName)
	{
		if(element.tagName==tagName)
			return element;	
		var child = element.firstChild;
		while(child!=null)
		{
			var el = G2_FindElementByTagName(child, tagName);
			if(el!=null)
				return el;
			child = child.nextSibling;
		}
		return null;
	},

	G2_FindNodeByNameValue : function(element, name, value)
	{
		if(element[name]==value)
			return element;	
		var child = element.firstChild;
		while(child!=null)
		{
			var el = G2_FindNodeByNameValue(child, name, value);
			if(el!=null)
				return el;
			child = child.nextSibling;
		}
		return null;
	},


	// When a page detects it is opened in a popup window, it calls this method
	G2Dialog_Init : function()
	{
		//Try accessing window.top.dialogArguments
		try
		{
			if (window.top.dialogArguments!=null)
			{
				//If that succeeds, we are in a non-SSL popup 
				//In that case, un-hook the onunload event handler
				window.top.document.getElementById('IFRM').contentWindow.onunload = null;		
				
			}
		} catch(bloodyerror)
		{
		}
	},
	G2_FireEventArray : function(owner, array)
	{
		for(var i=0;i<array.length;i++)
		{
			array[i](array.owner);
		}
	},

	G2_GetChildControlById : function(namingContainer, innerElementId)
	{
		return document.getElementById(namingContainer.id+"_"+innerElementId);
	},

	G2FindControlsById : function(controlIds)
	{
		var ret = [];
		if(controlIds==null)
			return ret;
		if (typeof(controlIds)=="string")
		{
			if (controlIds.length==0)
				return ret;			
			controlIds = controlIds.split(/,/g);	
		}
		for(var i=0,j=controlIds.length;i<j;i++)
		{
				var ctrl = document.getElementById(controlIds[i]);
				if (ctrl)
					ret.push(ctrl);
		}
		return ret;
	},

	G2ContextChange : function(func,context)
	{
		return function()
		{
			func.apply(context,arguments);
		}
	},
	
	//***********************************************************
	//                   Processing image                       *
	//***********************************************************
	
	getProcessingImageID : function()
	{
	  return window.ProcessingImageID;
	},
	
	setProcessingImageID : function(value)
	{
	  if(window.ProcessingImageID == value)
	    return;
	  window.ProcessingImageID = value;
	  window.ProcessingImage = null;
	},
	
	getProcessingImage : function()
	{
	  if(window.ProcessingImage==null && ProcessingImageID!=null)
	    window.ProcessingImage = document.getElementById(ProcessingImageID);
	  return window.ProcessingImage;
	},
	
	getElementsToHideWhileProcessing_Cache : function()
	{
	 if(window.ElementsToHideWhileProcessing_Cache == null)
	 {
	  window.ElementsToHideWhileProcessing_Cache = [];
	  
	  if(window.ElementsToHideWhileProcessing!=null)
	  {
	    var list = window.ElementsToHideWhileProcessing.split(',');
	    var eth = window.ElementsToHideWhileProcessing_Cache;
	    for (var i=0;i<list.length;i++)
		  {
			  var e = document.getElementById(list[i]);
			  if (e==null)
				  continue;
  			  
			  eth.push(e);
		  }
	   }
	 }
	 return window.ElementsToHideWhileProcessing_Cache;
	},
	
	getElementsToHideWhileProcessing : function()
	{
	  if(window.ElementsToHideWhileProcessing==null)
	    return "";
	  return window.ElementsToHideWhileProcessing;
	},
      
  setElementsToHideWhileProcessing : function(value)
	{
	  if(window.ElementsToHideWhileProcessing==value)
	    return;
	  window.ElementsToHideWhileProcessing = value;
	  window.ElementsToHideWhileProcessing_Cache = null;
	},
	  
	ShowProcessingImage : function(targetEl)
	{
		//flag that the processing image is activated
		window.ProcessingImageActive = true;
		var eventX = -1;
		var eventY = -1;
		if (!isMoz && event && event.type != "")
		{
			eventX = event.clientX;
			eventY = event.clientY;
		}
		window.setTimeout(function() {ShowProcessingImage_Timeout(targetEl, eventX, eventY);}, 100);
	},

	ShowProcessingImage_Timeout : function(targetEl, eventX, eventY)
	{
	//This function is running asynchronously, so we must check 
	//if the processing image is still required, and hasn't been switched off.
		if (window.ProcessingImageActive == false)
			return;
	    
		var processingImage = getProcessingImage();
		
		//Hide other elements
		var list = window.getElementsToHideWhileProcessing_Cache();
		for (var i=0;i<list.length;i++)
		{
			list[i].style.display='none';
		}
		
		//show processing image
		if (processingImage != null)
		{
			processingImage.style.display = '';
			if (processingImage.isDynamic == 'true')
			{   
					G2_ShowDisabler(true);
					processingImage.style.zIndex = 10001;
					
					if (eventX != -1 && eventY != -1)
					{
							processingImage.style.position = 'absolute';
							processingImage.style.left = Math.max(0, document.documentElement.scrollLeft + eventX - (processingImage.scrollWidth) / 2) + "px";
							processingImage.style.top = Math.max(0, document.documentElement.scrollTop + eventY - (processingImage.scrollHeight / 2)) + "px";
					}
					else
					{
						G2_PlaceElementAbsolutlyNear(processingImage, targetEl, "bl:bl", true);
						G2_VerifyAbsoluteElementNotCropped(processingImage);
					}
			}
		}
	},

	HideProcessingImage : function()
	{
		//switch flag off
		window.ProcessingImageActive = false;
		if (G2_IsNavigating())
		{
			return; //Keep the processing image until we are done navigating
		}	
		
		//hide processing image
		var processingImage = getProcessingImage();
		if (processingImage != null)
		{
			//Debug.writeln("hiding processing image: "+processingImage.id);
			processingImage.style.display = 'none';
		}
		
		//Show other elements
		var list = window.getElementsToHideWhileProcessing_Cache();
		for (var i=0;i<list.length;i++)
		{
			list[i].style.display='block';
		}
	},
	G2_PrintPopup : function(target)
	{
		if(G2_IsInPopup())
		{
			var win = window.open(target.location.href + "&HideButtons=true");
			if(win!=null)
			{
				G2_AttachEvent(win, "onload", function()
				{
					window.setTimeout(function(){	win.print();win.close();}, 500);
				});
			}
		}
		else
		{
			target.focus(); 
			target.print(); 
		}
	},
	// printing an html table
	Print : function(tableId)
	{
		window.focus();
		//Added by Arnon in case 5103
		var TableToPrintObj = document.getElementById(tableId)
		var TableToPrintWidth;
		if(TableToPrintObj && !(typeof document.body.style.maxHeight != "undefined"))//Not IE 7 and ID exist
		{
			// changeing width to fit printing sheet
			TableToPrintWidth = TableToPrintObj.style.pixelWidth;
			TableToPrintObj.style.width="640px";
		}
		window.print();
		if(TableToPrintObj && !(typeof document.body.style.maxHeight != "undefined")) //Not IE 7 and ID exist
		{
			// restore width
			TableToPrintObj.style.width=TableToPrintWidth+"px";
		}
	},
	G2_PreventInputPost : function(id)
	{
		if(typeof(id)=="string")
			G2_PreventPostElementIds[id] = true;
		else
			Debug.writeln("id is not a string");
		//input.disabled = true;
	},
	Select_SetAllSelected : function(select, selected)
	{
		if(select.tagName!="SELECT")
			throw new Error("Select Object expected "+select.tagName);
		//The visibility trick optimizes the selection performance
		var useVisiblityTrick = select.style.visibility=="";
		if(useVisiblityTrick)
			select.style.visibility = "hidden";
		var option = select.options[0];
		while(option!=null)
		{
			if(option.tagName=="OPTION")
				option.selected = selected;
			option = option.nextSibling;
		}
		G2.notifyInputChanged(select);
		if(useVisiblityTrick)
			select.style.visibility = "";
	},
	G2ListBox_SelectAll : function(id)
	{
		var select = $(id);
		if(select==null || select.disabled)
			return;
		Select_SetAllSelected(select, true);
	},
	G2ListBox_SelectNone : function(id)
	{
		var select = $(id);
		if(select==null || select.disabled)
			return;
		Select_SetAllSelected(select, false);	
	},
	G2_DisableBack : function()
	{
			if (window.backIsDisabled != true)
			{
				window.backIsDisabled = true;
				for(var i=0;i<2;i++)
				{
					window.location.hash = "#p"+i;
				}

				window.setInterval(function()
				{
				    if(docTitle!= null)
				    {
				        document.title = docTitle;
				    }
				    if(window.history.forward(1) != null)
						window.history.forward(1);
				}, 100);

			}
		},
		G2_ShowBeforeUnloadMessage : function (e, message, checkFunction)
		{
			if (window.allowUnloadMessage == false)
			{
				window.allowUnloadMessage = true;
			  return;
			}
			if (window[checkFunction] != null)
				if (!window[checkFunction]())
					return;
			return message;
		},
		
		// ------------------------- G2Alert ----------------------------
		//open alert Popup
		G2Alert : function(message, width)
		{
			if(width == null)
				width = 200;
				
			var doc = window.top.document;
			// build alert html
			var alertObj = doc.createElement("DIV");
			
			alertObj.innerHTML = '<TABLE style="width:' + width + '" class=modalPopup><TBODY>' +
			'<TR>' +
			'<TD style="PADDING-TOP: 5px" align="center">' +
			message + 
			'</TD></TR>' +
			'<TR>' +
			'<TD style="PADDING-TOP: 10px;cursor:pointer" align="center" onclick="G2CloseAlert();"><u>OK</u></TD>' +
			'</TR></TBODY></TABLE>';

			 // clone the Div and show the clone
			 alertObj.id = "AlertDiv";

			//return if already shown
			if (alertObj.style.display == 'block')
				return;
				
			// append messagePopup to the form and not to the body (case 11229)
			var container = doc.forms[0];
			
			// create a cover div 
			var coverDiv = G2_CreateModalCoverDiv();
			coverDiv.style.filter = "alpha(opacity=70)";

			// append cover div to form
			if(container != null)
				container.appendChild(coverDiv);
			else
				doc.getElementsByTagName("body")[0].appendChild(coverDiv);

			//set popup div position
			alertObj.style.position = 'absolute';
			
			alertObj.style.left = Math.max(0, doc.documentElement.scrollLeft + (doc.documentElement.clientWidth / 2) - (alertObj.scrollWidth / 2)) + "px";
			alertObj.style.top = Math.max(0, doc.documentElement.scrollTop + (doc.documentElement.clientHeight / 2) - (alertObj.scrollHeight / 2)) + "px";

			alertObj.style.zIndex = 1001;
			G2_AttachFrame(alertObj);

			// append element to form
			if(container != null)
				container.appendChild(alertObj);
			else
				doc.body.appendChild(alertObj);
			
			// verify that the popup is in the boreder of the screen
			G2_VerifyAbsoluteElementNotCropped(alertObj);
		},
		
		// close alert popup
		G2CloseAlert : function()
		{
			var doc = window.top.document;
			var alertObj = doc.getElementById("AlertDiv");
			// remove the cloned Div
			var container = alertObj.parentElement;
			if (alertObj != null && container !=  null)
				container.removeChild(alertObj);
			// remove the cover Div
			var coverDiv = doc.getElementById("CoverDiv");
			container = coverDiv.parentElement;
			if (coverDiv != null && container !=  null)
					container.removeChild(coverDiv);
			G2_DetachFrame(alertObj);
		},

		//create cover div for the modal effect
		G2_CreateModalCoverDiv : function(win)
		{
			var doc = window.top.document;
			if(win != null)
				doc = win.document;
				
			var coverDiv = doc.createElement('DIV');
			coverDiv.id = "CoverDiv";
			coverDiv.className = "CoverDiv";
			coverDiv.style.left = "0px";
			coverDiv.style.top = "0px";
			docHeight = Math.max (doc.documentElement.offsetHeight,doc.documentElement.scrollHeight);
			docWidth = Math.max ( doc.documentElement.offsetWidth, doc.documentElement.scrollWidth);
			coverDiv.style.height = docHeight+"px";
			coverDiv.style.width = docWidth+"px";
			coverDiv.style.zIndex="10";
			coverDiv.style.position="absolute";
			return coverDiv;
		},
		
		G2_VerifyScrollableElementHeight : function(pnlID, maxHeight)
		{
			var pnl = $(pnlID);
			if(pnl == null)
				return;
			if(maxHeight == null || maxHeight == 0)
				return;
				
			if(pnl.clientHeight > maxHeight)
			{
				pnl.style.overflowY = 'scroll';
				pnl.style.height = maxHeight;
			}
		},
		G2_VerifyScrollableElementWidth : function(pnlID, maxWidth)
		{
			var pnl = $(pnlID);
			if(pnl == null)
				return;
			if(maxWidth == null || maxWidth == 0)
				return;
				
			if(pnl.clientWidth > maxWidth)
			{
				pnl.style.overflowX = 'scroll';
				pnl.style.width = maxWidth;
			}
		}
	
});
G2_PreventPostElementIds = new Object();

//**************************************************************************************************

WebForm_InitCallback = function(){};//this is disabled in purpose. we use G2_InitCallback;
var G2_SetFocus_ThreadId = null;
//var G2_InitCallbackFirstTime = true;
var _registeredScripts;
var HtmlSelectEmptyValue = "_NULL_"; //empty strings causes problems with tabs and selectedIndex

if(typeof(Date_ShortMonthNames)=="undefined")
	Date_ShortMonthNames = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
if(typeof(Date_MonthNames)=="undefined")
	Date_MonthNames = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
if(typeof(G2_ShortDays)=="undefined")
	G2_ShortDays = ["Su","Mo","Tu","We","Th","Fr","Sa"];

var G2_maxZ=999;
var G2_FixFrame = null;
var enableResizing = false; 
var G2Tooltips = new Array();



G2_PreventInputPost("G2_RootAppPath");





String.IsNullOrEmpty = function(value)
{
	return value==null || value=="";
}

String.Format = function(format, args)
{
	for(var i=1;i<arguments.length;i++)
	{
		var arg = arguments[i];
		var exp = new RegExp("[{]"+(i-1)+"[}]", "g");
		format = format.replace(exp, arg);
	}
	return format;
}

String.Replace = function(s, search, replace)
{
	var exp = new RegExp(search, "g");
	return s.replace(exp, replace);
}








//**************************************************************************************************






function Stopper()
{
	this.laps = new Array();
	this.lapsInfos = new Array();
}

Stopper.prototype.start = function ()
{
	var now = new Date();
	this.laps.push(now);
}

Stopper.prototype.lap = function (name)
{
	var now = new Date();
	this.laps.push(now);
	if(name==null)
	  name="Lap";
	this.lapsInfos.push(name);
	return now-this.laps[this.laps.length-2];
}

Stopper.prototype.total = function ()
{
	var now = new Date();
	return now-this.laps[0];
}

Stopper.prototype.maxIndex = function ()
{
  var maxIndex = -1;
  var max=0;
	for(var i=1; i<this.laps.length; i++)
	{
	  var start = this.laps[i];
	  var end = this.laps[i-1];
	  var lap = start-end;
	  if(lap>max)
	  {
	    maxIndex = i;
	    max = lap;
	  }
  }
  return maxIndex;
}

Stopper.prototype.totalLaps = function ()
{
	var start = this.laps[0];
	var end = this.laps[this.laps.length-1];
	return end-start;
}

var StopperWinID = 0;
Stopper.prototype.report = function (title)
{
  var winID = "Stoper_"+StopperWinID;
  StopperWinID++;
	var win = window.open(null, winID, "height=300,width=300,status=no,toolbar=no, menubar=no, location=no, resizable=yes");
	var doc = win.document;
	doc.open();
	
	doc.write("<html><body>");
	//var now = new Date();
	doc.write("<div style='font-size:8px;'><b>"+title+"</b></div>");
	var maxIndex = this.maxIndex();
	doc.write("<table>");
	doc.write("<tbody>");
	for(var i=1; i<this.laps.length; i++)
	{
	  var start = this.laps[i];
	  var end = this.laps[i-1];
	  doc.write("<tr>");
	  doc.write("<td>");
	  doc.write("<div style='"); 
	  if(i==maxIndex)
	  {
	    doc.write("color:red;");
	  }
	  doc.write("'>"+i.toString());
	  doc.write("</div>");
	  doc.write("</td>");
	  doc.write("<td>");
	  doc.write(this.lapsInfos[i-1]);
	  doc.write("</td>");
	  doc.write("<td>");
	  doc.write((start-end)+"");
	  doc.write("</td>");
	  doc.write("</tr>");
	}
	doc.write("</tbody>");
	doc.write("</table>");
	doc.write("<hr />");
	doc.write("<div style='color:blue'>Total: <b>" + this.totalLaps()+ "</b>ms</div>"); 
	doc.write("</body></html>");
	doc.close();	
}


var specialCopyKey = 17; //ctrl + q 



Char = 
{
	Backspace : 8,
	Tab : 9,
	Enter : 13,
	Ctrl : 16,
	Alt : 17,
	Pause : 19,
	CapsLock : 20,
	Escape : 27,
	PageUp : 33,
	PageDown : 34,
	End : 35,
	Home : 36,
	ArrowLeft : 37,
	ArrowUp : 38,
	ArrowRight : 39,
	ArrowDown : 40,
	Insert : 45,
	Delete : 46,
	categories : {Digit:/[0-9]/, Upper:/[A-Z]/, Lower:/[a-z]/},
	IsDigit : function(charOrCode)
	{
		return this.IsInCategory(charOrCode, "Digit");
	},
	IsInCategory : function(charOrCode, categoryName)
	{
		if(charOrCode==null)
			return false;
		var s = typeof(charOrCode)=="number" ? String.fromCharCode(charOrCode) : charOrCode;
		return this.categories[categoryName].test(s);
	},
	IsUpper : function(charOrCode)
	{
		return this.IsInCategory(charOrCode, "Upper");
	},
	IsLower : function(charOrCode)
	{
		return this.IsInCategory(charOrCode, "Lower");
	},
	ToUpperKeyCode : function(keyCode)
	{
		return keyCode-32;
	},
	//
	// returns a value indicating whether the given charCode is a key that changes the cursor position
	//
	IsCursorPositionCharCode : function (charCode)
	{
		if
		(
			charCode==this.ArrowUp || 
			charCode==this.ArrowDown || 
			charCode==this.ArrowLeft || 
			charCode==this.ArrowRight || 
			charCode==this.Home || 
			charCode==this.End || 
			charCode==this.PageUp || 
			charCode==this.PageDown
		)
		{
			return true;
		}
		return false;
	}


}

//46 Delete 
//TODO:
//91 Left Windows 
//92 Right Windows 
//93 Context Menu 
//96 NumPad 0 
//97 NumPad 1 
//98 NumPad 2 
//99 NumPad 3 
//100 NumPad 4 
//101 NumPad 5 
//102 NumPad 6 
//103 NumPad 7 
//104 NumPad 8 
//105 NumPad 9 
//106 NumPad * 
//107 NumPad + 
//109 NumPad - 
//110 NumPad . 
//111 NumPad / 
//112 F1 
//113 F2 
//114 F3 
//115 F4 
//116 F5 
//117 F6 
//118 F7 
//119 F8 
//120 F9 
//121 F10 
//122 F11 
//123 F12 
//144 Num Lock 
//145 Scroll Lock 
//186 ; 
//187 = 
//188 , 
//189 - 
//190 . 
//191 / 
//192 ` 
//219 [ 
//220 \ 
//221 ] 
//222 ' 


function G2KeysClass()
{
  this.up = 38; //up arrow  
  this.down = 40; //down arrow
  this.left =  37; //left arrow
  this.right =  39; //right arrow
  this.pageUp =  33; //page up  
  this.pageDown =  34; //page down  
  this.home =  36; //home  
  this.end =  35; //end                  
  this.enter =  13; //enter  
  this.tab =  9; //tab  
  this.esc =  27; //esc  
  this.shift =  16; //shift  
  this.ctrl =  17; //ctrl  
  this.alt =  18; //alt  
  this.caps =  20; //caps lock
  this.backspace =  8; //backspace  
  this.del =  46; //delete
  
  this.controlKeys = new Array(this.up, this.down, this.left, this.right, this.pageUp, this.pageDown, this.home, this.end, this.enter, this.tab, this.shift, this.ctrl, this.alt, this.caps, this.backspace, this.del);
}
var G2Keys = new G2KeysClass();


G2EventArray = function(owner)
{
	this.owner = owner;
}
G2_DeclareClass(G2EventArray, "G2EventArray", Array,
{
	fire : function()
	{
		for(var i=0;i<this.length;i++)
		{
			this[i](this.owner);
		}
	}
});




//Add trim() to String.
String.prototype.trim = trim;
	/*
	function G2PopupWindow_Open2(url, context, modal, name, features)
	{	
		if (features==null && context!=null)
		{
			var h = document.all[context];
			if(h!=null)
				features = h.value;
		}   
		if (modal==null)
			modal=true;
			
		if(modal)
		{
			var h = G2PopupWindow_ExtractParameter(features,"dialogHeight");
			var w = G2PopupWindow_ExtractParameter(features,"dialogWidth");
					
			//Fix for callbacks on popup closed event
			var me = window;
			function f()
			{
				window.showModalDialog(G2_MapPath("~/Client/Dialog.aspx"),{url:url,obj:me,width:w,height:h}, features);
			}		
			f();
		}
		else
		{
	  
			//Workaround for bug #3634: 
			// IE popup blocker blocked the popup, because it was not initiated by a user click.		
			
			//Note: The following is a workaround for IE popup blockers. It is not jiffacode.
			var temporaryButton = G2DOM.G2CreateElement("<input type='Button' style='display:none'></input>");
			temporaryButton.id = temporaryButton.uniqueID;
			temporaryButton.onclick = function()
			{
				if (null == window.open(url, name, features))
				{
					alert('popup blocker detected!');
				}
			}
			document.body.appendChild(temporaryButton);
			temporaryButton.click();
			document.body.removeChild(temporaryButton);
		}
	}*/
if(ENABLE_PROFILER)
	Profiler.createDebugDiv();

ListSet = function()
{
	this._list = [];
	this._set = {};
}
G2_DeclareClass(ListSet, "ListSet", null, 
{
	addRange : function(array)
	{
		for(var i=0;i<array.length;i++)
		{
			this.add(array[i]);
		}
	},
	add : function(item)
	{
		if(this._set[item]!=null)
			return false;
		this._list.push(item);
		this._set[item] = this._list.length-1;
		return true;
	},
	remove : function(item)
	{
		if(this._set[item]==null)
			return false;
		var index = this._set[item];
		this._list.splice(index, 1); //removeAt
		this._set[item] = null;
		for(var i=index;i<this._list.length;i++) //perform reindexing
		{
			var item = this._list[index];
			this._set[item] = index;
		}
		return true;
	},
	toString : function(seperator)
	{
		return this._list.join(seperator);
	}
	
});

/* G2PopupManager
Manages all popups and tooltips within the application.
*/
G2PopupManager = 
{
//	popups : {},
//	tooltipTargets : [],
//	allowTooltips : true,
	
	init : function()
	{
		this.attachToOnClick(document, true);
		this.allowTooltips = true;
		if(window.top.G2PopupManager==this)
		{
		  this.popups = new Object();
		  this.tooltipTargets = new Array();
		}
		else
		{
		  var tm = window.top.G2PopupManager;
		  this.popups = tm.popups;
		  this.tooltipTargets = tm.tooltipTargets;
		}
	},
		
	attachToOnClick : function(doc, includeFrames)
	{
	  if(doc.attachEvent) //G2Dom is not available right now
		{
			doc.attachEvent("onmousedown", this.__document_onclick);
//			if(IE6) //memory leaks
//			  doc.parentWindow.attachEvent("onunload", this.window_onunload);
		}
		else if(document.addEventListener)
		{
			doc.addEventListener("mousedown", this.__document_onclick, false);
		}
//		if(!includeFrames || doc.parentWindow==null || doc.parentWindow.document==doc)
//		  return;
//		
//	  doc = doc.parentWindow.document;
//	  this.attachToOnClick(doc, includeFrames);
	},
	window_onunload : function(e)
	{
	  G2PopupManager.unload();
	},
	unload : function(e)
	{
	  for(var p in this.popups)
	  {
	    this.popups[p] = null;
	  }
	},
	__document_onclick : function(e)
	{
		G2PopupManager._document_onclick(e);
	},
	_document_onclick : function(e)
	{
		var element = e.srcElement;
		
		if(element!=null && element.tagName=="HTML")
		  return;//Clicked on scroll, ignore
		 
		while(element!=null)
		{
			var popup = this.popups[element.uniqueID];
			if(popup!=null)
				return;
			element = element.parentElement;
		}
		this.closeAllPopups(true);
		this.closeAllTooltips();
	},
	
	//Use this method to display a popup element relatively to a specific element
	//
	openPopup : function(element, relativeElement, dock, onTopWindow)
	{
		this.closeAllPopups();
		var popup = {element:element, relativeElement:relativeElement, dock:dock, isOpen:true, allowCloseOnDocumentClick:false};
		this.popups[element.uniqueID] = popup;
		if(relativeElement==null)
			throw new Error("relative element not found, cannot show popup");
		if(element.g2closepopup=="false")
			element.style.display = "";
		G2_PlaceElementAbsolutlyNear(element, relativeElement, dock, onTopWindow);
		if(dock==null || !dock.contains(","))
			G2_VerifyAbsoluteElementNotCropped(element);
		G2_BringToFront(element);
		G2_AttachFrame(element);
		
		window.setTimeout(
		function()
		{
			popup.allowCloseOnDocumentClick = true;
		}, 0);
		
	  if (element.onOpened!=null)
	    element.onOpened(element);			
	},
	
	//Closes all registered popups in the window
	closeAllPopups : function(isDocumentClick)
	{
		for(var p in this.popups)
		{
			var pp = this.popups[p];
			if(pp!=null && pp.isOpen)
			{
				if(isDocumentClick && !pp.allowCloseOnDocumentClick)
					continue;
				this.closePopup(pp.element);
			}
		}
	},
	isPopupOpened : function(element)
	{
		var popup = this.getPopup(element);
		if(popup!=null && popup.isOpen)
			return true;
		return false;
	},
	
	//Retrives a specific popup element
	getPopup : function(element)
	{
		return this.popups[element.uniqueID];
	},
	
	//Closes a given popup by its element
	closePopup : function(element)
	{
		var popup = this.getPopup(element);
		if(popup==null)
			return;
		if (popup.element.onBeforeClose!=null)
		  popup.element.onBeforeClose(popup.element);
		G2_DetachFrame(element);
		if(element.g2closepopup=="false")
		{
			element.style.display = "none";
		}
		else if(element.parentElement!=null)
		{
			element.parentElement.removeChild(element);
		}
		popup.isOpen = false;
		if(element.onPopupClosed)
		  element.onPopupClosed();
		 
		delete this.popups[element.uniqueID];
	},
	
	
	
	//Displayes the provided HTML as a tooltip
	//A typical use is to attach an onmouseenter handler to the target element such as
	//target.onomuseenter = "G2PopupManager.showTooltipHtml(this, '<b>Hello</b>', event);";
	showTooltipHtml : function(targetElement, html, e)
  {
	  if (!e)
		  e = window.event;
  	
	  var el = targetElement._tooltipElement;
	  if(el==null)
	  {
	    el = G2DOM.G2CreateElementFromHtml("<TABLE border='0' cellpadding='0' cellspacing='0'><TR><TD>"+html+"</TD></TR></TABLE>");
	    if(el.parentElement!=null)//TODO: Remove quick fix
	      el.parentElement.removeChild(el);
	  }
	  this.showTooltipStart(targetElement, el,e);
  },
  
  showTooltipText : function(targetElement, text, e)
  {
    if (!e)
		  e = window.event;
	  var html = "<div style='background-color: #fffacd;border-right: black 1px solid;border-top: black 1px solid;font-size: 8pt;border-left: black 1px solid;color: black;border-bottom: black 1px solid;font-family: Arial;padding:4px;'>"+text+"</div>";
	  this.showTooltipHtml(targetElement, html, e);
  },
  
  showTooltipStart : function(targetElement, el,e)
  {
    if(!this.allowTooltips)//Tooltips are disabled during postbacks
      return;
	  if (!e)
		  e = window.event;
	  
	  this.closeAllTooltips();
	  targetElement._tooltipElement = el;//Cache
	  
	  var posx = 0;
	  var posy = 0;
	  var winWidth = 1024;
	  var winHeight = 700;
  	 
  	if(el.parentElement == null)
  	  document.body.appendChild(el);
	  el.style.position="absolute";
	  offSet = 0
	  if (e.pageX || e.pageY)
	  {
		  winWidth = window.innerWidth;
		  winHeight = window.innerHeight;
		  posx = e.pageX;// + window.pageXOffset;
		  posy = e.pageY;// + window.pageYOffset;
	  }
	  else if (e.clientX || e.clientY)
	  {
		  winWidth = document.body.offsetWidth;
		  winHeight = document.body.offsetHeight;
		  posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		  posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	  }
	  
	  el.style.display = "block";
	  
	  //Fix flowing out of window
		var right = posx + el.offsetWidth;
	  if(right>winWidth)
	  {
	    var newPosx = (posx-el.offsetWidth);
	    if(newPosx>0)
	      posx = newPosx;
	  }
		var bottom = posy + el.offsetHeight;
	  if(bottom>winHeight)
	  {
	    newPosy = (posy-el.offsetHeight);
	    if(newPosy>0)
	      posy = newPosy; 
	  }
	  
	  posy++;		//Avoid some flickering in FireFox
	  el.style.pixelLeft = posx;
	  el.style.pixelTop = posy;
	  G2_VerifyAbsoluteElementNotCropped(el);
	  
	  targetElement.title = "";
	  this.tooltipTargets.push(targetElement);
	  
	  
	  
	  G2_BringToFront(el);
	  G2_AttachFrame(el);
	  el.enterToolTip = false;
	  	  
      if(targetElement.onmouseleave==null)
      {
          targetElement.onmouseleave=function(){
            setTimeout(function(){CloseIfNotInToolTip(targetElement, el)}, 500);
          };
          if (isMoz)
          {
            G2_AttachEvent(targetElement, "onmouseout",targetElement.onmouseleave); 
          }	    
	   }
	  if(el.onmouseenter==null)
      {
          el.onmouseenter=function(){el.enterToolTip = true;}; 
          if (isMoz)
          {
            G2_AttachEvent(el, "onmousein",el.onmouseenter); 
          }	      
	  }
	  if(el.onmouseleave==null)
      {
          el.onmouseleave=function(){
            G2PopupManager.closeTooltipFor(targetElement);
            el.enterToolTip = false;
          }; 
          if (isMoz)
          {
            G2_AttachEvent(el, "onmouseout",el.onmouseleave); 
          }	      
	  }
	  if(el.onmousedown==null)
      {
          el.onmousedown=function(){
           e.cancelBubble = true;
          };   
	  }
  },	
  closeAllTooltips : function()
  {
    while(this.tooltipTargets.length > 0)
    {
      var tt = this.tooltipTargets.pop();
      this.closeTooltipFor(tt);
    }
  },
  closeTooltipFor : function(targetElement)
	{
	  if(targetElement._tooltipElement !=null)
	    targetElement._tooltipElement.style.display="none";
	  G2_DetachFrame(targetElement._tooltipElement);
	},
	
	disableTooltips : function()
	{
	  this.allowTooltips = false;
	},
	
	enableTooltips : function()
	{
	  this.allowTooltips = true;
	}
	
};
G2_DeclareUtilInstance(G2PopupManager);
G2PopupManager.init();

G2FrameManager = 
{
	autoSizeThreadId : null,
	frames : {},
	registerFrame : function(frameOrId)
	{
		if(typeof(frameOrId)=="string")
			this.frames[frameOrId] = null;
		else
			this.frames[frameOrId.id] = frameOrId;
		if(this.autoSizeThreadId==null)
		{
			var caller = this;
			this.autoSizeThreadId = window.setInterval(
			function()
			{
				caller.autoSizeAllFrames();
			}, 300);
		}
	},
	unregisterFrame : function(frame)
	{
	    delete this.frames[frame.id];
	},
	autoSizeAllFrames : function()
	{
		for(var id in this.frames)
		{
			var frame = this.frames[id];
			if(frame==null)
			{
				frame = document.getElementById(id);
				this.frames[id] = frame;
			}
			frame.className = frame.className.replace("Hide", "");
			if(frame.autosize!="false" && frame.readyState=="complete")
			{
				try
				{
					if(frame.autosizeheight!="false")
					{
					  //  Following is the standard html page doctype definition as produced by Visual Studio with default settings
					  var doctypeString = '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">';
					  var height, includesDTD = false;
					  //  Check if doctype is one of iframe document childs and retrieve the proper scrollHeight value
					  for(var i=0; i<frame.contentWindow.document.childNodes.length; i++)
					  {
					    if(frame.contentWindow.document.childNodes[i].text == doctypeString)
					    {
					      includesDTD = true;
					      break;
					    }
					  }
					  if(includesDTD) 
						  height = frame.contentWindow.document.documentElement.scrollHeight;
						else
						  height = frame.contentWindow.document.body.scrollHeight;
						if(frame.style.pixelHeight!=height)
							frame.style.height = height+"px";
					}
					if(frame.autosizewidth!="false")
					{
						var width = frame.contentWindow.document.documentElement.scrollWidth;
						if(frame.style.pixelWidth!=width)
							frame.style.width = width+"px";
					}
				}
				catch(err)
				{
					1;
					1;
				}
			}
		}
	}
}
G2_DeclareUtilInstance(G2FrameManager);



function G2_Print()
{
  window.print();
}


//
// Allows performing actions in the background
// action = function + arguments
// when the action occurs - 'this' keywork returns the background worker
//
G2BackgroundWorker = function(maxConcurrentActions)
{
	this.actions = [];
	this.concurrentActionsCount = 0;
	this.maxConcurrentActions = maxConcurrentActions || 1;
}

G2_DeclareClass(G2BackgroundWorker, "G2BackgroundWorker", null, 
{
	addAction : function(func, args, options)
	{
		this.actions.push({func:func,args:args,options:options});
		if(this.actions.length==1)
		{
			this._requestDoWorkIfNeeded();
		}
	},
	_requestDoWorkIfNeeded : function()
	{
		var caller = this;
		if(this.actions.length>0)
		{
			window.setTimeout(
			function()
			{
				caller.doWork();
			}, 0);
		}
		else if(this.concurrentActionsCount<=0)
		{
			this.onFinish();
		}
	},
	onActionStart : function(action)
	{
		this.concurrentActionsCount++;
	},
	onActionEnd : function()
	{
		if(this.concurrentActionsCount<=0)
			throw new Error("no current actions");
		this.concurrentActionsCount--;
		this._requestDoWorkIfNeeded();
	},
	doWork : function()
	{
		while(this.concurrentActionsCount<this.maxConcurrentActions && this.actions.length>0)
		{
			var action = this.actions.dequeue();
			this.onActionStart(action);
			this.currentAction = action;
			action.func.apply(this, action.args);
			if(action.options==null || !action.options.manualActionEndNotification)
				this.onActionEnd();
		}
	},
	onFinish : function()
	{
	}


});

//All (crappy) focus code taken from asp.net
function G2_FindFirstFocusableChild(control) 
{
  if (!control || !(control.tagName)) 
	{
    return null;
  }
  var tagName = control.tagName.toLowerCase();
  if (tagName == "undefined") 
	{
    return null;
  }
  var children = control.childNodes;
  if (children) 
	{
    for (var i = 0; i < children.length; i++) 
		{
      try 
			{
        if (WebForm_CanFocus(children[i])) 
				{
          return children[i];
        }
        else 
				{
          var focused = WebForm_FindFirstFocusableChild(children[i]);
          if (WebForm_CanFocus(focused)) 
					{
            return focused;
          }
				}
			} 
			catch (e) 
			{
			}
		}
	}
	return null;
}

function G2_AutoFocus(focusId) 
{
  var targetControl;
  if (__nonMSDOMBrowser) 
	{
    targetControl = document.getElementById(focusId);
  }
  else 
	{
    targetControl = document.all[focusId];
  }
  var focused = targetControl;
  if (targetControl && (!WebForm_CanFocus(targetControl)) ) 
	{
      focused = WebForm_FindFirstFocusableChild(targetControl);
  }
  if (focused) 
	{
    try 
		{
      focused.focus();
      if (__nonMSDOMBrowser) 
			{
        focused.scrollIntoView(false);
      }
      if (window.__smartNav) 
			{
        window.__smartNav.ae = focused.id;
      }
      return true;
    }
    catch (e) 
		{
			return false;
    }
  }
  else
		return false;
}
function G2_CanFocus(element) 
{
    if (!element || !(element.tagName)) return false;
    var tagName = element.tagName.toLowerCase();
    return (!(element.disabled) &&
            (!(element.type) || element.type.toLowerCase() != "hidden") &&
            WebForm_IsFocusableTag(tagName) &&
            WebForm_IsInVisibleContainer(element)
            );
}
function G2_IsFocusableTag(tagName) 
{
    return (tagName == "input" ||
            tagName == "textarea" ||
            tagName == "select" ||
            tagName == "button" ||
            tagName == "a");
}
function G2_IsInVisibleContainer(ctrl) 
{
  var current = ctrl;
  while((typeof(current) != "undefined") && (current != null)) 
	{
    if (current.disabled ||
        ( typeof(current.style) != "undefined" &&
        ( ( typeof(current.style.display) != "undefined" &&
            current.style.display == "none") ||
            ( typeof(current.style.visibility) != "undefined" &&
            current.style.visibility == "hidden") ) ) ) 
		{
      return false;
    }
    if (typeof(current.parentNode) != "undefined" &&
            current.parentNode != null &&
            current.parentNode != current &&
            current.parentNode.tagName.toLowerCase() != "body") 
		{
      current = current.parentNode;
    }
    else 
		{
      return true;
    }
  }
  return true;
}

function G2_ShowDisabler(show) 
{
  if(window.g2disabler == null)
  {
    if(show==false)
      return;
    var html = "<div id='g2disabler' class='g2Disabler' onclick='return false;' onmouseover='return false;' onmouseout='return false;'></div>";
    var disablerElement= G2DOM.G2CreateElementFromHtml(html, document);
    document.body.appendChild(disablerElement);
    window.g2disabler = disablerElement;
  }
  if(show)
  {
    window.g2disabler.style.pixelHeight = document.documentElement.scrollHeight;
		window.g2disabler.style.pixelWidth = Math.max(document.documentElement.offsetWidth-4, 0);
    window.g2disabler.style.display = '';
    window.g2disabler.lastDocumentOverflowX = document.documentElement.style.overflowX;
		document.documentElement.style.overflowX = 'hidden';
  }
  else
  {
	  window.setTimeout(function() {
    window.g2disabler.style.display = 'none';
    document.documentElement.style.overflowX = window.g2disabler.lastDocumentOverflowX;}, 1);
  }
}

function G2_DetectAcrobatReader() 
{
    var acrobat=new Object(); 
    acrobat.installed=false; 
    acrobat.version='0.0'; 
    if (navigator.plugins && navigator.plugins.length) { 
        for (x=0; x<navigator.plugins.length;x++) { 
              if (navigator.plugins[x].description.indexOf('Adobe Acrobat')!= -1) 
              { 
                    acrobat.version=parseFloat(navigator.plugins[x].description.split('Version ')[1]); 
                    if (acrobat.version.toString().length == 1) acrobat.version+='.0'; 
                          return acrobat; 
              } 
        } 
    } 
    else if (window.ActiveXObject) 
    { 
        for (x=2; x<10; x++) 
        { 
            try 
            { 
                oAcro=eval("new ActiveXObject('PDF.PdfCtrl."+x+"');"); 
                if (oAcro) 
                { 
                     acrobat.installed=true; 
                     acrobat.version=x+'.0'; 
                 } 
            } 
            catch(e) {} 
            } 
            try 
            { 
                oAcro4=new ActiveXObject('PDF.PdfCtrl.1'); 
                if (oAcro4) 
                { 
                      acrobat.installed=true; 
                      acrobat.version='4.0'; 
               } 
            } 
            catch(e) {} 
            try 
            { 
                oAcro7=new ActiveXObject('AcroPDF.PDF.1'); 
                if (oAcro7) 
                { 
                      acrobat.installed=true; 
                      acrobat.version='7.0'; 
                } 
            } 
            catch(e) {} 
        } 
        return acrobat; 
}
function CloseIfNotInToolTip(trgElm,curToolTip)
{
    if(!curToolTip.enterToolTip)
    {
        G2PopupManager.closeTooltipFor(trgElm);
    }
}
function SaveDocumentTitle(title)
{
    docTitle = title;
}

// Get the topest available window
function GetTopAvailableWindow()
{
	var win = window;
	var tmpElement;
	
	// For each window parent
	while((typeof(win.parent) != "undefined") && (win.parent != null) && (win != win.parent))
	{
	  // Try to access the window parent - else return the current window
		try
		{
			tmpElement = win.parent.document.createElement('DIV');
			win = win.parent;
		}
		catch(e)
		{
			return win;
		}
	}
	
	return win;
}

WebForm_FindFirstFocusableChild = G2_FindFirstFocusableChild;
WebForm_AutoFocus = G2_AutoFocus;
WebForm_CanFocus = G2_CanFocus;
WebForm_IsFocusableTag = G2_IsFocusableTag;
WebForm_IsInVisibleContainer = G2_IsInVisibleContainer;


/**********************************************************************
 *           G2 Cross-platform Javascript library                     *
 **********************************************************************/
Array.prototype.dequeue = function() {var r = this[0]; this.splice(0,1); return r;};
Array.prototype.FirstOrDefault = function(predicate)
{
	for(var i=0;i<this.length;i++)
	{
		var item = this[i];
		if(predicate(item))
			return item;
	}
	return null;
}
Array.prototype.ForEach = function(action)
{
	for(var i=0;i<this.length;i++)
	{
		var item = this[i];
		action(item);
	}
}
Array.prototype.RemoveItem = function(itemToRemove)
{
    for(var i=0;i<this.length;i++)
	{
		if (this[i] == itemToRemove)
		{
		    this.splice(i,1);
		    break;
		}
	}
}

var G2DOM = 
{
	GetChildElementById : function(element, id)
	{
		if(isIE)
		{
			var child = element.all[id];
			if(child==null)
				return null;
			if(child.length!=null)
				return child[0];
			return child;
		}
		else if(isMoz)
		{
			return this._GetChildElementById(element, id);
		}
		else
			throw new Error("not supported");
	},
	_GetChildElementById : function(element, id)
	{
		var child = element.firstChild;
		while(child!=null)
		{
			if(child.id==id)
				return child;
			var grandChild = this._GetChildElementById(child, id);
			if(grandChild!=null)
				return grandChild;
			child = child.nextSibling;
		}
		return null;
	},
	
	// This method gets a root element and a progid value and find the first child element with the progid specified
	// In case you got the whole progId path it is preffered to use the method 'findControl' below. It is much faster.
	// This method uses Depth-First-Search(DFS) recursively.
	GetChildByProgid_dfs : function(root, childProgid)
	{
		if (! root)
			return null;

		if (root.progid == childProgid)
			return root;

		var child = root.firstChild;
		while (child)
		{
			var res = this.GetChildByProgid(child, childProgid);
			if (res != null)
				return res;
			child = child.nextSibling;
		}
		
		return null;
	},
	

	// This method gets a root element and a progid value and find the first child element with the progid specified
	// This method uses Breadth-First-Search (BFS) instead of Depth-First-Search(DFS). It is therefore non-recursive.
	GetChildByProgid : function(root, childProgid)
	{
		if (! root)
			return null;
			
		if (root.progid == childProgid)
			return root;
			
		var queue = [root];		
		while (queue.length>0)
		{
			root = queue.dequeue();
			if (root.progid == childProgid)
				return root;
			var children = root.children;
			for (var i=0,j=children.length;i<j;i++)
				queue.push(children[i]);
		}	
				
		return null;
	},
	
	// This method gets a root element and a progid value and find the first parent element with the progid specified
	GetParentByProgid : function(root, childProgid)
	{
		while(root && root.progid != childProgid)
		{
			root = root.parentElement;
		}
		
		return root;
	},

	// gets the given object position	
	findPos : function(obj)
	{
		var curleft = 0;
		var curtop = 0;
		if (obj.offsetParent)
		{
			curleft = obj.offsetLeft;
			curtop = obj.offsetTop;
			while (obj = obj.offsetParent)
			{
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
					
		    // taking into account scrooling with in overflow scroll elements
		    if(obj.tagName != 'HTML' && obj.scrollTop != null)
			    curtop -= obj.scrollTop;
			}
		}
		return [curleft,curtop];
	},
		
	// Create a covering DIV for a modal effect.
	// The input parameters:
	// side - left, top, right or bottom
	// tableId - the modal element or its id
	// errorMsg - message to shown when clicking on the div. optional
	CreateCoverDiv : function(side,tableId,errorMsg)
	{
		// validate modal element
		if(tableId == null)
			return;

		var tbl = tableId;
		if(typeof(tableId) == "string")
			tbl = $(tableId);

		var arr = this.findPos(tbl)	
		var docHeight,docWidth;
		var coverDiv = document.createElement('DIV');
		var div;
		if (side == "left")
		{
				div = $('leftCoverDiv');
			if (div!=null)
				return div;
			docHeight = document.documentElement.scrollHeight;		
			docWidth = arr[0];
			coverDiv.id = "leftCoverDiv";
		}
		else if (side == "top")
		{
				div = $('topCoverDiv');
			if (div!=null)
				return div;
			docWidth = document.documentElement.scrollWidth;
			docHeight = arr[1];	
			coverDiv.id = "topCoverDiv";
		}			
		else if (side == "right")
		{
				div = $('rightCoverDiv');
			if (div!=null)
				return div;
			docWidth = document.documentElement.scrollWidth-tbl.offsetWidth;
			docHeight = tbl.offsetHeight;
			coverDiv.id = "rightCoverDiv";
		}			
		else if(side == "bottom")
		{
				div = $('bottomCoverDiv');
			if (div!=null)
				return div;
			docWidth = document.documentElement.scrollWidth;
			docHeight = window.document.documentElement.scrollHeight-(arr[1]+tbl.offsetHeight);
			coverDiv.id = "bottomCoverDiv";
		}			
		coverDiv.className = "CoverDiv";
		if (side == "left" || side == "top")
		{
				coverDiv.style.left = "0px";
				coverDiv.style.top = "0px";
		}
		else if (side == "right")
		{
				coverDiv.style.left = arr[0]+tbl.offsetWidth+"px";
				coverDiv.style.top = arr[1]+"px";
		}
		else if (side == "bottom")
		{
				coverDiv.style.left = "0px";
				coverDiv.style.top = arr[1]+tbl.offsetHeight+2+"px";
		}
		coverDiv.style.height = docHeight+"px";
		coverDiv.style.width = docWidth+"px";	
		coverDiv.style.position="absolute";			
		coverDiv.onclick = function()
		{
			if(errorMsg)
				alert(errorMsg);
			else
				alert("You are in Edit Mode, Click Done to save or Cancel to exit");
		};
		return coverDiv;
	},

	//Transfers the custom attributes from the element to its properties (they are the same in IE, not in FF)
	G2TransferAttributes : function(elem)
	{
		if (isIE || elem==null || elem.attributesTransferred) //IE is nice enough
			return;
		elem.attributesTransferred = true;
		for (var atnum in elem.attributes)
		{
			var atNode = elem.attributes[atnum];
			var atname = atNode.nodeName;
			var atvalue = atNode.nodeValue;
			if (typeof(elem[atname])=="undefined")
				elem[atname] = atvalue;
		}	
	},

	G2GetSelection : function()
	{
		return (window.getSelection || (document.getSelection && document.getSelection()) || document.selection);
	},

	G2GetNextChild : function ( n )
	{
		if (isIE)
			return n.nextSibling;

		do
		{
			n	 = n.nextSibling;
		} 
		while (n!=null && n.nodeType == Node.TEXT_NODE);

		return n;
	},
	G2CreateElementFromHtml : function(html, doc)
	{
	  if(doc==null)
	    doc = document;
		var tagName = html.substr(html.search("<")+1, 2).toUpperCase();
		var div = doc.createElement('div');
		if(tagName=="TR")		
		{
			div.innerHTML = "<table><tbody>"+html+"</tbody></table>";
			var newRow = div.firstChild.firstChild.firstChild;
			newRow.parentElement.removeChild(newRow);
			return newRow;
		}
		else if(tagName=="TD")
		{
			var div = doc.createElement("div");
			div.innerHTML = "<table><tr>"+outerHTML+"</tr></table>";
			var cell = div.firstChild.firstChild.firstChild.firstChild;
			return cell;
		}
		else
		{
			div.innerHTML = html;
			return div.children[0]; //FF
		}
	},

	//Replaces a node's outerHTML (Already Implemented in IE, not in FF)
	//TODO: Check if this is needed or if the outerHTML setter works in FF 2.0
	G2ReplaceOuterHTML : function(obj,outerHTML)
	{
		if(isIE)
		{
			//added by dan-el - the simple method doesn't work for TR's.
			if(obj.tagName=="TR")
			{
				var tempDiv = document.createElement('div');
				tempDiv.innerHTML = "<table>"+outerHTML+"</table>";
				var newRow = tempDiv.firstChild.firstChild.firstChild;
				var row = obj;
				var table = obj.parentNode;
				table.replaceChild(newRow, row);
			}
			else if(obj.tagName=="TD")
			{
				var div = document.createElement("div");
				div.innerHTML = "<table><tr>"+outerHTML+"</tr></table>";
				var cell = div.firstChild.firstChild.firstChild.firstChild;
				obj.replaceNode(cell);
			}
			else
			{
				obj.outerHTML = outerHTML;
//				var div = document.createElement("div");
//				div.innerHTML = outerHTML;
//				if (div.firstChild)
//					obj.replaceNode(div.firstChild);
			}
		}
		else //this method caused problems with image caching in Explorer
		{
			obj.outerHTML = outerHTML; //Changed by Alon
			/*var tempDiv = document.createElement('div');
			tempDiv.innerHTML = outerHTML;
			obj.replaceNode(tempDiv.firstChild);*/
		}
	},

	//Firefox stores attributes in a different manner than IE
	G2GetAttribute : function (obj,attributeName)
	{	
		if (isIE)
			return obj[attributeName];
		else if (obj!=null && obj.hasAttribute!=null && obj.hasAttribute(attributeName.toLowerCase()))
			return obj.attributes[attributeName.toLowerCase()].nodeValue;
		else 
		{
			var t = obj.attributes[attributeName.toLowerCase()];
			if (t!=null)
				return t.nodeValue;				
			else
			t = obj[attributeName.toLowerCase()] || obj[attributeName];
			return t;
		}
	},

	G2SetAttribute : function (obj,attributeName,val)
	{
		if (isIE)
			obj[attributeName] = val;
		else
			obj.attributes[attributeName.toLowerCase()].nodeValue = val;
	},

	G2CreateElement : function(t)
	{
		if (isIE || t.charAt(0)!="<")
			return document.createElement(t); //  e.g. document.createElement("DIV")
			
		var tempDiv = document.createElement("DIV");
		tempDiv.innerHTML = t;
		return tempDiv.childNodes[0];
	},

	// This method return row.rowIndex
	GetRowIndex : function(row)
	{
		var body = row.parentElement;
		if (!body)
			return -1;
		var currRow = body.firstChild;
		var index = 0;
		while(currRow)
		{
			if (currRow == row)
				return index;
			index++;
			currRow = currRow.nextSibling;
		}
		return -1;
	},

	// This methods returns a row by its index by going throw the table rowafter row 
	// instead of using the table indexing
	GetRowByIndex : function(table, rowIndex)
	{	
		var row = table.firstChild;
		if (! row)
			return null;
			
		while (row && row.tagName != "TR")
			row = row.firstChild;
			
		if (! row)
			return null;
		
		if (rowIndex == 0)
			return row;
		
		for(var i = 0; i < rowIndex; i++)
		{
			row = row.nextSibling;
			if (!row)
				return null;
		}
		return row;
	},

	// Gets a table and return the number of rows
	GetRowsLength : function(table)
	{
		var row = table.firstChild;
		if (! row)
			return 0;
			
		while (row && row.tagName != "TR")
			row = row.firstChild;
		if (! row)
			return 0;
			
		var count = 0;
		while(row)
		{
			row = row.nextSibling;
			count++;
		}
		return count;
	},
	
	GetCellByIndex : function(row, cellIndex)
	{	
		var cell = row.firstChild;
		if (! cell)
			return null;
		
		if (cellIndex == 0)
			return cell;
		
		for(var i = 0; i < cellIndex; i++)
		{
			cell = cell.nextSibling;
			if (!cell)
				return null;
		}
		return cell;
	},
	
	// Gets a row and return the number of cells
	GetCellsLength : function(row)
	{
		var cell = row.firstChild;
		if (! cell)
			return 0;
			
		var count = 0;
		while(cell)
		{
			cell = cell.nextSibling;
			count++;
		}
		return count;
	},
    G2DisableSelects : function()
    {
         if (!IE6)
            return;
            
        selects = document.getElementsByTagName('SELECT');
        for (var i = 0; i < selects.length; i++)
        {
            sel = selects[i];
            if (sel.isDisabled == false)
            {
              sel.disabled = true;
              sel.wasGenerallyDisabled  = true; 
            }
         }
          
    },
    G2EnableSelects : function()
    {
       if (!IE6)
            return;
            
        selects = document.getElementsByTagName('SELECT');
        for (var i = 0; i < selects.length; i++)
        {
            sel = selects[i];
            if (sel.isDisabled && sel.wasGenerallyDisabled)
            {
                sel.disabled = false;
                sel.wasGenerallyDisabled = false;
             }
         }
    },
    G2InsertRowToTable : function(table, index)
    {
        if (index == null)
            index = table.rows.length;
        return table.insertRow(index);
    },
    
    G2InsertCellToRow : function (row, index)
    {
        if (index == null)
            index = row.cells.length;
        return row.insertCell(index);
    },
    
    G2RemoveNode : function (elem)
    {
        elem.parentNode.removeChild(elem);
    },
    
    G2Focus : function (elem)
    {
			try{
				elem.focus();
			}
			catch(e){
				//do nothing- error when pressing the widget of combo is unclear but cause no problem. 
				// the menu is displayed as usual.
			}
    },
    
    G2HTMLEncode : function (text)
    {
	    if ( !text )
		    return '' ;

	    text = text.replace( /&/g, '&amp;' ) ;
	    text = text.replace( /</g, '&lt;' ) ;
	    text = text.replace( />/g, '&gt;' ) ;
	    return text ;
    },
    
		// Set the flash elements in the iframe to transparent
		SetFlashElementsTransparent : function(iframe)
		{
			if(isMoz)
			{
				var objects = iframe.Document.getElementsByTagName('embed');  
				for (var i = 0; i < objects.length; i++) 
				{   
					var newObject = objects[i].cloneNode(true); 
					newObject.setAttribute('wmode', 'transparent');           
					objects[i].parentNode.replaceChild(newObject, objects[i]);    
				}
			}
			else
			{
				var elementToAppend = iframe.Document.createElement('param');    
				elementToAppend.setAttribute('name', 'wmode');    
				elementToAppend.setAttribute('value', 'transparent');    
				var objects = iframe.Document.getElementsByTagName('OBJECT');    
				for (var i = 0; i < objects.length; i++) 
				{        
					var newObject = objects[i].cloneNode(true);        
					elementToAppend = elementToAppend.cloneNode(true);        
					newObject.appendChild(elementToAppend);        
					objects[i].parentNode.replaceChild(newObject, objects[i]);    
				}
			}
    }
  
}

G2_DeclareUtilInstance(G2DOM);

//the following script adds document.getElementById if it is not present
if(document.all && !document.getElementById) 
{
	document.getElementById = function(id) 
	{
		return document.all[id];
	}
}


/**********************************************************************
 *           G2 Event handling                                        *
 *     portions taken from the Prototype library version 1.4.0        *
 **********************************************************************/

G2_DeclareFunctions(
{
	G2_AttachEventWithCaller : function(element, eventName, handler, caller)
	{
		element.attachEvent(eventName, G2.GetDelegate(caller, handler));
	},
	G2_DetachEventWithCaller : function(element, eventName, handler, caller)
	{
		element.detachEvent(eventName, G2.GetDelegate(caller, handler));
	},


	G2_FireEvent : function(target, eventName, eventArgs)
	{
		if(isIE)
		{
			return target.fireEvent(eventName, eventArgs);
		}
		else
		{
			var handler = target[eventName];
			if (handler!=null)
			{
				if (typeof(handler)=="function")
					handler();
				else eval(handler);
			}
			else
				throw new Error("not supported");
		}
	},

	// This method wraps an event handler, to achieve two goals:
	// 1. When the method executes, its 'this' context will be the actual object (who 'owns' the function)
	// 2. Cross-platform event handling:
	//    In IE, the current event that is being process is stored in window.event
	//    In Mozilla (and FireFox), the event object is passed as an argument to the event handler
	G2_PrepareEvent : function(newContext,method)
	{
		if (method.preparedEvent && method.preparedEvent!=null)
		{
			return method.preparedEvent;
		}
		method.preparedEvent = function(event)
		{
			if (event==null)
				event = window.event;
			return method.call(newContext,event);
		}
		
		return method.preparedEvent;
	},

	// Attaches an event handler to the target, as a response to that event
	// The handler should be a function that receives a single argument, named 'event'.
	// It should NOT use window.event, only the supplied event.
	G2_AttachEvent : function(target, eventName, handler, capture)
	{
		if (eventName.substr(0,2)=="on")
			eventName = eventName.substring(2);
		
		//Note: Capture is only supported in FireFox
		if (!capture)
			capture = false;
		
		if(isIE)
		{
			target.attachEvent('on'+eventName, G2_PrepareEvent(target,handler));
		}
		else if (target.addEventListener!=null)
		{		
				target.addEventListener(eventName,G2_PrepareEvent(target,handler),capture);
		} 
		else
			throw new Error("not supported");
	},


	G2_DetachEvent : function(target,eventName, handler, capture)
	{
		if (eventName.substr(0,2)=="on")
			eventName = eventName.substring(2);
		
		//Note: Capture is only supported in FireFox
		if (!capture)
			capture = false;
		
		if (isIE) 
		{
				target.detachEvent('on' + eventName, G2_PrepareEvent(target,handler));
		}
		else if (target.removeEventListener!=null)
		{
				target.removeEventListener(eventName, G2_PrepareEvent(target,handler), capture);
		} 
		else 
			throw new Error("not supported");
	},
	G2StopEvent : function(event)
	{
		G2Event.stop(event);
	},
		
	// Get child element in a given element by its id
	G2_FindChildControlById : function(element, id)
	{
		if(String.EndsWith(element.id, id))
			return element;
		var child = element.firstChild;
		while(child!=null)
		{
			var found = G2_FindChildControlById(child, id);
			if(found!=null)
				return found;
			child=child.nextSibling;
		}
		return null;
	},
	
	// Get the first child element in a given element with a specified tagName
	G2_FindChildControlByTagName : function(element, tagName)
	{
		if(! element)
			return null;
		if (element.tagName)
			if(element.tagName.toLowerCase() == tagName.toLowerCase())
				return element;
		var child = element.firstChild;
		while(child!=null)
		{
			var found = G2_FindChildControlByTagName(child, tagName);
			if(found!=null)
				return found;
			child=child.nextSibling;
		}
		return null;
	},

	///
	///Recursivly searches an element from the current control and up that has a certain tag name
	///
	G2_GetParentElementByTagName : function(control, tagName)
	{	
		tagName = tagName.toUpperCase();
		return _G2_GetParentElementByTagName(control, tagName);
	},
	_G2_GetParentElementByTagName : function(control, tagName)
	{	
		if(control==null)
			return null;
		if(control.tagName==tagName) //TODO: Compare case insensitive
			return control;
		control = control.parentElement;
		return _G2_GetParentElementByTagName(control, tagName);
	},

	//returns an array of all the nodes under node with progid=parentProgId that have the 
	//specified attribute name and value 
	findControlsByAttribute : function(node, parentProgId, attributeName, attributeValue)
	{
		
		var pred = function(el)
		{
			if(G2DOM.G2GetAttribute(el, "progid")==parentProgId)
					return el;
		}
		var testAttribute = function(node)
		{
			if(G2DOM.G2GetAttribute(node, attributeName)==attributeValue)
					return node;
		}
		var curNode = searchUp(node, pred);
		if(curNode == null)
			return null;

		var childrenArray = new Array();
		
		collectChildrenByAttribute(curNode, testAttribute, childrenArray);
		return childrenArray; 
	},
	
	collectChildrenByAttribute : function (obj, predicate, childrenArray)
	{
		if (obj==null)
			obj = this;
			
		if (obj.childNodes.length==0)
			return childrenArray;
			
		var c = obj.firstChild;
		
		while(c!=null)
		{
			collectChildrenByAttribute(c,predicate, childrenArray);
			if (c.nodeType == 1 && predicate(c))
				childrenArray.push(c);
			c = c.nextSibling;
		}
	},
	
		
	//Finds an element by progid
	//Usage: provide a start node and a path seperated by dots, i.e. findControl(el, 'div1.panel2.button3');
	//       in this example, a node with progid div will be searched UPWARDS from el
	//       Then a div1 child element with progid 'panel2'will be searched DOWN.
	//       Then a panel2 child element with progid 'button3'will be searched DOWN. 
	//Returns: the first element with the last progid in the path that matches
	findControl : function(node, progIdpath)
	{
		var tokens = progIdpath.split('.');
		if(tokens.length==0)
			return null;
		var progid=tokens[0];
		tokens.splice(0,1);//Remove first token
	  
		var pred = function(el)
		{
			if(G2DOM.G2GetAttribute(el, "progid")==progid)
					return el;
		}
		var curNode = searchUp(node, pred);
		if(curNode == null)
			return null;
		if(tokens.length==0)
			return curNode;
		var newPath = tokens.join('.');
		return _findChildControl(curNode, newPath); 
	},

	_findChildControl : function(node, progIdpath)
	{
		var curNode = node;
		var tokens = progIdpath.split('.');
		if(tokens.length==0)
			return curNode;
		
		var tokensLength = tokens.length;
		for(var i=0; i<tokensLength; i++)
		{
			var progid=tokens[i];
			var pred = function(el)
			{
				if(G2DOM.G2GetAttribute(el, "progid")==progid)
					return el;
			}
			curNode = searchDown(curNode, pred);  
			if(curNode==null)
				return null;
		}
		return curNode;
	},

	searchUp : function(node, predicate)
	{
		while(node!=null)
		{
			if(predicate(node))
				return node;
			node = node.parentElement;
		}  
		return null;
	},
	searchDown : function(node, predicate)
	{
		return _searchDown(node, predicate);
	},
	_searchDown : function(node, predicate)
	{
		if(predicate(node))
				return node;
		node = node.firstChild; 
		if (node!=null && node.nodeType != 1)
			node = G2DOM.G2GetNextChild(node);
		while(node!=null)
		{
			var n = _searchDown(node, predicate);
			if(n!=null)
				return n;
			node = G2DOM.G2GetNextChild(node);
		}  
		return null;
	}
	
});

var G2Event = {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,  
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_SPECIAL_COPY: 17,

	//Returns the target(FF)/source(IE) element - which is the event's context
	//Usage:  Event.element( e )
  element: function(event) {
		if (event==null)
			event = window.event;
    return event.target || event.srcElement;
  },

	//Returns true if the click was a left mouse click
	//Usage:  Event.isLeftClick( e )
  isLeftClick: function(event) {
		if (event==null)
			event = window.event;
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },
	
	//Returns the cursor X coordinate (relative to the page)
	//Usage:  Event.pointerX( e )
  pointerX: function(event) {
		if (event==null)
			event = window.event;
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
  },

	//Returns the cursor Y coordinate (relative to the page)
	//Usage:  Event.pointerY( e )
  pointerY: function(event) {
		if (event==null)
			event = window.event;
    return event.pageY || (event.clientY +
      (document.documentElement.scrollTop || document.body.scrollTop));
  },

	//Stops the event propagation
	//Usage:  Event.stop( e )
  stop: function(event) {
		if (event==null)
			event = window.event;
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },

  // Finds the first node with the given tagName, starting from the
  // node the event was triggered on; traverses the DOM upwards
  findElement: function(event, tagName) {
		if (event==null)
			event = window.event;
    var element = Event.element(event);
    while (element.parentNode && (!element.tagName ||
        (element.tagName.toUpperCase() != tagName.toUpperCase())))
      element = element.parentNode;
    return element;
  }/*,

  observers: false,

  _observeAndCache: function(element, name, observer, useCapture) {
    if (!this.observers) this.observers = [];
    if (element.addEventListener) {
      this.observers.push([element, name, observer, useCapture]);
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      this.observers.push([element, name, observer, useCapture]);
      element.attachEvent('on' + name, observer);
    }
  },

  unloadCache: function() {
    if (!Event.observers) return;
    for (var i = 0; i < Event.observers.length; i++) {
      Event.stopObserving.apply(this, Event.observers[i]);
      Event.observers[i][0] = null;
    }
    Event.observers = false;
  },

  observe: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.attachEvent))
      name = 'keydown';

    this._observeAndCache(element, name, observer, useCapture);
  },

  stopObserving: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.detachEvent))
      name = 'keydown';

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      element.detachEvent('on' + name, observer);
    }
  }*/
};




//Add Debug.writeln support for Firefox
//In order to enable logging:
// 1. open firefox
// 2. open about:config
// 3. right-click and New->String
// 4. Name the new entry "browser.dom.window.dump.enabled"
// 5. Set its value to true
// 6. Open firefox with the -console parameter (it might complain, but it works).
// For additional information, contact Alon.
// 
// Note: Console is disabled by default. On production systems no change needs to be done.
if (typeof(Debug)=="undefined")
	Debug = {writeln:function(txt){window.dump(txt+"\n");}};
	


/**********************************************************************
 *           G2 Firefox HTMLElement extension                         *
 **********************************************************************/

if(!document.documentElement.outerHTML)
{

    HTMLElement.prototype.getAttributes = function(){
       var attStr = "";
       if(this && this.attributes.length > 0){
          for(a = 0; a < this.attributes.length; a ++){
             attStr += " " + this.attributes.item(a).nodeName + "=\"";
             attStr += this.attributes.item(a).nodeValue + "\"";
          }
       }
       return attStr;
    }

    HTMLElement.prototype.getInsideNodes = function(){
       if(this){
          var cNodesStr = "", i = 0;
          var iEmpty = /^(img|embed|input|br|hr|bgsound)$/i;
          var cNodes = this.childNodes;
          for(i = 0; i < cNodes.length; i ++){
             switch(cNodes.item(i).nodeType){
                 case 1 :
                    cNodesStr += "<" + cNodes.item(i).nodeName.toLowerCase();
                    if(cNodes.item(i).attributes.length > 0){
                       cNodesStr += cNodes.item(i).getAttributes();
                    }
                    cNodesStr += (cNodes.item(i).nodeName.match(iEmpty))? "" : ">";
                    if(cNodes.item(i).childNodes.length > 0){
                       cNodesStr += cNodes.item(i).getInsideNodes();
                    }
                    if(cNodes.item(i).nodeName.match(iEmpty)){
                       cNodesStr += " />";
                    } else {
                       cNodesStr += "</" + cNodes.item(i).nodeName.toLowerCase() + ">";
                    }
                    break;
                 case 3 :
                    cNodesStr += cNodes.item(i).nodeValue;
                    break;
                 case 8 :
                    cNodesStr += "<!--" + cNodes.item(i).nodeValue + "-->";
                    break;
             }
          }
          return cNodesStr;
       }
    }

    G2MozGetOuterHTML = function(){
       var strOuter = "";
       var iEmpty = /^(img|embed|input|br|hr|bgsound)$/i;
       switch(this.nodeType){
          case 1 :
             strOuter += "<" + this.nodeName.toLowerCase();
             strOuter += this.getAttributes();
             if(this.nodeName.match(iEmpty)){
                 strOuter += " />";
             } else {
                 strOuter += ">" + this.getInsideNodes();
                 strOuter += "</" + this.nodeName.toLowerCase() + ">";
             }
             break;
          case 3 :
             strOuter += this.nodeValue;
             break;
          case 8 :
             cNodesStr += "<!--" + this.nodeValue + "-->";
             break;
       }
       return strOuter;
    }

    G2MozSetOuterHTML = function(str){
       var iRange = document.createRange();
       iRange.setStartBefore(this);
       var strFragment = iRange.createContextualFragment(str);
       var sRangeNode = iRange.startContainer;
       iRange.insertNode(strFragment);
       sRangeNode.removeChild(this);
    }
    
    //Returns the object's document
		G2GetDocument = function (obj)
		{
			if (obj == null)
				obj = this;
			return obj.ownerDocument;
		}

		// Artificially get the 'Children' array for the given node.
		// Added as a getter to the Node class in FF
		G2GetChildren = function (obj)
		{
			if (obj==null)
				obj = this;
				
			var childrenArray = new Array();
			if (obj.childNodes.length==0)
				return childrenArray;
				
			var c = obj.firstChild;
			while(c!=null)
			{
				if (c.nodeType != Node.TEXT_NODE)
					childrenArray.push(c);
				c = c.nextSibling;
			}
			
			childrenArray.namedItem = function(name)
			{
				for (var i=0;i<this.length;i++)
				{
					var node = this[i];
					if (node.id == name)
						return node;
				}
				return null;
			}
			
			return childrenArray;
		}
		
		G2GetTagName = function(obj)
		{
			if (obj==null)
				obj = this;
			return obj.nodeName;
		}

		function G2GetParent(obj)
		{	
			if (obj==null)
				obj = this;
			return obj.parentNode;
		}
		
		function G2GetCurrentStyle(obj)
		{
			if (obj==null)
				obj = this;
			return window.getComputedStyle(obj,null);
		}
		
		function G2GetInnerText(obj)
		{
			if (obj==null)
					obj = this;
			return obj.textContent;
		}
		
		function G2SetInnerText(txt)
		{
			this.innerHTML = txt;
		}
		
		function G2ContainsChild(c)
		{
			var chlrn = this.children;
			for (var i=0,j=chlrn.length;i<j;i++)
				if (chlrn[i]==c)
					return true;
			return false;
		}
		
		function G2GetContentDocument()
		{
			return this.contentDocument;
		}
		
		function G2MozGetParentWindow()
		{
			return this.defaultView;
		}
		
		HTMLElement.prototype.contains = G2ContainsChild;
		
		//Implement insertAdjacentElement, insertAdjacentText and insertAdjacentHTML
		HTMLElement.prototype.insertAdjacentElement = function(where,parsedNode)
		{
			switch (where)
			{
				case "beforeBegin":
					this.parentNode.insertBefore(parsedNode,this)
					break;
				case "afterBegin":
					this.insertBefore(parsedNode,this.firstChild);
					break;
				case "beforeEnd":
					this.appendChild(parsedNode);
					break;
				case "afterEnd":
					if (this.nextSibling)
						this.parentNode.insertBefore(parsedNode,this.nextSibling);
					else 
						this.parentNode.appendChild(parsedNode);
					break;
			}
		}
		
		HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr)
		{
			var r = this.ownerDocument.createRange();
			r.setStartBefore(this);
			var parsedHTML = r.createContextualFragment(htmlStr);
			this.insertAdjacentElement(where,parsedHTML)
		}
		
		HTMLElement.prototype.insertAdjacentText = function(where,txtStr)
		{
			var parsedText = document.createTextNode(txtStr)
			this.insertAdjacentElement(where,parsedText)
		}
		var lastGivenID = 1000;			
		function G2GetElementUniqueID ()
		{
			if (this._uniqueID) //already defined
				return this._uniqueID;
			//Generate using counter
			this._uniqueID = lastGivenID;
			lastGivenID++;
			return this._uniqueID;
		}	
		
		function G2GetEventSourceElement() 
		{
			var node = this.target;
			while (node.nodeType != 1) node = node.parentNode;
			return node;
		}
		
		function G2GetProgId()
		{
			if (this.hasAttribute("progid"))
				return this.attributes["progid"].nodeValue;
		}
		
		HTMLElement.prototype.attachEvent = function(eventName, handler, capture) //Simulate AttachEvent on Mozilla
	  {
	    if (eventName.substr(0,2)=="on")
		  	eventName = eventName.substring(2);		  
		  if (!capture)
		    capture = false;
	    this.addEventListener(eventName,handler,capture);
	  }
	  
	  HTMLElement.prototype.detachEvent = function(eventName, handler, capture) //Simulate DetachEvent on Mozilla
	  {
	    if (eventName.substr(0,2)=="on")
		  	eventName = eventName.substring(2);		  
		  if (!capture)
		    capture = false;
	    this.removeEventListener(eventName,handler,capture);
	  }
		
		function defineStyleProperties(names)
		{
			for(var i=0;i<names.length;i++)
			{
				var shortName = names[i];
				var pixelName = "pixel"+shortName.substring(0,1).toUpperCase()+shortName.substring(1);
				defineStyleProperty(shortName,pixelName);
			}
		}

		function defineStyleProperty(shortName,pixelName)
		{
			CSSStyleDeclaration.prototype.__defineGetter__(pixelName,function(){return parseInt(this[shortName])});
			CSSStyleDeclaration.prototype.__defineSetter__(pixelName,function(v){this[shortName]=v+"px";});
		}
		
		
		defineStyleProperties(["width","height","left","top"]);
		
		/*function Selection(doc)
		{		
		  this._doc = doc;
		}
		Selection.prototype.createRange = function(element)
		{
		  debugger;
		  var sel = window.getSelection();		  
		  var range = null;
		  if (sel.rangeCount==0)
		  {
		    if (element!=null)
		    {
 		      range = document.createRange();
 		      range.selectNodeContents(element);
 		      //range.setStart(element, 0);
 		      //var len = (element.nodeType==1 && element.tagName=="INPUT") ? element.value.length : element.innerText.length;
          //range.setEnd(element,0);
          //range.expand
		      sel.addRange(range);
		    }
		  }
		  else range = sel.getRangeAt(0);
		  var rng = new G2MozRange(range);
		  return rng;
		}
    function G2GetDocumentSelection()
		{
		  if (this._emulatedSelectionObject==null)
		    this._emulatedSelectionObject = new Selection(this);
		  return this._emulatedSelectionObject;
		}
		
		function G2MozRange(rng)
		{
		  this._range = rng;
		}
		function G2MozRange_GetText()
		{
		  return this._range.toString();
		}
		function G2MozRange_SetText(value)
		{
		  //this.commonAncestorContainer.innerText = value;
		  debugger;
		  var lastElement = this._range.endContainer;
		  if (lastElement==null)
		    debugger;
		  if (lastElement.nodeType==1)
		  {
		    if (lastElement.tagName=="INPUT")
		    {
		      lastElement.value += value;
		    }
		    else
		      lastElement.innerText += value;
		  }
		  else if (lastElement.nodeType==3)
		  {
		    lastElement.nodeValue += value;
		  }
		    
		}
		G2MozRange.prototype.__defineGetter__("text",G2MozRange_GetText);
		G2MozRange.prototype.__defineSetter__("text",G2MozRange_SetText);
		*/
		//Fix for firefox BACK
		window.addEventListener("pageshow",function(e){if(e.persisted) {window.location.href = window.location.href;}},false);
    
    HTMLDocument.prototype.__defineGetter__("parentWindow",G2MozGetParentWindow);
    //HTMLDocument.prototype.__defineGetter__("selection",G2GetDocumentSelection);
    HTMLElement.prototype.__defineGetter__("progid",G2GetProgId);
    HTMLElement.prototype.__defineGetter__("outerHTML",G2MozGetOuterHTML);
		HTMLElement.prototype.__defineSetter__("outerHTML",G2MozSetOuterHTML);
		HTMLElement.prototype.__defineGetter__("innerText",G2GetInnerText);
		HTMLElement.prototype.__defineSetter__("innerText",G2SetInnerText);
		HTMLElement.prototype.__defineGetter__("children",G2GetChildren);
		HTMLElement.prototype.__defineGetter__("document",G2GetDocument);
		HTMLElement.prototype.__defineGetter__("tagName",G2GetTagName);
		HTMLElement.prototype.__defineGetter__("parentElement",G2GetParent);
		HTMLElement.prototype.__defineGetter__("currentStyle",G2GetCurrentStyle);
		HTMLElement.prototype.__defineGetter__("uniqueID",G2GetElementUniqueID);
		HTMLIFrameElement.prototype.__defineGetter__("Document",G2GetContentDocument);
		Event.prototype.__defineGetter__("srcElement", G2GetEventSourceElement);
		
		
}
// returns true if the string 's' ends with the string 'endsWith'
String.EndsWith = function(s, endsWith)
{
	if(s==null)
		return endsWith==null;
	return s.substr(s.length-endsWith.length, endsWith.length)==endsWith;
}


//this function gets a control
//and disables/enables it and all its children recursively
SetControlDisability = function(control, disable)
{
	if(control == null)
		return;
	if (control.supportdisabledcss == "true")
	{
		control.disabled = disable;
		//we want the main css class to be standing alone
		//so when disabling, replace css class by disabled css class
		//when enabling if there are other classes, just remove disabled
		if (disable || control.className == control.disabledcssclass)
			G2_ReplaceCssClass(control, control.cssclass, control.disabledcssclass, disable);
		else
			G2_RemoveCssClass(control, control.disabledcssclass);
	}
	//we don't want to replace the initial css class but to add the disable css class
	else if (control.supportdefauldisabledtcss == "true") 
	{
		control.disabled = disable;
		if (disable)
			G2_AddCssClass(control, control.disabledcssclass);
		else
			G2_RemoveCssClass(control, control.disabledcssclass);
	}
	G2_VerifyControlInitialized(control);
	if(typeof(control.setEnabled)=="function")
		control.setEnabled(!disable);
	else
	{
		control.disabled = disable;
		SetControlChildrenDisability(control, disable);
	}
}

SetControlChildrenDisability = function(control, disable)
{
		if(control.children.length > 0)
		{
			var child = control.children[0];
			//lets be sure we are talking about html tag
			while(child != null)
			{
				if(child.nodeType == 1)
				{
					child.disabled = disable;
					SetControlDisability(child, disable);
				}
	
				child = child.nextSibling;
			}
		}
	}
	

/* 
Constants to determine browser type / version
*/
var isOpera = navigator.userAgent.indexOf('Opera') > -1;
var isIE = navigator.userAgent.indexOf('MSIE') > 1 && !isOpera;
var isMoz = navigator.userAgent.indexOf('Mozilla/5.') == 0 && !isOpera;
var isMac = (navigator.appVersion.indexOf("Mac")!=-1) ? true : false;
var NS4 = (document.layers) ? true : false;
var IE4plus = (document.all) ? true : false;
var IE4 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 4.")!=-1)) ? true : false;
var IE5 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 5.")!=-1)) ? true : false;
var IE6 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 6.")!=-1)) ? true : false;
var IE7 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 7.")!=-1)) ? true : false;
var ver4 = (NS4 || IE4plus) ? true : false;
var NS6 = (!document.layers) && (navigator.userAgent.indexOf('Netscape')!=-1);
var isGecko = /gecko/i.test(navigator.userAgent); //added by dan-el
var docTitle = null;

/* 
Constants that enables/disables specific G2Page features
*/
var ENABLE_PROFILER = false;
var ENABLE_CLIENT_VALIDATION = true;
var ENABLE_POSTDATA_ONDEMAND = true;
var ENABLE_FAKE_POSTBACKS = false;
var NOTIFY_SERVER_HISTORY_CHANGE = false;
var CALLBACK_TIMEOUT = 5000; // the maximum time we will wait for a postback to return from server
// to enable this add in G2Page.PreRender:	TryRegisterG2ClientScriptFile("dhtmlHistory.js");

/*
Global window vars
*/
timings = [];
G2UseSyncCallbacks = false;
G2PartialPostDataElementIds = new Object();
G2InputChangedObservers = new Array();
var mainAdminTabControl = null;
G2AdminInputChangedObservers = new Object();
G2_EvalCache = {};

// a safty net for multiple post back all in the dame time.
var waitForCallback = null;


/*
Static methods that allows declaring various JS structures
*/


/*
G2_DeclareFunctions
Desc:
Methods declared with this function can be profiled
Usage:
regex to find function ggg(a, b, c)
function {.*}\({.*}\)
\1 : function(\2)
*/
G2_DeclareFunctions = function(json)
{
	1;
	for(var memberName in json)
	{
		var member = json[memberName];
		if(typeof(member)=="function")
		{
			member.name = memberName;
			eval(memberName+"=member;");
			if(ENABLE_PROFILER)
				Profiler.profile(member);
		}
	}
}

/*
G2_DeclareUtilInstance
Desc:
Allows declaring a static like instance in JS. Examples are: G2PopupManager, G2FrameManager, G2DOM
*/
G2_DeclareUtilInstance = function(instance)
{
	for(var memberName in instance)
	{
		var member = instance[memberName];
		if(typeof(member)=="function")
		{
			member.name = memberName;
			if(ENABLE_PROFILER)
				Profiler.profileUtilInstanceFunction(instance, member);
		}
	}
}

ImportInto = function(target, source)
{
	for(var memberName in source)
	{
		var member = source[memberName];
		target[memberName] = member;
		if(typeof(member)=="function")
		{
			member.name = memberName;
		}
	}
	if(source.toString!=Object.prototype.toString)
	{
		var member = source.toString;
		if(typeof(member)=="function")
			member.name = "toString";
		target.toString = member;
	}
}

G2_DeclareClass = function(type, name, baseType, json)
{
	type.name = name;
	if(baseType!=null)
		ImportInto(type.prototype, baseType.prototype);
	ImportInto(type.prototype, json);
	if(ENABLE_PROFILER)
	{
		for(var p in json)
		{
			var func = json[p];
			if(typeof(func)=="function")
				Profiler.profileTypeFunction(type, json[p]);
		}
	}

}

if(ENABLE_PROFILER)
{
	var Profiler = 
	{
		_pFuncs: [],
		profileUtilInstanceFunction : function(instance, func)
		{
			var pFunc = this._createProfilerFunction(func);
			if(pFunc==null)
				return;//cannot profile function
			instance[func.name] = pFunc;
		},
		profileTypeFunction : function(type, func)
		{
			var pFunc = this._createProfilerFunction(func);
			if(pFunc==null)
				return;//cannot profile function
			type.prototype[func.name] = pFunc;
		},
		profile : function(func)
		{
			var pFunc = this._createProfilerFunction(func);
			eval(func.name+"=pFunc;");
		},
		_createProfilerFunction : function(func)
		{
			if(func.name==null)
				return; //cannot profile function without a name
			var pFunc = function()
			{
				var pCallee = arguments.callee;
				pCallee.totalCalls++;
				var startInvoke = new Date().getTime();
				var result = pCallee.realFunc.apply(this, arguments);
				var endInvoke = new Date().getTime();
				var timeInvoke = endInvoke-startInvoke;
				pCallee.totalWithChildren += timeInvoke;
				var pCaller = pCallee.caller;
				var x = 0;
				while(pCaller!=null && pCaller.totalOfChildren==undefined && pCaller!=pCallee && x<5)
				{
					pCaller = pCaller.caller;
					x++;
				}
				if(pCaller!=null && pCaller.totalOfChildren!=undefined && pCaller!=pCallee)
				{
					pCaller.totalOfChildren+=timeInvoke;
				}
				return result;
			}
			pFunc.realFunc = func;
			pFunc.totalWithoutChildren = 0;
			pFunc.totalOfChildren = 0;
			pFunc.totalWithChildren = 0;
			pFunc.totalCalls = 0;
//			pFunc.totalOfChildrenWithProfiler = 0; //
			pFunc.name = func.name;
			this._pFuncs.push(pFunc);
			return pFunc;
		},
		clearData : function()
		{
			for(var i=0;i<this._pFuncs.length;i++)
			{
				var pFunc = this._pFuncs[i];
				pFunc.totalWithoutChildren = 0;
				pFunc.totalOfChildren = 0;
				pFunc.totalWithChildren = 0;
				pFunc.totalCalls = 0;
			}
		},
		takeSnapshot : function(sortBy)
		{
			if(sortBy==null)
				sortBy="totalCalls";
			var desc = sortBy!="name" ? -1 : 1;
			var arr = [];
			for(var i=0;i<this._pFuncs.length;i++)
			{
				var pFunc = this._pFuncs[i];
				pFunc.totalWithoutChildren = pFunc.totalWithChildren-pFunc.totalOfChildren;
				if(pFunc.totalCalls>0)
					arr.push(pFunc);
			}
			var array = arr.sort(function(x, y)
			{
				var valueX = x[sortBy];
				var valueY = y[sortBy];
				if(valueX==null || valueY==null)
				{
					if(valueX==valueY)
						return 0;
					return valueX==null ? 1*desc : -1*desc;
				}
				if(typeof(valueX)=="string" && typeof(valueY)=="string")
					return valueX.localeCompare(valueY)*desc;
				return (valueX.valueOf()-valueY.valueOf())*desc;
			});
			return array;
		},
		createDebugDiv : function()
		{
			if(Profiler.debugWindow==null)
			{
				if(window.opener!=null && window.opener.Profiler.debugWindow!=null)
				{
					Profiler.debugWindow = window.opener.Profiler.debugWindow;
				}
				else
				{
					var debugWindow = window.open(G2_MapPath('~/Client/Scripts/profiler.htm'), "debugWindow");
					Profiler.debugWindow = debugWindow;
				}
//				Profiler.debugWindow.registerWindow(window);
			}
		}
	}
	
}

/* 
Language extenstions
*/

String.prototype.endsWith = function String$endsWith(suffix) 
{
	return (this.substr(this.length - suffix.length) === suffix);
}

String.prototype.startsWith = function String$startsWith(prefix) 
{
  return (this.substr(0, prefix.length) === prefix);
}
String.prototype.contains = function(s)
{
	return this.indexOf(s)!=-1;
}


/* 
ASP.NET JS overrides
*/

if(typeof(WebForm_DoCallback)=="function")
{
	AspNet_WebForm_DoCallback = WebForm_DoCallback;
	AspNet_WebForm_CallbackComplete_Sync = WebForm_CallbackComplete;
}
window.net__doPostBack = window.__doPostBack;

window.__doPostBack = function(eventTarget, eventArgument,forcesilent) 
{
	// check lock to prevent multuple postbacks all in the same time
	if(waitForCallback)
	{
		// if we pass the the timeout value go on
		if(new Date() - waitForCallback <= CALLBACK_TIMEOUT)
		{
			// try again in 0.5 seconds
			window.setTimeout(function () { __doPostBack(eventTarget, eventArgument, forcesilent); }, 500);
			return;
		}
	}
	// lock this code
	waitForCallback = new Date();

  if (theForm==null || theForm.__EVENTTARGET == null) //This is sometimes caused when posting back from a popup that's closed.
		return;

	if (forcesilent == null)
		forcesilent = false;
	//Validation
	var targetEl = null;
	if(typeof(eventTarget)=="object")
	{
		targetEl = eventTarget;
		eventTarget = eventTarget.id;//String.Replace(eventTarget.id, "_", "$");
	}
	else
	{
		targetEl = G2_GetEventTargetElement(eventTarget);
	}
  if(targetEl!=null)
  {
		// 'CancelPostBackOnDisabled' attribute was added for canceling post back in case of disabled linkButton.
		// Any one can add this attribute in order to cancel postBack if the control is disabled.
		if (targetEl.cancelPostBackOnDisabled && targetEl.isDisabled)
			return;
			
		if (document.isPostingFromAClosedPopup) //Handle 'error 84' in IE when trying to postback from a closed popup.
			return;
    if(ENABLE_CLIENT_VALIDATION && (G2DOM.G2GetAttribute(targetEl,"causesvalidation")=="true" || (window.validateAll == "true" && G2DOM.G2GetAttribute(targetEl,"ignorevalidation") != "true"))) 
    {
      if(typeof(G2Validation_PerformValidation)=="function" && G2Validation_PerformValidation(targetEl)==false) 
        return;
      if(targetEl.onvalidatedclientclick!=null)
      {
     		var func = new Function(targetEl.onvalidatedclientclick);
				var res = func.call(targetEl);
				if (res == false)
					return;
      }
      if(targetEl.onbeforepostback!=null)
        window[targetEl.onbeforepostback](eventTarget, eventArgument);
    }
  }
  else
  {
    Debug.writeln("Could not find element " + eventTarget);
  }
  
 	if (theForm.onsubmit && (theForm.onsubmit() == false))
    return false;

  //Disable tooltips during silent postbacks.
  G2PopupManager.disableTooltips();
  //Display the processing image
  if (targetEl != null)
  {
    if (G2DOM.G2GetAttribute(targetEl,"showprocessingimage")=="true")
    {
      ShowProcessingImage(targetEl);
    }
    if (G2DOM.G2GetAttribute(targetEl,"showdisabler")=="true")
    {
      G2_ShowDisabler(true); 
    }
  }
  else
  {
    Debug.writeln("Could not find element " + eventTarget);
  }
  
  if(window.OnBeforePostbackClientFunction!=null)
  {
     window[window.OnBeforePostbackClientFunction]({eventTarget:eventTarget, eventArgument:eventArgument});
  }
  var doClassicPostBack = !G2IsSilent(eventTarget, eventArgument, targetEl) && !forcesilent;
  if(doClassicPostBack && !ENABLE_FAKE_POSTBACKS)
  {
 		for(var id in G2PartialPostDataElementIds)
		{
		  var element = G2PartialPostDataElementIds[id];
		  if(element==null || element.parentElement==null)
		  {
			  element = document.getElementById(id);
			}
			//isValueDirty might not be declared because it might've been updated dynamically, and lazy initialized.
			if(element!=null && typeof(element.isValueDirty)=="function" && !element.isValueDirty())
			{
				element.disabled = true;
			}
		}
 		for(var id in G2_PreventPostElementIds)
		{
			var element = document.getElementById(id);
			if(element!=null)
				element.disabled = true;
		}
		//we do not use the real __doPostback because it checks onsubmit again.
		theForm.__EVENTTARGET.value = eventTarget;
		theForm.__EVENTARGUMENT.value = eventArgument
		theForm.submit();

//		window.net__doPostBack(eventTarget, eventArgument);
		return;
  }
	var arg;
	if(ENABLE_FAKE_POSTBACKS && doClassicPostBack)
	{
		arg = "FakePostBack";
	}
	else
		arg = "SilentPostBack";
//		
  theForm.__EVENTTARGET.value = eventTarget;
  theForm.__EVENTARGUMENT.value = eventArgument;
	var arg = arg+"|" + eventTarget + "|" + eventArgument;
	G2_DoCallback('__Page', arg ,G2CallbackManager_HandleResult,{eventTarget:eventTarget,eventArgument:eventArgument},G2_OnCallbackError,false, false);
}

function WebForm_FireDefaultButton(event, target)
{
    if (event.keyCode == 13 && !(event.srcElement && (event.srcElement.tagName.toLowerCase() == "textarea"))) 
    {
			var defaultButton;
			if (__nonMSDOMBrowser) 
			{
				defaultButton = document.getElementById(target);
			}
    else 
    {
      defaultButton = document.all[target];
    }
    if (defaultButton && typeof(defaultButton.click) != "undefined") 
    {
			//added by dan-el - causes any other focused element to blur and fire the onchange event, #7457
			try
			{
				defaultButton.focus(); 
			}
			catch(err)
			{
				event.srcElement.blur();
			}
			defaultButton.click();
      event.cancelBubble = true;
      if (event.stopPropagation) 
				event.stopPropagation();
      return false;
    }
  }
  return true;
}
G2_onHistoryChange = function(newLocation, historyData)
{
	__doPostBack("__Page", "HistoryChange|"+newLocation, true);
}

/* 
G2 General Library Util Instance
*/

G2 = 
{
	AppendQueryString : function(url, qs)
	{
		if(url.search(/\?/)!=-1)
			return url+"&"+qs;
		return url+"?"+qs;
	},
	ArgumentsFrom : function(args, index)
	{
		var arr = [];
		for(var i=index;i<args.length;i++)
		{
			arr.push(args[i] || null);
		}
		return arr;
	},
	GetRelativeMouseX : function(e, relativeElement)
	{
		return e.clientX-G2_GetX(relativeElement)+relativeElement.scrollLeft;
	},
	GetRelativeMouseY : function(e, relativeElement)
	{
		return e.clientY-G2_GetY(relativeElement)+relativeElement.scrollTop;
	},
	Delegates : {},
	GetDelegate : function(target, func)
	{
		if(target==null)
			return func;
		if(typeof(func)=="string")
			func = target[func];
		var key = this.GetHashKey(func)+"$$"+this.GetHashKey(target);
		var delegate = this.Delegates[key];
		if(delegate==null)
		{
			delegate = function()
			{
				return arguments.callee.func.apply(arguments.callee.target, arguments);
			};
			delegate.func = func;
			delegate.target = target;
			delegate.isDelegate = true;
			this.Delegates[key] = delegate;
		}
		return delegate;
	},

	_hashIndex : 1,
	GetHashKey : function(obj)
	{
		if(obj===undefined)
			return "undefined";
		if(obj===null)
			return "null";
		var typeOf = typeof(obj);
		if(typeOf=="object" || typeOf=="function")
		{
			if(obj._hashKey==null)
			{
				obj._hashKey = typeOf+"$"+this._hashIndex;
				this._hashIndex++;
			}
			return obj._hashKey;
		}
		return obj.valueOf().toString();
	},
	historyIndex : 0,
	// check if any control was registered due to a change.
	ChangesWasMadeToControls : function()
	{
		if (this.changedInputs)
		{
			var i=0;
			for (var j in this.changedInputs)
				i++;
			if (i == 0)
				return false;
		}		
		return true
	},

	notifyInputPropertyChanged : function(e)
	{
	1;//value for textboxes, checked for checkboxes, selectedIndex for combos
		if(e.propertyName=="value" || e.propertyName=="checked" || e.propertyName=="selectedIndex") //checked is for checkbox and radiobutton
			this.notifyInputChanged(e.srcElement);
	},
	changedInputs : new Object(),
	notifyInputChangedFF_Watch : function(inputId, oldVal, newVal)
	{
		G2.notifyInputChanged(this);
		return newVal;
	},
	notifyInputChangedFF_Event : function(evnt)
	{
		G2.notifyInputChanged(evnt.target);
	},
	RegisterPropertyChangeWatch : function(elementID)
	{
		if (isMoz)
		{
			var e = document.getElementById(elementID);
			e.watch("value",this.notifyInputChangedFF_Watch	);
			e.watch("checked",this.notifyInputChangedFF_Watch);
			e.watch("selectedIndex",this.notifyInputChangedFF_Watch);
			e.addEventListener("change",this.notifyInputChangedFF_Event,false);
		}
	},	
	RegisterPropertyChangeWatchWithHandler : function(elementID,handler)
	{
		if (isMoz)
		{
			var e = document.getElementById(elementID);
			var watchHandler = function(){handler(this);};
			e.watch("value",watchHandler);
			e.watch("checked",watchHandler);
			e.watch("selectedIndex",watchHandler);
			var eventHandler = function(evnt){handler(evnt.target);};
			e.addEventListener("change",eventHandler,false);
		}
	},	
	notifyInputChanged : function(input)
	{
	   if(input.isInitializing)
	    return;
		this.changedInputs[input.id] = input;
		if(input.notifyobserver == null || input.notifyobserver == "true")		
			this.fireNotifyInputChangedEvent();
	},
	undoNotifyInputChanged : function(input)
	{
		if(this.changedInputs[input.id] != null)
		{
			delete this.changedInputs[input.id];
		}
	},	
	notifyCheckBoxPropertyChange : function(e)
	{
		if(e.propertyName=="value" || e.propertyName=="checked")
		{
			var checkbox = e.srcElement;
			this.notifyInputChanged(checkbox);
			if(typeof(checkbox.g2PerformUndo)=="undefined")
			{
				checkbox.originalValue = !checkbox.checked; //the value before the click
				checkbox.g2PerformUndo = G2.CheckBox_PerformUndo;
				checkbox.g2SetOriginalValue = G2.CheckBox_SetOriginalValue;
				checkbox.g2IsDirty = G2.CheckBox_IsDirty;
			}
		}
	},
	notifyCheckBoxClicked : function(checkbox)
	{
		this.notifyInputChanged(checkbox);
		if(typeof(checkbox.g2PerformUndo)=="undefined")
		{
			checkbox.originalValue = !checkbox.checked; //the value before the click
			checkbox.g2PerformUndo = G2.CheckBox_PerformUndo;
			checkbox.g2SetOriginalValue = G2.CheckBox_SetOriginalValue;
			checkbox.g2IsDirty = G2.CheckBox_IsDirty;
		}
	},
	CheckBox_PerformUndo : function(checkbox)
	{
		checkbox = checkbox || this;
		checkbox.checked = checkbox.originalValue;
	},
	CheckBox_SetOriginalValue : function(checkbox)
	{
		checkbox = checkbox || this;
		checkbox.originalValue = checkbox.checked;
	},
	CheckBox_IsDirty : function(checkbox)
	{
		checkbox = checkbox || this;
		return checkbox.checked != checkbox.originalValue;
	},
	getAdminToolsActiveTabId : function ()
	{
		if (mainAdminTabControl == null)
			mainAdminTabControl = $('adminTabControlDiv').firstChild;
		if (mainAdminTabControl.ActiveTab) //already initialized
			return mainAdminTabControl.ActiveTab.id;
		else //not yet initialized
			return mainAdminTabControl.activetabid;
	},
	getAdminToolsObserversInTab : function(tabId)
	{
		if (typeof(tabId) == 'undefined')
			tabId = this.getAdminToolsActiveTabId();
		if (typeof (G2AdminInputChangedObservers[tabId]) == 'undefined')
			G2AdminInputChangedObservers[tabId] = new Object();
		return G2AdminInputChangedObservers[tabId]; 
	},
	attachObserver : function (id, tabId)
	{		
		var observers = this.getAdminToolsObserversInTab(tabId);
		if (observers[id] == true) //Change by Adi Eduard
		  return;
		observers[id] = false; 
	},
	detachObserver : function (id, tabId)
	{		
		var observers = this.getAdminToolsObserversInTab(tabId);
		delete observers[id];
	},
	fireNotifyInputChangedEvent : function (tabId)
	{
	  if (window.IsAdminToolsMainPage != true) //this feature works only in the admin tools
			return; 
		var observers = this.getAdminToolsObserversInTab(tabId);
		for(var obs in observers)
		{
			observers[obs] = true;
		}
	},
	setObjectChanged : function (id, tabId)
	{
		var observers = this.getAdminToolsObserversInTab(tabId);
		observers[id] = true;
	},
	setObjectUnchanged : function (id, tabId)
	{
		var observers = this.getAdminToolsObserversInTab(tabId);
		(observers[id] != null)
			observers[id] = false;
	},
	IsObjectChanged : function (id, tabId)
	{
			var observers = this.getAdminToolsObserversInTab(tabId);
			return observers[id] == true;
	},
	AreThereAnyChanges : function ()
	{
		var allObservers = G2AdminInputChangedObservers;
		for (var tab in allObservers)
		{
			tabObservers = allObservers[tab];
			for (var obsId in tabObservers)
			{
				if (tabObservers[obsId] == true)
					return true;
			}
		}
		return false;
	}
	
};
G2_DeclareUtilInstance(G2);

G2_DeclareFunctions(
{
	G2InitParentControl : function(sender, e)
	{
		if(sender.g2HasInitedParentControl)
			return;
		sender.g2HasInitedParentControl = true;
		var control = sender;
		var controlType;
		while(control!=null)
		{
			controlType = G2DOM.G2GetAttribute(control, "g2control")
			if(controlType!=null)
				break;
			control = control.parentElement;
		}
		if(control.g2IsInited)
			return;
		if(control.isDisabled)
			return;
		window[controlType+"_Init"](control, e);
		if(!control.g2IsInited)
			control.g2IsInited = true;
	},
	G2_VerifyControlInitialized : function(control, e)
	{
		if(control.g2IsInited)
			return;
		var controlType = G2DOM.G2GetAttribute(control, "g2control");
		if(controlType==null)
			return;
		window[controlType+"_Init"](control, e);
		if(!control.g2IsInited)
			control.g2IsInited = true;
	},

	G2_DoCallback : function(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync, classicPostback)
	{
	  G2_OnBeforeCallback();
	  WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync, classicPostback);
	},
	G2_OnBeforeCallback : function()
	{
		document.body.style.cursor="wait";
	},

	G2_OnCallbackError : function(result, context)
	{
		var err = "Callback Error: "+result;
		alert(err);
		
		G2_OnCallbackFinally(result, context);
	},

	G2_OnCallbackFinally : function(result, context)
	{
 		document.body.style.cursor = "";
 		//Close and reebable tooltips (disabled during silent postbacks)
 		G2PopupManager.enableTooltips();
 		G2PopupManager.closeAllTooltips();
	},
	//taken from aspnet scripts - performed MAJOR optimizations (removed the foreach loop)
	G2_InitCallback : function() 
	{
 		var context = {postData:new Array(), postCollection:new Array()};
		G2_InitCallbackRecursive(context);
		return context;
//		__theFormPostData =context.postData.join("");
//		__theFormPostCollection = context.postCollection;
	},


	G2CallbackManager_HandleResult : function(result, aspNetContext)
	{
		// unlock dopostback
		waitForCallback = null;
		
		var r = result.split("%||%");
		var context = {resultArray:r, aspNetContext:aspNetContext};
//		//moved to start by dan-el  
//		var viewState = r[4];
//		G2CallbackManager_UpdateViewState(viewState);
		//Handle hidden fields


		var scriptIncludes = r[1].split("||||");
		var srcArray = new Array();
		for(var i=0; i<scriptIncludes.length; i++)
		{
			var src = scriptIncludes[i];
			if(src==null || src=="")
				continue;
			srcArray.push(src);
		}
		G2_RegisterScripts(srcArray, function(){G2_HandleCallbackResultPhase2(result, context);});
		
		
		
	},

	
	G2_HandleCallbackResult_UpdateDomElements : function(htmlData)
	{
		for(var i=0; i<htmlData.length; i++)
		{
			if(htmlData[i]=="" || htmlData[i]==null)
				break;
			var element=document.getElementById(htmlData[i]);
			i++;
			var newHtml = htmlData[i];
			if (element != null)
			{
				var controlElement = element;
				if(element.getcontrolelement!=null)
				{
					controlElement = G2_Eval(element.getcontrolelement, element);
					if(controlElement==null)
					{
						G2_Warn("G2_HandleCallbackResult_UpdateDomElements", "controlElement wasn't found for element "+element.id);
						continue;
					}
				}
				G2DOM.G2ReplaceOuterHTML(controlElement,newHtml);
			}
		}
	},
	
	G2_Eval : function(code, target)
	{
		var cache = G2_EvalCache;
		var func = cache[code];
		if(func==null)
		{
			func = new Function(code);
			cache[code] = func;
		}
		return func.call(target);
	},
	StartTiming : function()
	{
		timings.push(new Date().getTime());
	},
	EndTiming : function(name)
	{
		name = name || arguments.callee.caller.name;
		var end = new Date().getTime();
		var start = timings.pop();
		var span= end-start;
//		if(span>500)
//			alert(name+" took "+span+"ms!");
	},
	
	G2_HandleCallbackResult_AddRepeaterElement: function(htmlData)
	{
		for(var i=0; i<htmlData.length; i++)
		{
			if(htmlData[i]=="" || htmlData[i]==null)
				break;
			var element=document.getElementById(htmlData[i]);
			i++;
			if(element != null)
			{
				var tbody = element.firstChild.tBodies[0];
				var newElement = G2DOM.G2CreateElementFromHtml(htmlData[i]);
				tbody.appendChild(newElement);
			}
		}		
	},
	
	G2_HandleCallbackResult_RemoveElement: function(itemsToRemove)
	{
		for(var i=0; i<itemsToRemove.length; i++)
		{
			if(itemsToRemove[i]=="" || itemsToRemove[i]==null)
				break;
			var element = document.getElementById(itemsToRemove[i]);			
			if(element != null)
			{
				element.removeNode(true)				
			}
		}		
	},
	
	G2_HandleCallbackResult_UpdateHiddenFields : function(hfHtml)
	{
		var div=document.createElement("DIV");
		div.innerHTML = hfHtml;
		var divChildren = div.children;
		var addElements = new Array();
		for(var i=0;i<divChildren.length; i++)
		{
			var hf = divChildren[i];
			var curHf = document.getElementById(hf.id);
			if(curHf!=null)
				curHf.value = hf.value;
			else
				addElements.push(hf); //we don't appendChild now because the length will change.
		}
		for(var i=0;i<addElements.length;i++)
		{
			document.forms[0].appendChild(addElements[i]);
		}
	},
	G2_HandleCallbackResult_UpdateActiveElement : function(activeElementID, prevActiveElement)
	{
		var el = document.getElementById(activeElementID);
		if(el!=null && el.tagName!="A" && prevActiveElement!=el)
		{
			var f = function()
			{	
				//the following line handles focusing an element that was replaced during a callback
				if(el.parentElement==null) //Element is detached from the dom
					el = document.getElementById(el.id);//Find the new element in the dom
				try
				{
				  el.isFocusingAfterPostback = true;//Indicate to the element that this is autofocus 
					el.focus(); //This may fail if the control is hidden etc.
				} 
				catch(e)
				{
				}
			}
			window.setTimeout(f, 50);
		}
	},
	G2_HandleCallbackResult_EvalStartupStatements : function(scriptData)
	{
		StartTiming();
		eval(scriptData);
		EndTiming();
	},
	G2_ReplaceCssClass : function(element, addCss, removeCss, inverse)
	{
		if(inverse)
		{
			var temp = removeCss;
			removeCss = addCss;
			addCss = temp;
		}
		var classes = G2_ParseCssClasses(element);
		classes.remove(removeCss);
		classes.add(addCss);
		G2_SetCssClasses(element, classes);

  },
	G2_RemoveCssClass : function(element, className)
	{
		var index = G2_FindWholeWord(element.className, className);
		if(index!=-1)
		{
			var begin = element.className.substr(0, index-1);
			var end = element.className.substr(index+className.length+1);
			if(begin!="" && end!="")
				element.className = begin+" "+end;
			else
				element.className = begin+end;
		}
  },
	G2_ParseCssClasses : function(element)
	{
		var list = element.className.split(/ /g);
		var obj = new ListSet();
		if(list.length==1 && list[0]=="")
		{
		}
		else
		{
			obj.addRange(list);
		}
		return obj;
  },
	G2_SetCssClasses : function(element, listset)
	{
		element.className = listset.toString(" ");
  },

	G2_AddCssClass : function(element, className)
	{
    if (!G2_ContainsCssClass(element, className)) 
    {
      if (element.className === '') 
      {
        element.className = className;
      }
      else 
      {
        element.className += ' ' + className;
      }
    }
  },
	G2_ContainsCssClass : function(element, className)
	{
		return G2_FindWholeWord(element.className, className)!=-1;
	},
	G2_FindWholeWord : function(text, word, seperator)
	{
		if(seperator==null)
			seperator = " ";
		if(word==null || word=="" || word.indexOf(seperator)!=-1)
			throw new Error("error in word: "+word);
		if(text=="")
			return -1;
		var x = 0;
		for(var i=0;i<text.length;i++)
		{
			if(text.charAt(i)==seperator)
			{
				if(x==word.length)
					return i-x;
				x=0;
			}
			else if(text.charAt(i)==word.charAt(x))
				x++;
			else
				x=0;
		}
		if(x==word.length)
			return i-x;
		return -1;
  },

	G2_HandleCallbackResultPhase2 : function(result, context)
	{	
		var resultArray = context.resultArray;

		//Handle html repeater data
		var htmlRepeaterData = resultArray[5].split("||||");
		G2_HandleCallbackResult_AddRepeaterElement(htmlRepeaterData);
				
		//Handle removing items
		var itemsToRemove = resultArray[6].split("||||");
		G2_HandleCallbackResult_RemoveElement(itemsToRemove);
		
		//Handle html data
		var htmlData = resultArray[0].split("||||");
		var activeElementID = null;
		var activeElement = document.activeElement;
		if(activeElement && !String.IsNullOrEmpty(activeElement.id))
		{
			activeElementID = activeElement.id;
		}
		G2_HandleCallbackResult_UpdateDomElements(htmlData);				
		
		//aspnet holds a strong reference to the form element, (in a variable named theForm)
		//which might be updated dynamically, so we update that reference
		if(theForm.parentElement==null) 
			theForm = document.forms[0];
		var hfHtml = resultArray[2];
		if(hfHtml!=null && hfHtml!="")
		{
			G2_HandleCallbackResult_UpdateHiddenFields(hfHtml);
		}

		if(activeElementID!=null)
		{
			G2_HandleCallbackResult_UpdateActiveElement(activeElementID, activeElement);
		}
			
		//Handle scripts
		var scriptData = resultArray[3];
		if(scriptData!=null && scriptData!="")
		{
			G2_HandleCallbackResult_EvalStartupStatements(scriptData);
		}
		
 	  //Handle the processing image - AFTER the startup statements (since we might navigate, and in that case we don't want to hide the image)
		HideProcessingImage();
		
		G2_ShowDisabler(false);
		
		//Handle last scripts
		var lastScriptData = resultArray[4];
		if(lastScriptData!=null && lastScriptData!="")
		{
			window.setTimeout(function(){	G2_HandleCallbackResult_EvalStartupStatements(lastScriptData); }, 10);
		}
		
		if(window.OnAfterCallbackClientFunction!=null)
		{
			window[window.OnAfterCallbackClientFunction]();
		}
		
		
		if(NOTIFY_SERVER_HISTORY_CHANGE)
		{
			if(context.aspNetContext.eventTarget=="__Page" && context.aspNetContext.eventArgument.startsWith("HistoryChange"))
			{
			}
			else
			{
				G2.historyIndex++;
				dhtmlHistory.add(G2.historyIndex.toString(), "Hello World " + "Data")
			}
		}
		G2_OnCallbackFinally(result, context);

		//event validation - doesn't work
	//  var eventValidationFieldValue = r[3];
	//  var eventValidationField = document.getElementById("__EVENTVALIDATION");
	//  eventValidationField.value = eventValidationFieldValue;
	},



	G2CallbackManager_UpdateViewState : function(viewState)
	{
		var div = document.createElement("div");
		div.innerHTML = viewState;
		document.getElementById("__VIEWSTATE").value =div.firstChild.value;
	},


	G2_InitCallbackAddField : function(name, value, context) 
	{
	//	WebForm_InitCallbackAddField(name, value);
//			var nameValue = new Object();
//			nameValue.name = name;
//			nameValue.value = value;
//			context.postCollection.push(nameValue);
			context.postData.push(name);
			context.postData.push("=");
			context.postData.push(WebForm_EncodeCallback(value));
			context.postData.push("&");
	},

	EnableSupportForPartialPostData : function(element)
	{
		element.isValueDirty = EnableSupportForPartialPostData_IsValueDirty;
		element.setValueAsNotDirty = EnableSupportForPartialPostData_SetValueAsNotDirty;
		element._originalValue = element.value;
		G2PartialPostDataElementIds[element.id] = element;
		if(ENABLE_POSTDATA_ONDEMAND)
		{
			if (isIE)
			{
				if((element.tagName=="INPUT" && element.type=="text") || element.tagName=="SELECT" || element.tagName=="TEXTAREA")
				{
					G2_AttachEvent(element, "onchange", function()
					{
						G2.notifyInputChanged(this);
					});
				}
				else
				{
					G2_AttachEvent(element, "onpropertychange", function()
					{
						if(event.propertyName=="value")
							G2.notifyInputChanged(this);
					});
				}
			} 
			else if (isMoz)
			{
				G2.RegisterPropertyChangeWatch(element.id);
			}
		}
	},
	
	EnableSupportForPartialPostData_SetValueAsNotDirty : function()
	{
		this._originalValue = this.value;
	},
	
	EnableSupportForPartialPostData_IsValueDirty : function()
	{
		return !(this.value===this._originalValue);
	},
	G2_InitCallbackByIds : function(ids, context)
	{
		for(var i=0;i<ids.length;i++)
		{
			var element = $(ids[i]);
			if(element!=null)
			{
				G2_InitCallbackForElement(element, context);
			}
			else if(ids[i]=="__WINDOWID" && window.location.href.search("WindowID")==-1)
			{
				throw new Error("window id not found");
			}
		}
	},

	G2_InitCallbackRecursive : function(context)
	{
		if(ENABLE_POSTDATA_ONDEMAND)
		{
			G2_InitCallbackAddField("__PARTIALPOSTDATA", "true", context);
			G2_InitCallbackByIds(["__EVENTTARGET", "__EVENTARGUMENT",  "__EVENTVALIDATION", "__VIEWSTATE", "__WINDOWID"], context);
			var inputsToRemove = new Object();
			for(var id in G2.changedInputs)
			{
				var element = $(id)
				if (element) //the element may be detached from the DOM
				{
					G2_InitCallbackForElement(element, context);
					inputsToRemove[id] = id;
				}
			}
			for (var id in inputsToRemove)//remove sent inputs
			{
				delete G2.changedInputs[id];
			}
		}
		else
			G2_PerformRecursiveActionOnElement(theForm, G2_InitCallbackForElement, context);
	},

	G2_InitCallbackForElement : function(element, context)
	{
		if(element.doesNotContainInputs)
			return false;
		if(G2_PreventPostElementIds[element.id]==true)
			return false;
		var tagName = element.tagName.toLowerCase();
		if (tagName == "input") 
		{
			var type = element.type;
			if ((type == "text" || type == "hidden" || type == "password" ||
					((type == "checkbox" || type == "radio"))) && // && element.checked
					(element.id != "__EVENTVALIDATION")) 
			{
				var name = element.name;
				var value = element.value;
				if(type == "checkbox")
				{
					if(ENABLE_POSTDATA_ONDEMAND)
					{
						value = element.checked ? "on" : "off";
					}
					else if(!element.checked)
						return false;
				}
				else if(type == "radio")
				{
					if(ENABLE_POSTDATA_ONDEMAND)
					{
						if(type == "radio" && element.g2rb=="true")
						{
							name = element.id;
						  value = element.checked ? "on" : "off";
						}
						else
					  {
					    G2_InitCallbackAddField(name, value, context);
					    return false;
					  }
					}
					else if(!element.checked)
						return false;
				}

				if(typeof(element.isValueDirty)=="function")
				{
					if(element.isValueDirty())
					{
						element.setValueAsNotDirty();
					}
					else
						return false;
				}
				G2_InitCallbackAddField(name, value, context);
				return false;
			}
		}
		else if (tagName == "select") 
		{
			var selectCount = element.options.length;
			var selCount = 0;
			for (var j = 0; j < selectCount; j++) 
			{
				var selectChild = element.options[j];
				if (selectChild.selected == true) 
				{
					selCount++;
					G2_InitCallbackAddField(element.name, selectChild.value, context);
					if(!element.multiple)
						return false;
				}
			}
			//We send null value to the ListBox
			if(selCount==0 && element.multiple)
				G2_InitCallbackAddField(element.name, "__NULL__", context);
		}
		else if (tagName == "textarea") 
		{
			G2_InitCallbackAddField(element.name, element.value, context);
			return false;
		}
		return true;
	},





	G2_GetEventTargetID : function(eventTarget) 
	{
		var realId;
		if(eventTarget.indexOf("$")>-1)
			realId = eventTarget.replace(/\$/g, '_');
		else if(eventTarget.indexOf(":")>-1)
			realId = eventTarget.replace(/:/g, '_');
		else
			realId = eventTarget;
		return realId; 
	},

	G2_GetEventTargetElement : function(eventTarget)
	{
		var el = $(eventTarget);
		if(el==null)
		{
			if(eventTarget.indexOf("$")>-1)
				eventTarget = eventTarget.replace(/\$/g, '_');
			else if(eventTarget.indexOf(":")>-1)
				eventTarget = eventTarget.replace(/:/g, '_');
			else
				return null;
			el = $(eventTarget);
		}
		return el;
	},


	G2_RefreshElement : function(element)
	{
		element.outerHTML = element.outerHTML;
	},

	G2IsSilent : function(eventTarget, eventArgument, eventTargetElement) 
	{
		if(window.silentPostbacks==true)
			return true;
		if (window.DisableSilentPostBack==true)
			return false;
		if(eventTargetElement!=null && eventTargetElement.getAttribute("silentpostback")=="true")
			return true;
		return false;
		var targets = window.silentPostbacksTargets;
		if(targets==null)
			return false;
		var val = targets[eventTarget];
		//TODO: find what causes this
		if(val==null && eventTarget.indexOf("$")>-1)
		{
			eventTarget = eventTarget.replace(/\$/g, '_');
			val = targets[eventTarget];
		}
		if(val==null && eventTarget.indexOf(":")>-1)
		{
			eventTarget = eventTarget.replace(/:/g, '_');
			val = targets[eventTarget];
		}
		if(val==null)
			return false;
		if(!String.IsNullOrEmpty(eventArgument) && val.args!=null)
		{
			var childValue = val.args[eventArgument];
			if(childValue!=null)
				return childValue;
		}
		return val.silent;
	},

	G2SetSilentPostBacks : function(json) 
	{
		if(window.silentPostbacksTargets==null)
		{
			window.silentPostbacksTargets = json;
		}
		else
		{
			for(var p in json)
			{
				window.silentPostbacksTargets[p] = json[p];
			}
		}
	},


	G2SetSilentPostBacksAll : function(isSilent)
	{
		window.silentPostbacks = isSilent;
	},

	//*****************************************************************
	//*                      G2ScriptManager                          *
	//*****************************************************************
	G2_GetRegisteredScripts : function()
	{
		if(_registeredScripts==null)
		{
			var elements = document.getElementsByTagName("script");
			_registeredScripts = new Object();
			for(var i=0;i<elements.length;i++)
			{
				var element = elements[i];
				if(element.src!="")
					_registeredScripts[element.src] = true;
			}
		}
		return _registeredScripts;
	},

	G2_IsScriptRegistered : function(src)
	{
		return G2_GetRegisteredScripts()[src]==true;
	},

	G2_GetUnregisteredScripts : function(srcArray)
	{
		if(srcArray==null)
			return null;
		var sources = new Array();
		for(var i=0;i<srcArray.length;i++)
		{
			var src = srcArray[i];
			if(!G2_IsScriptRegistered(src))
			{
				sources.push(src);
			}
		}
		return sources;
	},
	//
	// Gets an array of src strings, and loads these scripts. returns a callback when all scripts are loaded
	//
	G2_RegisterScripts : function(srcArray, loadCompletedCallback)
	{
		var sources = G2_GetUnregisteredScripts(srcArray);
		if(sources!=null && sources.length>0)
		{
			var context = {total:sources.length, loadCompletedCallback:loadCompletedCallback, sources:sources};
			for(var i=0;i<sources.length;i++)
			{
				var src = sources[i];
//				didNothing = false;
				var element = document.createElement("SCRIPT");
				element.src = src;
				element.setAttribute("type","text/javascript"); //Check if really needed
				document.body.appendChild(element); //TODO: this is a problem - the included file takes time to load 
				
				if(loadCompletedCallback!=null)
				{
					G2_AttachEvent(element, isIE ? "onreadystatechange" : "onload", function(e){G2_WaitForScripts(e ? e : event,context);}	);
				}
			}
		}
		else if(loadCompletedCallback!=null)
		{
			loadCompletedCallback();
		}
	},
	//*****************************************************************
	//*               End of G2ScriptManager                          *
	//*****************************************************************

	G2_WaitForScripts : function(event,context)
	{
		var element = G2Event.element(event);
		if(element.readyState=="loaded" || element.readyState=="complete" || isMoz)
		{
			context.total--;
			//clean up
			G2_DetachEvent(element, isIE ? "onreadystatechange" : "onload", G2_WaitForScripts);
			//end 
			_registeredScripts[element.src] = true;
			if(context.total==0)
			{
				context.loadCompletedCallback();
			}
		}
	},
	
	G2_CreateXmlHttp : function()
	{
		var xmlRequest,e;
		try 
		{
			xmlRequest = new XMLHttpRequest();
		}
		catch(e) 
		{
			try 
			{
				xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e) {
			}
		}
		var setRequestHeaderMethodExists = true;
		try 
		{
			setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);
		}
		catch(e) {}
		if(!setRequestHeaderMethodExists)
			return null;
		return xmlRequest;
	},

	WebForm_DoCallback : function (eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync, classicPostback, g2context) 
	{
		if(g2context==null) //this may happen when calling DoCallback directly (when using ClientScript.GetCallbackReference
		{
			g2context = G2_InitCallback();
		}

		g2context.postData.push("__CALLBACKID=");
		g2context.postData.push(WebForm_EncodeCallback(eventTarget));
		g2context.postData.push("&__CALLBACKPARAM=");
		g2context.postData.push(WebForm_EncodeCallback(eventArgument));
		if (theForm["__EVENTVALIDATION"]) 
		{
			g2context.postData.push("&__EVENTVALIDATION=");
			g2context.postData.push(WebForm_EncodeCallback(theForm["__EVENTVALIDATION"].value));
		}
		var postData = g2context.postData.join("");
		var xmlRequest = G2_CreateXmlHttp();
		
		var callback = new Object();
		callback.eventCallback = eventCallback;
		callback.context = context;
		callback.errorCallback = errorCallback;
		callback.async = useAsync;
		var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);
		if (!useAsync) 
		{
				if (__synchronousCallBackIndex != -1) {
						__pendingCallbacks[__synchronousCallBackIndex] = null;
				}
				__synchronousCallBackIndex = callbackIndex;
		}
		if (xmlRequest!=null) 
		{
			if(!G2UseSyncCallbacks)
				xmlRequest.onreadystatechange = WebForm_CallbackComplete;
			callback.xmlRequest = xmlRequest;
			xmlRequest.open("POST", theForm.action, !G2UseSyncCallbacks); //was hardcoded true - modified by Alon to force sync. calls to allow popups to be opened.
			xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			xmlRequest.send(postData);
			if(G2UseSyncCallbacks)
				WebForm_CallbackComplete();
			return;
		}
		WebForm_DoCallback_WithIFrame();
	},
	//this code exists in asp.net callbacks code - and used when browser doesn't support xmlhttp.
	//removed for now.
	WebForm_DoCallback_WithIFrame : function()
	{
		throw new Error("not implemented");
	},


	WebForm_CallbackComplete : function() 
	{
			for (var i = 0; i < __pendingCallbacks.length; i++) 
			{
					callbackObject = __pendingCallbacks[i];
					if (callbackObject && callbackObject.xmlRequest && (callbackObject.xmlRequest.readyState == 4)) 
					{
							WebForm_ExecuteCallback(callbackObject);
							//TODO: HACK: added by dan-el - when closing popups the item is not there. probably related to registration to callbackreference
							if(__pendingCallbacks[i]!=null) 
							{
								if (!__pendingCallbacks[i].async) 
								{
										__synchronousCallBackIndex = -1;
								}
							}
							__pendingCallbacks[i] = null;
							var callbackFrameID = "__CALLBACKFRAME" + i;
							var xmlRequestFrame = document.getElementById(callbackFrameID);
							if (xmlRequestFrame) 
							{
									xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
							}
					}
			}
	},

	WebForm_ExecuteCallback : function(callbackObject) 
	{
		var response = callbackObject.xmlRequest.responseText;
		if (response.charAt(0) == "s") 
		{
			if ((typeof(callbackObject.eventCallback) != "undefined") && (callbackObject.eventCallback != null)) 
			{
				callbackObject.eventCallback(response.substring(1), callbackObject.context);
			}
		}
		else if (response.charAt(0) == "e") 
		{
			if ((typeof(callbackObject.errorCallback) != "undefined") && (callbackObject.errorCallback != null)) 
			{
				callbackObject.errorCallback(response.substring(1), callbackObject.context);
			}
		}
		else 
		{
			var separatorIndex = response.indexOf("|");
			if (separatorIndex != -1) 
			{
				var validationFieldLength = parseInt(response.substring(0, separatorIndex));
				if (!isNaN(validationFieldLength)) 
				{
					var validationField = response.substring(separatorIndex + 1, separatorIndex + validationFieldLength + 1);
					if (validationField != "") 
					{
						var validationFieldElement = theForm["__EVENTVALIDATION"];
						if (!validationFieldElement) 
						{
							validationFieldElement = document.createElement("INPUT");
							validationFieldElement.type = "hidden";
							validationFieldElement.name = "__EVENTVALIDATION";
							theForm.appendChild(validationFieldElement);
						}
						validationFieldElement.value = validationField;
					}
					if ((typeof(callbackObject.eventCallback) != "undefined") && (callbackObject.eventCallback != null)) 
					{
						callbackObject.eventCallback(response.substring(separatorIndex + validationFieldLength + 1), callbackObject.context);
					}
				}
			}
			else
			{
				var location = callbackObject.xmlRequest.getResponseHeader("location"); //if Response.RedirectLocation is used
				if(location!=null && location!="")
				{
					G2_Navigate(location);
				}
				else
				{
   				callbackObject.errorCallback(response, callbackObject.context);
   			}
			}
		}
	},

	G2_UseSyncCallbacks : function()
	{
		G2UseSyncCallbacks = true;
//		WebForm_DoCallback = WebForm_DoCallback_Sync;
//		WebForm_CallbackComplete = WebForm_CallbackComplete_Sync;
	},


	//
	//recursivle iterates on all child elements of a certain element,
	//and calls the specified action with the element and context, action(element, context)
	//if the action returns false, it will stop the recursive operation inside that element
	//
	G2_PerformRecursiveActionOnElement : function(element, action, context)
	{
		_G2_PerformRecursiveActionOnElement(element, action, context);
	},
	_G2_PerformRecursiveActionOnElement : function(element, action, context)
	{
		if(element.nodeType!=1) //textnode
			return;

		var result = action(element, context);
		if(result==false)
			return;
		var child = element.firstChild;
		while(child!=null)
		{
			_G2_PerformRecursiveActionOnElement(child, action, context);
			child = child.nextSibling;
		}
	},


	G2_SetFocus : function(elementId)
	{
		if(G2_SetFocus_ThreadId!=null)
		{
			window.clearTimeout(G2_SetFocus_ThreadId);
			G2_SetFocus_ThreadId = null;
		}
		G2_SetFocus_ThreadId = window.setTimeout(
			function()
			{
				G2_SetFocus_ThreadId = null;
				var success = G2_AutoFocus(elementId);
				if(success) //case 8578 - sometimes after the successful focus, the body is somehow focused. this hack fixes it.
				{
					if(document.activeElement==null || document.activeElement.id!=elementId)
					{
						success = G2_AutoFocus(elementId);
					}
				}
			}, 50);
	},


	///
	/// Finds a server control by server ID (using id.contains(id))
	///
	G2_FindServerControl : function(fromElement, id)
	{
		return _G2_FindServerControl(fromElement, id);
	},
	_G2_FindServerControl : function(fromElement, id)
	{
		if(fromElement.id!=null && fromElement.id.endsWith(id))
			return fromElement;

		if(fromElement.doesNotContainInputs || fromElement.tagName=="SELECT")
			return null;

		var element = fromElement.firstChild;
		while(element!=null)
		{
			var foundControl = _G2_FindServerControl(element, id)
			if(foundControl!=null)
				return foundControl;
			element = element.nextSibling;
		}
		return null;
	},



	G2ReturnValue : function(value)
	{
		this.value = value;
	},
	
	// Get current page theme
	G2_PageTheme : function()
	{
		return document.getElementById("G2_PageTheme").value;
	},


	G2_MapPath : function(virtualUrl)
	{
		var rootAppPath = document.getElementById("G2_RootAppPath").value;
		var path = virtualUrl.replace("~/", rootAppPath);
		return path;
	},
	G2_IsNavigating : function()
	{
	  return window.top.IsNavigating;
	},
	
	G2_Navigate : function(url, isInternalNavigation, targetFrame, navigateWithForms)
	{
	    var navigationWindow = null;
	    if (isInternalNavigation && isInternalNavigation != 'false')
		{
		      if(targetFrame!="" && targetFrame!=null) //navigate inside a frame
		      {
		        var f = document.getElementById(targetFrame);
		        f.contentWindow.document.location.href = url;
		        return;
		      }
		      else //navigate in this window
		         navigationWindow = window; 
		}
		else //navigate in the topmost window
		{
		      navigationWindow = window.top;
	    }
	    if (navigateWithForms && navigateWithForms != 'false') //naviage throught form submit
	        G2_FormNavigate(navigationWindow, url);
	     else //navigate through url change
	     {
	        navigationWindow.IsNavigating = true;
	        navigationWindow.window.location.href = url;
	        
	     }
	},
	
	G2_FormNavigate : function (windowObj, url)
	{
	    windowObj.IsNavigating = true;
	    var navForm = window.document.createElement("FORM");
	    navForm.method = "get";
	    var urlPair = url.toString().split('?');
	    var navUrl = urlPair[0];
	    if (urlPair.length > 1)
	    {
            var query = urlPair[1];
            queryStringKeys = new Array();	
            queryStringValues = new Array();
	        var pairs = query.split("&");
        	for (var i=0; i < pairs.length; i++)
            {
	            var pos = pairs[i].indexOf('=');
	            if (pos >= 0)
	            {
		            var argname = pairs[i].substring(0,pos);
		            var value = pairs[i].substring(pos+1);
		            var input = window.document.createElement('INPUT');
		            input.name = argname;
		            input.value = value;
		            input.type = 'hidden';
		            input.style.display = 'none';
		            navForm.appendChild(input);
	            }
             }
        }
    	windowObj.document.body.appendChild(navForm);
	    navForm.action = navUrl;
	    navForm.submit();
	},
	
	G2_Warn : function(sender, msg)
	{
		G2_Trace(sender, "************************************");
		G2_Trace(sender, msg);
		G2_Trace(sender, "************************************");
	},

	G2_Trace : function(sender, msg)
	{
		var id = null;
		if(sender!=null)
		{
			id = sender.id!=null ?  sender.id : sender.toString();
		}
		var now = new Date();
		var time = Date_ToString(now, "HH:mm:ss:ff");
		Debug.writeln(time+", "+id+": "+msg);
	},

	//New version by Alon.
	G2_GetData : function(url, callback, errorCallback)
	{
		url = encodeURI(url); //added by dan-el - when url has querystring arguments that contains chinese (for example) - will only work with encoding.
		if (isIE && window.ActiveXObject)
		{
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			if (xmlhttp!=null)
			{
				xmlhttp.onreadystatechange=function()
				{
					var x = xmlhttp.readyState;
					var y = xmlhttp.readyState;
					if(x==y)
					{
					}
					// if xmlhttp shows "loaded"
					if (xmlhttp.readyState==4)
					{
						// if "OK"
						if (xmlhttp.status==200)
						{
							callback(xmlhttp);
						// ...some code here...
						}
						else
						{
							errorCallback(xmlhttp);
						}
					}
				}
				xmlhttp.open("GET",url,true);
				xmlhttp.send(null);
			}
		} 
		else if (window.XMLHttpRequest)
		{
			try
			{
				var xmlhttp=new XMLHttpRequest();
				xmlhttp.open("GET",url,false);
				xmlhttp.send(null);
				callback(xmlhttp);		
			} 
			catch(everything)
			{
			  if (G2_Trace!=null)
			  {
				  G2_Trace("G2_GetData", everything.description);
				}
				errorCallback(xmlhttp);
			}
		} 
		else
		{
			alert("Your browser does not support XMLHTTP.");
		}
	},

	//function G2Page_Wait()
	//{
	//  setTimeout("G2Page_Wait_Timeout();",150);
	//}

	//function G2Page_Wait_Timeout()
	//{
	//  if(!Page_IsValid)
	//   return;
	//  var hf = document.getElementById("G2_WaitingImage");
	//  if(hf.value!="")
	//  {
	//    var img = document.getElementById(hf.value);
	//    img.style.display = "block";
	//    var srcWas = img.src;
	//    img.src = "";
	//    img.src = srcWas;
	//  }
	//}

	G2_IsInPopup : function()
	{
		try
		{
			parentDoc = parent.document;
			return (parentDoc!=null && parentDoc!=document)
		} 
		catch(everything)
		{	
			G2_Trace("IsInPopup", everything.description);
			Debug.writeln("IsInPopup() FAILED");
			return false;
		}  
	},


	//now registered inline from g2page.cs
	//function G2Page_Init()
	//{
	//	G2_AttachEvent(window, "onload", G2Page_OnLoad);
	//}


	//Unless explicitly specified, resizing is DISABLED until page is loaded.
	//When the page is loaded, the auto-size feature is enabled
	G2Page_OnLoad : function()
	{
	//	G2_DetachEvent(window, "onload", G2Page_OnLoad);
		G2_PreventInputPost("G2_OnLoadStatement");
		var s = document.getElementById("G2_OnLoadStatement");
		enableResizing = true;
		if(s!=null)
		{
			eval(s.value);
		}	
		if (G2_IsInPopup())
		{
			G2Dialog_Init();
		}
	},

	G2_FirePopupClosed : function(popupID, popupResult, silent, uniqueId)
	{
		if (uniqueId!=null)
			popupID = popupID + "###"+uniqueId;
		var hf1 = document.getElementById('__PopupWindowID');
		var hf2 = document.getElementById('__PopupResult');
		hf1.value = popupID;
		hf2.value = popupResult;
		G2.notifyInputChanged(hf1);
		G2.notifyInputChanged(hf2);
		__doPostBack('__Page','G2PopupClosed',silent);  
	},

	G2HtmlFrame_Init : function(iframeId, targetElementId, tooltipKey, autoSize)
	{
		if(tooltipKey!=null && tooltipKey!="")
		{
			G2Tooltips[tooltipKey] = iframeId;
		}
		if(targetElementId!="")
		{
			var target = document.getElementById(targetElementId);
			var iframe = document.getElementById(iframeId);
			target._tooltipFrame = iframe;
			iframe.style.position="absolute";
	    
			target.onmouseover=function()
			{
				x = event.clientX + document.body.scrollLeft;
				y = event.clientY + document.body.scrollTop;
				this._tooltipFrame.style.pixelLeft = x;
				this._tooltipFrame.style.pixelTop = y;
				this._tooltipFrame.style.display = "block";
			}
			target.onmouseout=function()
			{
				this._tooltipFrame.style.display = "none";
			}
		}
		
		if(autoSize)
			window.setTimeout(function() { G2FrameManager.registerFrame(iframeId); }, 0);
	},

	G2ShowTooltip : function(target, tooltipKey,event)
	{
		var iframeId = G2Tooltips[tooltipKey];
		var iframe = document.getElementById(iframeId);
		if (!iframe)
			return;
		if (!event)
			event = window.event;
		G2ShowTooltipElement(target, iframe,event);
	},
	
  G2ShowTooltipElement : function(targetElement, tooltipElementOrId,e)
  {
	  if (!e)
		  e = window.event;
  		
	  if(typeof(tooltipElementOrId)=="string")
	   el = document.getElementById(tooltipElementOrId);
	  else
	   el = tooltipElementOrId;
  	 
	  G2PopupManager.showTooltipStart(targetElement, el,e);
  },  

	Date_Parse : function(strDate)
	{
		var date = new Date(strDate);
		if(isNaN(date))
			return null;
		return date;
	},



	//------- G2 Utils -----------------------------------------------------------
	//UNUSED
	G2SyncTables : function(tbl1ID,tbl2ID)
	{
		var table1 = document.getElementById(tbl1ID);
		var table2 = document.getElementById(tbl2ID);

		if(table1==null || table2==null)
			return;
		var tbl1AmoutOfRows= table1.rows.length;
		var tbl2AmoutOfRows= table2.rows.length;
		var minRowSize=0;


		if(tbl1AmoutOfRows>tbl2AmoutOfRows)
			minRowSize= tbl2AmoutOfRows;
		else 
			minRowSize= tbl1AmoutOfRows;
	    
		var i =0;
		var j =0;
		var minColSize=0;
		if(table1.rows[0].cells.length <table2.rows[0].cells.length)
			minColSize=table1.rows[0].cells.length;
		else 
			minColSize=table2.rows[0].cells.length;
	    
		while(i<minRowSize){
				j=0;
				while(j<minColSize){
									if(table1.rows[i].cells[j].style.width<table2.rows[i].cells[j].style.width)
										table1.rows[i].cells[j].style.width=table2.rows[i].cells[j].style.width;
									else
										table2.rows[i].cells[j].style.width=table1.rows[i].cells[j].style.width;
								 j=j+1;
				}
			i=i+1;
		}
	},

	String_ToInt : function(text)
	{
		if(text==null || text.length==0)
			return null;
		text = String_TrimLeft(text, "0");//because of js bug: parseInt('08') returns 0 as a result
		if(text.length==0)
			return 0;
		var x = parseInt(text);
		if(isNaN(x))
			return null;
		return x;
	},

	String_TrimLeft : function(text, trimChar)
	{
		while(text.length>0 && text.charAt(0)==trimChar)
		{
			text = text.substr(1, text.length-1);
		}
		return text;
	},

	Select_FindByValue : function(select, value)
	{
		for(var i=0;i<select.options.length;i++)
		{
			if(select.options[i].value==value)
				return select.options[i];
		}
		return null;
	},

	Select_IndexOfValue : function(select, value)
	{
		for(var i=0;i<select.options.length;i++)
		{
			if(select.options[i].value==value)
				return i;
		}
		return null;
	},
	Select_ContainsValue : function(select, value)
	{
		return Select_IndexOfValue(select, value)!=null;
	},

	//
	// returns the index of the first occurance of a specific item in an array
	//
	Array_IndexOf : function(array, value)
	{
		for(var i=0;i<array.length;i++)
		{
			if(array[i]==value)
				return i;
		}
		return -1;
	},
	G2_findPreviousControl : function(ctrl , tagName)
	{
		while (ctrl!=null && ctrl.tagName!=tagName)
		{
			if (ctrl.previousSibling==null)
				ctrl = ctrl.parentElement;
			else
				ctrl = ctrl.previousSibling;
		}
		return ctrl;

	},

	G2_getDayName : function(year , month , day)
	{
		var dDate = new Date();
		dDate.setFullYear(year,month-1,day);
		return weekDays[dDate.getDay()];
	},


	DateRange_GetDays : function(dateRange, hoursToAdd)
	{
		return DateRange_GetNights(dateRange, hoursToAdd)+1;
	},

	DateRange_GetNights : function(dateRange, hoursToAdd)
	{
		//case 7606: in case of date range over Summertime trnsition (start date in summertime 
		//and end date in regulare time or the other way around)
		dateRange = dateRange + hoursToAdd*1000*60*60;
		return Math.ceil(dateRange/(24*60*60*1000));
	},

	DateRange_GetYears : function(dateRange)
	{
		return dateRange/(365*24*60*60*1000);
	},

	Date_AddHours : function(date,hours) 
	{
		return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours() + hours, date.getMinutes(), date.getSeconds());
	},

	Date_AddDays : function(date,days) 
	{
		return new Date(date.getFullYear(), date.getMonth(), date.getDate()+days, date.getHours(), date.getMinutes(), date.getSeconds());
	},

	Date_SubtractDays : function(date,days) 
	{
		return new Date(date.getFullYear(), date.getMonth(), date.getDate()-days, date.getHours(), date.getMinutes(), date.getSeconds());
	},

	Date_ToDotNetString : function(date) 
	{
		return Date_ToString(date, "MM-dd-yyyy");
	},

	Date_VerifyLeadingZero : function(str)
	{
		if(str.length==1)
			str = "0"+str;
		return str;
	},

	///Parses a string like 'Aug' or '8' or '08' into the month number (not javascript month)
	///and returns it - like 8 in this case
	Date_ParseMonth : function(text)
	{
		var month = Array_IndexOf(Date_ShortMonthNames, text);
		if(month!=-1)
		{
			return month+1;
		}
		
		month = String_ToInt(text);
		return month;
	},

	Number_Extension : function(str)
	{
			var lastDigit = str.charAt(str.length-1);
			var last = parseInt(lastDigit);
			var prev = 0;
			if (str.length >= 2) 
			{
				var prevDigit = str.charAt(str.length-2);
				prev = parseInt(prevDigit);
			}
			
			if (prev != 1) //When the number doesn't end with 11, 12 or 13, the extension is according the last digit
			{
				if (last == 1)
					return "st";
				else if (last == 2)
					return "nd";
				else if (last == 3)
					return "rd";
				else
				 return "th"; // 0, 4, 5, 6, 7, 8 and 9
			}
			else //When the number ends with 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, when the tenth digit is 1
				return "th"; 
			
	},

	Number_Format : function(number, format)
	{
		if(format=="#")
		{
			return number.toString();
		}
		else if(format=="##")
		{
			var s = number.toString();
			while(s.length<2)
			{
				s = "0"+s;
			}
			return s;
		}
		else if(format=="##xx")
		{
			var s = Number_Format(number, "##");
			var ext = Number_Extension(s);
			s += ext;
			return s;
		}
		else if(format=="#xx")
		{
			var s = Number_Format(number, "#");
			var ext = Number_Extension(s);
			s += ext;
			return s;
		}
		throw new Error("number format is not supported");
	},

	//
	// Formats a javascript Date object to string in a manner similar to .net framework.
	// currently supports: day, month, year, hour, minute,
	// seperators: '/', ':'
	//
	Date_ToString : function(date, format) 
	{
		if(date==null)
			return "";
			
		if(format=="H")
		{
			return date.getHours().toString();
		}
		else if(format=="HH")
		{
			return Date_VerifyLeadingZero(date.getHours().toString());
		}
		else if(format=="m")
		{
			return date.getMinutes().toString();
		}
		else if(format=="mm")
		{
			return Date_VerifyLeadingZero(date.getMinutes().toString());
		}
		else if(format=="s")
		{
			return date.getSeconds().toString();
		}
		else if(format=="ss")
		{
			return Date_VerifyLeadingZero(date.getSeconds().toString());
		}
		else if(format=="ff")
		{
			return Date_VerifyLeadingZero(date.getMilliseconds().toString());
		}
		else if(format=="d")
		{
			return date.getDate().toString();
		}
		else if(format=="dxx")
		{
			var day = date.getDate();
			var s = Number_Format(day, "#xx");
			return s;
		}
		else if(format=="dd")
		{
			return Date_VerifyLeadingZero(date.getDate().toString());
		}
		else if(format=="ddxx")
		{
			var day = date.getDate();
			var s = Number_Format(day, "##xx");
			return s;
		}
		else if(format=="M")
		{
			return (date.getMonth()+1).toString();
		}
		else if(format=="MM")
		{
			return Date_VerifyLeadingZero((date.getMonth()+1).toString());
		}
		else if(format=="MMM")
		{
			return Date_ShortMonthNames[date.getMonth()];
		}
		else if(format=="MMMM")
		{
			return Date_MonthNames[date.getMonth()];
		}
		else if(format=="y")
		{
			throw new Error("'y' is not a valid datetime format");
		}
		else if(format=="yy")
		{
			var str = date.getFullYear().toString();
			if(str.length==4)
				str = str.substr(2, 2);
			return str;
		}
		else if(format=="yyyy")
		{
			return date.getFullYear().toString();
		}
		else if(format.search(":")!=-1)
		{
			return _Date_ToString(date, format, ":");
		}
		else if(format.search("/")!=-1)
		{
			return _Date_ToString(date, format, "/");
		}
		else if(format.search("\\\\")!=-1)
		{
			return _Date_ToString(date, format, "\\");
		}
		else if(format.search("-")!=-1)
		{
			return _Date_ToString(date, format, "-");
		}
		else if(format.search(" ")!=-1)
		{
			return _Date_ToString(date, format, " ");
		}
		else if(format.search(".")!=-1)
		{
			return _Date_ToString(date, format, ".");
		}
		else
			throw new Error("date format is not supported");
	},

	//	var myDate = new Object();
	//	myDate.Day = date.getDate();
	//	myDate.Month = date.getMonth()+1;
	//	myDate.Year = date.getFullYear();
	//	myDate.ShortYear = date.getYear();

	//	if(format=="dd/MM/yy")
	//	{
	//		var s = (myDate.Day+"/"+myDate.Month+"/"+myDate.ShortYear);//.getDate()+"-" + date.getMonth()+1)+"-" + date.getFullYear();
	//		return s;
	//	}

	_Date_ToString : function(date, format, seperator)
	{
		var str="";
		var tokens = format.split(seperator);
		for(var i=0;i<tokens.length;i++)
		{
			var token = tokens[i];
			if(token!=null && token.length>0)
				str += Date_ToString(date, token);
			if(i!=tokens.length-1) //if not last, add seperator
				str += seperator;
		}
		return str;
	},


	// -------------------------------------------------------------------
	// autoComplete (text_input, select_input, ["text"|"value"], [true|false])
	//   Use this function when you have a SELECT box of values and a text
	//   input box with a fill-in value. Often, onChange of the SELECT box
	//   will fill in the selected value into the text input (working like
	//   a Windows combo box). Using this function, typing into the text
	//   box will auto-select the best match in the SELECT box and do
	//   auto-complete in supported browsers.
	//   Arguments:
	//      field = text input field object
	//      select = select list object containing valid values
	//      property = either "text" or "value". This chooses which of the
	//                 SELECT properties gets filled into the text box -
	//                 the 'value' or 'text' of the selected option
	//      forcematch = true or false. Set to 'true' to not allow any text
	//                 in the text box that does not match an option. Only
	//                 supported in IE (possible future Netscape).
	// -------------------------------------------------------------------
	G2DropDown_AutoComplete  : function(field, select, property, forcematch) 
	{
		var found = false;
		for (var i = 0; i < select.options.length; i++) {
		if (select.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0) {
			found=true; break;
			}
		}
		if (found) { select.selectedIndex = i; }
		else { select.selectedIndex = -1; }
		if (field.createTextRange) 
		{
			if (forcematch && !found) 
			{
				field.value=field.value.substring(0,field.value.length-1); 
				return;
			}
			var cursorKeys ="8;46;37;38;39;40;33;34;35;36;45;";
			if (cursorKeys.indexOf(event.keyCode+";") == -1) 
			{
				var r1 = field.createTextRange();
				var oldValue = r1.text;
				var newValue = found ? select.options[i][property] : oldValue;
				if (newValue != field.value) 
				{
					field.value = newValue;
					var rNew = field.createTextRange();
					rNew.moveStart('character', oldValue.length) ;
					rNew.select();
				}
			}
		}
	},

	Select_SetValue : function(select, value, suppressOnChangeEvent)
	{
		select.value = value;
		if(!suppressOnChangeEvent)
			G2_FireEvent(select, "onchange");
	},

	String_PadEnd : function(src, count, paddingChar)
	{
		if(paddingChar==null)
			paddingChar=" ";
		var s="";	
		for(var i=0;i<count;i++)
		{
			s+=paddingChar;
		}
		return src+s;
	},


	String_InsertAt : function(src, index, value)
	{
		var s1 = src.substr(0, index);
		var s2 = src.substr(index, src.length-index);
		return s1+value+s2;
	},

	String_RemoveAt : function(src, index)
	{
		var s1 = src.substr(0, index);
		var s2 = src.substr(index+1, src.length-index+1);
		return s1+s2;
	},

	String_RemoveAll : function(src, search)
	{
		var tokens = src.split(search);
		var s = "";
		for(var i=0;i<tokens.length;i++)
		{
			s+=tokens[i];
		}
		return s;
	},
	
	String_StartsWith : function(text, start)
	{
		if(start.length>text.length)
			return false;
		for(var i=0;i<start.length;i++)
		{
			if(start.charAt(i)!=text.charAt(i))
				return false;
		}
		return true;
	},

	G2_CopyArray : function(sourceArray, startIndex)
	{
		if(startIndex==null)
			startIndex = 0;
		var array = new Array();
		array.length = sourceArray.length-startIndex;
		var j=0;
		for (var i=startIndex;i<sourceArray.length;i++)
		{
			array[j] = sourceArray[i];
			j++;
		}
		return array;
	},

	G2_ShowControl : function(control, useVisibility)
	{
		if(useVisibility)
		{
			control.style.visibility = "visible";
		}
		else
		{
			control.style.display = "";//FOLLOWUPDAN-EL

		}
		if(typeof(control.OnShow)!="undefined")
		{
			control.OnShow();
		}
		return true;
	},
	
	G2_IsElementVisible : function(element, checkParents)
  {
	  if(element.style && element.style.display=="none")
		  return false;
	  if(checkParents)
	  {
		  if(element.parentElement!=null)
			  return G2_IsElementVisible(element.parentElement, checkParents);
		  else
		      if (isMoz) //Moz has a parent for the documentElement (html tag)
		          return element instanceof Document;
		      else
			      return element==element.document.documentElement; //only when element reaches to the top doc element we can be (pretty) sure it's visible.
  			
	  }
	  return true;
  },

	G2_HideControl : function(control, useVisibility)
	{
 		if(useVisibility)
		{
			control.style.visibility = "hidden";
		}
		else
		{
			control.style.display = "none";
		}
		if(typeof(control.OnHide)!="undefined")
		{
			control.OnHide();
		}
		return false;
	},
	G2_ToggleElementVisibility : function(element)
	{
		if(element==null)
			return; //TODO: warn
		if(element.style.display=="none")
			G2_ShowControl(element);
		else
			G2_HideControl(element);
	},

	G2_ShowHideControl : function(control, show, useVisibility)
	{
		if(show)
		{
			return G2_ShowControl(control, useVisibility);
		}
		else
		{
			return G2_HideControl(control, useVisibility);
		}
	},

	G2Page_ErrorCallback : function(message)
	{
		alert('An error occurred on the server:\n' + message);
	},

	G2_RecursiveSetPropertyValue : function(rootElement, propertyName, value)
	{
		if(rootElement.nodeName!="#text" && rootElement[propertyName]!=value)
		{
			rootElement[propertyName] = value;
		}
		var rootElementChildren = rootElement.children;
		for(var i=0;i<rootElementChildren.length;i++)
		{
			var child = rootElementChildren[i];
			G2_RecursiveSetPropertyValue(child, propertyName, value);
		}
	},

	//----------------------------------------------------------------------	

	G2_GetY : function(element)
	{
		var y = 0;
		while( element != null ) 
		{
			y += parseInt(element.offsetTop);
			
			// taking into account scrooling with in overflow scroll elements
			if(element.tagName != 'HTML' && element.scrollTop != null)
				y -= element.scrollTop;
			if(element.tagName == 'IFRAME')
				y -= document.documentElement.scrollTop;
			
			element = element.offsetParent;
		}
		return y;
	},

	G2_GetX : function(element)
	{
		var x = 0;
		while( element != null ) 
		{
			x += parseInt(element.offsetLeft);
			element = element.offsetParent;
		}
		return x;
	},

	G2Validator_ValidateElementOnChange : function(element)
	{
		if(element!=null && element.Validators!=null)
		{
			var dummyEvent = new Object();
			dummyEvent.srcElement = element; //IE
			dummyEvent.target = element; //FF
			ValidatorOnChange(dummyEvent);
		}
	},

	//---------------------------------------------

	isFixedPositioned : function(elem)
	{
		while (elem!=null)
		{
			if (elem && elem.style && elem.currentStyle.position == "fixed")
				return true;
			elem = elem.parentElement;
		}
		return false;
	},

  G2_BringToFront : function(elementToFloat)
	{
	  //marked by dan-el elementToFloat.style.zIndex = G2_maxZ++;
	},
	
	G2_FloatElement : function(elementToFloat, positionElement, dir, useFrame,useFixedPositioning)
	{
		//G2_Trace("G2_FloatElement", "start");
		var parent = elementToFloat.parentElement;
		if(parent!=null)
		{
			parent.removeChild(elementToFloat);
		}
		document.body.appendChild(elementToFloat);
		elementToFloat.style.position = useFixedPositioning ? "fixed" : "absolute";
		G2_BringToFront(elementToFloat);
		//this.bringElementToFront(elementToFloat);
		var N=(dir.indexOf("N")>-1);
		var S=(dir.indexOf("S")>-1);
		var E=(dir.indexOf("E")>-1);
		var W=(dir.indexOf("W")>-1);
		if(!N && !S)
			S=true;
		if(!E && !W)
		{
			E=true;
		}
		
		var x = G2_GetX(positionElement);
		var y = G2_GetY(positionElement);

	  
		if (S)
			y += positionElement.offsetHeight;
		if (W)
			x += positionElement.offsetWidth;
		elementToFloat.style.pixelTop = y;
		elementToFloat.style.pixelLeft = x;
	  
		elementToFloat.style.display = "block";
	  
		//iframe is the only one that can hide select tags in IE
		if(useFrame) 
		{
			window.setTimeout(function(){G2_AttachFrame(elementToFloat,useFixedPositioning);}, 0);
		}
 		//G2_Trace("G2_FloatElement", "end");
	},

	G2_HideFloatingElement : function(targetElement)
	{
		G2_DetachFrame(targetElement);
		targetElement.style.display = "none";
	},
	G2_CreateIFrame : function(doc, frameBorder, scrolling)
	{
		doc = doc || document;
		var frame = doc.createElement("IFRAME");
		if(frameBorder==null)
			frameBorder = 0;
		frame.frameBorder = frameBorder.toString();
		if(scrolling!=null)
			frame.scrolling = scrolling ? "yes" : "no";
		
		// validate body exist
		var body = doc.body;
		if(body == null)
		  body = document.body;
		  
		body.appendChild(frame);
		var frameDoc = frame.contentWindow.document;
		frameDoc.open();
		frameDoc.write("<html><body></body></html>");
		frameDoc.close();
		body.removeChild(frame);
		return frame;
	},
	G2_AttachFrame : function(targetElement,useFixedPositioning)
	{
		if(!IE6)
			return;
		//G2_Trace("G2_AttachFrame", "start");

		if(G2_FixFrame==null)
		{
			G2_FixFrame = G2_CreateIFrame(targetElement.document, 0, false);
			G2_FixFrame.setAttribute("id", "fixFrame");
			targetElement.insertAdjacentElement("beforeBegin", G2_FixFrame);
		}
	  
		//TODO: some of the size properties causes performance overhead of about a second
		G2_FixFrame.style.position = useFixedPositioning ? "fixed" : "absolute";
		G2_FixFrame.style.width = targetElement.offsetWidth+"px";
		G2_FixFrame.style.height = targetElement.offsetHeight+"px";
		G2_FixFrame.style.top = G2_GetY(targetElement)+"px";
		G2_FixFrame.style.left = G2_GetX(targetElement)+"px";
		//G2_FixFrame.style.zIndex = targetElement.currentStyle.zIndex - 1;
		G2_FixFrame.style.display = "block";
		targetElement._popupFixFrame = G2_FixFrame;
		targetElement.onresize = function()
		{
			this._popupFixFrame.style.width = this.offsetWidth+"px";
			this._popupFixFrame.style.height = this.offsetHeight+"px";
		}
		targetElement.onmove = function()
		{
			this._popupFixFrame.style.pixelTop = this.offsetTop;
			this._popupFixFrame.style.pixelLeft = this.offsetLeft;
		}
 		//G2_Trace("G2_AttachFrame", "end");
	},
	G2_DetachFrame : function(targetElement)
	{
		if(!IE6)
			return;
		if(targetElement._popupFixFrame==null)
			return;
		targetElement._popupFixFrame.style.display = "none";
		targetElement._popupFixFrame = null;
		//G2_FixFrame.style.display = "none";
		targetElement.onresize = null;
		targetElement.onmove = null;
	},

	//added by rony - for validation control re evaluation.
	G2ReEvaluateValidationControl : function(validationControl) {
			Page_InvalidControlToBeFocused = null;
			if (typeof(Page_Validators) == "undefined") {
					return true;
			}
			validationControl.isvalid = true;
			if (typeof(validationControl.enabled) == "undefined" || validationControl.enabled != false) {
					if (typeof(validationControl.evaluationfunction) == "function") {
							validationControl.isvalid = validationControl.evaluationfunction(validationControl);
							if (!validationControl.isvalid && Page_InvalidControlToBeFocused == null &&
									typeof(validationControl.focusOnError) == "string" && validationControl.focusOnError == "t") {
									ValidatorSetFocus(validationControl, event);
							}
					}
			}
			ValidatorUpdateDisplay(validationControl);
	},

	/*
	resizing the hieght for the outer ifram element from a current page
	*/

	FixOuterIFramHight : function(){
		//FixIFrameHeight(window.frameElement.id);
		var iframe = window.frameElement;
		if (iframe.addEventListener)
		{
			iframe.addEventListener("load", readjustIframe, false);
		}
		else if (iframe.attachEvent)
		{
			iframe.attachEvent("onload", readjustIframe);
		}
		iframe.style.display = "";
	},
	/*
	Resizing IFrame dynamically
	Addaed by Arnon 21.10.06
	*/


	FixIFrameHeight : function(iframeId,doc,dontUseEvents)
	{
		if (doc==null)
			doc = document;			  
			
		if (dontUseEvents==null)
			dontUseEvents = false;

		var iframe = doc.getElementById(iframeId);
		
		if (iframe==null)
			return;
			
		if (iframe.addEventListener)
		{
			iframe.addEventListener("load", readjustIframe, false);
		}
		else if (iframe.attachEvent && !dontUseEvents)
		{
			iframe.attachEvent("onload", readjustIframe);
		} 
		else 
			readjustIframe({currentTarget:iframe});
		iframe.style.display = "";
	},

	readjustIframe : function(loadevt)
	{
		var crossevt=(window.event && window.event.type=="load" )? event : loadevt;
		var iframe=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement;
		if (iframe)
		{
				iframe.style.height=iframe.Document.body.scrollHeight+"px";
				iframe.style.width=iframe.Document.body.scrollWidth+"px";
		}	
	},

	// Set the iframe flash elements transparent
	fixFlashInIframe : function(iframeId)
	{
		var iframe = document.getElementById(iframeId);
		fixFlashForIframe(iframe);
	},
	
	// Set the flash param wmode to transparent
	fixFlashForIframe : function(iframe)
	{
		G2DOM.SetFlashElementsTransparent(iframe);
		
		var iframes = iframe.Document.getElementsByTagName('iframe');
		for (var i = 0; i < iframes.length; i++) 
		{   
			  fixFlashForIframe(iframes[i]);
		}
	},
	
	// Fix the flash on iframe load
	FixIFrameFlash : function(iframeId)
	{
		var iframe = document.getElementById(iframeId);
		var fixFlash = function()
		{
			fixFlashInIframe(iframeId);
		}
		G2_AttachEvent(window, "onload", fixFlash,false);
	},
	
	FixIFrameSize : function(iframeId)
	{
		var iframe = document.getElementById(iframeId);
		iframe.style.border="0px";
		var onloaded = function()
		{
			readjustIframe({currentTarget:iframe});
		}
		if (iframe.addEventListener)
		{
			iframe.addEventListener("load", onloaded, false);
		}
		else if (iframe.attachEvent)
		{
			iframe.attachEvent("onload", onloaded);
		}
			
		iframe.style.display = "";
	},



	readjustIframeSize : function(loadevt)
	{
		var crossevt=(window.event)? event : loadevt;
		var iframe=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement;
		if (iframe)
		{
			iframe.style.height=iframe.document.body.scrollHeight+"px";
		//	iframe.style.width=iframe.document.body.scrollWidth+"px";
			iframe.style.border="0px";
		}	
	},
	///*End of Resizing IFrame dynamically*/

	G2_AmntKeyPress : function()
	{
		var key = window.event.keyCode;
		if ((key < 48 || key > 57) && key != 46 && key != 45)
			window.event.keyCode = 0;
	},

	// TextBox: simulate [Tab] key press when number of characters reach maxLength
	G2_AutoSkip : function(thisEl, force,evnt)
	{
		if (force || (thisEl.value.length == thisEl.maxLength && evnt.keyCode != 9 && evnt.keyCode != 16)) 
		{
			nextEl = G2_GetNextElementToSkip(thisEl);
			if (nextEl != null) 
			{
				try {
					nextEl.focus();
					if (nextEl.select)
						nextEl.select();
				}
				catch (e) {}
			}
		}
	},

	// Get next element in tabIndex/creationOrder
	G2_GetNextElementToSkip : function(thisEl)
	{
		var currTabIndex = thisEl.tabIndex;
		var minDiffFromCurrTabIndex = 32767, minTabIndex = 32767;
		var nextCreateOrderEl = null, nextTabOrderEl = null, minTabOrderEl = null, nextEl = null;
		var getNextCreateOrder = false;
		for (var i = 0; i < thisEl.form.elements.length; i++) 
		{
			var element = thisEl.form.elements[i];
			if (element.type != "hidden" && !element.disabled && element.style.display != "none") 
			{
				if (element == thisEl) 
				{
					getNextCreateOrder = true;
				}
				else if (element.tabIndex >= 0)
				{
					// Find element with next creation order
					if (getNextCreateOrder) {
						nextCreateOrderEl = thisEl.form.elements[i];
						getNextCreateOrder = false;
						if (thisEl.tabIndex == 0)
							break;
					}
					if (element.tabIndex > 0) 
					{
						// Find element with next tabIndex
						var diff = element.tabIndex - currTabIndex;
						if (diff > 0) 
						{
							if (diff < minDiffFromCurrTabIndex) 
							{
								minDiffFromCurrTabIndex = diff;
								nextTabOrderEl = element;
							}
						}
					}
					// Find element with min tabIndex
					if (element.tabIndex < minTabIndex) 
					{
						minTabIndex = element.tabIndex;
						minTabOrderEl = element;
					}
				}
			}
		}
		if (thisEl.tabIndex == 0 && nextCreateOrderEl != null && nextCreateOrderEl.tabIndex == 0)
			nextEl = nextCreateOrderEl;
		else if (nextTabOrderEl != null)
			nextEl = nextTabOrderEl;
		else if (minTabOrderEl != null)
			nextEl = minTabOrderEl;
		else
			nextEl = nextCreateOrderEl;
		return nextEl;
	},

	G2Menu_ChangeMouseOver : function(parent)
	{	
		if (typeof(parent)=="string")
			parent = document.getElementById(parent);
		if (parent==null)
			return;
		var element = parent.firstChild;
		while(element!=null)
		{
			if(element.onmouseover!=null)
			{
				if(element.onmouseover!=null)
				{
					var func = element.onmouseover;
					element.onmouseover = null;	
					G2_AttachEvent(element, "onclick",function(e)
					{
						Menu_HoverStatic(this);
						e.cancelBubble = true;
					});
				}
			}
			if(element.style!=null && element.style.cursor!="hand")
			{
				element.style.cursor = "hand";
			}
			G2Menu_ChangeMouseOver(element);
			element = element.nextSibling;
		}
	},



	G2Menu_ChangeMouseOver_Old : function(targetElement) //new implementation by dan-el
	{
		var curEl = targetElement.firstChild;
		var firstLevelFound = false;
		while(curEl!=null)
		{
			if(!firstLevelFound && curEl.onmouseover!=null)
				firstLevelFound = true;
	      
			if(firstLevelFound)
			{
				curEl.onclick = function()
				{
					Menu_HoverStatic(this);
					event.cancelBubble = true;
					//return false;
				};
				//Yucki!
				var aa = curEl.getElementsByTagName("A");
				var a= null;
				if(aa.length>0)
					a = aa[0];
	      
				var nolink = "javascript:void(0)";
	        
				if(a!=null && a.href!=nolink)
				{
					if(a.href.indexOf("javascript:")>-1)
					{
						a.href = nolink;//Fix for case 4457. (nolink was: #)
					}
					else if(a.href.lastIndexOf("#") == a.href.length-1)
					{
						a.href = nolink; //Fix for case 4457. (nolink was: #)
					}
				}
	      
				curEl.onmouseover=null;
				curEl.ondeactivate = function(){Menu_Unhover(this);};
				curEl.onmouseout = null;
				//alert("before: " + curEl.style.cursor);
				curEl.style.cursor = "hand";
				if(a!=null)//TODO: Bug - Gilad
					a.style.cursor = "hand";
				//alert("after: " + curEl.style.cursor);
			}
			curEl = curEl.nextSibling;
		}
	  
		if(firstLevelFound)
			return true;
	  
		curEl = targetElement.firstChild;
		while(curEl!=null)
		{    
			//if (curEl.onmouseover!=null)
			//{
				G2Menu_ChangeMouseOver(curEl);
				curEl.onmouseover=null;    
			//}
			curEl = curEl.nextSibling;
		}
	},

	G2ConfirmBox_Show : function(text, eventTarget)
	{
		var eventArgument = confirm(text);
		__doPostBack(eventTarget, eventArgument);
	},

	//
	// findRel Usage:
	//
	// findRel( tag , "style.display == 'none'", G2GetParent )
	// This will find the nearest hidden tag in the hierarchy (moving up)
	// third parameter must be a function, like function(t){return t.nextSibling;} 
	findRel : function(node, predicate, nav)
	{
		if (typeof(predicate)=="string")
			eval("var compiledPredicate = function(){ return this."+predicate+";}");
		else
			compiledPredicate = predicate;

		try
		{
			while (node!=null)
			{			
				if (compiledPredicate.call(node))
					return node;
					
				node = nav(node);			
			}
		} 
		catch(e)
		{
		}
		return null;
	},

	$ : function( a )
	{
		return document.getElementById(a);
	},
		
	EventAttr : function(name)
	{
		if (event.srcElement.attributes[name] == null)
		{
			if (event.srcElement.parentElement.attributes[name] == null)
				return "";
				
			return event.srcElement.parentElement.attributes[name].nodeValue;
		}
			
		return event.srcElement.attributes[name].nodeValue;
	},

	G2Page_ShowWaiting : function()
	{
		//alert('waiting');
	},

	G2Page_ShowReady : function()
	{
		//alert('ready');
	},

	/**************************************************************************
	 *
	 * Popups and related functions
	 *
	 **************************************************************************/

	G2PopupWindow_ExtractParameter : function(features, paramname, defaultValue)
	{
		var poz = features.indexOf(paramname);
		if (poz==-1)
			return defaultValue;
		
		var f = features.substring(poz+paramname.length+1);
		poz = f.indexOf(';');
		var poz2 = f.indexOf(',');
		if (poz2!=-1 && poz ==-1)
			poz = poz2;
		if (poz!=-1)
			f = f.substring(0,poz);
		poz = f.indexOf('px');
		if (poz!=-1)
			f = f.substring(0,poz);
		return f;
		
	},

	// Modal Dialog Box  from http://www.eggheadcafe.com/articles/javascript_modal_dialog.asp
	/*
	var ModalDialogWindow;
	var ModalDialogInterval;
	var ModalDialog = new Object;

	ModalDialog.value = '';
	ModalDialog.eventhandler = '';

	function ModalDialogMaintainFocus()
	{
		try
		{
			if (ModalDialogWindow.closed)
			 {
					window.clearInterval(ModalDialogInterval);
					eval(ModalDialog.eventhandler);       
					return;
			 }
			ModalDialogWindow.focus(); 
		}
		catch (everything) {   }
	}

	function ModalDialogRemoveWatch()
	 {
			ModalDialog.value = '';
			ModalDialog.eventhandler = '';
	 }
	*/

	//This method is used to overcome google toolbar's popup blocker
	G2ExecuteSync : function(f)
	{
		var temporaryButton = G2DOM.G2CreateElement("<input type='Button' style='display:none'></input>");
			temporaryButton.id = temporaryButton.uniqueID;
			temporaryButton.onclick = f;
			document.body.appendChild(temporaryButton);
			temporaryButton.click();
			document.body.removeChild(temporaryButton);
	},

	ModalDialogShow : function(url,name,features,w,h,wndargs)
	{
		var me = window;
		var fullPath = G2_MapPath("~/Client/Dialog.aspx");
		if (IE6 && wndargs.title && wndargs.title!="")
		{
		fullPath += "?Title="+encodeURI(wndargs.title);
		wndargs.title=null;
		}
		//The following is a hack to run a function synchronously using a temporary hidden button   
		function ie_f()
		{
				return null!= window.showModalDialog(fullPath,wndargs,features);//{url:url,obj:me,width:w,height:h}, features);
		}
		function moz_f()
		{	
			var t =  window.open(fullPath,"G2POPUP","modal,"+features);//{url:url,obj:me,width:w,height:h}, features);				
			if (t!=null)
			{
				t.dialogArguments = wndargs;
				t.focus();
			}
			return null!=t;
		}
		if (isIE)
			G2ExecuteSync(ie_f);
		else
			moz_f();
	},


  G2_GetWindowId : function()
  {
    var el = document.getElementById('__WindowID');
    if(el==null)
      return null;
    return el.value
  },
  G2_CreateTable : function(rows, cols, onTopWindow, cellPadding, cellSpacing)
  {
    
		if (onTopWindow)
		{ 
			var win = GetTopAvailableWindow();
			var doc = win.document;
		}
		else
			var doc = document;
		
    
		cellPadding = cellPadding || 0;
		cellSpacing = cellSpacing || 0;
		var table = doc.createElement("table");
		table.cellPadding = cellPadding;
		table.cellSpacing = cellSpacing;
		for(var i=0;i<rows;i++)
		{
			var row = table.insertRow();
			for(var j=0;j<cols;j++)
			{
				var cell = row.insertCell();
			}
		}
		return table;
  },
  
	G2PopupWindow_Open : function(url, context, modal, name, features, title, uniqueID)
	{	
		if (features==null && context!=null)
		{
			//var h = document.getElementById(context);
			//if(h!=null)
			features = window[context];//h.value;
		}   
		if (modal==null)
			modal = features.indexOf('modal=0') == -1;
		url = url.replace(/\$quot\$/g,"'");		
							
		if(modal)
		{
			var wid = G2_GetWindowId();
			if(wid!=null)
			{
				if (url.indexOf('?') == -1)
					url += "?IsPopup=True";
				else
					url+="&IsPopup=True";
			}
	  	var h = parseInt(G2PopupWindow_ExtractParameter(features,"dialogHeight",""));
			var w = parseInt(G2PopupWindow_ExtractParameter(features,"dialogWidth",""));
			var minH = parseInt(G2PopupWindow_ExtractParameter(features,"dialogMinHeight","0"));
			var minW = parseInt(G2PopupWindow_ExtractParameter(features,"dialogMinWidth","0"));
			var autoSize = parseInt(G2PopupWindow_ExtractParameter(features,"autoSize","1"));
			var synthetic = G2PopupWindow_ExtractParameter(features,"SyntheticPopup","0");
			var fade = G2PopupWindow_ExtractParameter(features,"FadeSyntheticPopup","0");			
			var horzMargin = parseInt(G2PopupWindow_ExtractParameter(features,"HorizontalMargin","5"));
			var vertMargin = parseInt(G2PopupWindow_ExtractParameter(features,"VerticalMargin","5"));
			var scroll = G2PopupWindow_ExtractParameter(features,"scroll","0");
			var closeBtn = G2PopupWindow_ExtractParameter(features,"closeBtn","0");
			var closeClientFunction = G2PopupWindow_ExtractParameter(features,"OnCloseClientFunction","");
			var me = window;
			
			//If title was specified, but not name - copy title to name
			if (title && title!=null && title!="" && !name && (name==null||name==""))
				name=title;
			
			//If name was specified, but not title, copy name to title
			if (!title && (title==null||title=="") && name && name!=null && name!="")
				title=name;
			if (synthetic!="0")	
			{
				window.setTimeout(function(){		//This causes 'Operation Aborted' when showing popups in full postbacks
				var wnd = SyntheticModalDialogShow(url,name,features,h,w,{url:url,obj:me,width:w,height:h,title:title,autoSize:(autoSize=="1"),vertMargin:vertMargin,horzMargin:horzMargin, scroll : (scroll=="1"),closeBtn : (closeBtn=="1"), fade : (fade=="1"), minH : minH, minW : minW, uniqueID : uniqueID, closeClientFunction:closeClientFunction});
				},0);
			}
			else
			{	
				var wnd = ModalDialogShow(url,name,features,h,w,{url:url,obj:me,width:w,height:h,title:title,autoSize:autoSize});
			}
		}
		else
		{
			//Workaround for bug #3634: 
			// IE popup blocker blocked the popup, because it was not initiated by a user click.		
			
			//Note: The following is a workaround for IE popup blockers. It is not jiffacode.
			var temporaryButton = G2DOM.G2CreateElement("<input type='Button' style='display:none'></input>");
			temporaryButton.id = temporaryButton.uniqueID;
			temporaryButton.onclick = function()
			{
				var wnd = window.open(url, name, features);
				
				if (null == wnd)
				{
					alert('popup blocker detected!');
				} 
				else
				{
					if (features.indexOf('maximized=yes')!=-1)
						{
							wnd.moveTo( 0, 0 );
		
							wnd.resizeTo( screen.availWidth, screen.availHeight );
						}
				}
			}
			document.body.appendChild(temporaryButton);
			temporaryButton.click();
			document.body.removeChild(temporaryButton);
		}
	},

	updatePopupTitle : function(newTitle)
	{
		if (G2_IsInPopup() && window.top.document.popup!=null)
		{
			window.top.document.popup.setTitle(newTitle);
		}	
	},

	CreateModalContainer : function(contentid,h,w,title)
	{
			h = parseInt(h);
			w = parseInt(w);
			var marginHeight = (document.body.clientHeight - h) / 2;
			var marginWidth = (document.body.clientWidth - w) / 2;
			
			var containerTable = document.createElement("Table");
						
			//containerTable.id = id;
			containerTable.style.position="absolute";
			containerTable.style.pixelLeft=0;
			containerTable.style.pixelTop=0;
			containerTable.style.width=document.body.clientWidth+"px";
			containerTable.style.height=document.body.clientHeight+"px";
			G2_BringToFront(containerTable);
			containerTable.style.display="none"
			containerTable.style.background="transparent";
			containerTable.style.border="0px";
			containerTable.cellPadding = "0";
			containerTable.cellSpacing = "0";
			
			

			//Top Row
			var topRow = containerTable.insertRow();
			topRow.style.height=marginHeight+"px";
			var topRowCell = topRow.insertCell();
			topRowCell.colSpan = "3";
			topRowCell.className="MessageBoxContainer";
			topRowCell.innerHTML="<div style='background:#ccccee; width:300px'><b>"+title+"</b></div>";
			topRowCell.style.textAlign="center";
			topRowCell.style.verticalAlign="bottom";
			////////////////////////////////////////////////////////////////////////
			
			
			//Middle Row
			var middleRow = containerTable.insertRow();
			middleRow.style.height=w+"px";
			
			
			//Middle-Left
			var middleLeftCell = middleRow.insertCell();
			middleLeftCell.style.width=marginWidth+"px";
			middleLeftCell.style.height=h+"px";
			middleLeftCell.innerHTML="&nbsp;";
			middleLeftCell.className = "MessageBoxContainer";
			
			//Content cell
			var ContentCell = middleRow.insertCell();
			ContentCell.align="center";
			ContentCell.id = contentid;
			ContentCell.valign="middle";
			ContentCell.id = "modalContent";
			ContentCell.style.backgroundColor="white";
			ContentCell.style.width=w+"px";
			ContentCell.style.height=h+"px";
			
			//Middle-Right
			var middleRightCell = middleRow.insertCell();
			middleRightCell.style.width=marginWidth+"px";
			middleRightCell.style.height=h+"px";
			middleRightCell.innerHTML="&nbsp;";		
			middleRightCell.className = "MessageBoxContainer";
			
			////////////////////////////////////////////////////////////////////////
			//Bottom Row
			var bottomRow = containerTable.insertRow();
			bottomRow.style.height=marginHeight+"px";
			var bottomRowCell = bottomRow.insertCell();
			bottomRowCell.colSpan = "3";
			bottomRowCell.className="MessageBoxContainer";
			bottomRowCell.innerHTML="&nbsp;";
			
			return containerTable;
				
	},


	G2PopupWindow_CloseAndRedirect : function(url)
	{
		var parentWindow = window.opener; 
		G2_ClosePopupWindow();
		//window.close();
		parentWindow.location = url;
	},

	min : function(a,b)
	{
		return (a<b) ? a : b;
	},

	max : function(a,b)
	{
		return (a>b) ? a : b;
	},

	minInt : function(a,b)
	{
		var valA = parseInt(a);
		var valB = parseInt(b);
		
		if (isNaN(valA))
			return valB;
		if (isNaN(valB))
			return valA;
		return min(valA,valB);
	},

	maxInt : function(a,b)
	{
		var valA = parseInt(a);
		var valB = parseInt(b);
		
		if (isNaN(valA))
			return valB;
		if (isNaN(valB))
			return valA;
		return max(valA,valB);
	},

	// Removes leading whitespaces
	LTrim : function( value ) 
	{	
		var re = /\s*((\S+\s*)*)/;
		return value.replace(re, "$1");	
	},

	// Removes ending whitespaces
	RTrim : function( value ) 
	{	
		var re = /((\s*\S+)*)\s*/;
		return value.replace(re, "$1");	
	},

	// Removes leading and ending whitespaces
	trim : function( value ) 
	{	
		if (!value || value==null)
			value = this;
		return LTrim(RTrim(value));	
	},

	//----------------------------------------------------------------
	// Source: http://www.xs4all.nl/~zanstra/logs/jsLog.htm
	//----------------------------------------------------------------

	verifyObjectShown : function(obj)
	{
		var t=1;
		if (!InView(obj,5))
		{
			ScrollIntoView(obj,false,5);
			//obj.scrollIntoView(false); //align to bottom -- don't use unlesss previouse method fails (and it shouldn't)
		}
	},

	InView : function(element,margin) 
	{
		if(!margin) margin=0;
		var Top=GetTop(element), ScrollTop=GetScrollTop();
		return !(Top<ScrollTop+margin||
			Top>ScrollTop+GetWindowHeight()-element.offsetHeight-margin);
	},

	ScrollIntoView : function(element,bAlignTop,margin) 
	{
		if(!margin) margin=0;
		var posY = GetTop(element);
		if(bAlignTop) 
			posY -= margin;
		else 
			posY += element.offsetHeight+margin-GetWindowHeight();
		window.scrollTo(0, posY);
	},
	
	GetTopWindowHeight : function() 
	{
		return window.top.innerHeight ||
			window.top.document.documentElement&&window.top.document.documentElement.clientHeight ||
			window.top.document.body.clientHeight || 0;
	},

	GetWindowHeight : function() 
	{
		return window.innerHeight ||
			document.documentElement&&document.documentElement.clientHeight ||
			document.body.clientHeight || 0;
	},
	GetScrollTop : function() 
	{
		return window.pageYOffset ||
			document.documentElement && document.documentElement.scrollTop ||
			document.body.scrollTop || 0;
	},
	GetTop : function(element) 
	{
		var pos=0;
		do 
		{
			pos += element.offsetTop;
		}
		while(element=element.offsetParent);
		return pos;
	},


	////////////////////////////////////////////////////////////
	//        Range and selection relates functions           //
	////////////////////////////////////////////////////////////


	G2_SetSelectionRange : function(input, selectionStart, selectionEnd) 
	{
		if (input.setSelectionRange) 
		{
			input.focus();
			input.setSelectionRange(selectionStart, selectionEnd);
		}
		else if (input.createTextRange) 
		{
			var range = input.createTextRange();
			range.collapse(true);
			range.moveEnd('character', selectionEnd);
			range.moveStart('character', selectionStart);
			range.select();
		} else Debug.writeln('Cannot set selection');
	},

	G2_GetSelectionStartFromRange : function(range) 
	{
		var range = document.selection.createRange();
		var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
		if (!isCollapsed)
			range.collapse(true);
		var b = range.getBookmark();
		return b.charCodeAt(2) - 2;
	},
	G2_GetSelectionStart : function(input) 
	{
		if (isGecko)
			return input.selectionStart;
		var range = document.selection.createRange();
		var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
		if (!isCollapsed)
			range.collapse(true);
		var b = range.getBookmark();
		return b.charCodeAt(2) - 2;
	},

	G2_GetSelectionEnd : function(input) 
	{
		if (isGecko)
			return input.selectionEnd;
		var range = document.selection.createRange();
		var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
		if (!isCollapsed)
			range.collapse(false);
		var b = range.getBookmark();
		return b.charCodeAt(2) - 2;
	},
	G2_SetCaretPosition : function(input, index)
	{
		G2_SetSelectionRange(input, index, 0);
	},

	G2_GetCaretPosition : function(input)
	{
		var range = input.document.selection.createRange();
		var pos = 0;
		while(range.move("character", -1)!=0)
			pos++;
		return pos;
	},



	Find : function(array, predicate, context)
	{
		for(var i=0;i<array.length;i++)
		{
			var item = array[i];
			if(predicate(item, context))
				return item;
		}
		return null;
	},

	//
	//iterates an array, and performs the specified action with the specified context.
	//
	ForEach : function(array, action, context)
	{
		if(array==null || action==null)
			return;
		for(var i=0;i<array.length;i++)
		{
			action(array[i], context);
		}
	},

	ForEachSibling : function(element, action, context, predicate)
	{
		if(element==null)
			return;
		action(element, context);
		var nextSibling = element.nextSibling;
		if (predicate != null)
		{
		    while (nextSibling != null && !predicate(nextSibling))
		        nextSibling = nextSibling.nextSibling;   
		}
		ForEachSibling(nextSibling, action, context, predicate);
	},

	G2_PlaceElementAbsolutlyBeside : function(element, parentElement , position)
	{ 
		element.style.position = "absolute";
		parentElement.document.body.appendChild(element);
		element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement)+parentElement.scrollWidth;
		if(position == "Left")
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement)-element.scrollWidth;
		
		element.style.pixelTop = (G2_GetAbsoluteTop(parentElement));
		
		// keep element from exiting screen limits
		G2_VerifyAbsoluteElementNotCropped(element);
	},
	G2_PlaceElementAbsolutlyAbove : function(element, parentElement, position, align)
	{
		element.style.position = "absolute";
		parentElement.document.body.appendChild(element);
		
		if(position == "Left")
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement) - element.scrollWidth;
		else
			element.style.pixelLeft = (G2_GetAbsoluteLeft(parentElement));
			
		element.style.pixelTop = G2_GetAbsoluteTop(parentElement)-element.scrollHeight;
		
		// keep element from exiting screen limits
		G2_VerifyAbsoluteElementNotCropped(element);
	},

	G2_PlaceElementAbsolutlyBelow : function(element, parentElement, position)
	{
		element.style.position = "absolute";
		parentElement.document.body.appendChild(element);
		
		if(position == "Left")
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement) - element.scrollWidth;
		else
			element.style.pixelLeft = G2_GetAbsoluteLeft(parentElement);
			
		element.style.pixelTop = G2_GetAbsoluteTop(parentElement)+parentElement.scrollHeight;
		
		// keep element from exiting screen limits
		G2_VerifyAbsoluteElementNotCropped(element);
	},
	//pos=T,B,R,L
	G2_GetAbsolute : function(element, pos, includeFrames, posInfo)
	{
		if(pos=="t")
			return G2_GetAbsoluteTop(element, includeFrames, posInfo);
		else if(pos=="l")
			return G2_GetAbsoluteLeft(element, includeFrames, posInfo);
		if(pos=="b")
			return G2_GetAbsoluteBottom(element, includeFrames, posInfo);
		else if(pos=="r")
			return G2_GetAbsoluteRight(element, includeFrames, posInfo);
		return null;
	},
	//pos=t,b,r,l
	G2_SetAbsolute : function(element, pos, value, ignoreCurrentTopAndLeft)
	{
		if(value==null)
			return;
		if(pos=="t")
			element.style.pixelTop = value;
		else if(pos=="l")
			element.style.pixelLeft = value;
		else if(pos=="b")
		{
			if(element.style.top=="" || ignoreCurrentTopAndLeft)
				element.style.top = (value-element.offsetHeight)+"px";
			else
				element.style.height=(value - element.style.pixelTop)+"px";
		}
		else if(pos=="r")
		{
			if(element.style.left==""  || ignoreCurrentTopAndLeft)
				element.style.left = (value-element.offsetWidth)+"px";
			else
				element.style.width=(value - element.style.pixelLeft)+"px";
		}
	},
	
	// this method returns true if a change was made, and false otherwise. case 11147
	G2_VerifyAbsoluteElementNotCropped : function(element)
	{
		var result = false;
		var elementOffsetWidth = element.offsetWidth;
		var offsetParent = element.offsetParent;
		if (offsetParent==null)
		  return false;
	  if (isIE)
	    element.style.display = "none";
	  if(element.offsetLeft+elementOffsetWidth>offsetParent.clientWidth)
	  {
		  element.style.pixelLeft-=element.offsetLeft+elementOffsetWidth-offsetParent.clientWidth;
		  result = true;
	  }
	  element.style.display = "";
	  
	   //locate the element in a proper place if it overflow the client screen	height  
	  var scrollTop =  window.top.document.documentElement.scrollTop;
	  var elementOffsetHeight = element.offsetHeight;
		var offsetParent = element.offsetParent;
		if (offsetParent==null)
		 return;
	 	
	 	if(G2_GetAbsoluteTop(element)+elementOffsetHeight > GetTopWindowHeight() + scrollTop)
	 	{
		  element.style.pixelTop -= G2_GetAbsoluteTop(element)+elementOffsetHeight-(GetTopWindowHeight() + scrollTop);
		  result = true;
	  }
	  
	  if(element.style.pixelTop < 0)
			element.style.pixelTop = 0;
			
		return result;
	},
	//places an element near another element - dock = string = "tl:bl,tr:br" etc... tl=TopLeft tl:br,
	G2_PlaceElementAbsolutlyNear : function(element, relativeElement, dock, onTopWindow, appendToElement)
	{
		var parent = onTopWindow ? window.top.document.body : relativeElement.document.body;
		
		if(appendToElement)
			parent = appendToElement;
			
		if(element.parentElement!=parent)
			parent.appendChild(element);
		if (isMoz)
		  element.style.display = "none";
		element.style.position = "absolute";
		var tokens = dock.split(",");
		var settings = {};
		for(var i=0;i<tokens.length;i++)
		{
			var token = tokens[i];
			var miniTokens = token.split(":");
			var relCorner = miniTokens[0];
			var absCorner = miniTokens[1];
			
			var rel1 = relCorner.charAt(0);
			var rel2 = relCorner.charAt(1);
			var abs1 = absCorner.charAt(0);
			var abs2 = absCorner.charAt(1);
			var posInfo = new Object();
			var rel1Val = G2_GetAbsolute(relativeElement, rel1, onTopWindow, posInfo);
			var rel2Val = G2_GetAbsolute(relativeElement, rel2, onTopWindow, posInfo);
			if(posInfo.offsetParent!=null && posInfo.offsetParent.currentStyle!=null)
			{
			  if(posInfo.offsetParent.currentStyle.position=="fixed")
			    element.style.position = "fixed";
			}
			settings[abs1] = rel1Val;
			settings[abs2] = rel2Val;
		}
		if (isMoz)
		  element.style.display = "";
		//the top and left MUST be set before the bottom and right
		G2_SetAbsolute(element, "t", settings["t"]); 
		G2_SetAbsolute(element, "l", settings["l"]); 
		G2_SetAbsolute(element, "b", settings["b"], settings["t"]==null); 
		G2_SetAbsolute(element, "r", settings["r"], settings["l"]==null); 
	},	
	G2_IsAbsolutlyPositioned : function(element)
	{
		if(element==null)
			return false;
		if(element.style.position=="absolute")
			return true;
		return G2_IsAbsolutlyPositioned(element.parentElement);
	},


	G2_GetElement : function(idOrElement)
	{
		if(typeof(idOrElement)=="string")
			return document.getElementById(idOrElement);
		return idOrElement;
	},
	
	G2_GetAbsoluteLeft : function(element, includeFrames, posInfo) 
	{
	  var x = 0;
    var originalElement = element;
    while( element != null ) 
    {
      x += element.offsetLeft;
      //bug in ie - when using 'relative right:50px' the offsetLeft is wrong //TODO: check in firefox  (dan-el)
 			if(element.style.position=="relative" && element.style.right.contains("px") && element.offsetParent!=element.parentElement)
			{
				x-=element.style.pixelRight;
			}
      if(posInfo!=null)
        posInfo.offsetParent = element;
      if (isMoz && element.currentStyle.position=="fixed")
        element = null;
      else
        element = element.offsetParent;
    }
    if (includeFrames && originalElement.document.parentWindow.frameElement!=null)
    {
      var f = originalElement.document.parentWindow.frameElement;
      var fb = 0;
      if(f.frameBorder == "1" || f.frameBorder == "yes")
        fb = 2;
      x += G2_GetAbsoluteLeft(f, includeFrames) + fb;
    }
    return x;
	},

	G2_GetAbsoluteTop : function(element, includeFrames, posInfo) 
	{
	  var y = 0;
    var originalElement = element;
    while( element != null ) 
    {
      y += element.offsetTop;

			// taking into account scrooling with in overflow scroll elements
      if(element.tagName != 'HTML' && element.scrollTop != null)
				y -= element.scrollTop;
			if(element.tagName == 'IFRAME')
				y -= document.documentElement.scrollTop;

      if(posInfo!=null)
        posInfo.offsetParent = element;
      if (isMoz && element.currentStyle.position=="fixed")
        element = null;
      else
        element = element.offsetParent;
    }
    if (includeFrames && originalElement.document.parentWindow.frameElement!=null)
    {
      var f = originalElement.document.parentWindow.frameElement;
      var fb = 0;
      if(f.frameBorder == "1" || f.frameBorder == "yes")
        fb = 2;
      y += G2_GetAbsoluteTop(f, includeFrames) + fb;
    }
    return y;
	},
	G2_GetAbsoluteBottom : function(element, includeFrames) 
	{
		return G2_GetAbsoluteTop(element, includeFrames)+element.offsetHeight;
	},
	G2_GetAbsoluteRight : function(element, includeFrames) 
	{
		return G2_GetAbsoluteLeft(element, includeFrames)+element.offsetWidth;
	},
	isInSyntheticPopup : function()
	{
		return (parent.document.body.closeSyntheticPopup!=null || document.body.closeSyntheticPopup!=null);
	},

	/**
			This method is called by G2Page.CloseWindow()


	**/
	 G2_ClosePopupWindow : function(openerFunctionScript_functionToCall,
										result,
										firePopupClosedOnOpener,
										fireCloseScript_functionToCall,
										fireCloseScript_windowID,
										fireCloseScript_forceSilentPopupClosedOnOpener)
	{
	  // The window parent should register G2PopupWindow2.js in order to 
	  // Get the popup window (the problem happens when the parent window
	  // of the popup is not the same as the window which open the popup)
		if(window.parent!=window && window.parent.G2PopupWindow2!=null)
		{
			var popup = window.parent.G2PopupWindow2.GetCurrentPopup(window);
			if(popup!=null)
			{
				var silent = fireCloseScript_forceSilentPopupClosedOnOpener ? true : null;
				popup.Close(firePopupClosedOnOpener, fireCloseScript_windowID, silent);
				return;
			}
		}
			if (isInSyntheticPopup())
				return G2_CloseSyntheticPopupWindow(openerFunctionScript_functionToCall,
										result,
										firePopupClosedOnOpener,
										fireCloseScript_functionToCall,
										fireCloseScript_windowID,
										fireCloseScript_forceSilentPopupClosedOnOpener);
				
			var op = window.top.opener;    
			if (op == null && window.dialogArguments == null)
			{
					//'Access Denied' detected.
					if (!String.IsNullOrEmpty(result))
							throw "Error - Result cannot be set with SSL Pages. To return a value from a popup to its opener, use the returnValue property on G2Page.";
					window.top.close();
					return;
			}
			else
			{            
					if (op == null)
						op = window.dialogArguments.obj;
						
					if (!String.IsNullOrEmpty(openerFunctionScript_functionToCall))
					{
									var openerFunction = op[openerFunctionScript_functionToCall];
									openerFunction(result);
					}
	        
					if (window.top.dialogArguments)
							window.top.dialogArguments.CloseEventFired = true;
					window.top.close();
	        
					if (firePopupClosedOnOpener)
					{
						try
						{
							var closeCallback = op.G2_FirePopupClosed;
							if (closeCallback!=null)
								closeCallback.call(op,fireCloseScript_windowID,result,fireCloseScript_forceSilentPopupClosedOnOpener);        
						}
						catch(accessDenied)
						{
							//This is a known limitation. SSL pages and non-SSL pages cannot communicate with each other
						}
							
					}       
			}
	},


	G2_FindElementById : function(element, id)
	{
		return _G2_FindElementById(element, id);
	},
	_G2_FindElementById : function(element, id)
	{
		if(element.id==id)
			return element;	
		if(element.doesNotContainInputs || element.tagName=="SELECT")
			return null;

		var child = element.firstChild;
		while(child!=null)
		{
			var el = _G2_FindElementById(child, id);
			if(el!=null)
				return el;
			child = child.nextSibling;
		}
		return null;
	},

	G2_FindParentElementByG2Tag : function(element, g2tag)
	{
		return _G2_FindParentElementByG2Tag(element, g2tag);
	},
	_G2_FindParentElementByG2Tag : function(element, g2tag)
	{
		if(element==null)
			return null;
		if(G2DOM.G2GetAttribute(element,'g2tag')==g2tag)
			return element;
		return _G2_FindParentElementByG2Tag(element.parentElement, g2tag);
	},

	G2_FindElementByTagName : function(element, tagName)
	{
		if(element.tagName==tagName)
			return element;	
		var child = element.firstChild;
		while(child!=null)
		{
			var el = G2_FindElementByTagName(child, tagName);
			if(el!=null)
				return el;
			child = child.nextSibling;
		}
		return null;
	},

	G2_FindNodeByNameValue : function(element, name, value)
	{
		if(element[name]==value)
			return element;	
		var child = element.firstChild;
		while(child!=null)
		{
			var el = G2_FindNodeByNameValue(child, name, value);
			if(el!=null)
				return el;
			child = child.nextSibling;
		}
		return null;
	},


	// When a page detects it is opened in a popup window, it calls this method
	G2Dialog_Init : function()
	{
		//Try accessing window.top.dialogArguments
		try
		{
			if (window.top.dialogArguments!=null)
			{
				//If that succeeds, we are in a non-SSL popup 
				//In that case, un-hook the onunload event handler
				window.top.document.getElementById('IFRM').contentWindow.onunload = null;		
				
			}
		} catch(bloodyerror)
		{
		}
	},
	G2_FireEventArray : function(owner, array)
	{
		for(var i=0;i<array.length;i++)
		{
			array[i](array.owner);
		}
	},

	G2_GetChildControlById : function(namingContainer, innerElementId)
	{
		return document.getElementById(namingContainer.id+"_"+innerElementId);
	},

	G2FindControlsById : function(controlIds)
	{
		var ret = [];
		if(controlIds==null)
			return ret;
		if (typeof(controlIds)=="string")
		{
			if (controlIds.length==0)
				return ret;			
			controlIds = controlIds.split(/,/g);	
		}
		for(var i=0,j=controlIds.length;i<j;i++)
		{
				var ctrl = document.getElementById(controlIds[i]);
				if (ctrl)
					ret.push(ctrl);
		}
		return ret;
	},

	G2ContextChange : function(func,context)
	{
		return function()
		{
			func.apply(context,arguments);
		}
	},
	
	//***********************************************************
	//                   Processing image                       *
	//***********************************************************
	
	getProcessingImageID : function()
	{
	  return window.ProcessingImageID;
	},
	
	setProcessingImageID : function(value)
	{
	  if(window.ProcessingImageID == value)
	    return;
	  window.ProcessingImageID = value;
	  window.ProcessingImage = null;
	},
	
	getProcessingImage : function()
	{
	  if(window.ProcessingImage==null && ProcessingImageID!=null)
	    window.ProcessingImage = document.getElementById(ProcessingImageID);
	  return window.ProcessingImage;
	},
	
	getElementsToHideWhileProcessing_Cache : function()
	{
	 if(window.ElementsToHideWhileProcessing_Cache == null)
	 {
	  window.ElementsToHideWhileProcessing_Cache = [];
	  
	  if(window.ElementsToHideWhileProcessing!=null)
	  {
	    var list = window.ElementsToHideWhileProcessing.split(',');
	    var eth = window.ElementsToHideWhileProcessing_Cache;
	    for (var i=0;i<list.length;i++)
		  {
			  var e = document.getElementById(list[i]);
			  if (e==null)
				  continue;
  			  
			  eth.push(e);
		  }
	   }
	 }
	 return window.ElementsToHideWhileProcessing_Cache;
	},
	
	getElementsToHideWhileProcessing : function()
	{
	  if(window.ElementsToHideWhileProcessing==null)
	    return "";
	  return window.ElementsToHideWhileProcessing;
	},
      
  setElementsToHideWhileProcessing : function(value)
	{
	  if(window.ElementsToHideWhileProcessing==value)
	    return;
	  window.ElementsToHideWhileProcessing = value;
	  window.ElementsToHideWhileProcessing_Cache = null;
	},
	  
	ShowProcessingImage : function(targetEl)
	{
		//flag that the processing image is activated
		window.ProcessingImageActive = true;
		var eventX = -1;
		var eventY = -1;
		if (!isMoz && event && event.type != "")
		{
			eventX = event.clientX;
			eventY = event.clientY;
		}
		window.setTimeout(function() {ShowProcessingImage_Timeout(targetEl, eventX, eventY);}, 100);
	},

	ShowProcessingImage_Timeout : function(targetEl, eventX, eventY)
	{
	//This function is running asynchronously, so we must check 
	//if the processing image is still required, and hasn't been switched off.
		if (window.ProcessingImageActive == false)
			return;
	    
		var processingImage = getProcessingImage();
		
		//Hide other elements
		var list = window.getElementsToHideWhileProcessing_Cache();
		for (var i=0;i<list.length;i++)
		{
			list[i].style.display='none';
		}
		
		//show processing image
		if (processingImage != null)
		{
			processingImage.style.display = '';
			if (processingImage.isDynamic == 'true')
			{   
					G2_ShowDisabler(true);
					processingImage.style.zIndex = 10001;
					
					if (eventX != -1 && eventY != -1)
					{
							processingImage.style.position = 'absolute';
							processingImage.style.left = Math.max(0, document.documentElement.scrollLeft + eventX - (processingImage.scrollWidth) / 2) + "px";
							processingImage.style.top = Math.max(0, document.documentElement.scrollTop + eventY - (processingImage.scrollHeight / 2)) + "px";
					}
					else
					{
						G2_PlaceElementAbsolutlyNear(processingImage, targetEl, "bl:bl", true);
						G2_VerifyAbsoluteElementNotCropped(processingImage);
					}
			}
		}
	},

	HideProcessingImage : function()
	{
		//switch flag off
		window.ProcessingImageActive = false;
		if (G2_IsNavigating())
		{
			return; //Keep the processing image until we are done navigating
		}	
		
		//hide processing image
		var processingImage = getProcessingImage();
		if (processingImage != null)
		{
			//Debug.writeln("hiding processing image: "+processingImage.id);
			processingImage.style.display = 'none';
		}
		
		//Show other elements
		var list = window.getElementsToHideWhileProcessing_Cache();
		for (var i=0;i<list.length;i++)
		{
			list[i].style.display='block';
		}
	},
	G2_PrintPopup : function(target)
	{
		if(G2_IsInPopup())
		{
			var win = window.open(target.location.href + "&HideButtons=true");
			if(win!=null)
			{
				G2_AttachEvent(win, "onload", function()
				{
					window.setTimeout(function(){	win.print();win.close();}, 500);
				});
			}
		}
		else
		{
			target.focus(); 
			target.print(); 
		}
	},
	// printing an html table
	Print : function(tableId)
	{
		window.focus();
		//Added by Arnon in case 5103
		var TableToPrintObj = document.getElementById(tableId)
		var TableToPrintWidth;
		if(TableToPrintObj && !(typeof document.body.style.maxHeight != "undefined"))//Not IE 7 and ID exist
		{
			// changeing width to fit printing sheet
			TableToPrintWidth = TableToPrintObj.style.pixelWidth;
			TableToPrintObj.style.width="640px";
		}
		window.print();
		if(TableToPrintObj && !(typeof document.body.style.maxHeight != "undefined")) //Not IE 7 and ID exist
		{
			// restore width
			TableToPrintObj.style.width=TableToPrintWidth+"px";
		}
	},
	G2_PreventInputPost : function(id)
	{
		if(typeof(id)=="string")
			G2_PreventPostElementIds[id] = true;
		else
			Debug.writeln("id is not a string");
		//input.disabled = true;
	},
	Select_SetAllSelected : function(select, selected)
	{
		if(select.tagName!="SELECT")
			throw new Error("Select Object expected "+select.tagName);
		//The visibility trick optimizes the selection performance
		var useVisiblityTrick = select.style.visibility=="";
		if(useVisiblityTrick)
			select.style.visibility = "hidden";
		var option = select.options[0];
		while(option!=null)
		{
			if(option.tagName=="OPTION")
				option.selected = selected;
			option = option.nextSibling;
		}
		G2.notifyInputChanged(select);
		if(useVisiblityTrick)
			select.style.visibility = "";
	},
	G2ListBox_SelectAll : function(id)
	{
		var select = $(id);
		if(select==null || select.disabled)
			return;
		Select_SetAllSelected(select, true);
	},
	G2ListBox_SelectNone : function(id)
	{
		var select = $(id);
		if(select==null || select.disabled)
			return;
		Select_SetAllSelected(select, false);	
	},
	G2_DisableBack : function()
	{
			if (window.backIsDisabled != true)
			{
				window.backIsDisabled = true;
				for(var i=0;i<2;i++)
				{
					window.location.hash = "#p"+i;
				}

				window.setInterval(function()
				{
				    if(docTitle!= null)
				    {
				        document.title = docTitle;
				    }
				    if(window.history.forward(1) != null)
						window.history.forward(1);
				}, 100);

			}
		},
		G2_ShowBeforeUnloadMessage : function (e, message, checkFunction)
		{
			if (window.allowUnloadMessage == false)
			{
				window.allowUnloadMessage = true;
			  return;
			}
			if (window[checkFunction] != null)
				if (!window[checkFunction]())
					return;
			return message;
		},
		
		// ------------------------- G2Alert ----------------------------
		//open alert Popup
		G2Alert : function(message, width)
		{
			if(width == null)
				width = 200;
				
			var doc = window.top.document;
			// build alert html
			var alertObj = doc.createElement("DIV");
			
			alertObj.innerHTML = '<TABLE style="width:' + width + '" class=modalPopup><TBODY>' +
			'<TR>' +
			'<TD style="PADDING-TOP: 5px" align="center">' +
			message + 
			'</TD></TR>' +
			'<TR>' +
			'<TD style="PADDING-TOP: 10px;cursor:pointer" align="center" onclick="G2CloseAlert();"><u>OK</u></TD>' +
			'</TR></TBODY></TABLE>';

			 // clone the Div and show the clone
			 alertObj.id = "AlertDiv";

			//return if already shown
			if (alertObj.style.display == 'block')
				return;
				
			// append messagePopup to the form and not to the body (case 11229)
			var container = doc.forms[0];
			
			// create a cover div 
			var coverDiv = G2_CreateModalCoverDiv();
			coverDiv.style.filter = "alpha(opacity=70)";

			// append cover div to form
			if(container != null)
				container.appendChild(coverDiv);
			else
				doc.getElementsByTagName("body")[0].appendChild(coverDiv);

			//set popup div position
			alertObj.style.position = 'absolute';
			
			alertObj.style.left = Math.max(0, doc.documentElement.scrollLeft + (doc.documentElement.clientWidth / 2) - (alertObj.scrollWidth / 2)) + "px";
			alertObj.style.top = Math.max(0, doc.documentElement.scrollTop + (doc.documentElement.clientHeight / 2) - (alertObj.scrollHeight / 2)) + "px";

			alertObj.style.zIndex = 1001;
			G2_AttachFrame(alertObj);

			// append element to form
			if(container != null)
				container.appendChild(alertObj);
			else
				doc.body.appendChild(alertObj);
			
			// verify that the popup is in the boreder of the screen
			G2_VerifyAbsoluteElementNotCropped(alertObj);
		},
		
		// close alert popup
		G2CloseAlert : function()
		{
			var doc = window.top.document;
			var alertObj = doc.getElementById("AlertDiv");
			// remove the cloned Div
			var container = alertObj.parentElement;
			if (alertObj != null && container !=  null)
				container.removeChild(alertObj);
			// remove the cover Div
			var coverDiv = doc.getElementById("CoverDiv");
			container = coverDiv.parentElement;
			if (coverDiv != null && container !=  null)
					container.removeChild(coverDiv);
			G2_DetachFrame(alertObj);
		},

		//create cover div for the modal effect
		G2_CreateModalCoverDiv : function(win)
		{
			var doc = window.top.document;
			if(win != null)
				doc = win.document;
				
			var coverDiv = doc.createElement('DIV');
			coverDiv.id = "CoverDiv";
			coverDiv.className = "CoverDiv";
			coverDiv.style.left = "0px";
			coverDiv.style.top = "0px";
			docHeight = Math.max (doc.documentElement.offsetHeight,doc.documentElement.scrollHeight);
			docWidth = Math.max ( doc.documentElement.offsetWidth, doc.documentElement.scrollWidth);
			coverDiv.style.height = docHeight+"px";
			coverDiv.style.width = docWidth+"px";
			coverDiv.style.zIndex="10";
			coverDiv.style.position="absolute";
			return coverDiv;
		},
		
		G2_VerifyScrollableElementHeight : function(pnlID, maxHeight)
		{
			var pnl = $(pnlID);
			if(pnl == null)
				return;
			if(maxHeight == null || maxHeight == 0)
				return;
				
			if(pnl.clientHeight > maxHeight)
			{
				pnl.style.overflowY = 'scroll';
				pnl.style.height = maxHeight;
			}
		},
		G2_VerifyScrollableElementWidth : function(pnlID, maxWidth)
		{
			var pnl = $(pnlID);
			if(pnl == null)
				return;
			if(maxWidth == null || maxWidth == 0)
				return;
				
			if(pnl.clientWidth > maxWidth)
			{
				pnl.style.overflowX = 'scroll';
				pnl.style.width = maxWidth;
			}
		}
	
});
G2_PreventPostElementIds = new Object();

//**************************************************************************************************

WebForm_InitCallback = function(){};//this is disabled in purpose. we use G2_InitCallback;
var G2_SetFocus_ThreadId = null;
//var G2_InitCallbackFirstTime = true;
var _registeredScripts;
var HtmlSelectEmptyValue = "_NULL_"; //empty strings causes problems with tabs and selectedIndex

if(typeof(Date_ShortMonthNames)=="undefined")
	Date_ShortMonthNames = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
if(typeof(Date_MonthNames)=="undefined")
	Date_MonthNames = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
if(typeof(G2_ShortDays)=="undefined")
	G2_ShortDays = ["Su","Mo","Tu","We","Th","Fr","Sa"];

var G2_maxZ=999;
var G2_FixFrame = null;
var enableResizing = false; 
var G2Tooltips = new Array();



G2_PreventInputPost("G2_RootAppPath");





String.IsNullOrEmpty = function(value)
{
	return value==null || value=="";
}

String.Format = function(format, args)
{
	for(var i=1;i<arguments.length;i++)
	{
		var arg = arguments[i];
		var exp = new RegExp("[{]"+(i-1)+"[}]", "g");
		format = format.replace(exp, arg);
	}
	return format;
}

String.Replace = function(s, search, replace)
{
	var exp = new RegExp(search, "g");
	return s.replace(exp, replace);
}








//**************************************************************************************************






function Stopper()
{
	this.laps = new Array();
	this.lapsInfos = new Array();
}

Stopper.prototype.start = function ()
{
	var now = new Date();
	this.laps.push(now);
}

Stopper.prototype.lap = function (name)
{
	var now = new Date();
	this.laps.push(now);
	if(name==null)
	  name="Lap";
	this.lapsInfos.push(name);
	return now-this.laps[this.laps.length-2];
}

Stopper.prototype.total = function ()
{
	var now = new Date();
	return now-this.laps[0];
}

Stopper.prototype.maxIndex = function ()
{
  var maxIndex = -1;
  var max=0;
	for(var i=1; i<this.laps.length; i++)
	{
	  var start = this.laps[i];
	  var end = this.laps[i-1];
	  var lap = start-end;
	  if(lap>max)
	  {
	    maxIndex = i;
	    max = lap;
	  }
  }
  return maxIndex;
}

Stopper.prototype.totalLaps = function ()
{
	var start = this.laps[0];
	var end = this.laps[this.laps.length-1];
	return end-start;
}

var StopperWinID = 0;
Stopper.prototype.report = function (title)
{
  var winID = "Stoper_"+StopperWinID;
  StopperWinID++;
	var win = window.open(null, winID, "height=300,width=300,status=no,toolbar=no, menubar=no, location=no, resizable=yes");
	var doc = win.document;
	doc.open();
	
	doc.write("<html><body>");
	//var now = new Date();
	doc.write("<div style='font-size:8px;'><b>"+title+"</b></div>");
	var maxIndex = this.maxIndex();
	doc.write("<table>");
	doc.write("<tbody>");
	for(var i=1; i<this.laps.length; i++)
	{
	  var start = this.laps[i];
	  var end = this.laps[i-1];
	  doc.write("<tr>");
	  doc.write("<td>");
	  doc.write("<div style='"); 
	  if(i==maxIndex)
	  {
	    doc.write("color:red;");
	  }
	  doc.write("'>"+i.toString());
	  doc.write("</div>");
	  doc.write("</td>");
	  doc.write("<td>");
	  doc.write(this.lapsInfos[i-1]);
	  doc.write("</td>");
	  doc.write("<td>");
	  doc.write((start-end)+"");
	  doc.write("</td>");
	  doc.write("</tr>");
	}
	doc.write("</tbody>");
	doc.write("</table>");
	doc.write("<hr />");
	doc.write("<div style='color:blue'>Total: <b>" + this.totalLaps()+ "</b>ms</div>"); 
	doc.write("</body></html>");
	doc.close();	
}


var specialCopyKey = 17; //ctrl + q 



Char = 
{
	Backspace : 8,
	Tab : 9,
	Enter : 13,
	Ctrl : 16,
	Alt : 17,
	Pause : 19,
	CapsLock : 20,
	Escape : 27,
	PageUp : 33,
	PageDown : 34,
	End : 35,
	Home : 36,
	ArrowLeft : 37,
	ArrowUp : 38,
	ArrowRight : 39,
	ArrowDown : 40,
	Insert : 45,
	Delete : 46,
	categories : {Digit:/[0-9]/, Upper:/[A-Z]/, Lower:/[a-z]/},
	IsDigit : function(charOrCode)
	{
		return this.IsInCategory(charOrCode, "Digit");
	},
	IsInCategory : function(charOrCode, categoryName)
	{
		if(charOrCode==null)
			return false;
		var s = typeof(charOrCode)=="number" ? String.fromCharCode(charOrCode) : charOrCode;
		return this.categories[categoryName].test(s);
	},
	IsUpper : function(charOrCode)
	{
		return this.IsInCategory(charOrCode, "Upper");
	},
	IsLower : function(charOrCode)
	{
		return this.IsInCategory(charOrCode, "Lower");
	},
	ToUpperKeyCode : function(keyCode)
	{
		return keyCode-32;
	},
	//
	// returns a value indicating whether the given charCode is a key that changes the cursor position
	//
	IsCursorPositionCharCode : function (charCode)
	{
		if
		(
			charCode==this.ArrowUp || 
			charCode==this.ArrowDown || 
			charCode==this.ArrowLeft || 
			charCode==this.ArrowRight || 
			charCode==this.Home || 
			charCode==this.End || 
			charCode==this.PageUp || 
			charCode==this.PageDown
		)
		{
			return true;
		}
		return false;
	}


}

//46 Delete 
//TODO:
//91 Left Windows 
//92 Right Windows 
//93 Context Menu 
//96 NumPad 0 
//97 NumPad 1 
//98 NumPad 2 
//99 NumPad 3 
//100 NumPad 4 
//101 NumPad 5 
//102 NumPad 6 
//103 NumPad 7 
//104 NumPad 8 
//105 NumPad 9 
//106 NumPad * 
//107 NumPad + 
//109 NumPad - 
//110 NumPad . 
//111 NumPad / 
//112 F1 
//113 F2 
//114 F3 
//115 F4 
//116 F5 
//117 F6 
//118 F7 
//119 F8 
//120 F9 
//121 F10 
//122 F11 
//123 F12 
//144 Num Lock 
//145 Scroll Lock 
//186 ; 
//187 = 
//188 , 
//189 - 
//190 . 
//191 / 
//192 ` 
//219 [ 
//220 \ 
//221 ] 
//222 ' 


function G2KeysClass()
{
  this.up = 38; //up arrow  
  this.down = 40; //down arrow
  this.left =  37; //left arrow
  this.right =  39; //right arrow
  this.pageUp =  33; //page up  
  this.pageDown =  34; //page down  
  this.home =  36; //home  
  this.end =  35; //end                  
  this.enter =  13; //enter  
  this.tab =  9; //tab  
  this.esc =  27; //esc  
  this.shift =  16; //shift  
  this.ctrl =  17; //ctrl  
  this.alt =  18; //alt  
  this.caps =  20; //caps lock
  this.backspace =  8; //backspace  
  this.del =  46; //delete
  
  this.controlKeys = new Array(this.up, this.down, this.left, this.right, this.pageUp, this.pageDown, this.home, this.end, this.enter, this.tab, this.shift, this.ctrl, this.alt, this.caps, this.backspace, this.del);
}
var G2Keys = new G2KeysClass();


G2EventArray = function(owner)
{
	this.owner = owner;
}
G2_DeclareClass(G2EventArray, "G2EventArray", Array,
{
	fire : function()
	{
		for(var i=0;i<this.length;i++)
		{
			this[i](this.owner);
		}
	}
});




//Add trim() to String.
String.prototype.trim = trim;
	/*
	function G2PopupWindow_Open2(url, context, modal, name, features)
	{	
		if (features==null && context!=null)
		{
			var h = document.all[context];
			if(h!=null)
				features = h.value;
		}   
		if (modal==null)
			modal=true;
			
		if(modal)
		{
			var h = G2PopupWindow_ExtractParameter(features,"dialogHeight");
			var w = G2PopupWindow_ExtractParameter(features,"dialogWidth");
					
			//Fix for callbacks on popup closed event
			var me = window;
			function f()
			{
				window.showModalDialog(G2_MapPath("~/Client/Dialog.aspx"),{url:url,obj:me,width:w,height:h}, features);
			}		
			f();
		}
		else
		{
	  
			//Workaround for bug #3634: 
			// IE popup blocker blocked the popup, because it was not initiated by a user click.		
			
			//Note: The following is a workaround for IE popup blockers. It is not jiffacode.
			var temporaryButton = G2DOM.G2CreateElement("<input type='Button' style='display:none'></input>");
			temporaryButton.id = temporaryButton.uniqueID;
			temporaryButton.onclick = function()
			{
				if (null == window.open(url, name, features))
				{
					alert('popup blocker detected!');
				}
			}
			document.body.appendChild(temporaryButton);
			temporaryButton.click();
			document.body.removeChild(temporaryButton);
		}
	}*/
if(ENABLE_PROFILER)
	Profiler.createDebugDiv();

ListSet = function()
{
	this._list = [];
	this._set = {};
}
G2_DeclareClass(ListSet, "ListSet", null, 
{
	addRange : function(array)
	{
		for(var i=0;i<array.length;i++)
		{
			this.add(array[i]);
		}
	},
	add : function(item)
	{
		if(this._set[item]!=null)
			return false;
		this._list.push(item);
		this._set[item] = this._list.length-1;
		return true;
	},
	remove : function(item)
	{
		if(this._set[item]==null)
			return false;
		var index = this._set[item];
		this._list.splice(index, 1); //removeAt
		this._set[item] = null;
		for(var i=index;i<this._list.length;i++) //perform reindexing
		{
			var item = this._list[index];
			this._set[item] = index;
		}
		return true;
	},
	toString : function(seperator)
	{
		return this._list.join(seperator);
	}
	
});

/* G2PopupManager
Manages all popups and tooltips within the application.
*/
G2PopupManager = 
{
//	popups : {},
//	tooltipTargets : [],
//	allowTooltips : true,
	
	init : function()
	{
		this.attachToOnClick(document, true);
		this.allowTooltips = true;
		if(window.top.G2PopupManager==this)
		{
		  this.popups = new Object();
		  this.tooltipTargets = new Array();
		}
		else
		{
		  var tm = window.top.G2PopupManager;
		  this.popups = tm.popups;
		  this.tooltipTargets = tm.tooltipTargets;
		}
	},
		
	attachToOnClick : function(doc, includeFrames)
	{
	  if(doc.attachEvent) //G2Dom is not available right now
		{
			doc.attachEvent("onmousedown", this.__document_onclick);
//			if(IE6) //memory leaks
//			  doc.parentWindow.attachEvent("onunload", this.window_onunload);
		}
		else if(document.addEventListener)
		{
			doc.addEventListener("mousedown", this.__document_onclick, false);
		}
//		if(!includeFrames || doc.parentWindow==null || doc.parentWindow.document==doc)
//		  return;
//		
//	  doc = doc.parentWindow.document;
//	  this.attachToOnClick(doc, includeFrames);
	},
	window_onunload : function(e)
	{
	  G2PopupManager.unload();
	},
	unload : function(e)
	{
	  for(var p in this.popups)
	  {
	    this.popups[p] = null;
	  }
	},
	__document_onclick : function(e)
	{
		G2PopupManager._document_onclick(e);
	},
	_document_onclick : function(e)
	{
		var element = e.srcElement;
		
		if(element!=null && element.tagName=="HTML")
		  return;//Clicked on scroll, ignore
		 
		while(element!=null)
		{
			var popup = this.popups[element.uniqueID];
			if(popup!=null)
				return;
			element = element.parentElement;
		}
		this.closeAllPopups(true);
		this.closeAllTooltips();
	},
	
	//Use this method to display a popup element relatively to a specific element
	//
	openPopup : function(element, relativeElement, dock, onTopWindow)
	{
		this.closeAllPopups();
		var popup = {element:element, relativeElement:relativeElement, dock:dock, isOpen:true, allowCloseOnDocumentClick:false};
		this.popups[element.uniqueID] = popup;
		if(relativeElement==null)
			throw new Error("relative element not found, cannot show popup");
		if(element.g2closepopup=="false")
			element.style.display = "";
		G2_PlaceElementAbsolutlyNear(element, relativeElement, dock, onTopWindow);
		if(dock==null || !dock.contains(","))
			G2_VerifyAbsoluteElementNotCropped(element);
		G2_BringToFront(element);
		G2_AttachFrame(element);
		
		window.setTimeout(
		function()
		{
			popup.allowCloseOnDocumentClick = true;
		}, 0);
		
	  if (element.onOpened!=null)
	    element.onOpened(element);			
	},
	
	//Closes all registered popups in the window
	closeAllPopups : function(isDocumentClick)
	{
		for(var p in this.popups)
		{
			var pp = this.popups[p];
			if(pp!=null && pp.isOpen)
			{
				if(isDocumentClick && !pp.allowCloseOnDocumentClick)
					continue;
				this.closePopup(pp.element);
			}
		}
	},
	isPopupOpened : function(element)
	{
		var popup = this.getPopup(element);
		if(popup!=null && popup.isOpen)
			return true;
		return false;
	},
	
	//Retrives a specific popup element
	getPopup : function(element)
	{
		return this.popups[element.uniqueID];
	},
	
	//Closes a given popup by its element
	closePopup : function(element)
	{
		var popup = this.getPopup(element);
		if(popup==null)
			return;
		if (popup.element.onBeforeClose!=null)
		  popup.element.onBeforeClose(popup.element);
		G2_DetachFrame(element);
		if(element.g2closepopup=="false")
		{
			element.style.display = "none";
		}
		else if(element.parentElement!=null)
		{
			element.parentElement.removeChild(element);
		}
		popup.isOpen = false;
		if(element.onPopupClosed)
		  element.onPopupClosed();
		 
		delete this.popups[element.uniqueID];
	},
	
	
	
	//Displayes the provided HTML as a tooltip
	//A typical use is to attach an onmouseenter handler to the target element such as
	//target.onomuseenter = "G2PopupManager.showTooltipHtml(this, '<b>Hello</b>', event);";
	showTooltipHtml : function(targetElement, html, e)
  {
	  if (!e)
		  e = window.event;
  	
	  var el = targetElement._tooltipElement;
	  if(el==null)
	  {
	    el = G2DOM.G2CreateElementFromHtml("<TABLE border='0' cellpadding='0' cellspacing='0'><TR><TD>"+html+"</TD></TR></TABLE>");
	    if(el.parentElement!=null)//TODO: Remove quick fix
	      el.parentElement.removeChild(el);
	  }
	  this.showTooltipStart(targetElement, el,e);
  },
  
  showTooltipText : function(targetElement, text, e)
  {
    if (!e)
		  e = window.event;
	  var html = "<div style='background-color: #fffacd;border-right: black 1px solid;border-top: black 1px solid;font-size: 8pt;border-left: black 1px solid;color: black;border-bottom: black 1px solid;font-family: Arial;padding:4px;'>"+text+"</div>";
	  this.showTooltipHtml(targetElement, html, e);
  },
  
  showTooltipStart : function(targetElement, el,e)
  {
    if(!this.allowTooltips)//Tooltips are disabled during postbacks
      return;
	  if (!e)
		  e = window.event;
	  
	  this.closeAllTooltips();
	  targetElement._tooltipElement = el;//Cache
	  
	  var posx = 0;
	  var posy = 0;
	  var winWidth = 1024;
	  var winHeight = 700;
  	 
  	if(el.parentElement == null)
  	  document.body.appendChild(el);
	  el.style.position="absolute";
	  offSet = 0
	  if (e.pageX || e.pageY)
	  {
		  winWidth = window.innerWidth;
		  winHeight = window.innerHeight;
		  posx = e.pageX;// + window.pageXOffset;
		  posy = e.pageY;// + window.pageYOffset;
	  }
	  else if (e.clientX || e.clientY)
	  {
		  winWidth = document.body.offsetWidth;
		  winHeight = document.body.offsetHeight;
		  posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		  posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	  }
	  
	  el.style.display = "block";
	  
	  //Fix flowing out of window
		var right = posx + el.offsetWidth;
	  if(right>winWidth)
	  {
	    var newPosx = (posx-el.offsetWidth);
	    if(newPosx>0)
	      posx = newPosx;
	  }
		var bottom = posy + el.offsetHeight;
	  if(bottom>winHeight)
	  {
	    newPosy = (posy-el.offsetHeight);
	    if(newPosy>0)
	      posy = newPosy; 
	  }
	  
	  posy++;		//Avoid some flickering in FireFox
	  el.style.pixelLeft = posx;
	  el.style.pixelTop = posy;
	  G2_VerifyAbsoluteElementNotCropped(el);
	  
	  targetElement.title = "";
	  this.tooltipTargets.push(targetElement);
	  
	  
	  
	  G2_BringToFront(el);
	  G2_AttachFrame(el);
	  el.enterToolTip = false;
	  	  
      if(targetElement.onmouseleave==null)
      {
          targetElement.onmouseleave=function(){
            setTimeout(function(){CloseIfNotInToolTip(targetElement, el)}, 500);
          };
          if (isMoz)
          {
            G2_AttachEvent(targetElement, "onmouseout",targetElement.onmouseleave); 
          }	    
	   }
	  if(el.onmouseenter==null)
      {
          el.onmouseenter=function(){el.enterToolTip = true;}; 
          if (isMoz)
          {
            G2_AttachEvent(el, "onmousein",el.onmouseenter); 
          }	      
	  }
	  if(el.onmouseleave==null)
      {
          el.onmouseleave=function(){
            G2PopupManager.closeTooltipFor(targetElement);
            el.enterToolTip = false;
          }; 
          if (isMoz)
          {
            G2_AttachEvent(el, "onmouseout",el.onmouseleave); 
          }	      
	  }
	  if(el.onmousedown==null)
      {
          el.onmousedown=function(){
           e.cancelBubble = true;
          };   
	  }
  },	
  closeAllTooltips : function()
  {
    while(this.tooltipTargets.length > 0)
    {
      var tt = this.tooltipTargets.pop();
      this.closeTooltipFor(tt);
    }
  },
  closeTooltipFor : function(targetElement)
	{
	  if(targetElement._tooltipElement !=null)
	    targetElement._tooltipElement.style.display="none";
	  G2_DetachFrame(targetElement._tooltipElement);
	},
	
	disableTooltips : function()
	{
	  this.allowTooltips = false;
	},
	
	enableTooltips : function()
	{
	  this.allowTooltips = true;
	}
	
};
G2_DeclareUtilInstance(G2PopupManager);
G2PopupManager.init();

G2FrameManager = 
{
	autoSizeThreadId : null,
	frames : {},
	registerFrame : function(frameOrId)
	{
		if(typeof(frameOrId)=="string")
			this.frames[frameOrId] = null;
		else
			this.frames[frameOrId.id] = frameOrId;
		if(this.autoSizeThreadId==null)
		{
			var caller = this;
			this.autoSizeThreadId = window.setInterval(
			function()
			{
				caller.autoSizeAllFrames();
			}, 300);
		}
	},
	unregisterFrame : function(frame)
	{
	    delete this.frames[frame.id];
	},
	autoSizeAllFrames : function()
	{
		for(var id in this.frames)
		{
			var frame = this.frames[id];
			if(frame==null)
			{
				frame = document.getElementById(id);
				this.frames[id] = frame;
			}
			frame.className = frame.className.replace("Hide", "");
			if(frame.autosize!="false" && frame.readyState=="complete")
			{
				try
				{
					if(frame.autosizeheight!="false")
					{
					  //  Following is the standard html page doctype definition as produced by Visual Studio with default settings
					  var doctypeString = '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">';
					  var height, includesDTD = false;
					  //  Check if doctype is one of iframe document childs and retrieve the proper scrollHeight value
					  for(var i=0; i<frame.contentWindow.document.childNodes.length; i++)
					  {
					    if(frame.contentWindow.document.childNodes[i].text == doctypeString)
					    {
					      includesDTD = true;
					      break;
					    }
					  }
					  if(includesDTD) 
						  height = frame.contentWindow.document.documentElement.scrollHeight;
						else
						  height = frame.contentWindow.document.body.scrollHeight;
						if(frame.style.pixelHeight!=height)
							frame.style.height = height+"px";
					}
					if(frame.autosizewidth!="false")
					{
						var width = frame.contentWindow.document.documentElement.scrollWidth;
						if(frame.style.pixelWidth!=width)
							frame.style.width = width+"px";
					}
				}
				catch(err)
				{
					1;
					1;
				}
			}
		}
	}
}
G2_DeclareUtilInstance(G2FrameManager);



function G2_Print()
{
  window.print();
}


//
// Allows performing actions in the background
// action = function + arguments
// when the action occurs - 'this' keywork returns the background worker
//
G2BackgroundWorker = function(maxConcurrentActions)
{
	this.actions = [];
	this.concurrentActionsCount = 0;
	this.maxConcurrentActions = maxConcurrentActions || 1;
}

G2_DeclareClass(G2BackgroundWorker, "G2BackgroundWorker", null, 
{
	addAction : function(func, args, options)
	{
		this.actions.push({func:func,args:args,options:options});
		if(this.actions.length==1)
		{
			this._requestDoWorkIfNeeded();
		}
	},
	_requestDoWorkIfNeeded : function()
	{
		var caller = this;
		if(this.actions.length>0)
		{
			window.setTimeout(
			function()
			{
				caller.doWork();
			}, 0);
		}
		else if(this.concurrentActionsCount<=0)
		{
			this.onFinish();
		}
	},
	onActionStart : function(action)
	{
		this.concurrentActionsCount++;
	},
	onActionEnd : function()
	{
		if(this.concurrentActionsCount<=0)
			throw new Error("no current actions");
		this.concurrentActionsCount--;
		this._requestDoWorkIfNeeded();
	},
	doWork : function()
	{
		while(this.concurrentActionsCount<this.maxConcurrentActions && this.actions.length>0)
		{
			var action = this.actions.dequeue();
			this.onActionStart(action);
			this.currentAction = action;
			action.func.apply(this, action.args);
			if(action.options==null || !action.options.manualActionEndNotification)
				this.onActionEnd();
		}
	},
	onFinish : function()
	{
	}


});

//All (crappy) focus code taken from asp.net
function G2_FindFirstFocusableChild(control) 
{
  if (!control || !(control.tagName)) 
	{
    return null;
  }
  var tagName = control.tagName.toLowerCase();
  if (tagName == "undefined") 
	{
    return null;
  }
  var children = control.childNodes;
  if (children) 
	{
    for (var i = 0; i < children.length; i++) 
		{
      try 
			{
        if (WebForm_CanFocus(children[i])) 
				{
          return children[i];
        }
        else 
				{
          var focused = WebForm_FindFirstFocusableChild(children[i]);
          if (WebForm_CanFocus(focused)) 
					{
            return focused;
          }
				}
			} 
			catch (e) 
			{
			}
		}
	}
	return null;
}

function G2_AutoFocus(focusId) 
{
  var targetControl;
  if (__nonMSDOMBrowser) 
	{
    targetControl = document.getElementById(focusId);
  }
  else 
	{
    targetControl = document.all[focusId];
  }
  var focused = targetControl;
  if (targetControl && (!WebForm_CanFocus(targetControl)) ) 
	{
      focused = WebForm_FindFirstFocusableChild(targetControl);
  }
  if (focused) 
	{
    try 
		{
      focused.focus();
      if (__nonMSDOMBrowser) 
			{
        focused.scrollIntoView(false);
      }
      if (window.__smartNav) 
			{
        window.__smartNav.ae = focused.id;
      }
      return true;
    }
    catch (e) 
		{
			return false;
    }
  }
  else
		return false;
}
function G2_CanFocus(element) 
{
    if (!element || !(element.tagName)) return false;
    var tagName = element.tagName.toLowerCase();
    return (!(element.disabled) &&
            (!(element.type) || element.type.toLowerCase() != "hidden") &&
            WebForm_IsFocusableTag(tagName) &&
            WebForm_IsInVisibleContainer(element)
            );
}
function G2_IsFocusableTag(tagName) 
{
    return (tagName == "input" ||
            tagName == "textarea" ||
            tagName == "select" ||
            tagName == "button" ||
            tagName == "a");
}
function G2_IsInVisibleContainer(ctrl) 
{
  var current = ctrl;
  while((typeof(current) != "undefined") && (current != null)) 
	{
    if (current.disabled ||
        ( typeof(current.style) != "undefined" &&
        ( ( typeof(current.style.display) != "undefined" &&
            current.style.display == "none") ||
            ( typeof(current.style.visibility) != "undefined" &&
            current.style.visibility == "hidden") ) ) ) 
		{
      return false;
    }
    if (typeof(current.parentNode) != "undefined" &&
            current.parentNode != null &&
            current.parentNode != current &&
            current.parentNode.tagName.toLowerCase() != "body") 
		{
      current = current.parentNode;
    }
    else 
		{
      return true;
    }
  }
  return true;
}

function G2_ShowDisabler(show) 
{
  if(window.g2disabler == null)
  {
    if(show==false)
      return;
    var html = "<div id='g2disabler' class='g2Disabler' onclick='return false;' onmouseover='return false;' onmouseout='return false;'></div>";
    var disablerElement= G2DOM.G2CreateElementFromHtml(html, document);
    document.body.appendChild(disablerElement);
    window.g2disabler = disablerElement;
  }
  if(show)
  {
    window.g2disabler.style.pixelHeight = document.documentElement.scrollHeight;
		window.g2disabler.style.pixelWidth = Math.max(document.documentElement.offsetWidth-4, 0);
    window.g2disabler.style.display = '';
    window.g2disabler.lastDocumentOverflowX = document.documentElement.style.overflowX;
		document.documentElement.style.overflowX = 'hidden';
  }
  else
  {
	  window.setTimeout(function() {
    window.g2disabler.style.display = 'none';
    document.documentElement.style.overflowX = window.g2disabler.lastDocumentOverflowX;}, 1);
  }
}

function G2_DetectAcrobatReader() 
{
    var acrobat=new Object(); 
    acrobat.installed=false; 
    acrobat.version='0.0'; 
    if (navigator.plugins && navigator.plugins.length) { 
        for (x=0; x<navigator.plugins.length;x++) { 
              if (navigator.plugins[x].description.indexOf('Adobe Acrobat')!= -1) 
              { 
                    acrobat.version=parseFloat(navigator.plugins[x].description.split('Version ')[1]); 
                    if (acrobat.version.toString().length == 1) acrobat.version+='.0'; 
                          return acrobat; 
              } 
        } 
    } 
    else if (window.ActiveXObject) 
    { 
        for (x=2; x<10; x++) 
        { 
            try 
            { 
                oAcro=eval("new ActiveXObject('PDF.PdfCtrl."+x+"');"); 
                if (oAcro) 
                { 
                     acrobat.installed=true; 
                     acrobat.version=x+'.0'; 
                 } 
            } 
            catch(e) {} 
            } 
            try 
            { 
                oAcro4=new ActiveXObject('PDF.PdfCtrl.1'); 
                if (oAcro4) 
                { 
                      acrobat.installed=true; 
                      acrobat.version='4.0'; 
               } 
            } 
            catch(e) {} 
            try 
            { 
                oAcro7=new ActiveXObject('AcroPDF.PDF.1'); 
                if (oAcro7) 
                { 
                      acrobat.installed=true; 
                      acrobat.version='7.0'; 
                } 
            } 
            catch(e) {} 
        } 
        return acrobat; 
}
function CloseIfNotInToolTip(trgElm,curToolTip)
{
    if(!curToolTip.enterToolTip)
    {
        G2PopupManager.closeTooltipFor(trgElm);
    }
}
function SaveDocumentTitle(title)
{
    docTitle = title;
}

// Get the topest available window
function GetTopAvailableWindow()
{
	var win = window;
	var tmpElement;
	
	// For each window parent
	while((typeof(win.parent) != "undefined") && (win.parent != null) && (win != win.parent))
	{
	  // Try to access the window parent - else return the current window
		try
		{
			tmpElement = win.parent.document.createElement('DIV');
			win = win.parent;
		}
		catch(e)
		{
			return win;
		}
	}
	
	return win;
}

WebForm_FindFirstFocusableChild = G2_FindFirstFocusableChild;
WebForm_AutoFocus = G2_AutoFocus;
WebForm_CanFocus = G2_CanFocus;
WebForm_IsFocusableTag = G2_IsFocusableTag;
WebForm_IsInVisibleContainer = G2_IsInVisibleContainer;


/**********************************************************************
 *           G2 Cross-platform Javascript library                     *
 **********************************************************************/
Array.prototype.dequeue = function() {var r = this[0]; this.splice(0,1); return r;};
Array.prototype.FirstOrDefault = function(predicate)
{
	for(var i=0;i<this.length;i++)
	{
		var item = this[i];
		if(predicate(item))
			return item;
	}
	return null;
}
Array.prototype.ForEach = function(action)
{
	for(var i=0;i<this.length;i++)
	{
		var item = this[i];
		action(item);
	}
}
Array.prototype.RemoveItem = function(itemToRemove)
{
    for(var i=0;i<this.length;i++)
	{
		if (this[i] == itemToRemove)
		{
		    this.splice(i,1);
		    break;
		}
	}
}

var G2DOM = 
{
	GetChildElementById : function(element, id)
	{
		if(isIE)
		{
			var child = element.all[id];
			if(child==null)
				return null;
			if(child.length!=null)
				return child[0];
			return child;
		}
		else if(isMoz)
		{
			return this._GetChildElementById(element, id);
		}
		else
			throw new Error("not supported");
	},
	_GetChildElementById : function(element, id)
	{
		var child = element.firstChild;
		while(child!=null)
		{
			if(child.id==id)
				return child;
			var grandChild = this._GetChildElementById(child, id);
			if(grandChild!=null)
				return grandChild;
			child = child.nextSibling;
		}
		return null;
	},
	
	// This method gets a root element and a progid value and find the first child element with the progid specified
	// In case you got the whole progId path it is preffered to use the method 'findControl' below. It is much faster.
	// This method uses Depth-First-Search(DFS) recursively.
	GetChildByProgid_dfs : function(root, childProgid)
	{
		if (! root)
			return null;

		if (root.progid == childProgid)
			return root;

		var child = root.firstChild;
		while (child)
		{
			var res = this.GetChildByProgid(child, childProgid);
			if (res != null)
				return res;
			child = child.nextSibling;
		}
		
		return null;
	},
	

	// This method gets a root element and a progid value and find the first child element with the progid specified
	// This method uses Breadth-First-Search (BFS) instead of Depth-First-Search(DFS). It is therefore non-recursive.
	GetChildByProgid : function(root, childProgid)
	{
		if (! root)
			return null;
			
		if (root.progid == childProgid)
			return root;
			
		var queue = [root];		
		while (queue.length>0)
		{
			root = queue.dequeue();
			if (root.progid == childProgid)
				return root;
			var children = root.children;
			for (var i=0,j=children.length;i<j;i++)
				queue.push(children[i]);
		}	
				
		return null;
	},
	
	// This method gets a root element and a progid value and find the first parent element with the progid specified
	GetParentByProgid : function(root, childProgid)
	{
		while(root && root.progid != childProgid)
		{
			root = root.parentElement;
		}
		
		return root;
	},

	// gets the given object position	
	findPos : function(obj)
	{
		var curleft = 0;
		var curtop = 0;
		if (obj.offsetParent)
		{
			curleft = obj.offsetLeft;
			curtop = obj.offsetTop;
			while (obj = obj.offsetParent)
			{
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
					
		    // taking into account scrooling with in overflow scroll elements
		    if(obj.tagName != 'HTML' && obj.scrollTop != null)
			    curtop -= obj.scrollTop;
			}
		}
		return [curleft,curtop];
	},
		
	// Create a covering DIV for a modal effect.
	// The input parameters:
	// side - left, top, right or bottom
	// tableId - the modal element or its id
	// errorMsg - message to shown when clicking on the div. optional
	CreateCoverDiv : function(side,tableId,errorMsg)
	{
		// validate modal element
		if(tableId == null)
			return;

		var tbl = tableId;
		if(typeof(tableId) == "string")
			tbl = $(tableId);

		var arr = this.findPos(tbl)	
		var docHeight,docWidth;
		var coverDiv = document.createElement('DIV');
		var div;
		if (side == "left")
		{
				div = $('leftCoverDiv');
			if (div!=null)
				return div;
			docHeight = document.documentElement.scrollHeight;		
			docWidth = arr[0];
			coverDiv.id = "leftCoverDiv";
		}
		else if (side == "top")
		{
				div = $('topCoverDiv');
			if (div!=null)
				return div;
			docWidth = document.documentElement.scrollWidth;
			docHeight = arr[1];	
			coverDiv.id = "topCoverDiv";
		}			
		else if (side == "right")
		{
				div = $('rightCoverDiv');
			if (div!=null)
				return div;
			docWidth = document.documentElement.scrollWidth-tbl.offsetWidth;
			docHeight = tbl.offsetHeight;
			coverDiv.id = "rightCoverDiv";
		}			
		else if(side == "bottom")
		{
				div = $('bottomCoverDiv');
			if (div!=null)
				return div;
			docWidth = document.documentElement.scrollWidth;
			docHeight = window.document.documentElement.scrollHeight-(arr[1]+tbl.offsetHeight);
			coverDiv.id = "bottomCoverDiv";
		}			
		coverDiv.className = "CoverDiv";
		if (side == "left" || side == "top")
		{
				coverDiv.style.left = "0px";
				coverDiv.style.top = "0px";
		}
		else if (side == "right")
		{
				coverDiv.style.left = arr[0]+tbl.offsetWidth+"px";
				coverDiv.style.top = arr[1]+"px";
		}
		else if (side == "bottom")
		{
				coverDiv.style.left = "0px";
				coverDiv.style.top = arr[1]+tbl.offsetHeight+2+"px";
		}
		coverDiv.style.height = docHeight+"px";
		coverDiv.style.width = docWidth+"px";	
		coverDiv.style.position="absolute";			
		coverDiv.onclick = function()
		{
			if(errorMsg)
				alert(errorMsg);
			else
				alert("You are in Edit Mode, Click Done to save or Cancel to exit");
		};
		return coverDiv;
	},

	//Transfers the custom attributes from the element to its properties (they are the same in IE, not in FF)
	G2TransferAttributes : function(elem)
	{
		if (isIE || elem==null || elem.attributesTransferred) //IE is nice enough
			return;
		elem.attributesTransferred = true;
		for (var atnum in elem.attributes)
		{
			var atNode = elem.attributes[atnum];
			var atname = atNode.nodeName;
			var atvalue = atNode.nodeValue;
			if (typeof(elem[atname])=="undefined")
				elem[atname] = atvalue;
		}	
	},

	G2GetSelection : function()
	{
		return (window.getSelection || (document.getSelection && document.getSelection()) || document.selection);
	},

	G2GetNextChild : function ( n )
	{
		if (isIE)
			return n.nextSibling;

		do
		{
			n	 = n.nextSibling;
		} 
		while (n!=null && n.nodeType == Node.TEXT_NODE);

		return n;
	},
	G2CreateElementFromHtml : function(html, doc)
	{
	  if(doc==null)
	    doc = document;
		var tagName = html.substr(html.search("<")+1, 2).toUpperCase();
		var div = doc.createElement('div');
		if(tagName=="TR")		
		{
			div.innerHTML = "<table><tbody>"+html+"</tbody></table>";
			var newRow = div.firstChild.firstChild.firstChild;
			newRow.parentElement.removeChild(newRow);
			return newRow;
		}
		else if(tagName=="TD")
		{
			var div = doc.createElement("div");
			div.innerHTML = "<table><tr>"+outerHTML+"</tr></table>";
			var cell = div.firstChild.firstChild.firstChild.firstChild;
			return cell;
		}
		else
		{
			div.innerHTML = html;
			return div.children[0]; //FF
		}
	},

	//Replaces a node's outerHTML (Already Implemented in IE, not in FF)
	//TODO: Check if this is needed or if the outerHTML setter works in FF 2.0
	G2ReplaceOuterHTML : function(obj,outerHTML)
	{
		if(isIE)
		{
			//added by dan-el - the simple method doesn't work for TR's.
			if(obj.tagName=="TR")
			{
				var tempDiv = document.createElement('div');
				tempDiv.innerHTML = "<table>"+outerHTML+"</table>";
				var newRow = tempDiv.firstChild.firstChild.firstChild;
				var row = obj;
				var table = obj.parentNode;
				table.replaceChild(newRow, row);
			}
			else if(obj.tagName=="TD")
			{
				var div = document.createElement("div");
				div.innerHTML = "<table><tr>"+outerHTML+"</tr></table>";
				var cell = div.firstChild.firstChild.firstChild.firstChild;
				obj.replaceNode(cell);
			}
			else
			{
				obj.outerHTML = outerHTML;
//				var div = document.createElement("div");
//				div.innerHTML = outerHTML;
//				if (div.firstChild)
//					obj.replaceNode(div.firstChild);
			}
		}
		else //this method caused problems with image caching in Explorer
		{
			obj.outerHTML = outerHTML; //Changed by Alon
			/*var tempDiv = document.createElement('div');
			tempDiv.innerHTML = outerHTML;
			obj.replaceNode(tempDiv.firstChild);*/
		}
	},

	//Firefox stores attributes in a different manner than IE
	G2GetAttribute : function (obj,attributeName)
	{	
		if (isIE)
			return obj[attributeName];
		else if (obj!=null && obj.hasAttribute!=null && obj.hasAttribute(attributeName.toLowerCase()))
			return obj.attributes[attributeName.toLowerCase()].nodeValue;
		else 
		{
			var t = obj.attributes[attributeName.toLowerCase()];
			if (t!=null)
				return t.nodeValue;				
			else
			t = obj[attributeName.toLowerCase()] || obj[attributeName];
			return t;
		}
	},

	G2SetAttribute : function (obj,attributeName,val)
	{
		if (isIE)
			obj[attributeName] = val;
		else
			obj.attributes[attributeName.toLowerCase()].nodeValue = val;
	},

	G2CreateElement : function(t)
	{
		if (isIE || t.charAt(0)!="<")
			return document.createElement(t); //  e.g. document.createElement("DIV")
			
		var tempDiv = document.createElement("DIV");
		tempDiv.innerHTML = t;
		return tempDiv.childNodes[0];
	},

	// This method return row.rowIndex
	GetRowIndex : function(row)
	{
		var body = row.parentElement;
		if (!body)
			return -1;
		var currRow = body.firstChild;
		var index = 0;
		while(currRow)
		{
			if (currRow == row)
				return index;
			index++;
			currRow = currRow.nextSibling;
		}
		return -1;
	},

	// This methods returns a row by its index by going throw the table rowafter row 
	// instead of using the table indexing
	GetRowByIndex : function(table, rowIndex)
	{	
		var row = table.firstChild;
		if (! row)
			return null;
			
		while (row && row.tagName != "TR")
			row = row.firstChild;
			
		if (! row)
			return null;
		
		if (rowIndex == 0)
			return row;
		
		for(var i = 0; i < rowIndex; i++)
		{
			row = row.nextSibling;
			if (!row)
				return null;
		}
		return row;
	},

	// Gets a table and return the number of rows
	GetRowsLength : function(table)
	{
		var row = table.firstChild;
		if (! row)
			return 0;
			
		while (row && row.tagName != "TR")
			row = row.firstChild;
		if (! row)
			return 0;
			
		var count = 0;
		while(row)
		{
			row = row.nextSibling;
			count++;
		}
		return count;
	},
	
	GetCellByIndex : function(row, cellIndex)
	{	
		var cell = row.firstChild;
		if (! cell)
			return null;
		
		if (cellIndex == 0)
			return cell;
		
		for(var i = 0; i < cellIndex; i++)
		{
			cell = cell.nextSibling;
			if (!cell)
				return null;
		}
		return cell;
	},
	
	// Gets a row and return the number of cells
	GetCellsLength : function(row)
	{
		var cell = row.firstChild;
		if (! cell)
			return 0;
			
		var count = 0;
		while(cell)
		{
			cell = cell.nextSibling;
			count++;
		}
		return count;
	},
    G2DisableSelects : function()
    {
         if (!IE6)
            return;
            
        selects = document.getElementsByTagName('SELECT');
        for (var i = 0; i < selects.length; i++)
        {
            sel = selects[i];
            if (sel.isDisabled == false)
            {
              sel.disabled = true;
              sel.wasGenerallyDisabled  = true; 
            }
         }
          
    },
    G2EnableSelects : function()
    {
       if (!IE6)
            return;
            
        selects = document.getElementsByTagName('SELECT');
        for (var i = 0; i < selects.length; i++)
        {
            sel = selects[i];
            if (sel.isDisabled && sel.wasGenerallyDisabled)
            {
                sel.disabled = false;
                sel.wasGenerallyDisabled = false;
             }
         }
    },
    G2InsertRowToTable : function(table, index)
    {
        if (index == null)
            index = table.rows.length;
        return table.insertRow(index);
    },
    
    G2InsertCellToRow : function (row, index)
    {
        if (index == null)
            index = row.cells.length;
        return row.insertCell(index);
    },
    
    G2RemoveNode : function (elem)
    {
        elem.parentNode.removeChild(elem);
    },
    
    G2Focus : function (elem)
    {
			try{
				elem.focus();
			}
			catch(e){
				//do nothing- error when pressing the widget of combo is unclear but cause no problem. 
				// the menu is displayed as usual.
			}
    },
    
    G2HTMLEncode : function (text)
    {
	    if ( !text )
		    return '' ;

	    text = text.replace( /&/g, '&amp;' ) ;
	    text = text.replace( /</g, '&lt;' ) ;
	    text = text.replace( />/g, '&gt;' ) ;
	    return text ;
    },
    
		// Set the flash elements in the iframe to transparent
		SetFlashElementsTransparent : function(iframe)
		{
			if(isMoz)
			{
				var objects = iframe.Document.getElementsByTagName('embed');  
				for (var i = 0; i < objects.length; i++) 
				{   
					var newObject = objects[i].cloneNode(true); 
					newObject.setAttribute('wmode', 'transparent');           
					objects[i].parentNode.replaceChild(newObject, objects[i]);    
				}
			}
			else
			{
				var elementToAppend = iframe.Document.createElement('param');    
				elementToAppend.setAttribute('name', 'wmode');    
				elementToAppend.setAttribute('value', 'transparent');    
				var objects = iframe.Document.getElementsByTagName('OBJECT');    
				for (var i = 0; i < objects.length; i++) 
				{        
					var newObject = objects[i].cloneNode(true);        
					elementToAppend = elementToAppend.cloneNode(true);        
					newObject.appendChild(elementToAppend);        
					objects[i].parentNode.replaceChild(newObject, objects[i]);    
				}
			}
    }
  
}

G2_DeclareUtilInstance(G2DOM);

//the following script adds document.getElementById if it is not present
if(document.all && !document.getElementById) 
{
	document.getElementById = function(id) 
	{
		return document.all[id];
	}
}


/**********************************************************************
 *           G2 Event handling                                        *
 *     portions taken from the Prototype library version 1.4.0        *
 **********************************************************************/

G2_DeclareFunctions(
{
	G2_AttachEventWithCaller : function(element, eventName, handler, caller)
	{
		element.attachEvent(eventName, G2.GetDelegate(caller, handler));
	},
	G2_DetachEventWithCaller : function(element, eventName, handler, caller)
	{
		element.detachEvent(eventName, G2.GetDelegate(caller, handler));
	},


	G2_FireEvent : function(target, eventName, eventArgs)
	{
		if(isIE)
		{
			return target.fireEvent(eventName, eventArgs);
		}
		else
		{
			var handler = target[eventName];
			if (handler!=null)
			{
				if (typeof(handler)=="function")
					handler();
				else eval(handler);
			}
			else
				throw new Error("not supported");
		}
	},

	// This method wraps an event handler, to achieve two goals:
	// 1. When the method executes, its 'this' context will be the actual object (who 'owns' the function)
	// 2. Cross-platform event handling:
	//    In IE, the current event that is being process is stored in window.event
	//    In Mozilla (and FireFox), the event object is passed as an argument to the event handler
	G2_PrepareEvent : function(newContext,method)
	{
		if (method.preparedEvent && method.preparedEvent!=null)
		{
			return method.preparedEvent;
		}
		method.preparedEvent = function(event)
		{
			if (event==null)
				event = window.event;
			return method.call(newContext,event);
		}
		
		return method.preparedEvent;
	},

	// Attaches an event handler to the target, as a response to that event
	// The handler should be a function that receives a single argument, named 'event'.
	// It should NOT use window.event, only the supplied event.
	G2_AttachEvent : function(target, eventName, handler, capture)
	{
		if (eventName.substr(0,2)=="on")
			eventName = eventName.substring(2);
		
		//Note: Capture is only supported in FireFox
		if (!capture)
			capture = false;
		
		if(isIE)
		{
			target.attachEvent('on'+eventName, G2_PrepareEvent(target,handler));
		}
		else if (target.addEventListener!=null)
		{		
				target.addEventListener(eventName,G2_PrepareEvent(target,handler),capture);
		} 
		else
			throw new Error("not supported");
	},


	G2_DetachEvent : function(target,eventName, handler, capture)
	{
		if (eventName.substr(0,2)=="on")
			eventName = eventName.substring(2);
		
		//Note: Capture is only supported in FireFox
		if (!capture)
			capture = false;
		
		if (isIE) 
		{
				target.detachEvent('on' + eventName, G2_PrepareEvent(target,handler));
		}
		else if (target.removeEventListener!=null)
		{
				target.removeEventListener(eventName, G2_PrepareEvent(target,handler), capture);
		} 
		else 
			throw new Error("not supported");
	},
	G2StopEvent : function(event)
	{
		G2Event.stop(event);
	},
		
	// Get child element in a given element by its id
	G2_FindChildControlById : function(element, id)
	{
		if(String.EndsWith(element.id, id))
			return element;
		var child = element.firstChild;
		while(child!=null)
		{
			var found = G2_FindChildControlById(child, id);
			if(found!=null)
				return found;
			child=child.nextSibling;
		}
		return null;
	},
	
	// Get the first child element in a given element with a specified tagName
	G2_FindChildControlByTagName : function(element, tagName)
	{
		if(! element)
			return null;
		if (element.tagName)
			if(element.tagName.toLowerCase() == tagName.toLowerCase())
				return element;
		var child = element.firstChild;
		while(child!=null)
		{
			var found = G2_FindChildControlByTagName(child, tagName);
			if(found!=null)
				return found;
			child=child.nextSibling;
		}
		return null;
	},

	///
	///Recursivly searches an element from the current control and up that has a certain tag name
	///
	G2_GetParentElementByTagName : function(control, tagName)
	{	
		tagName = tagName.toUpperCase();
		return _G2_GetParentElementByTagName(control, tagName);
	},
	_G2_GetParentElementByTagName : function(control, tagName)
	{	
		if(control==null)
			return null;
		if(control.tagName==tagName) //TODO: Compare case insensitive
			return control;
		control = control.parentElement;
		return _G2_GetParentElementByTagName(control, tagName);
	},

	//returns an array of all the nodes under node with progid=parentProgId that have the 
	//specified attribute name and value 
	findControlsByAttribute : function(node, parentProgId, attributeName, attributeValue)
	{
		
		var pred = function(el)
		{
			if(G2DOM.G2GetAttribute(el, "progid")==parentProgId)
					return el;
		}
		var testAttribute = function(node)
		{
			if(G2DOM.G2GetAttribute(node, attributeName)==attributeValue)
					return node;
		}
		var curNode = searchUp(node, pred);
		if(curNode == null)
			return null;

		var childrenArray = new Array();
		
		collectChildrenByAttribute(curNode, testAttribute, childrenArray);
		return childrenArray; 
	},
	
	collectChildrenByAttribute : function (obj, predicate, childrenArray)
	{
		if (obj==null)
			obj = this;
			
		if (obj.childNodes.length==0)
			return childrenArray;
			
		var c = obj.firstChild;
		
		while(c!=null)
		{
			collectChildrenByAttribute(c,predicate, childrenArray);
			if (c.nodeType == 1 && predicate(c))
				childrenArray.push(c);
			c = c.nextSibling;
		}
	},
	
		
	//Finds an element by progid
	//Usage: provide a start node and a path seperated by dots, i.e. findControl(el, 'div1.panel2.button3');
	//       in this example, a node with progid div will be searched UPWARDS from el
	//       Then a div1 child element with progid 'panel2'will be searched DOWN.
	//       Then a panel2 child element with progid 'button3'will be searched DOWN. 
	//Returns: the first element with the last progid in the path that matches
	findControl : function(node, progIdpath)
	{
		var tokens = progIdpath.split('.');
		if(tokens.length==0)
			return null;
		var progid=tokens[0];
		tokens.splice(0,1);//Remove first token
	  
		var pred = function(el)
		{
			if(G2DOM.G2GetAttribute(el, "progid")==progid)
					return el;
		}
		var curNode = searchUp(node, pred);
		if(curNode == null)
			return null;
		if(tokens.length==0)
			return curNode;
		var newPath = tokens.join('.');
		return _findChildControl(curNode, newPath); 
	},

	_findChildControl : function(node, progIdpath)
	{
		var curNode = node;
		var tokens = progIdpath.split('.');
		if(tokens.length==0)
			return curNode;
		
		var tokensLength = tokens.length;
		for(var i=0; i<tokensLength; i++)
		{
			var progid=tokens[i];
			var pred = function(el)
			{
				if(G2DOM.G2GetAttribute(el, "progid")==progid)
					return el;
			}
			curNode = searchDown(curNode, pred);  
			if(curNode==null)
				return null;
		}
		return curNode;
	},

	searchUp : function(node, predicate)
	{
		while(node!=null)
		{
			if(predicate(node))
				return node;
			node = node.parentElement;
		}  
		return null;
	},
	searchDown : function(node, predicate)
	{
		return _searchDown(node, predicate);
	},
	_searchDown : function(node, predicate)
	{
		if(predicate(node))
				return node;
		node = node.firstChild; 
		if (node!=null && node.nodeType != 1)
			node = G2DOM.G2GetNextChild(node);
		while(node!=null)
		{
			var n = _searchDown(node, predicate);
			if(n!=null)
				return n;
			node = G2DOM.G2GetNextChild(node);
		}  
		return null;
	}
	
});

var G2Event = {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,  
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_SPECIAL_COPY: 17,

	//Returns the target(FF)/source(IE) element - which is the event's context
	//Usage:  Event.element( e )
  element: function(event) {
		if (event==null)
			event = window.event;
    return event.target || event.srcElement;
  },

	//Returns true if the click was a left mouse click
	//Usage:  Event.isLeftClick( e )
  isLeftClick: function(event) {
		if (event==null)
			event = window.event;
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },
	
	//Returns the cursor X coordinate (relative to the page)
	//Usage:  Event.pointerX( e )
  pointerX: function(event) {
		if (event==null)
			event = window.event;
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
  },

	//Returns the cursor Y coordinate (relative to the page)
	//Usage:  Event.pointerY( e )
  pointerY: function(event) {
		if (event==null)
			event = window.event;
    return event.pageY || (event.clientY +
      (document.documentElement.scrollTop || document.body.scrollTop));
  },

	//Stops the event propagation
	//Usage:  Event.stop( e )
  stop: function(event) {
		if (event==null)
			event = window.event;
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },

  // Finds the first node with the given tagName, starting from the
  // node the event was triggered on; traverses the DOM upwards
  findElement: function(event, tagName) {
		if (event==null)
			event = window.event;
    var element = Event.element(event);
    while (element.parentNode && (!element.tagName ||
        (element.tagName.toUpperCase() != tagName.toUpperCase())))
      element = element.parentNode;
    return element;
  }/*,

  observers: false,

  _observeAndCache: function(element, name, observer, useCapture) {
    if (!this.observers) this.observers = [];
    if (element.addEventListener) {
      this.observers.push([element, name, observer, useCapture]);
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      this.observers.push([element, name, observer, useCapture]);
      element.attachEvent('on' + name, observer);
    }
  },

  unloadCache: function() {
    if (!Event.observers) return;
    for (var i = 0; i < Event.observers.length; i++) {
      Event.stopObserving.apply(this, Event.observers[i]);
      Event.observers[i][0] = null;
    }
    Event.observers = false;
  },

  observe: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.attachEvent))
      name = 'keydown';

    this._observeAndCache(element, name, observer, useCapture);
  },

  stopObserving: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.detachEvent))
      name = 'keydown';

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      element.detachEvent('on' + name, observer);
    }
  }*/
};




//Add Debug.writeln support for Firefox
//In order to enable logging:
// 1. open firefox
// 2. open about:config
// 3. right-click and New->String
// 4. Name the new entry "browser.dom.window.dump.enabled"
// 5. Set its value to true
// 6. Open firefox with the -console parameter (it might complain, but it works).
// For additional information, contact Alon.
// 
// Note: Console is disabled by default. On production systems no change needs to be done.
if (typeof(Debug)=="undefined")
	Debug = {writeln:function(txt){window.dump(txt+"\n");}};
	


/**********************************************************************
 *           G2 Firefox HTMLElement extension                         *
 **********************************************************************/

if(!document.documentElement.outerHTML)
{

    HTMLElement.prototype.getAttributes = function(){
       var attStr = "";
       if(this && this.attributes.length > 0){
          for(a = 0; a < this.attributes.length; a ++){
             attStr += " " + this.attributes.item(a).nodeName + "=\"";
             attStr += this.attributes.item(a).nodeValue + "\"";
          }
       }
       return attStr;
    }

    HTMLElement.prototype.getInsideNodes = function(){
       if(this){
          var cNodesStr = "", i = 0;
          var iEmpty = /^(img|embed|input|br|hr|bgsound)$/i;
          var cNodes = this.childNodes;
          for(i = 0; i < cNodes.length; i ++){
             switch(cNodes.item(i).nodeType){
                 case 1 :
                    cNodesStr += "<" + cNodes.item(i).nodeName.toLowerCase();
                    if(cNodes.item(i).attributes.length > 0){
                       cNodesStr += cNodes.item(i).getAttributes();
                    }
                    cNodesStr += (cNodes.item(i).nodeName.match(iEmpty))? "" : ">";
                    if(cNodes.item(i).childNodes.length > 0){
                       cNodesStr += cNodes.item(i).getInsideNodes();
                    }
                    if(cNodes.item(i).nodeName.match(iEmpty)){
                       cNodesStr += " />";
                    } else {
                       cNodesStr += "</" + cNodes.item(i).nodeName.toLowerCase() + ">";
                    }
                    break;
                 case 3 :
                    cNodesStr += cNodes.item(i).nodeValue;
                    break;
                 case 8 :
                    cNodesStr += "<!--" + cNodes.item(i).nodeValue + "-->";
                    break;
             }
          }
          return cNodesStr;
       }
    }

    G2MozGetOuterHTML = function(){
       var strOuter = "";
       var iEmpty = /^(img|embed|input|br|hr|bgsound)$/i;
       switch(this.nodeType){
          case 1 :
             strOuter += "<" + this.nodeName.toLowerCase();
             strOuter += this.getAttributes();
             if(this.nodeName.match(iEmpty)){
                 strOuter += " />";
             } else {
                 strOuter += ">" + this.getInsideNodes();
                 strOuter += "</" + this.nodeName.toLowerCase() + ">";
             }
             break;
          case 3 :
             strOuter += this.nodeValue;
             break;
          case 8 :
             cNodesStr += "<!--" + this.nodeValue + "-->";
             break;
       }
       return strOuter;
    }

    G2MozSetOuterHTML = function(str){
       var iRange = document.createRange();
       iRange.setStartBefore(this);
       var strFragment = iRange.createContextualFragment(str);
       var sRangeNode = iRange.startContainer;
       iRange.insertNode(strFragment);
       sRangeNode.removeChild(this);
    }
    
    //Returns the object's document
		G2GetDocument = function (obj)
		{
			if (obj == null)
				obj = this;
			return obj.ownerDocument;
		}

		// Artificially get the 'Children' array for the given node.
		// Added as a getter to the Node class in FF
		G2GetChildren = function (obj)
		{
			if (obj==null)
				obj = this;
				
			var childrenArray = new Array();
			if (obj.childNodes.length==0)
				return childrenArray;
				
			var c = obj.firstChild;
			while(c!=null)
			{
				if (c.nodeType != Node.TEXT_NODE)
					childrenArray.push(c);
				c = c.nextSibling;
			}
			
			childrenArray.namedItem = function(name)
			{
				for (var i=0;i<this.length;i++)
				{
					var node = this[i];
					if (node.id == name)
						return node;
				}
				return null;
			}
			
			return childrenArray;
		}
		
		G2GetTagName = function(obj)
		{
			if (obj==null)
				obj = this;
			return obj.nodeName;
		}

		function G2GetParent(obj)
		{	
			if (obj==null)
				obj = this;
			return obj.parentNode;
		}
		
		function G2GetCurrentStyle(obj)
		{
			if (obj==null)
				obj = this;
			return window.getComputedStyle(obj,null);
		}
		
		function G2GetInnerText(obj)
		{
			if (obj==null)
					obj = this;
			return obj.textContent;
		}
		
		function G2SetInnerText(txt)
		{
			this.innerHTML = txt;
		}
		
		function G2ContainsChild(c)
		{
			var chlrn = this.children;
			for (var i=0,j=chlrn.length;i<j;i++)
				if (chlrn[i]==c)
					return true;
			return false;
		}
		
		function G2GetContentDocument()
		{
			return this.contentDocument;
		}
		
		function G2MozGetParentWindow()
		{
			return this.defaultView;
		}
		
		HTMLElement.prototype.contains = G2ContainsChild;
		
		//Implement insertAdjacentElement, insertAdjacentText and insertAdjacentHTML
		HTMLElement.prototype.insertAdjacentElement = function(where,parsedNode)
		{
			switch (where)
			{
				case "beforeBegin":
					this.parentNode.insertBefore(parsedNode,this)
					break;
				case "afterBegin":
					this.insertBefore(parsedNode,this.firstChild);
					break;
				case "beforeEnd":
					this.appendChild(parsedNode);
					break;
				case "afterEnd":
					if (this.nextSibling)
						this.parentNode.insertBefore(parsedNode,this.nextSibling);
					else 
						this.parentNode.appendChild(parsedNode);
					break;
			}
		}
		
		HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr)
		{
			var r = this.ownerDocument.createRange();
			r.setStartBefore(this);
			var parsedHTML = r.createContextualFragment(htmlStr);
			this.insertAdjacentElement(where,parsedHTML)
		}
		
		HTMLElement.prototype.insertAdjacentText = function(where,txtStr)
		{
			var parsedText = document.createTextNode(txtStr)
			this.insertAdjacentElement(where,parsedText)
		}
		var lastGivenID = 1000;			
		function G2GetElementUniqueID ()
		{
			if (this._uniqueID) //already defined
				return this._uniqueID;
			//Generate using counter
			this._uniqueID = lastGivenID;
			lastGivenID++;
			return this._uniqueID;
		}	
		
		function G2GetEventSourceElement() 
		{
			var node = this.target;
			while (node.nodeType != 1) node = node.parentNode;
			return node;
		}
		
		function G2GetProgId()
		{
			if (this.hasAttribute("progid"))
				return this.attributes["progid"].nodeValue;
		}
		
		HTMLElement.prototype.attachEvent = function(eventName, handler, capture) //Simulate AttachEvent on Mozilla
	  {
	    if (eventName.substr(0,2)=="on")
		  	eventName = eventName.substring(2);		  
		  if (!capture)
		    capture = false;
	    this.addEventListener(eventName,handler,capture);
	  }
	  
	  HTMLElement.prototype.detachEvent = function(eventName, handler, capture) //Simulate DetachEvent on Mozilla
	  {
	    if (eventName.substr(0,2)=="on")
		  	eventName = eventName.substring(2);		  
		  if (!capture)
		    capture = false;
	    this.removeEventListener(eventName,handler,capture);
	  }
		
		function defineStyleProperties(names)
		{
			for(var i=0;i<names.length;i++)
			{
				var shortName = names[i];
				var pixelName = "pixel"+shortName.substring(0,1).toUpperCase()+shortName.substring(1);
				defineStyleProperty(shortName,pixelName);
			}
		}

		function defineStyleProperty(shortName,pixelName)
		{
			CSSStyleDeclaration.prototype.__defineGetter__(pixelName,function(){return parseInt(this[shortName])});
			CSSStyleDeclaration.prototype.__defineSetter__(pixelName,function(v){this[shortName]=v+"px";});
		}
		
		
		defineStyleProperties(["width","height","left","top"]);
		
		/*function Selection(doc)
		{		
		  this._doc = doc;
		}
		Selection.prototype.createRange = function(element)
		{
		  debugger;
		  var sel = window.getSelection();		  
		  var range = null;
		  if (sel.rangeCount==0)
		  {
		    if (element!=null)
		    {
 		      range = document.createRange();
 		      range.selectNodeContents(element);
 		      //range.setStart(element, 0);
 		      //var len = (element.nodeType==1 && element.tagName=="INPUT") ? element.value.length : element.innerText.length;
          //range.setEnd(element,0);
          //range.expand
		      sel.addRange(range);
		    }
		  }
		  else range = sel.getRangeAt(0);
		  var rng = new G2MozRange(range);
		  return rng;
		}
    function G2GetDocumentSelection()
		{
		  if (this._emulatedSelectionObject==null)
		    this._emulatedSelectionObject = new Selection(this);
		  return this._emulatedSelectionObject;
		}
		
		function G2MozRange(rng)
		{
		  this._range = rng;
		}
		function G2MozRange_GetText()
		{
		  return this._range.toString();
		}
		function G2MozRange_SetText(value)
		{
		  //this.commonAncestorContainer.innerText = value;
		  debugger;
		  var lastElement = this._range.endContainer;
		  if (lastElement==null)
		    debugger;
		  if (lastElement.nodeType==1)
		  {
		    if (lastElement.tagName=="INPUT")
		    {
		      lastElement.value += value;
		    }
		    else
		      lastElement.innerText += value;
		  }
		  else if (lastElement.nodeType==3)
		  {
		    lastElement.nodeValue += value;
		  }
		    
		}
		G2MozRange.prototype.__defineGetter__("text",G2MozRange_GetText);
		G2MozRange.prototype.__defineSetter__("text",G2MozRange_SetText);
		*/
		//Fix for firefox BACK
		window.addEventListener("pageshow",function(e){if(e.persisted) {window.location.href = window.location.href;}},false);
    
    HTMLDocument.prototype.__defineGetter__("parentWindow",G2MozGetParentWindow);
    //HTMLDocument.prototype.__defineGetter__("selection",G2GetDocumentSelection);
    HTMLElement.prototype.__defineGetter__("progid",G2GetProgId);
    HTMLElement.prototype.__defineGetter__("outerHTML",G2MozGetOuterHTML);
		HTMLElement.prototype.__defineSetter__("outerHTML",G2MozSetOuterHTML);
		HTMLElement.prototype.__defineGetter__("innerText",G2GetInnerText);
		HTMLElement.prototype.__defineSetter__("innerText",G2SetInnerText);
		HTMLElement.prototype.__defineGetter__("children",G2GetChildren);
		HTMLElement.prototype.__defineGetter__("document",G2GetDocument);
		HTMLElement.prototype.__defineGetter__("tagName",G2GetTagName);
		HTMLElement.prototype.__defineGetter__("parentElement",G2GetParent);
		HTMLElement.prototype.__defineGetter__("currentStyle",G2GetCurrentStyle);
		HTMLElement.prototype.__defineGetter__("uniqueID",G2GetElementUniqueID);
		HTMLIFrameElement.prototype.__defineGetter__("Document",G2GetContentDocument);
		Event.prototype.__defineGetter__("srcElement", G2GetEventSourceElement);
		
		
}
// returns true if the string 's' ends with the string 'endsWith'
String.EndsWith = function(s, endsWith)
{
	if(s==null)
		return endsWith==null;
	return s.substr(s.length-endsWith.length, endsWith.length)==endsWith;
}


//this function gets a control
//and disables/enables it and all its children recursively
SetControlDisability = function(control, disable)
{
	if(control == null)
		return;
	if (control.supportdisabledcss == "true")
	{
		control.disabled = disable;
		//we want the main css class to be standing alone
		//so when disabling, replace css class by disabled css class
		//when enabling if there are other classes, just remove disabled
		if (disable || control.className == control.disabledcssclass)
			G2_ReplaceCssClass(control, control.cssclass, control.disabledcssclass, disable);
		else
			G2_RemoveCssClass(control, control.disabledcssclass);
	}
	//we don't want to replace the initial css class but to add the disable css class
	else if (control.supportdefauldisabledtcss == "true") 
	{
		control.disabled = disable;
		if (disable)
			G2_AddCssClass(control, control.disabledcssclass);
		else
			G2_RemoveCssClass(control, control.disabledcssclass);
	}
	G2_VerifyControlInitialized(control);
	if(typeof(control.setEnabled)=="function")
		control.setEnabled(!disable);
	else
	{
		control.disabled = disable;
		SetControlChildrenDisability(control, disable);
	}
}

SetControlChildrenDisability = function(control, disable)
{
		if(control.children.length > 0)
		{
			var child = control.children[0];
			//lets be sure we are talking about html tag
			while(child != null)
			{
				if(child.nodeType == 1)
				{
					child.disabled = disable;
					SetControlDisability(child, disable);
				}
	
				child = child.nextSibling;
			}
		}
	}
	

//Used in Dialog.aspx

var allowTitleUpdate = false;
var allowIframeResize = true;
var topdocument = document;
var PopupMinWidth = 250;
var PopupMinHeight = null;


// UpdateTitle is called to update the window's title
// Logic: When the WindowTitle attribute is set in G2PopupWindow, it is used
//        Otherwise, IE6 popups will have the default "Gilboa" title
//                   IE7 popups will use the content document's title
// (Related to case 4771)
UpdateTitle = function()
{
	if (!allowTitleUpdate)
		return;
	
	var ifrm = document.getElementById('IFRM');
	
	// Adi E: The try...catch was added due to a javaScript 'Permission denied' error in 'Use SSL' mode (case 4258) 
	try
	{
	    if (ifrm.Document!=null && ifrm.Document.title!=null)				
	    {
		    window.top.document.title = ifrm.Document.title;
	    }
	}
	catch(err)
  {
  }
}

// UpdateInnerFrameSize is called whenever the content is suspected to change its size
// The order of events should generally be:
//         1. Document content has changed
//         2. Document called G2Page_AutoSize  (common.js)
//         3. UpdateInnerFrameSize is called to update the IFRAME's size to match the content (shrink/expand)
//         4. G2Page_AutoSize is called to update the popup window's size to match the iframe
// If size was explicitly specified, use it. Otherwise, get from page
UpdateInnerFrameSize = function(doc)
{
	if (!allowIframeResize)
		return;
	if (!doc)
		doc = document;
	var ifrm = doc.getElementById('IFRM');		
	var innerDocument = ifrm.Document;				
		
	try
	{		
		if (innerDocument!=null && innerDocument.documentElement!=null && innerDocument.documentElement.scrollWidth)
		{	
			ifrm.style.width = maxInt(ifrm.style.width,parseInt(innerDocument.documentElement.scrollWidth)+10)+"px";	
			var prevW	= parseInt(innerDocument.documentElement.scrollWidth);			
			var prevH = parseInt(innerDocument.documentElement.scrollHeight);			
			Debug.writeln('Resizing popup. Initial estimated size: '+prevW+" x "+prevH);
			var initialWidth = prevW;
			do
			{
				prevW	= parseInt(innerDocument.documentElement.scrollWidth);
				ifrm.style.width = (parseInt(ifrm.style.width)-1)+"px";
			} while (parseInt(innerDocument.documentElement.scrollWidth)<prevW && parseInt(innerDocument.documentElement.scrollHeight)==prevH);
			
			//go back one step
			var newWidth = (parseInt(ifrm.style.width)+1);
			if (PopupMinWidth!=null)
				newWidth = maxInt(newWidth,PopupMinWidth);				
			ifrm.style.width = newWidth+"px";
		}
		
		if (innerDocument!=null && innerDocument.documentElement!=null && innerDocument.documentElement.scrollHeight)
		{
			var newHeight = parseInt(innerDocument.documentElement.scrollHeight+1);
			if (PopupMinHeight!=null)
				newHeight = maxInt(newHeight, PopupMinHeight);
			ifrm.style.height = newHeight+"px";
		}
	}
	catch(e)
	{
	}		
	ResizeDialogWindow(doc);
}



//Initializes the iframe and enables size updates (and title updates if title was not explicitly set)
InitIFrame = function()
{
	var ifrm = document.getElementById('IFRM');
	var popupWindowId = window.dialogArguments.url; //Extract WindowID parameter
	popupWindowId = popupWindowId.substring(popupWindowId.indexOf('&WindowID=')+10);
	popupWindowId = popupWindowId.substring(0,popupWindowId.indexOf('&'));
//	window.onunload = function() //Non-SSL Pages set dialogArguments.obj.CloseEventFired to true
//	{
//	    if (!dialogArguments.obj.CloseEventFired)
//	        dialogArguments.obj.G2_FirePopupClosed(popupWindowId,'',true);
//	}
	
	//If title was explicitly specified, use it
	if (window.dialogArguments.title!=null && window.dialogArguments.title!="")
	{
		window.top.document.title = window.dialogArguments.title;
	}
	else 
		allowTitleUpdate = true; //Allow updating the title when the page is loaded
	
  
	if (window.dialogArguments.width && ifrm.style.height)
	{		
		//TO DO:Fix G2PopupWindow_ExtractParameter in Common.js that will never return Nan.
	  var resized = false;  		
		if (!isNaN(window.dialogArguments.width))
		{
		  ifrm.style.width = window.dialogArguments.width+"px";
		  resized = true;
		}
		
		if (!isNaN(window.dialogArguments.height))
		{
		  ifrm.style.height = window.dialogArguments.height+"px";
		  resized = true;
		}
		
		if (resized)
			ResizeDialogWindow();//window.dialogArguments.width, window.dialogArguments.height);
	}
	
	if (window.dialogArguments.minWidth)
		PopupMinWidth = window.dialogArguments.minWidth;
	if (window.dialogArguments.minHeight)
		PopupMinHeight = window.dialogArguments.minHeight;
	
	allowIframeResize = window.dialogArguments.autoSize=="1";
		
	ifrm.src = window.dialogArguments.url; //Set IFrame source
}

//This method is calls UpdateInnerFrameSize with the top document as a context
G2Dialog_AutoSize = function ()
{
  pendingTimeout = -1;
	UpdateInnerFrameSize.apply(topdocument);	
}

var pendingTimeout = -1;
//This method schedules a call to G2Dialog_AutoSize in 300 mSec. if a call is already scheduled - it does nothing.
scheduleRefresh = function()
{	
	if (pendingTimeout!=-1)
	  return;
	
	pendingTimeout = window.setTimeout(G2Dialog_AutoSize,300);
}

//This method is called whenever a [new] image in the document has been loaded
contentImgReady = function(e)
{
	scheduleRefresh();			
	
	//Remove event handler to save some memory
	try
	{
		G2_DetachEvent(this,"onload",contentImgReady);
	} catch (e)
	{
		//An exception might be thrown when detaching events.
	}
}

//This method traverses the [new] images in the document, and subscribes to their Load event.
attachToImagesLoading = function()
{
	try
	{
		var ifrm = document.getElementById('IFRM');		
		var innerDocument = ifrm.Document;				
		var imgs = innerDocument.getElementsByTagName("IMG");
		for (var i=0;i<imgs.length;i++)
		{
			if (!imgs[i].scheduleRefreshAttached)
			{
				G2_AttachEvent(imgs[i],"onload",contentImgReady);
				imgs[i].scheduleRefreshAttached = true;
			}
		}
	} 
	catch(e) //Security violations etc.
	{
		G2_Trace("attachToImagesLoading", e.message);
	}
}

//The following line enables UpdateInnerFrameSize() calls. do not remove it
//This method is called by G2Page_AutoSize.
G2Dialog_NotifyContentChanged= function(noImages) 
{
	if (!noImages)
		attachToImagesLoading(); 		

	scheduleRefresh(); 
}

//Resizes the dialog window to be able to contain the IFRAME (use scrollbars as last resort)
function ResizeDialogWindow(/*windowWidth, windowHeight*/)
{
	if (G2_IsInPopup())
		return;
 
	var ifrm = document.getElementById('IFRM');	
	var ifrmWidth = parseInt(ifrm.style.width);
	var ifrmHeight = parseInt(ifrm.style.height);
	
  var sizeElement  = document.documentElement;
  var clientWidth  = ifrmWidth+25;
  var clientHeight = ifrmHeight;
		
  var screenHeight = screen.availHeight-50; //leave room for taskbar etc.
  var screenWidth  = screen.availWidth;
  
	if (IE6)
	{
		clientHeight += 75; //IE6 considers the window border to part of the height
	}
	
  var minWidth  = minInt(screenWidth,clientWidth);
	var minHeight = minInt(screenHeight,clientHeight);
	
	// Adi E: The try...catch was added due to a javaScript 'Permission denied' error in 'Use SSL' mode (case 4258)
	try
	{
		window.top.dialogWidth  = minWidth + "px";
		window.top.dialogHeight = minHeight + "px";		
		Debug.writeln('Dialog '+window.dialogArguments.url+' resized to '+minWidth+'(w) x'+minHeight+' (h)');
	}
	catch(err)
  {
  }
  
}

document.body.G2Dialog_NotifyContentChanged = G2Dialog_NotifyContentChanged;
// JScript File

//  function ExportToExcel2003(objToExport)
//  {
//        var sHTML;
//        var oExcel;
//        var oBook;
//        
//        sHTML = document.all.item(objToExport).outerHTML;
//        oExcel =  new ActiveXObject("Excel.Application");
//        
//        oBook.HTMLProject.HTMLProjectItems("Sheet1").Text = sHTML;
//        oBook.HTMLProject.RefreshDocument;
//        oExcel.Workbooks.Add(oBook);
//        oExcel.Visible = true;
//        oExcel.UserControl = true;
//  }
  
function ExportToExcel(tableID)
{
	// get the current table
	var curTable = $(tableID);
	
	// copy the table so the client wont see the removal of the icons
	// --------------------------------------------------------------
	var table = document.createElement('table');
	
	var oTBody = document.createElement('tbody');
	table.appendChild(oTBody);
	
	var rowNum = curTable.rows.length;
	var cellNum = curTable.rows[0].cells.length;
	for(var i = 0; i < rowNum; i++)
	{
		var curRow = document.createElement('tr');
		for(var j = 0; j < cellNum; j++)
		{
			if(curTable.rows[i].cells[j] != null)
			{
				var curCell = document.createElement('td');
				curCell.innerHTML = curTable.rows[i].cells[j].innerHTML;
				curRow.appendChild(curCell);
			}
		}
		
		oTBody.appendChild(curRow);
	}
	table.appendChild(oTBody);
	
	// Get rid of the image in the titles
	// ----------------------------------
	var cell;
	for(var k = 0; k < cellNum; k++)
	{
		cell = table.rows[0].cells[k];
		if(WebForm_GetElementByTagName(cell, 'span') != null)
			cell.innerHTML = WebForm_GetElementByTagName(cell, 'span').innerHTML;
		else if(WebForm_GetElementByTagName(cell, 'a') != null)
			cell.innerHTML = WebForm_GetElementByTagName(cell, 'a').innerText;
	}
	
	var frm = document.createElement("iframe");
	frm.style.display = "none";
	document.body.appendChild(frm);
	frm.Document.write(table.outerHTML);
	frm.Document.execCommand('SaveAs', false, 'ExcelReport.xls');
}
<!--
///////////////////////////////////////////////////////////////////////
//     This script was designed by Erik Arvidsson for WebFX          //
//                                                                   //
//     For more info and examples see: http://webfx.eae.net          //
//     or send mail to erik@eae.net                                  //
//                                                                   //
//     Feel free to use this code as lomg as this disclaimer is      //
//     intact.                                                       //
///////////////////////////////////////////////////////////////////////
//
// NOTE: This is not compatible with FF (Alon).
// Change document.all to document.getElementById
var checkZIndex = true;

var dragobject = null;
var tx;
var ty;

var ie5 = document.all != null && document.getElementsByTagName != null;

function getReal(el) {
	temp = el;

	while ((temp != null) && (temp.tagName != "BODY")) {
		if ((temp.className == "moveme") || (temp.className == "handle")){
			el = temp;
			return el;
		}
		temp = temp.parentElement;
	}
	return el;
}

function moveme_onmousedown() {
	el = getReal(G2Event.element(event))
	
	if (el.className == "moveme" || el.className == "handle") {
		if (el.className == "handle") {
			tmp = el.getAttribute("handlefor");
			if (tmp == null) {
				dragobject = null;
				return;
			}
			else
				dragobject = eval(tmp);
		}
		else 
			dragobject = el;
		
		if (checkZIndex) makeOnTop(dragobject);
		
		ty = window.event.clientY - getTopPos(dragobject);
		tx = window.event.clientX - getLeftPos(dragobject);
		
		window.event.returnValue = false;
		window.event.cancelBubble = true;
	}
	else {
		dragobject = null;
	}
}

function moveme_onmouseup() {
	if(dragobject) {
		dragobject = null;
	}
}

function moveme_onmousemove() {
	if (dragobject) {
		if (window.event.clientX >= 0 && window.event.clientY >= 0) {
			dragobject.style.left = window.event.clientX - tx;
			dragobject.style.top = window.event.clientY - ty;
		}
		window.event.returnValue = false;
		window.event.cancelBubble = true;
	}
}

function getLeftPos(el) {
	if (ie5) {
		if (el.currentStyle.left == "auto")
			return 0;
		else
			return parseInt(el.currentStyle.left);
	}
	else {
		return el.style.pixelLeft;
	}
}

function getTopPos(el) {
	if (ie5) {
		if (el.currentStyle.top == "auto")
			return 0;
		else
			return parseInt(el.currentStyle.top);
	}
	else {
		return el.style.pixelTop;
	}
}

function makeOnTop(el) {
	var daiz;
	var max = 0;
	var da = document.all;
	
	for (var i=0; i<da.length; i++) {
		daiz = da[i].style.zIndex;
		if (daiz != "" && daiz > max)
			max = daiz;
	}
	
	el.style.zIndex = max + 1;
}

if (document.all) { //This only works in IE4 or better
	document.onmousedown = moveme_onmousedown;
	document.onmouseup = moveme_onmouseup;
	document.onmousemove = moveme_onmousemove;
}

var msgbox;
function G2_Alert(title, message)
{
  msgbox = document.createElement("DIV");
  msgbox.id= "msgbox";
  theForm.appendChild(msgbox);
	msgbox.className="msgon"; 
	msgbox.innerHTML='<TABLE WIDTH="100%" CELLSPACING="0" CELLPADDING="3" BORDER="">'
	              + '<TR><TD BGCOLOR="#FF0000"><DIV CLASS="handle" HANDLEFOR="msgbox">'
				  + title 
				  + '</DIV></TD>'
				  + '<TD ALIGN="center" BGCOLOR="#000000" WIDTH="2%"><SPAN CLASS="msgbar" onMousedown="msgbox.className=\'msgoff\';">&nbsp;X&nbsp;</SPAN></TD></TR>'
				  + '<TR><TD BGCOLOR="#FFFFE1" COLSPAN=2><DIV CLASS="boxtext">' 
				  + message 
				  + '</DIV></TD></TR></TABLE>';
}

//-->

//Change this key to force reloading items from server between versions
var G2ComboBox_VERSION = "3_9";
var G2ComboBox_MIN_SIZE_FOR_BG_INIT = 10000;
var G2ComboBox_BG_INIT_BLOCK_SIZE = 100;
var G2ComboBox_IgnoreKeyUps;

G2_DeclareFunctions(
{
	G2ComboBox_Init : function(cb, e)
	{
		if(typeof(cb)=="string")
			cb = document.getElementById(cb);
		if(cb==null) //happen in multi-view
			return;
		if(cb.g2IsInited)
			return;
			
		cb.g2IsInited = true;
		
		var elementMap = G2ComboBox_FindElements(cb, ["TBText", "TBValue", "Widget"]);
		var tbText = elementMap["TBText"];
		
		if(e!=null)
		{
		  if(e.type=="focus" /*|| e.type=="mousedown" */)
		  {
		    if(tbText.isFocusingAfterPostback==true)
		    {
		      tbText.isFocusingAfterPostback=null;
		    }
		    else
		    {
			    cb.showPopupWhenLoaded = true;
			    G2StopEvent(e);
			  }
		  }
		}
		
		
   
		G2DOM.G2TransferAttributes(cb);

		cb.g2OnSelectedValueChanged = new Array();//event
		cb.AllowNull = cb.nullvalue != null || cb.nulldisplaytext != null;
		cb.alwaysshownullparentitems = cb.alwaysshownullparentitems=="true";
		cb.filterallwhenparentnull = cb.filterallwhenparentnull=="true";
		cb.showFixField = cb.showFixField=="true";

		var itemsPopup = window.top.document.createElement("DIV");

		var popup = window.top.document.createElement("DIV");
//		popup.style.display = "none";
		popup.g2closepopup = "false"; //to allow this popup to remain on the document
		popup.className = cb.popupcssclass || "G2ComboBox_Popup";
		popup.doesNotContainInputs = true; //optimization
		popup.appendChild(itemsPopup);
		
		if(cb.style.zIndex)
			popup.style.zIndex = cb.style.zIndex;

		if (cb.showFixField == true)
		{
			var fixField = window.top.document.createElement("DIV");
			fixField.className = "G2ComboBoxField";
			// build fix field
			fixField.innerText = cb.fixFieldDisplayText;
			fixField.onclick = function()
			{
				FixFieldClick(cb);
			};

			popup.appendChild(fixField);
		}
		popup.onBeforeClose = G2ComboBox_BeforeClose;
		popup.onOpened = G2ComboBox_Opened;
		cb.popup = popup;
		popup.combo = cb;
		popup.popupParentElement = cb;
		popup.onPopupClosed = function()
		{
		  G2ComboBox_VerifySelectedValue(cb);
		};
		
		window.onscroll=function()
		{
			G2ComboBox_HidePopup(cb);
		}
		
		G2_PreventInputPost(tbText.id);
		cb.tbText = tbText;
	 
		/// this is on purpose - to avoid the validators to attach to this event
		G2_AttachEvent(tbText,"onchange",function(){});
	
		G2_AttachEvent(tbText,"onkeydown",
		function(event)
		{
			switch(event.keyCode)
			{
		      
				case 13: //Enter
					if (cb.popup.style.display=="none")
					{												
						return true;
					}		
					//close PopUp
					G2ComboBox_HidePopup(cb);			
					//the last action will be the focus.
					window.setTimeout(function(){try {tbText.focus();}catch(e){}},10);					
					var item = cb.selectedItem;
					if (item!=null)					
							G2ComboBox_SetSelectedValue(cb, item.value, item);
					return true;
				case 27: //Esc
					G2Event.stop(event);					
				case 9: //Tab
					//close PopUp
					G2ComboBox_HidePopup(cb);			
					//the last action will be the focus.
					//window.setTimeout(function(){try {tbText.focus();}catch(e){}},10);					
					var item = cb.selectedItem;
					if (item!=null)					
							G2ComboBox_SetSelectedValue(cb, item.value, item);
					return true;		
			}	  
		});
		G2_AttachEvent(tbText,"onkeyup",
		function(event)
		{	
			//if(G2CKeys[event.keyCode]==null)
			G2ComboBox_OnKeyUp(cb,event);
		});
		
		
		G2_AttachEvent(tbText,"onfocus",
		function(event)
		{
			G2ComboBox_OnFocus(cb,event);
		});
		if(cb.onfocus)
		{
			G2_AttachEvent(tbText,"onfocus", 
			function(event)
			{
				eval(cb.onfocus);
			});
		}
		
		G2_AttachEvent(tbText,"onblur",
		function(event)
		{
			G2ComboBox_OnBlur(cb,event);
		});
		
		if(cb.onblur)
		{
			G2_AttachEvent(tbText,"onblur",
			function(event)
			{
				 eval(cb.onblur);
			});
		}
		
		G2_AttachEvent(tbText,"ondeactivate",
		function(event)
		{
			G2ComboBox_OnDeactivate(cb,event);
		});
		
		
		var tbValue = elementMap["TBValue"];
		if(tbValue==null)
		{
			throw new Error(String.Format("G2ComboBox's {0} hidden field {1} wasn't found", cb.id, cb.hfName));
		}
		EnableSupportForPartialPostData(tbValue);
		cb.tbValue = tbValue;
	  
		var widget = elementMap["Widget"];
		cb.widget = widget;
	  
	  
	  
		G2_AttachEvent(widget,"onmousedown",
		function(e)
		{
		  if(G2Event.element(e) != this)
			  return;
		  G2Event.stop(e);
		  G2ComboBox_OnWidgetMouseDown(e,cb);
		});
		//attach event - removed by dan-el - doesn't work.. 
		G2_AttachEvent(tbText,"onmousedown",
		function(event)
		{
			if(G2Event.element(event) != this)
				return;
			G2Event.stop(event);
			G2ComboBox_TogglePopup(cb, false,event);
			var tb = this;
			window.setTimeout(function(){try {tb.select();}catch(e){}},0);
		}
		);

		if (isMoz)
		{
			//Special Mozilla/FireFox ondeactivate replacement. Still does not work (Alon)
			cb.hideSelf = function()
			{
				G2ComboBox_HidePopup(cb);
			}
		}
		G2ComboBox_GetParentComboBox(cb);
	  
		if(cb.lazyloaditems!="true" || cb.showPopupWhenLoaded)
			G2ComboBox_LoadItems(cb);
	  
		//cb.originalValue = G2ComboBox_GetSelectedValue(cb);
		G2ComboBox_SetOriginalValue(cb);
		cb.g2PerformUndo = G2ComboBox_PerformUndo;
		cb.g2SetOriginalValue = G2ComboBox_SetOriginalValue;
		cb.g2IsDirty = G2ComboBox_IsDirty;
		
		if(cb.disabledcssclass!=null)
		{
			G2_AttachEvent(cb,"onpropertychange",
			function(e)
			{
				if(e.propertyName=="disabled")
					G2_ReplaceCssClass(cb, cb.cssclass, cb.disabledcssclass, cb.isDisabled);
			});
		}
		cb.setEnabled = function(value)
		{
			G2ComboBox_SetEnabled(cb, value);
		}
		
		if (isMoz)
		{
			if (e != null)
				G2ComboBox_OnWidgetMouseDown(e,cb);
		}
	},
	
	G2ComboBox_OnParentComboSelectedValueChanged : function(cbid)
	{
		G2ComboBox_Init(cbid);
	},
	
	G2ComboBox_OnWidgetMouseDown : function(e,cb)
	{
	   
	  //ensure focus if items should be loaded
	  G2DOM.G2Focus(cb.tbText);
	  cb._wasFocused = true;
		G2ComboBox_TogglePopup(cb, false,e);
    //ensure focus if items should not be loaded
	  G2ComboBox_Focus(cb);
	},
	
	G2ComboBox_SetEnabled : function(cb, value)
	{
		cb.disabled = !value;
		if(cb.disabledcssclass!=null)
			G2_ReplaceCssClass(cb, cb.cssclass, cb.disabledcssclass, cb.isDisabled);
		SetControlChildrenDisability(cb, !value);
	},
	G2ComboBox_IsDirty : function(cb)
	{
		cb = cb || this;
		return cb.originalValue!=G2ComboBox_GetSelectedValue(cb);
	},
	
		
	/*changing null value of combo box.
		in case the current value of the combo is null value, updating
		tbText with the new null value*/
	G2ComboBox_SetNullDisplayText : function(cb, text)
	{				
		if(!cb.g2IsInited)
		{
			G2ComboBox_Init(cb);
			if(cb.lazyloaditems=="true")
				G2ComboBox_LoadItems(cb);
		}
		var hasNullValue = (cb.tbText.value == cb.nulldisplaytext)
		var item = G2ComboBox_GetItemByValue(cb,cb.nullvalue);
		cb.nulldisplaytext = text;
		if (!item)
			return;
			
		item.text = text;
		if (text=="")
			item.innerHTML="&nbsp";
		else			
			item.innerText = text;
		if(hasNullValue)
			cb.tbText.value = cb.tbText.defaultValue = text;
	},
	

	G2ComboBox_PerformUndo : function(cb)
	{
		cb = cb || this;
		G2ComboBox_SetSelectedValue(cb, cb.originalValue);
		//G2.undoNotifyInputChanged(cb.tbValue);
	},
	G2ComboBox_SetOriginalValue : function(cb)
	{
		cb = cb || this;
		cb.originalValue = G2ComboBox_GetSelectedValue(cb);
		G2.undoNotifyInputChanged(cb.tbValue);
	},
	G2ComboBox_Focus : function(cb)
	{
		window.setTimeout(function()
		{
			try //temprary, ask Dan-El
			{
				cb.tbText.focus();
			}
			catch(e)
			{
			}
		}, 50);
	},

	G2ComboBox_EnsureItems : function(cb)
	{
		if(cb._itemsLoaded!=true)
		 G2ComboBox_LoadItems(cb); 
	},

	G2ComboBox_OnBlur : function(cb)
	{
		if (cb.ClientOnBlur)
			eval(cb.ClientOnBlur);
	},
	G2ComboBox_OnDeactivate : function(cb)
	{
	//case 8718
	//	document.selection.empty();
	},

	G2ComboBox_OnFocus : function(cb)
	{
		if (cb.ClientOnFocus)
			eval(cb.ClientOnFocus);
		
		cb.tbText.select();
		cb.previouslySelectedItem = cb.selectedItem;
	},

	G2ComboBox_ShouldIgnoreKeyUp : function(keyCode)
	{
		if(G2ComboBox_IgnoreKeyUps==null)
		{
			G2ComboBox_IgnoreKeyUps = [G2Keys.tab, G2Keys.left, G2Keys.right, G2Keys.home, G2Keys.end, G2Keys.shift, G2Keys.ctrl, G2Keys.alt];
		}
		for(var i=0;i<G2ComboBox_IgnoreKeyUps.length;i++)
		{
			if(G2ComboBox_IgnoreKeyUps[i]==keyCode)
				return true;
		}
		return false;
	},
	
	
	G2ComboBox_OnKeyUp : function(cb,event)
	{
		cb.keyCode = event.keyCode;
		if(G2ComboBox_ShouldIgnoreKeyUp(event.keyCode))
			return;

//    if(event.keyCode==G2Keys.backspace)
//		{
//		  if(cb.tbText.value=="")
//		    G2ComboBox_SelectFirstItem(cb);
//		}
		if(event.keyCode==G2Keys.esc)
		{
			return;
		}
		if(event.keyCode==G2Keys.down)
		{
			G2ComboBox_SelectNextItem(cb);
			return;
		}
		else if(event.keyCode==G2Keys.up)
		{
			G2ComboBox_SelectPrevItem(cb);
			return;
		}
		else if(event.keyCode==G2Keys.enter)
		{
			cb.tbText.blur();
			return;
		}
	  
		if(cb.FilterItemsByTextThreadId!=null)
		{
			window.clearTimeout(cb.FilterItemsByTextThreadId);
			cb.FilterItemsByTextThreadId = null;
		}
		var autoSelect = true;
	  
		if (event.keyCode == G2Keys.del)
			autoSelect = false;
			
		if(!G2ComboBox_IsPopupOpened(cb))
			G2ComboBox_ShowPopup(cb,null,event);

		cb.FilterItemsByTextThreadId = window.setTimeout
		(
			function(event)
			{
				G2ComboBox_FilterItems(cb, true, autoSelect);
			}
		, 100);
		
	},

	G2ComboBox_OnSelectedValueChanged : function(cb)
	{
		//The following line was removed - Combobox is now NOT validated when the selected value changes
		//G2Validator_ValidateElementOnChange(cb.tbValue);

		if(cb.UpdateValueOnControl!=null)
		{
			var value = G2ComboBox_GetSelectedValue(cb);
			G2ComboBox_SetSelectedValue(cb.UpdateValueOnControl, value);
		}
		if(cb.g2onselectedvaluechanged!=null)
		{
			if(cb.g2onselectedvaluechanged_Compiled==null)
				cb.g2onselectedvaluechanged_Compiled = new Function(cb.g2onselectedvaluechanged);
			cb.g2onselectedvaluechanged_Compiled();
		}
		for(var i=0;i<cb.g2OnSelectedValueChanged.length;i++)
		{
			cb.g2OnSelectedValueChanged[i](cb);
		}
		if(cb.OnClientChange!=null)
		{
			var value = G2ComboBox_GetSelectedValue(cb);
			window[cb.OnClientChange](cb, value);
		}
	},

	G2ComboBox_IsFocused : function(cb)
	{
		return cb.tbText==document.activeElement;
	},

	G2ComboBox_LoadItems : function(cb)
	{
	  if(cb._itemsLoaded==true)
	    return;
		cb._itemsLoaded = true;
		var stopper = new Stopper();
		stopper.start();
	 
		cb._wasFocused = G2ComboBox_IsFocused(cb);
		cb.disabled = true;
		var loadingtext = cb.loadingtext;
		if(loadingtext==null)
		  loadingtext = "Loading...";
		if(cb.tbText.value!="")
		{
		  cb.valueBeforeLoadStart = cb.tbText.value;
		}
		G2ComboBox_SetText(cb, loadingtext);
		
		var sb = new Array();
		sb.push(G2_MapPath("~/CachePage.ashx?"));
		G2ComboBox_WriteUrlNameValue(sb, "Version", G2ComboBox_VERSION);
		G2ComboBox_WriteUrlNameValue(sb, "CacheDataKey", cb.cachedatakey);
		G2ComboBox_WriteUrlNameValue(sb, "DataTextField", cb.datatextfield);
		G2ComboBox_WriteUrlNameValue(sb, "DataValueField", cb.datavaluefield);
		G2ComboBox_WriteUrlNameValue(sb, "ParentDataValueField", cb.parentdatavaluefield);
		G2ComboBox_WriteUrlNameValue(sb, "NullValue", cb.nullvalue);
		G2ComboBox_WriteUrlNameValue(sb, "NullDisplayText", cb.nulldisplaytext);
		G2ComboBox_WriteUrlNameValue(sb, "AllowNull", cb.AllowNull);
		G2ComboBox_WriteUrlNameValue(sb, "DataTextFormatString", cb.datatextformatstring);
		G2ComboBox_WriteUrlNameValue(sb, "CachingKey", cb.clientsidecachingkey);
		G2ComboBox_WriteUrlNameValue(sb, "Language", cb.language);
		G2ComboBox_WriteUrlNameValue(sb, "ItemColorMember", cb.itemcolormember);
		G2ComboBox_WriteUrlNameValue(sb, "CacheDataInStorage", cb.cachedatainstorage);
		G2ComboBox_WriteUrlNameValue(sb, "StateStorageID", cb.statestorageid);
		G2ComboBox_WriteUrlNameValue(sb,  "StateStorageKey", cb.statestoragekey);
				
		var url = sb.join("");
		G2_GetData
		(
			url, 
			function(xmlhttp)
			{
			  if (G2ComboBox_LoadItemsCallback) //FireFox may remember this callback from a previous page
			  {
				  G2ComboBox_LoadItemsCallback(cb, xmlhttp.responseText, stopper);
				}
			},
			function(xmlhttp)
			{
			    if (document.getElementById(cb.id) != null)
				    alert("could not load items for "+cb.id+" "+xmlhttp.statusText+", "+xmlhttp.responeText);
			}
		);
	},

	G2ComboBox_WriteUrlNameValue : function(sb, name, value)
	{
		if(value!=null)
			sb.push(name +"="+value+"&");
	},

	G2ComboBox_GetParentComboBox : function(cb)
	{
		if(cb.ParentComboBox==null)
		{
			if(cb.parentlistcontrolid!=null)
			{
				var parentComboBoxes = [];
				var sArr = cb.parentlistcontrolid.split(',');
				
				if(sArr.length > 1)
				{
					for(var i = 0, j = sArr.length; i < j; i++)
					{
						var pcb = document.getElementById(sArr[i]);
						
						// make sure that the parent comboBOx is intialized
						if(!pcb.g2IsInited)
							G2ComboBox_Init(pcb);
							
						parentComboBoxes.push(pcb);
					}
					cb.ParentComboBox = parentComboBoxes;
				}
				else
					cb.ParentComboBox = [document.getElementById(cb.parentlistcontrolid)];
			}
		}
		return cb.ParentComboBox;
	},

	G2ComboBox_IsLoaded : function(cb)
	{
		return cb.IsLoaded;
	},


//	G2ComboBox_CreateHtmlFromJson : function(items)
//	{
//		//G2_Trace("G2ComboBox", "G2ComboBox_CreateHtmlFromJson start");

//		var sb = new Array();
//		sb.push("<table><tbody>");
//		var lastItem;
//		for(var i=0;i<items.length;i++)
//		{
//			var item = items[i];
//			if(lastItem!=null)
//				lastItem.nextItem = item;
//			item.visible = true;
//			item.previousItem = lastItem;

//			sb.push("<tr id='");
//			sb.push(item.value);
//			sb.push("'>");
//			if(item.pdv!=null)
//			{
//				sb.push(" pdv='");
//				sb.push(item.pdv);
//			}
//			sb.push("<td>");
//			if(item.text==null || item.text=="")
//				sb.push("&nbsp;");
//			else
//				sb.push(item.text);
//			sb.push("</td></tr>");
//			lastItem = item;
//		}
//		sb.push("</tbody></table>");
//		var html = sb.join("");
//		return html;

//	},


 	G2ComboBox_FillItemsBackground : function(cb, itemElement, count)
 	{
 	  var c = 0;
 	  while(true)
 	  {
		  if (itemElement.nodeType==1) //FF adds textNodes with "\n", IE doesn't
		  {
			  G2DOM.G2TransferAttributes(itemElement);
			  cb.popup.items.push(itemElement);
			  itemElement.visible = true;
			  if (isMoz && itemElement.innerText=="")
			  {
			    itemElement.innerHTML = "&nbsp;"; //Firefox hides this element beacause it has no text
			  }
			  //index++;
			  //G2ComboBox_InitItem(cb, item);
			  c++;
			  if(count!=null && c==count)
		      break;
		  }
		  itemElement = itemElement.nextSibling;
		  
		  if(itemElement==null)
		    break;		  
		}
		if(count!=null && itemElement!=null)
		{
  	  //window.status = index+" "+item.text;
  	  window.setTimeout(function()
		  {
		    G2ComboBox_FillItemsBackground(cb, itemElement, count);
		  }, 0);
		}
//		else
//		{
//		  window.status = "FINISHED!!!";
//		  cb.ss.lap("Init Items");
//	    cb.ss.report("LoadItemsCallback for "+cb.id);
//		}
 	},


	G2ComboBox_LoadItemsCallback : function(cb, responseText, stopper)
	{
		var tokens = responseText.split("||||");
		var html = tokens[0];
		var items = [];//eval(tokens[1]);
		
		//cb.ss = new Stopper();
		//cb.ss.start();
		cb.popup.firstChild.innerHTML = html;
		//cb.ss.lap("InnerHTML");
		
		cb.popup.firstChild.onmouseover = G2ComboBox_PopupMouseOver;
		cb.popup.firstChild.onmouseout = G2ComboBox_PopupMouseOut;
		cb.popup.firstChild.onclick = G2ComboBox_PopupMouseClick;
			
		var tb = cb.popup.firstChild.firstChild;
		if(tb==null)
		{
		  G2ComboBox_SetText(cb, "No Data Found");
		  return;
		}
		var itemElement = tb.children[0];
		cb.popup.items = items;
		var index=0;
		if(itemElement!=null)
		{
			// Initialize first visible item
			G2DOM.G2TransferAttributes(itemElement);
			cb.firstVisibleItem = itemElement;
		  //Determine wether to init items async.
		  //Only when there is no parent combo (async screwes up sub-filtering) and items html is "big"
		  var shouldLoadAsync=(cb.parentlistcontrolid==null && html.length>G2ComboBox_MIN_SIZE_FOR_BG_INIT);
		  if(shouldLoadAsync)
		    G2ComboBox_FillItemsBackground(cb, itemElement,  G2ComboBox_BG_INIT_BLOCK_SIZE);
		  else
		    G2ComboBox_FillItemsBackground(cb, itemElement);
		}

		//var cbPopupChildren = cb.popup.firstChild;
		//if (cbPopupChildren!=null) //fixed by yaniv for cases that there is no items.
			//cbPopupChildren.className = "G2ComboBox_ItemsTable ScrollBarStyle";
		
		cb.disabled = false;
		if(cb.valueBeforeLoadStart!=null)
		{
		  G2ComboBox_SetText(cb, cb.valueBeforeLoadStart);
		  cb.valueBeforeLoadStart = null;
		}
		else
	  {
		  G2ComboBox_SetText(cb, "");
		}
		G2ComboBox_VerifySelectedValue(cb);
		
		if(cb._wasFocused)
		{
			G2ComboBox_Focus(cb);
			cb._wasFocused = undefined;
		}
		var parentCombo = G2ComboBox_GetParentComboBox(cb);
		
		if(parentCombo!=null)
		{
			for(var i = 0, j = parentCombo.length; i < j; i++)
			{
				pcb = parentCombo[i];
				if(pcb)
				{
					G2ComboBox_Init(pcb);
					pcb.g2OnSelectedValueChanged.push(
						function(sender)
						{
							G2ComboBox_FilterItems(cb);
							var selectedItem = G2ComboBox_GetSelectedItem(cb);
							if(typeof(selectedItem)!="undefined" && selectedItem.isItemDisabled)
							{
								var firstItem = G2ComboBox_GetFirstItem(cb);
								if(firstItem==null)
								{
									throw new Error("no items left for selection in "+cb.id);
								}
								G2ComboBox_SetSelectedValue(cb, firstItem.value, firstItem);
							}
						}
					);
				}
			}

			G2ComboBox_FilterItems(cb);
		}
		
		cb.IsLoaded = true;
		if(cb.setfocus=="true")
		{
			try //TODO: find a better way
			{  
				cb.tbText.focus();
				cb.tbText.select();
			}
			catch(e)
			{
			}
		}
		
		if(cb.updatevalueoncontrolid!=null)
		{
			cb.UpdateValueOnControl = document.getElementById(cb.updatevalueoncontrolid);
		}
		
		if(cb.showPopupWhenLoaded)
		{
		  cb.showPopupWhenLoaded = false;
			G2ComboBox_ShowPopup(cb);
			
		}
		
		

	},

	G2ComboBox_GetParentsDataValue : function(parentComboList)
	{
		var res = [];
		var parentCombo;
		var pdv;
		for(var i = 0, j=parentComboList.length; i < j; i++)
		{
			parentCombo = parentComboList[i];
			if(parentCombo)
			{
				pdv = G2ComboBox_GetSelectedValue(parentCombo);
				if(parentCombo.nullvalue == pdv) // null value will be signal by 'null' in the list of values
					pdv = null;
			}
			else
				pdv = null;
				
			res.push(pdv);
		}
		
		return res.join(',');
	},

	G2ComboBox_CompareFilterValues : function(itemPdv, parentPdvList, cb)
	{
		// validate parameters
		
		
		var iv;
		if(itemPdv)
			iv = itemPdv.split(',');
		else
		{
			iv = [];
			iv.push('');
		}
		
		// in case there is only one parent perform the original action
		if(parentPdvList.length == 1)
		{
			if(!parentPdvList[0])
				return  cb.filterallwhenparentnull ? false : true;
				
			return itemPdv==parentPdvList[0] || (cb.alwaysshownullparentitems && (itemPdv || "") == (cb.nullvalue || ""));
		}

		// if the length do not match there is a bug. its not a possible situation
		if(parentPdvList.length != iv.length)
			return false;
		var parentIsNull;
		for(var i = 0, j = parentPdvList.length; i < j; i++)
		{
			parentIsNull = false;
			if(!parentPdvList[i])
				parentIsNull = cb.filterallwhenparentnull ? false : true;
				
			var b = parentIsNull || // show item if the parent value is null value
				iv[i]==parentPdvList[i] ||	// show item if the values match
				(cb.alwaysshownullparentitems && (itemPdv || "") == (cb.nullvalue || "")); // show item if this is a null value

			if(!b)
				return false;
		}
		
		return true;
	},
	
	G2ComboBox_FilterItemsByParent : function(cb)
	{			 
		var filterByParent = (cb.ParentComboBox!=null);
		if (filterByParent == false)
			return;
		
		var parentCombo = G2ComboBox_GetParentComboBox(cb);
		
		var pdv = G2ComboBox_GetParentsDataValue(parentCombo);
		
		// get parent values as list
		var parentPdvList;
		if(pdv)
			parentPdvList = pdv.split(',');
		else
		{
			parentPdvList = [];
			parentPdvList.push('');
		}
		//var pdv = G2ComboBox_GetSelectedValue(parentCombo);
		//var pdvIsNull = (pdv==parentCombo.nullvalue);

		cb.firstVisibleItem = null;	
		
		var items = cb.popup.items;
		var itemCount = items.length;
		
		var showItems = new Array();
		var hideItems = new Array();
		var visibleCount = 0;	
		
		for (var i=0;i<itemCount;i++)
		{
			var item = items[i];
			var visible = true;
			if(filterByParent)
			{
				if(G2ComboBox_IsNullItem(cb, item)) //do not filter the null item
					visible = true;
				else
					visible = G2ComboBox_CompareFilterValues(item.pdv, parentPdvList, cb);

				item.isItemDisabled = !visible;
			}
			if (visible)
			{
				visibleCount++;
				if(!item.visible)
					showItems.push(item);
			}
			else
			{
				if(item.visible)
					hideItems.push(item);
			}
			if(cb.firstVisibleItem==null && visible && !item.isItemDisabled)
				cb.firstVisibleItem = item;
		}

		G2ComboBox_ShowAndHideItems(cb, showItems, hideItems);
	},

	G2ComboBox_FilterItemsByText : function(cb)
	{
		var text = cb.tbText.value;//.toLowerCase();
		var textRegExp = new RegExp("^"+text, "i");

//		cb.firstVisibleItem = null;	
		var items = cb.popup.items;
		var itemCount = items.length;
		
		var showItems = new Array();
		var hideItems = new Array();
		var visibleCount = 0;	
		
		var firstMatchingItem = null;
		
		for (var i=0;i<itemCount;i++)
		{
			var item = items[i];
			if(!item.visible)
				continue;			//Only search in visible items
				
			var visible = true;
			if (firstMatchingItem==null &&								//Take only the first item
					text!="" &&																//Never take action when the searched string is empty
					item.text.search(textRegExp)!=-1 &&				//Only accept items that match the searched string
					!G2ComboBox_IsNullItem(cb, item))					//Never select the null item
			{
				firstMatchingItem = item;
				break;
			}
//			if(cb.firstVisibleItem==null && visible && !item.isItemDisabled)
//				cb.firstVisibleItem = item;
		}
		
		if (firstMatchingItem!=null)
		{			
			G2ComboBox_SetSelectedValue(cb, firstMatchingItem.value, firstMatchingItem,false,true,true);
			G2ComboBox_ClearPreviouslySelectedItem(cb);
			G2ComboBox_ScrollIntoView(cb,firstMatchingItem);
			cb.selectedItem = firstMatchingItem;
		}
	},

	//TODO: optimize - filtering on js objects is MUCH FASTER!!!
	G2ComboBox_FilterItems : function(cb, filterByText, autoselect)
	{
		var filterByParent = (cb.ParentComboBox!=null);
		if (filterByParent)
		{
			var parentCombo = G2ComboBox_GetParentComboBox(cb);
			var pdv = G2ComboBox_GetParentsDataValue(parentCombo);
			//var pdv = G2ComboBox_GetSelectedValue(parentCombo);
			if (cb.prevPdv != pdv)
			{
				G2ComboBox_FilterItemsByParent(cb);
				cb.prevPdv = pdv;
			}
		}
		if (filterByText!=false)
				G2ComboBox_FilterItemsByText(cb);
		
		cb.FilterItemsByTextThreadId = null;
	},
	
	G2ComboBox_ShouldLoadItemsAsync : function(cb)
	{
	  if(cb.parentlistcontrolid!=null)
	    return false;
	  return true;
	},


	G2ComboBox_ShowAndHideItems : function(cb, showItems, hideItems)
	{
		var totalItemsToShowOrHide = showItems.length+hideItems.length;
		var optimizeByRemovingTable = totalItemsToShowOrHide>700;
		var tbl = null;
		if(optimizeByRemovingTable)
		{
			tbl = cb.popup.firstChild;
			cb.popup.removeChild(tbl);
		}
		G2ComboBox_ShowHideItems(showItems, true);
		G2ComboBox_ShowHideItems(hideItems, false);
		if(optimizeByRemovingTable)
		{
			cb.popup.appendChild(tbl);
		}
	},

	G2ComboBox_ShowHideItems : function(items, show)
	{
			var itemCount = items.length;
		for(var i=0; i < itemCount; i++)
		{
			G2ComboBox_ShowHideItem(items[i], show);
		}
	},

	G2ComboBox_ShowHideItem : function(item, show)
	{
		if(item.visible!=show)
		{
			item.visible = show;
			item.style.display = show ? "" : "none";			//FOLLOWUPDAN-EL
		}
	},

	G2ComboBox_IsNullItem : function(cb, item)
	{
		return cb.AllowNull && cb.nullvalue==item.value;
	},

	//TODO: Optimize
//	G2ComboBox_InitItem : function(cb, item)
//	{
//		var itemElement = item;
//		
//		itemElement.isItem = true;
//	  //moved to html render in server (faster)  itemElement.className = "G2ComboBox_Item";
//		//TODO: try using event bubbling and attach only once
//		itemElement.onmouseover = G2ComboBox_OnItemMouseOver;
//		itemElement.onmouseout = G2ComboBox_OnItemMouseOut;
//		itemElement.onclick = G2ComboBox_OnItemMouseClick;
//		itemElement.item = item;
//		//G2DOM.G2TransferAttributes(itemElement);
//	},
	
	G2ComboBox_GetEvent : function(e)
	{
	  if(e!=null)
	    return e;
	  if(event!=null)
	    return event;
	  return window.top.event;//When the combo opens in an iframe the event occurs on top window
	},
	
	G2ComboBox_PopupMouseOver : function(e)
	{
		e = G2ComboBox_GetEvent(e);
		if(e.srcElement.value!=null)
			G2ComboBox_OnItemMouseOver(e.srcElement);
	},
	
	G2ComboBox_PopupMouseOut : function(e)
	{
		e = G2ComboBox_GetEvent(e);
		if(e.srcElement.value!=null)
			G2ComboBox_OnItemMouseOut(e.srcElement);
	},
	
	G2ComboBox_PopupMouseClick : function(e)
	{
		e = G2ComboBox_GetEvent(e);
		if(e.srcElement.value!=null)
			G2ComboBox_OnItemMouseClick(e.srcElement);
	},
	
  G2ComboBox_OnItemMouseOver : function(itemElement)
	{
		//var itemElement = this;
		itemElement.className = "G2ComboBox_ItemMouseOver";
	},

	G2ComboBox_OnItemMouseOut : function(itemElement)
	{
		//var itemElement = this;
		//var item = itemElement.item;
		if(itemElement.isItemSelected)
			itemElement.className = "G2ComboBox_Item_Selected";
		else
			itemElement.className = "G2ComboBox_Item";
	},

	G2ComboBox_OnItemMouseClick : function(itemElement)
	{
		//var itemElement = this;
		var cb = G2ComboBox_GetComboForItemElement(itemElement);
		G2ComboBox_SetSelectedValue(cb, itemElement.value);
		G2ComboBox_HidePopup(cb);
		G2ComboBox_Focus(cb);
		//G2StopEvent(event);
	},

	G2ComboBox_TogglePopup : function(cb, filterItems,event)
	{
		if(G2ComboBox_IsPopupOpened(cb))
		{
			G2ComboBox_HidePopup(cb);
		}
		else
		{
			G2ComboBox_ShowPopup(cb, filterItems, event) ;
		}
	},

	G2ComboBox_IsPopupOpened : function(cb)
	{
		return G2PopupManager.isPopupOpened(cb.popup);
	},

	G2ComboBox_ShowPopup : function(cb, filterItems,event)
	{
		if (isMoz && event!=null)
			G2StopEvent(event);
			
		if(G2ComboBox_IsPopupOpened(cb))
			return;
	  
	  
	  //var ss = new Stopper();
		//ss.start();
		
		G2ComboBox_EnsureItems(cb);
		
		//ss.lap("EnsureItems");
		//fixedPos = isFixedPositioned(cb) && IE7;
		
		
		//G2_FloatElement(cb.popup, cb.tbText, "S", isIE,fixedPos);
//		cb.popup.style.display="";
		G2PopupManager.openPopup(cb.popup, cb, "bl:tl,br:tr", true);
		if(cb.listwidth)
			cb.popup.style.width = cb.listwidth;
		else
			cb.popup.style.pixelWidth -= 2;
		
		if(cb.selectedItem!=null)
		{
			//cb.selectedItem.scrollIntoView();
		}
 		// verify that the popup is in the boreder of the screen
		G2_VerifyAbsoluteElementNotCropped(cb.popup);
	},
	
	G2ComboBox_BeforeClose : function(popup)
	{
	  if (isMoz)
	  {	    
	    popup.lastScrollTop = popup.children[0].children[0].scrollTop;
	  }
	},
	
	G2ComboBox_Opened : function(popup)
	{
	  if (isMoz && popup.lastScrollTop)
	  {	    
	    popup.children[0].children[0].scrollTop = popup.lastScrollTop;
	  }
	},
  
	G2ComboBox_HidePopup : function(cb)
	{	  
	  G2PopupManager.closePopup(cb.popup);
	},

	G2ComboBox_FindElements : function(cb, childIds)
	{
		var map = new Object();
		var count = childIds.length;
		for(var i=0;i<count;i++)
		{
			map[childIds[i]] = null;
		}
		_G2ComboBox_FindElements(cb, {map:map, count:count});
		return map;
	},
	
	_G2ComboBox_FindElements : function(element, context)
	{
		var child = element.firstChild;
		while(child!=null && context.count>0)
		{
			if(child.id!="")
			{
				for(var p in context.map)
				{
					if(context.map[p]!=null)
						continue;
					if(String.EndsWith(child.id, p))
					{
						context.map[p] = child;
						context.count--;
					}
				}
			}
			_G2ComboBox_FindElements(child, context);
			child = child.nextSibling;
		}
	},

	G2ComboBox_SetText : function(cb, text)
	{
		cb.tbText.value = text.trim();
	},

	G2ComboBox_ClearPreviouslySelectedItem : function(cb)
	{
		cb.previouslySelectedItem = null;
	},

	G2ComboBox_SetSelectedValue : function(cb, value, item, notifyServer, suppressChangeEvent, hightlightOnly, ensureItems)
	{
		if(!cb.g2IsInited)
			G2ComboBox_Init(cb);
		if(ensureItems)
			G2ComboBox_EnsureItems(cb);
		if(notifyServer==null)
			notifyServer = true;
		if(cb.selectedItem!=null)
		{
			cb.selectedItem.className="G2ComboBox_Item";
			cb.selectedItem.isItemSelected = false;
			cb.selectedItem = null;
		}
	 
		if (cb.tbValue.value != value)
			cb.tbValue.value = value;
		//ASP.NET Validation stuff
		//Set initialvalue and value props to yield to RequiredFieldValidatorEvaluateIsValid MS function
		if(cb.initialvalue==null)
			cb.initialvalue = value;
		cb.value = value;
		//---
		if(item==null)
		{
			item = G2ComboBox_GetItemByValue(cb, value);
			if(item==null)
			{
				//TODO: Handle properly
				return;
				//throw new Error("item with value "+value+" was not found");
				
			}
		}
		// set items color;
		if(item.style.color && item.style.color != "")
			cb.tbText.style.color = item.style.color;
		else
			cb.tbText.style.color = "";
		
		cb.selectedItem = item;
		cb.selectedItem.isItemSelected = true;
		cb.selectedItem.className="G2ComboBox_Item_Selected";
		if(item.offsetTop > cb.popup.offsetHeight)
		{
			//cb.popup.doScroll("down");
		}
	  
	  if (!hightlightOnly)
			G2ComboBox_SetText(cb, item.text);
		if(cb.nullcssclass!=null)
		{
			G2_ReplaceCssClass(cb, cb.cssclass, cb.nullcssclass, value==cb.nullvalue);
		}
		if(!suppressChangeEvent)
		{
				window.setTimeout(function(){
						G2ComboBox_OnSelectedValueChanged(cb);}, 10);
 		}
		if(notifyServer && cb.autocallback=="true")
		{
  			__doPostBack(cb, null, true);
		}
	},

	G2ComboBox_GetSelectedItem : function(cb)
	{
		return cb.selectedItem;
	},

	G2ComboBox_SelectFirstItem : function(cb)
	{
		var item = G2ComboBox_GetFirstItem(cb);
		G2ComboBox_SetSelectedValue(cb, item.value, item);
	},

	G2ComboBox_GetFirstVisibleItem : function(cb)
	{
		return cb.firstVisibleItem;
	},

	G2ComboBox_SelectNextItem : function(cb)
	{
		var item = G2ComboBox_GetSelectedItem(cb);
	  
		if(item==null)
		{
			item = G2ComboBox_GetFirstVisibleItem(cb);// G2ComboBox_GetFirstItem(cb);
		}
		var nextItem = item.nextSibling;
		while(nextItem!=null && (!nextItem.visible || nextItem.isItemDisabled))
		{
			nextItem = nextItem.nextSibling;
		}
	  
		if(nextItem!=null)
		{
			G2ComboBox_SetSelectedValue(cb, nextItem.value, nextItem);
			cb.tbText.select();
			G2ComboBox_ClearPreviouslySelectedItem(cb);
		}
	},

	G2ComboBox_SelectPrevItem : function(cb)
	{
		var item = G2ComboBox_GetSelectedItem(cb);
		if(item==null)
			return;
	  
		var prevItem=null;
		while(true)
		{
			item = item.previousSibling;
			if(item==null)
				break;
			if(!item.isItemDisabled && item.visible)
			{
				prevItem = item;
				break;
			}
		}
	  
		if(prevItem!=null)
		{
			G2ComboBox_SetSelectedValue(cb, prevItem.value, prevItem);
			cb.tbText.select();      
			G2ComboBox_ClearPreviouslySelectedItem(cb);  
		}
	},

	G2ComboBox_GetSelectedValue : function(cb)
	{
		if(cb.tbValue)
			return cb.tbValue.value;
	
		return cb.value;
	},

	G2ComboBox_VerifySelectedValue : function(cb)
	{
		var value = G2ComboBox_GetSelectedValue(cb);
		if(value=="" && cb.nullvalue!=null)
			value = cb.nullvalue;
		G2ComboBox_SetSelectedValue(cb, value, null, false, true);
	},


	G2ComboBox_GetComboForItemElement : function(itemElement)
	{
		return itemElement.parentElement.parentElement.parentElement.combo;
	},
	
	G2ComboBox_GetItems : function(cb)
	{	
		return cb.popup.items;
	},

	G2ComboBox_GetFirstItem : function(cb)
	{
		return cb.popup.items[0];
	},

	G2ComboBox_GetItemByValue : function(cb, value)
	{	
		var items = G2ComboBox_GetItems(cb);
		if (items)
		{
			for(var i=0;i<items.length;i++)
			{
				var item = items[i];
				if(item.value==value) //TODO: hash
					return item;
			}
		}
	},

	G2ComboBox_CallbackReturned : function(result)
	{
	},

	G2ComboBox_Callback : function(sender)
	{
	  
	},
	
	FixFieldClick : function(cb)
	{
		G2ComboBox_HidePopup(cb);
		//run client side code 
		if(cb.fixFieldClientClick != null)
		{
			if(cb._fixFieldClientClickFunc == null)
			{
				cb._fixFieldClientClickFunc = new Function("cb", cb.fixFieldClientClick);
			}
			var result = cb._fixFieldClientClickFunc(cb);
			if (result == false)
				return;
				
		}
		__doPostBack(cb, 'FixedItemOnClick', true); //eventArgument
	},


	//Autocomplete ---------------------------------------------------

	textboxSelect  : function(oTextbox, iStart, iEnd) {

		 switch(arguments.length) {
				 case 1:
						 oTextbox.select();
						 break;

				 case 2:
						 iEnd = oTextbox.value.length;
						 /* falls through */
	           
				 case 3:        
						 G2_SetSelectionRange(oTextbox, iStart, iEnd);
		 }

		 oTextbox.focus();
	},
	
	G2ComboBox_ScrollIntoView : function (cb,item)
	{
		var margin = 10;
		var itemTop = item.offsetTop;
		item.parentElement.scrollTop = itemTop;
	}
});


/*
//TODO: optimize - filtering on js objects is MUCH FASTER!!!
	G2ComboBox_FilterItems : function(cb, filterByText, autoselect)
	{
		if (autoselect==null)
			 autoselect = true; //true by default
			 
		//G2_Trace(cb, "G2ComboBox_FilterItems start");
		var filterByParent = (cb.ParentComboBox!=null);
		if(filterByText==null)
			filterByText = false;
	  
		var text = null;
		var textRegExp = null;
		if(filterByText)
		{
			text = cb.tbText.value;//.toLowerCase();
			textRegExp = new RegExp("^"+text, "i");
		}
		var _filterByText = filterByText;
	  filterByText = false; 
		var parentCombo = null;
		var pdv = null;
		var pdvIsNull = false;
		if(filterByParent)
		{
			parentCombo = G2ComboBox_GetParentComboBox(cb);
			pdv = G2ComboBox_GetSelectedValue(parentCombo);
			pdvIsNull = (pdv==parentCombo.nullvalue);
		}
			
		cb.firstVisibleItem = null;	
		var items = cb.popup.items;
		var itemCount = items.length;
		
		var showItems = new Array();
		var hideItems = new Array();
		var visibleCount = 0;	
		
		var firstMatchingItem = null;
		
		for (var i=0;i<itemCount;i++)
		{
			var item = items[i];
			var visible = true;
			if(filterByParent)
			{
				if(G2ComboBox_IsNullItem(cb, item)) //do not filter the null item
					visible = true;
				else if(pdvIsNull)
					visible = cb.filterallwhenparentnull ? false : true;
				else
				{
					visible = item.pdv==pdv || (cb.alwaysshownullparentitems && item.pdv==cb.nullvalue);
				}
				item.isItemDisabled = !visible;
			}
			if(filterByText && !item.isItemDisabled)
			{
				visible = text=="" || item.text.search(textRegExp)!=-1;
			}
			if (_filterByText &&
					firstMatchingItem==null &&								//Take only the first item
					text!="" &&																//Never take action when the searched string is empty
					item.text.search(textRegExp)!=-1 &&				//Only accept items that match the searched string
					!G2ComboBox_IsNullItem(cb, item))					//Never select the null item
			{
				firstMatchingItem = item;
			}
			if (visible)
			{
				visibleCount++;
				if(!item.visible)
					showItems.push(item);
			}
			else
			{
				if(item.visible)
					hideItems.push(item);
			}
			if(cb.firstVisibleItem==null && visible && !item.isItemDisabled)
				cb.firstVisibleItem = item;
		}

		G2ComboBox_ShowAndHideItems(cb, showItems, hideItems);
		
		if (visibleCount==1 && autoselect)
		{
			var item = cb.firstVisibleItem;
			G2ComboBox_SetSelectedValue(cb, item.value, item);
			G2ComboBox_ClearPreviouslySelectedItem(cb);
			G2ComboBox_HidePopup(cb);
			cb.blur();
			if(text!=null) //TODO: FOLLOWUP
				G2_SetSelectionRange(cb.tbText,text.length,cb.tbText.value.length); 
		}
		else if (visibleCount == 0 && autoselect)
		{ 
			if (text)
			{
				G2ComboBox_SetText(cb, text.substr(0,text.length - 1)); // ignore the key if there is no match
				G2ComboBox_FilterItems(cb, filterByText, autoselect);
				
			}
		} else if (_filterByText && firstMatchingItem!=null)
		{			
			G2ComboBox_SetSelectedValue(cb, firstMatchingItem.value, firstMatchingItem,false,true,true);
			G2ComboBox_ClearPreviouslySelectedItem(cb);
			G2ComboBox_ScrollIntoView(cb,firstMatchingItem);
			cb.previouslySelectedItem = firstMatchingItem;
		}
		
		cb.FilterItemsByTextThreadId = null;
	},
	
	*/
function G2ControlSelector_SelectControl(option, control1ID, control2ID)
{
  var cToShow;
  var cToHide;
  if(option==0)
  {
    cToShow = document.getElementById(control1ID);
    cToHide = document.getElementById(control2ID);
  }
  else
  {
    cToShow = document.getElementById(control2ID);
    cToHide = document.getElementById(control1ID);
  }
    
  if(cToShow!=null)
    G2_ShowControl(cToShow);
  if(cToHide!=null)
    G2_HideControl(cToHide);
}

var USE_NEW_CALENDAR = true; //use new (client side) calendar
var ParsableDateTimeFormat = "MM/dd/yyyy HH:mm:ss";

///Creates some more functions for a G2DatePicker node.
function G2DatePicker_Init(datePickerId)
{
	var datePicker = document.getElementById(datePickerId);
	if(datePicker==null)
	{
		Debug.writeln("datepicker "+datePickerId+" was not found");
		return;
	}
	G2DatePicker_VerifyInit(datePicker);
}

function G2DatePicker_CompareValidatorEvaluateIsValid(val) 
{
	var datePicker = document.getElementById(val.controltovalidate);
	var date = G2DatePicker_GetDate(datePicker);
	var datePicker2 = document.getElementById(val.controltocompare);
	var date2 = G2DatePicker_GetDate(datePicker2);
  return G2_DateMatch(date, date2, val.operator);
}



function G2_DateMatch(op1, op2, operator)
{
	var x = op1-op2;
  switch (operator) 
  {
    case "NotEqual":
        return (x!=0);
    case "GreaterThan":
        return (x>0);
    case "GreaterThanEqual":
        return (x>=0);
    case "LessThan":
        return (x<0);
    case "LessThanEqual":
        return (x<=0);
    default:
        return (x==0);
  }
}



///Creates some more functions for a G2DatePicker node.
function G2DatePicker_VerifyInit(datePicker, forceFireOnChangeEvent)
{
	if(datePicker.IsInited)
		return;
		
//	G2_AttachEvent(datePicker, "onfocus", G2DatePicker_OnFocus);
	datePicker.IsInited = true;
	G2DOM.G2TransferAttributes(datePicker);

	var hf = G2DatePicker_GetDateTimeHiddenField(datePicker);
	EnableSupportForPartialPostData(hf);
	datePicker.popcalendarabove = datePicker.popcalendarabove=="true";
	datePicker.G2OnSelectedDateChanged = new Array();//event
	if(datePicker.ClientOnSelectedDateChanged!=null && datePicker.ClientOnSelectedDateChanged.length>0)
	{
		var script = datePicker.ClientOnSelectedDateChanged.replace(new RegExp("this", "g"), "datePicker");
		datePicker.G2OnSelectedDateChanged.push(function(){eval(script);});
	}
	
	datePicker.getValue = function()
	{
	  return G2DatePicker_GetDate(this);
	}
	
	if(datePicker.mode=="Label")
	{
	}
	else if(datePicker.mode=="TextBox")
	{
		var tb = G2DatePicker_GetDateTextBox(datePicker);
		tb.DatePicker = datePicker;
		G2_AttachEvent(tb, "onkeypress", G2DatePicker_TextBox_OnKeyPress);
		G2_AttachEvent(tb, "onblur", G2DatePicker_TextBox_OnBlur);
		G2_AttachEvent(tb, "onfocus", G2DatePicker_TextBox_OnFocus);
		G2_PreventInputPost(tb.id);
			
			
//		G2_AttachEvent(tb, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
		if(!datePicker.disabled && datePicker.setfocus=="true")
		{
			tb.focus();
		}

	}
	else if(datePicker.mode=="DropDown")
	{
		var listDays = G2DatePicker_GetListDays(datePicker);
		datePicker.ShowDays = listDays!=null;
		if(listDays!=null)
		{
			G2NumericDropDown_VerifyInit(listDays);
			G2_PreventInputPost(listDays.id);
			G2_AttachEvent(listDays, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
		}

		if(G2DatePicker_SeperateYearAndMonth(datePicker))
		{
			var listYears = G2DatePicker_GetListYears(datePicker);
			var listMonths = G2DatePicker_GetListMonths(datePicker);
			G2_PreventInputPost(listYears.id);
			G2_PreventInputPost(listMonths.id);

			G2NumericDropDown_VerifyInit(listYears);
			G2_AttachEvent(listMonths, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
			G2_AttachEvent(listYears, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
			if(datePicker.setfocus=="true")
			{
				listYears.focus();
			}
			if(datePicker.defaultyear!=null)
			{
				listYears.onclick = function()
				{
					if(listYears.value=="")
					{
						Select_SetValue(listYears, datePicker.defaultyear);
					}
				}
			}
		}
		else
		{
			var listMonthYear = G2DatePicker_GetListMonthYear(datePicker);
			G2_PreventInputPost(listMonthYear.id);
			G2_AttachEvent(listMonthYear, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
//			listMonthYear.onchange=function(){G2DatePicker_Changed(datePicker, false);}
			if(datePicker.setfocus=="true")
			{
				try
				{
					listMonthYear.focus();	//This may cause an error if the item is hidden etc.
				}
				catch(e)
				{
				}
			}

		}
	}
	
	if(G2DatePicker_ShowTime(datePicker))
	{
		if(G2DatePicker_SeperateHourAndMinute(datePicker))
		{
			var ddlHours = G2DatePicker_GetHoursDropDown(datePicker);
//			G2DropDownList_VerifyInit(ddlHours);
			var ddlMinutes = G2DatePicker_GetMinutesDropDown(datePicker);
			G2_AttachEvent(ddlHours, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
			G2_AttachEvent(ddlMinutes, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
		}
		else
		{
			var ddlTime = G2DatePicker_GetTimeControl(datePicker);
			G2_AttachEvent(ddlTime, "onchange", function(){G2DatePicker_Changed(datePicker, false);});
		}
	}
	
	//TODO: cache related elements by ids.
	G2DatePicker_Changed(datePicker, true, forceFireOnChangeEvent);
	
	//datePicker.originalValue = G2DatePicker_GetDate(datePicker);
	G2DatePicker_SetOriginalValue(datePicker);
	datePicker.g2PerformUndo = G2DatePicker_PerformUndo;
	datePicker.g2SetOriginalValue = G2DatePicker_SetOriginalValue;
	datePicker.g2IsDirty = G2DatePicker_IsDirty;
	if(datePicker.disabledcssclass!=null)
	{
		G2_AttachEvent(datePicker,"onpropertychange",
		function(e)
		{
			if(e.propertyName=="disabled")
				G2_ReplaceCssClass(datePicker, datePicker.cssclass, datePicker.disabledcssclass, datePicker.isDisabled);
		});
	}
	datePicker.setEnabled = function(value)
	{
		G2DatePicker_SetEnabled(datePicker, value);
	}
}
	
function G2DatePicker_SetEnabled(dp, value)
{
	dp.disabled = !value;
	if(dp.disabledcssclass!=null)
		G2_ReplaceCssClass(dp, dp.cssclass, dp.disabledcssclass, !value);
	SetControlChildrenDisability(dp, !value);
}

function G2DatePicker_IsDirty(dp)
{
	dp = dp || this;
	return cb.originalValue!=G2DatePicker_GetDate(dp);
}

function G2DatePicker_PerformUndo(datePicker)
{
	datePicker = datePicker || this;
	G2DatePicker_SetDate(datePicker, datePicker.originalValue);
	//G2.undoNotifyInputChanged(datePicker);
}

function G2DatePicker_SetOriginalValue(datePicker)
{
	datePicker = datePicker || this;
	datePicker.originalValue = G2DatePicker_GetDate(datePicker);
	G2.undoNotifyInputChanged(datePicker);
}


//function G2DatePicker_OnFocus()
//{
//	var datePicker = event.srcElement;
//	datePicker.select();
//}
//
// returns the month value 
//
function G2DatePicker_GetMonth(datePicker)
{
	var month=null;
	if(datePicker.mode=="DropDown")
	{
		if(G2DatePicker_SeperateYearAndMonth(datePicker))
		{
 			var listMonth = G2DatePicker_GetListMonths(datePicker);
 			if(listMonth.value!="")
				month = String_ToInt(listMonth.value);
		}
		else
		{
			var listMonthYear = G2DatePicker_GetListMonthYear(datePicker);
			var monthYear = listMonthYear.value;
			if(monthYear!="")
			{
				var monthYearArray = monthYear.split(".");
				month = String_ToInt(monthYearArray[0]);
			}
		}
	}
	else if(datePicker.mode=="TextBox")
	{
		var tbDate = G2DatePicker_GetDateTextBox(datePicker);
		var strDate = tbDate.value;
		var tokens = strDate.split("/");
		if(tokens.length>=2)
		{
			month = Date_ParseMonth(tokens[1]);
		}
	}
	else if(datePicker.mode=="Label")
	{
		var date = G2DatePicker_GetHiddenFieldDate(datePicker);
		if(date!=null)
		{
			month = date.getMonth();
			month++;
		}
	}
	
	if(month!=null)
		month--;

	return month;
}


function G2DatePicker_GetHiddenFieldDate(datePicker)
{
	var hfDateTime = G2DatePicker_GetDateTimeHiddenField(datePicker);
	var date = Date_Parse(hfDateTime.value, ParsableDateTimeFormat);
	return date;
}

function G2DatePicker_GetYear(datePicker)
{
	var year;
 	if(datePicker.mode=="DropDown")
	{
		if(G2DatePicker_SeperateYearAndMonth(datePicker))
		{
			var listYears = G2DatePicker_GetListYears(datePicker);
			if(listYears.value!="")
				year = String_ToInt(listYears.value);
		}
		else
		{
			var listMonthYear = G2DatePicker_GetListMonthYear(datePicker);
			var monthYear = listMonthYear.value;
			if(monthYear!="")
			{
				var monthYearArray = monthYear.split(".");
				year = String_ToInt(monthYearArray[1]);
			}
		}
	}
	else if(datePicker.mode=="TextBox")
	{
		var tbDate = G2DatePicker_GetDateTextBox(datePicker);
		var strDate = tbDate.value;
		var tokens = strDate.split("/");
		var yearPos = 2;
		if (G2DatePicker_IsRtl(datePicker))
		    yearPos = 0;
		if(tokens.length>yearPos)
		{
			var yearPart = tokens[yearPos];
			if(yearPart.search(" ")==-1)
			{
				year = String_ToInt(yearPart);
				year = G2DatePicker_ResolveYear(datePicker, year);
			}
		}
	}
	else if(datePicker.mode=="Label")
	{
		var hfDateTime = G2DatePicker_GetDateTimeHiddenField(datePicker);
		var date = Date_Parse(hfDateTime.value, ParsableDateTimeFormat);
		if(date!=null)
			year = date.getFullYear();
	}
	return year;
}
//
// Resolves the correct year by checking the datepicker range.
//
function G2DatePicker_ResolveYear(datePicker, year)
{
	var minDate = G2DatePicker_GetMinDate(datePicker);
	if(minDate!=null)
	{
		var minYear = minDate.getFullYear();
		while(minYear>year)
		{
			year+=100;
		}
//		var maxDate = G2DatePicker_GetMaxDate(datePicker);
//		if(maxDate!=null && maxDate.getFullYear()<year)
//			return null; //invalid date. too big
		return year;
	}
	return year;
}

function G2DatePicker_GetMinDate(datePicker)
{
	if(datePicker.minDate==null && datePicker.mindate!=null)
	{
		datePicker.minDate = new Date(datePicker.mindate);
	}
	return datePicker.minDate;
}

function G2DatePicker_GetMaxDate(datePicker)
{
	if(datePicker.maxDate==null && datePicker.maxdate!=null)
	{
		datePicker.maxDate = new Date(datePicker.maxdate);
	}
	return datePicker.maxDate;
}


//text box edit mask
//01234567
//dd/mm/yy

function G2DatePicker_GetDay(datePicker)
{
	var day;
 	if(datePicker.mode=="DropDown")
	{
		if(datePicker.ShowDays)
		{
			var listDay = G2DatePicker_GetListDays(datePicker);
			if(listDay.value!="")
			{
				day = String_ToInt(listDay.value);
			}
		}
		else
		{
			day = 1;
		}
	}
	else if(datePicker.mode=="TextBox")
	{
		var tbDate = G2DatePicker_GetDateTextBox(datePicker);
		var strDate = tbDate.value;
		if(strDate.length>2)
		{
		    if (G2DatePicker_IsRtl(datePicker))
		        day = G2DatePicker_ParseNumber(strDate, strDate.length-2 , 2);
		    else		    
			    day = G2DatePicker_ParseNumber(strDate, 0, 2);
		}
	}
	else if(datePicker.mode=="Label")
	{
		var hfDateTime = G2DatePicker_GetDateTimeHiddenField(datePicker);
		var date = Date_Parse(hfDateTime.value, ParsableDateTimeFormat);
		if(date!=null)
		{
			day = date.getDate();
		}
	}
	return day;
}

function G2DatePicker_ParseNumber(str, startIndex, length)
{
	var s = str.substr(startIndex, length);
	var x = String_ToInt(s);
	if(isNaN(x))
		return null;
	return x;
}

function G2DatePicker_GetDateTextBox(datePicker)
{
	var tbDate = G2DatePicker_GetCachedProperty(datePicker, "tbdate");
	return tbDate;
}

function G2DatePicker_GetCachedProperty(element, propertyName)
{
	var cachedValue = G2DOM.G2GetAttribute(element,propertyName);
	if(cachedValue==null) //not found in cache - fetch it now
	{
		var elemID = G2DOM.G2GetAttribute(element,propertyName+"id");
		cachedValue = element.document.getElementById(elemID);
		element[propertyName] = cachedValue
	}
	return cachedValue;
}


function G2DatePicker_GetDate(datePicker, getDateWithoutTime)
{

  var day = G2DatePicker_GetDay(datePicker);
  var year = G2DatePicker_GetYear(datePicker);
  var month = G2DatePicker_GetMonth(datePicker);
  var hours=0;
  var minutes=0;
  var seconds=0;
  
	if(G2DatePicker_ShowTime(datePicker) && !getDateWithoutTime)
	{
		if(G2DatePicker_SeperateHourAndMinute(datePicker))
		{
			var ddlHours = G2DatePicker_GetHoursDropDown(datePicker);
			var ddlMinutes = G2DatePicker_GetMinutesDropDown(datePicker);
			hours = String_ToInt(ddlHours.value);
			minutes = String_ToInt(ddlMinutes.value);
		}
		else
		{
			var listTime = G2DatePicker_GetTimeControl(datePicker);
			if(listTime)
			{
				if(listTime.value && listTime.value!="__:__")
				{
					var timeArray = listTime.value.split(":");
					hours = String_ToInt(timeArray[0]);
					minutes = String_ToInt(timeArray[1]);
					
					// validate time is in range
					if(hours < 0 || hours > 23 || minutes < 0 || minutes > 59)
					{
						hours = 0;
						minutes = 0;
					}
				}
				
				listTime.parentElement.style['paddingLeft'] = '3px';
			}
		}
	}
	
	if(year==null || day==null || month==null)
		return null;
	if(!getDateWithoutTime  && (hours==null || minutes==null))
		return null;
	var date = Date_GetDateIfValid(year, month, day, hours, minutes, seconds)
	return date;
}

function G2DatePicker_Reset(datePicker)
{
	var defaultDate = G2DatePicker_GetHiddenFieldDate(datePicker);
//	if(!G2DatePicker_AllowNull(datePicker))
//	{
//		defaultDate = G2DatePicker_GetMinDate(datePicker);
//	}
	if(defaultDate)
		G2DatePicker_SetDate(datePicker, defaultDate);
}

function G2DatePicker_SetDate(datePicker, date, setDateWithoutTime)
{
	if(!G2DatePicker_IsDateInValidRange(datePicker, date))
	{
		alert("Date is not in valid range");
		G2DatePicker_Reset(datePicker);
		return;
	}
	if(datePicker.mode=="DropDown")
	{
		if(G2DatePicker_SeperateYearAndMonth(datePicker))
		{
 			var listYears = G2DatePicker_GetListYears(datePicker);
			listYears.value = Date_ToString(date, "yyyy");
 			var listMonths = G2DatePicker_GetListMonths(datePicker);
			listMonths.value =  Date_ToString(date, "M");
		}
		else
		{
			var monthYear = Date_ToString(date, "M.yyyy");//month+"."+year;
			var listMonthYear = G2DatePicker_GetListMonthYear(datePicker);
			listMonthYear.value = monthYear;
		}
		if(datePicker.ShowDays)
		{
			var listDay = G2DatePicker_GetListDays(datePicker);
			G2DatePicker_UpdateListDays(datePicker);
			listDay.value = date.getDate();
		}
		
	}
	else if(datePicker.mode=="TextBox")
	{
		G2DatePicker_SetTextBoxDate(datePicker, date);
	}
	else if(datePicker.mode=="Label")
	{
		var lblDate = G2DatePicker_GetDateLabel(datePicker);
		lblDate.innerText = Date_ToString(date, datePicker.dateformat);
	}
	if(G2DatePicker_ShowTime(datePicker) && !setDateWithoutTime)
	{
		if(G2DatePicker_SeperateHourAndMinute(datePicker))
		{
			var ddlHours = G2DatePicker_GetHoursDropDown(datePicker);
			var ddlMinutes = G2DatePicker_GetMinutesDropDown(datePicker);
			ddlHours.value = Date_ToString(date, "HH");//date.getHours();
			ddlMinutes.value = Date_ToString(date, "mm");//date.getMinutes();
//TODO?			ddlHours.onchange();
//TODO?			ddlMinutes.onchange();
		}
		else
		{
			var listTime = G2DatePicker_GetTimeControl(datePicker);
			listTime.value = Date_ToString(date, "HH:mm");
//TODO?			listTime.onchange();
		}
	}


	
	G2DatePicker_Changed(datePicker, false);
	//win.execScript(datePicker.onchange);
	
	UpdateDpToDate(date, datePicker.datepickertosynchronize);
	
	if(datePicker.autocallback=="true")
	{
		__doPostBack(datePicker, null, true);
	}
}


function G2DatePicker_SetTextBoxDate(datePicker, date)
{
	var tbDate = G2DatePicker_GetDateTextBox(datePicker);
	var s = "";
	if(date==null)
		s = datePicker.nulltext || "  /  /  ";
	else
	{
	    if (G2DatePicker_IsRtl(datePicker))
	        s = Date_ToString(date, "yy/MMM/dd");
	    else
		    s = Date_ToString(date, "dd/MMM/yy");
	}
	tbDate.value = s;
}

function G2DatePicker_OnPropertyChanged(datePicker)
{
	var datePickerChildren = datePicker.children;
	//KHEN: change below:
	//if(datePicker.disabled!=datePickerChildren[0].disabled)
	if(datePickerChildren.length>0 && datePicker.disabled!=datePickerChildren[0].disabled)
	{
		G2_RecursiveSetPropertyValue(datePicker, "disabled", datePicker.disabled);
		var hf = G2DatePicker_GetDateTimeHiddenField(datePicker);
		hf.disabled = false;
	}
}

//function G2DatePicker_Validate(validator, args)
//{
//	var datePicker = document.getElementById(validator.controltovalidate);
//	var date = G2DatePicker_GetDate(datePicker);
//	args.IsValid = G2DatePicker_IsDateInValidRange(datePicker, date);
//}

function G2DatePicker_VerifyCssClass(dp)
{
	if(dp.nullcssclass!=null)
	{
		var isNull = 	dp.SelectedDate==null;
		G2_ReplaceCssClass(dp, dp.cssclass, dp.nullcssclass, isNull);
	}
}
function G2DatePicker_Changed(datePicker, supressOnChangeEvent, forceFireOnChangeEvent)
{
	if(datePicker.mode=="DropDown")
	{
		if(datePicker.ShowDays)
		{
			G2DatePicker_UpdateListDays(datePicker);
		}
	}
	if(G2DatePicker_ShowDayOfWeek(datePicker))
		G2DatePicker_updateDayOfWeek(datePicker);

	var dateTime = G2DatePicker_GetDate(datePicker);
	
	// in case of non-valid week days
	if(datePicker.excludedweekdays != null)
	{
		// validate selected date
		if(!G2DatePicker_IsDateInValidRange(datePicker, dateTime))
		{
			alert("Date is not in valid range");
			G2DatePicker_Reset(datePicker);
			return;
		}
	}
	
	if(dateTime==null)
		datePicker.value = "";
	else
		datePicker.value = dateTime.toString();
	
	var oldDate = datePicker.SelectedDate;
	datePicker.SelectedDate = dateTime;
	G2DatePicker_VerifyCssClass(datePicker);
	if(!supressOnChangeEvent) //TODO: hotfix
	{
		G2DatePicker_SetDateTimeHiddenField(datePicker, dateTime);
	}

	if(!supressOnChangeEvent)
	{
		//TODO: deprecate
		if (isIE)
		{
			var win = datePicker.document.parentWindow;			
			win.execScript(datePicker.onchange);	
		}
		else
		{
			var evt = document.createEvent("HTMLEvents");
			evt.initEvent('change', false, true);
			datePicker.dispatchEvent(evt);
		}
		
		//-----------------------------
		for(var i=0;i<datePicker.G2OnSelectedDateChanged.length;i++)
		{
			datePicker.G2OnSelectedDateChanged[i]({oldValue:oldDate});
		}
	}
	
	if (forceFireOnChangeEvent)
	{
		if(datePicker.clientonchangedfunction!=null)
		{
			eval(datePicker.clientonchangedfunction);
		}
	}
	else if(!supressOnChangeEvent)
	{
		if(datePicker.clientonchangedfunction!=null)
		{
			eval(datePicker.clientonchangedfunction);
		}
	}
}

function G2DatePicker_GetDateLabel(datePicker)
{
	if(datePicker.lblDate==null)
	{
		datePicker.lblDate = G2_FindServerControl(datePicker, "lblDate");
	}
	return datePicker.lblDate;
}

function G2DatePicker_GetDateTimeHiddenField(datePicker)
{
	if(datePicker.hfDateTime==null)
	{
		//var array = document.getElementsByName(datePicker.hfname)[0];
		datePicker.hfDateTime = G2_GetChildControlById(datePicker, "hf");//document.getElementsByName(datePicker.hfname)[0];//document.get G2_FindServerControl(datePicker, "hfDateTime");
	}
	return datePicker.hfDateTime;
}

function G2DatePicker_SetDateTimeHiddenField(datePicker, date)
{
	if(!G2DatePicker_IsDateInValidRange(datePicker, date))
	{
		G2_Trace("date is not in valid range. "+datePicker.id+":"+date);
		//BUG
	}
	
	var hfDateTime = G2DatePicker_GetDateTimeHiddenField(datePicker);
	if(hfDateTime!=null)
	{
		hfDateTime.value = Date_ToString(date, ParsableDateTimeFormat);
	}
	else
	{
		throw new Error("datetime value field was not found");
	}
}

// Check if the selected day of week in the date picker is allowed
// according to the allowed week days - each char in the allowedWeekDays
// string represent the availability - "1" is available, and "0" is not.
function G2DatePicker_ValidateDay(datePicker, allowedWeekDays)
{
	var dateStart = G2DatePicker_GetDate(datePicker);

	if(dateStart != null && allowedWeekDays != null)
	{
		if(allowedWeekDays.substr(dateStart.getDay(),1)=="0")
				return false;		
	}
	return true;
}

function G2DatePicker_NextDate(dpClientID, weekDays)
{  
    var	msPerDay = 24*60*60*1000;
    var dp = document.getElementById(dpClientID);
    if (dp != null)
    {
        var maxDate = G2DatePicker_GetMaxDate(dp)
        var start_dt = G2DatePicker_GetDate(dp);
        do {
		    start_dt.setTime(start_dt.getTime()+msPerDay);
	    }
	    while (weekDays.substr(start_dt.getDay(),1)=="0" && start_dt <= maxDate);
	    if (start_dt <= maxDate && weekDays.substr(start_dt.getDay(),1)=="1")
            G2DatePicker_SetDate(dp, start_dt, true);
    }
}

function G2DatePicker_PreviousDate(dpClientID, weekDays)
{  
    var	msPerDay = 24*60*60*1000;
    var dp = document.getElementById(dpClientID);
    if (dp != null)
    {
        var minDate = G2DatePicker_GetMinDate(dp)
        var start_dt = G2DatePicker_GetDate(dp);
        do {
		    start_dt.setTime(start_dt.getTime()-msPerDay);
	    }
	    while (weekDays.substr(start_dt.getDay(),1)=="0" && start_dt >= minDate);
	    if (start_dt >= minDate && weekDays.substr(start_dt.getDay(),1)=="1")
            G2DatePicker_SetDate(dp, start_dt, true);
    }
}


function Date_GetHoursWithLeadingZero(date)
{
	var hours = date.getHours();
	if(hours<10)
		return "0"+hours.toString();
	return hours.toString();
}

function Date_GetMinutesWithLeadingZero(date)
{
	var minutes = date.getMinutes();
	if(minutes<10)
		return "0"+minutes.toString();
	return minutes.toString();
}

function G2DatePicker_IsDateInValidRange(datePicker, date)
{
	if(date==null)
	{
		var allowNull = G2DatePicker_AllowNull(datePicker);
//		if (!allowNull)
//		    alert('Date is null. returning allowNull: '+ allowNull);
		return allowNull;
	}
	
	// check the datePicker's excludedWeekDays
	if(datePicker.excludedweekdays != null &&
		datePicker.excludedweekdays.indexOf(date.getDay()) != -1)
		return false;
	
	var minDate = G2DatePicker_GetMinDate(datePicker);
	var maxDate = G2DatePicker_GetMaxDate(datePicker);
	
	if (maxDate == null || minDate == null)
		return true;
		
	if(datePicker.mode=="DropDown" && datePicker.ShowDays == false)
	{
		// in case we do not show days we do not regard them in the validation
		if (date.getFullYear() >= minDate.getFullYear() && date.getFullYear() <= maxDate.getFullYear() &&
			date.getMonth() <= minDate.getMonth() && date.getMonth() <= maxDate.getMonth())
			return true;
	}
	else
	{
		if(date>=minDate && date<=maxDate)
			return true;
	}
	return false;
}

// G2DatePicker functions
function G2DatePicker_UpdateListDays(datePicker)
{
	if(!datePicker.ShowDays)
		return;
		
	var listDays = G2DatePicker_GetListDays(datePicker);
//	var date = G2DatePicker_GetDate(datePicker);
//	if(date==null)
//		return;//TODO: reset the list to 1-31
		
	var month = G2DatePicker_GetMonth(datePicker);
	var year = G2DatePicker_GetYear(datePicker);
	if(month==null || year==null)
		return;

    // get the first value of the ddl
    var _newfirst;
    var _minmonth  = new Date(datePicker.mindate).getMonth();
    var _minyear = new Date(datePicker.mindate).getFullYear();
    if (_minmonth == month && _minyear == year)
        _newfirst = new Date(datePicker.mindate).getDate();
    else
        _newfirst = 1;
    
    // get the last value of the ddl
    var _newlast;
    var _maxmonth  = new Date(datePicker.maxdate).getMonth();
    var _maxyear = new Date(datePicker.maxdate).getFullYear();
    if (_maxmonth == month && _maxyear == year)
        _newlast = new Date(datePicker.maxdate).getDate();
    else
        _newlast = Date_GetNumOfDaysInMonth(year, month);
    
    // set the ddl range
    Select_SetRange(listDays, _newfirst, _newlast);
}

function G2_GetElement(idOrElement)
{
	if(typeof(idOrElement)=="string")
		return document.getElementById(idOrElement);
	return idOrElement;
}
//function G2_GetAbsoluteLeft(objectId) 
//{
//	// Get an object left position from the upper left viewport corner
//	// Tested with relative and nested objects
//	o = G2_GetElement(objectId)
//	oLeft = o.offsetLeft            // Get left position from the parent object
//	while(o.offsetParent!=null) {   // Parse the parent hierarchy up to the document element
//		oParent = o.offsetParent    // Get parent object reference
//		oLeft += oParent.offsetLeft // Add parent left position
//		o = oParent
//	}
//	// Return left postion
//	return oLeft
//}

//function G2_GetAbsoluteTop(objectId) 
//{
//	// Get an object top position from the upper left viewport corner
//	// Tested with relative and nested objects
//	o = G2_GetElement(objectId)
//	oTop = o.offsetTop            // Get top position from the parent object
//	while(o.offsetParent!=null) { // Parse the parent hierarchy up to the document element
//		oParent = o.offsetParent  // Get parent object reference
//		oTop += oParent.offsetTop // Add parent top position
//		o = oParent
//	}
//	// Return top position
//	return oTop
//}

function G2DatePicker_Calendar_SelectedDateChanged(sender)
{
	var cal = sender;
	
	// get DatePicker old date
	var datePickerDate = G2DatePicker_GetDate(cal.datePicker);
	var calenderDate = cal.getSelectedDate();
	
	// keep datePicker time instead of overiting it
	if(datePickerDate)
	{
		// get values from datePicker date
		var datePickerHours = datePickerDate.getHours();
		var datePickerMinutes = datePickerDate.getMinutes();
		var datePickerSeconds = datePickerDate.getSeconds();
		var datePickerMilliseconds = datePickerDate.getMilliseconds();
		// set values in calender date
		calenderDate.setHours(datePickerHours);
		calenderDate.setMinutes(datePickerMinutes);
		calenderDate.setSeconds(datePickerSeconds);
		calenderDate.setMilliseconds(datePickerMilliseconds);
	}
	
	// set the selected date
	G2DatePicker_SetDate(cal.datePicker, calenderDate);
	cal.closePopup();
}

//case 8725: if the fromDateDP is selected - the toDateDP is set accordingly
//this behavior occurs only if the 'ToDate' attribute of the fromDateDP is set to the ID of the toDateDP.
//in case the toDateDP is already set this update will not take place
function UpdateDpToDate(selectedDate, datePickerToSynchronize)
{
	if(datePickerToSynchronize != null && datePickerToSynchronize != "")
	{
		var dpToDate = $(datePickerToSynchronize);
		if(!dpToDate)
			return;

		var fixToDate = new Date(selectedDate) > new Date(dpToDate.value);
		if(dpToDate.value == "" || fixToDate)
			G2DatePicker_SetDate(dpToDate, selectedDate);
	}
}

function G2DatePicker_OpenCalendar(datePickerId,isModal)
{
	var datePicker = document.getElementById(datePickerId);
	if(datePicker.disabled)
		return;
	//Handle the case where the link was clicked twice (we already have a calendar opened so - close it)
	if(datePicker._g2calendar!=null)
	{
		G2DatePicker_CloseFloatingCalendar();
		return;
	}
	
	
	if (USE_NEW_CALENDAR)
	{
		var cal = datePicker._calendar;
		if(cal==null)
		{
			cal = new Calendar();
			cal.datePicker = datePicker;
			cal.setMinDate(G2DatePicker_GetMinDate(datePicker));
			cal.setMaxDate(G2DatePicker_GetMaxDate(datePicker));
			var selectedDate = G2DatePicker_GetDate(datePicker);
			cal.setSelectedDate(selectedDate);
			if(selectedDate!=null)
				cal.showDate(selectedDate);
			datePicker._calendar = cal;
			cal.element.style.zIndex = 10;
			cal.element.id = "floatingCalendarDiv";
			cal.setRelativeElement(datePicker);
			cal.setRelativeElementDock(datePicker.popcalendarabove ? "tl:bl" : "bl:tl");
			cal.attachEvent("SelectedDateChanged", G2DatePicker_Calendar_SelectedDateChanged);
			cal.render();
		}
		else
		{
			var selectedDate = G2DatePicker_GetDate(datePicker);
			cal.suspendLayout();
			
			if(selectedDate!=null)
			{
				cal.setSelectedDate(selectedDate);
				cal.showDate(selectedDate);
			}
			
			cal.resumeLayout();
		}
		cal.showPopup();
//		if(datePicker.popcalendarabove)
//			G2_PlaceElementAbsolutlyAbove(cal.element, datePicker);
//		else
//			G2_PlaceElementAbsolutlyBelow(cal.element, datePicker);
//		G2_AttachFrame(cal.element);
//		G2_AttachEvent(document, "onclick", G2DatePicker_CloseFloatingCalendar);
		return;
	}
	
	var minDate = Date_ToDotNetString(G2DatePicker_GetMinDate(datePicker));
	var maxDate = Date_ToDotNetString(G2DatePicker_GetMaxDate(datePicker));
	var selectedDate= Date_ToDotNetString(G2DatePicker_GetDate(datePicker));

	var path = G2_MapPath("~/Client/Controls/Calendar.aspx");
	var url = path+"?datePickerId=" + datePickerId+"&MinDate="+minDate+"&MaxDate="+maxDate+"&SelectedDate="+selectedDate;
	var windowparams = "width=200,height=230,left=270,top=180, location=false";
	var windowtitle = "cal";
	//window.open(rootUrl+"Client/Controls/Calendar.aspx?datePickerId=" + datePickerId+"&MinDate="+minDate+"&MaxDate="+maxDate+"&SelectedDate="+selectedDate, "cal", "width=200,height=230,left=270,top=180, location=false");
	if (isModal)
	{
		//Pop-up calendar
		G2PopupWindow_Open(url,null,false,windowtitle,windowparams);
	}
	else
	{	
		var locationStyle = "";
		if(datePicker.popcalendarabove)
		{
			var top = G2_GetAbsoluteTop(datePicker)-189;
			var left = G2_GetAbsoluteLeft(datePicker);
			
			if( IE7 && window.compactMode == true) //6651 - problem with the location of the calendare in IE7 in compact mode - diffrent calculation is needed
			{
				var top = G2_GetAbsoluteTop(datePicker)-345;
				var left = G2_GetAbsoluteLeft(datePicker)-90;				
			}
			locationStyle = String.Format("top:{0}px; left:{1}px; ", top, left);
		
		}
		
		var floatingDivHtml = String.Format('<DIV ID="floatingCalendarDiv" style="position:absolute; {0} width:184px; height:189px; margin:0px; background-color:transparent;z-index:1000;">', locationStyle);
		// Floating Calendar
		var floatingDiv = G2DOM.G2CreateElement(floatingDivHtml);//'<DIV ID="floatingCalendarDiv" style="position:absolute; left:'+(datePicker.left+225)+'px; top:'+(datePicker.top-15)+'px; width:184px; height:189px; margin:0px; background-color:transparent;z-index:1000;">');
		//Remove old calendar
		G2_DetachEvent(document,'onclick',G2DatePicker_CloseFloatingCalendar); //This will prevent closing the new calendar
		var oldCalendar = document.getElementById('floatingCalendarDiv');	
		var createNewCalendar = true;
		if (oldCalendar)
		{
			if (datePicker.contains(oldCalendar))
				createNewCalendar = false;
			oldCalendar.parentElement.removeChild(oldCalendar);			
		}
		
		if (createNewCalendar)
		{
			datePicker.appendChild(floatingDiv);
			datePicker._g2calendar = floatingDiv;
			//G2_AttachEvent(tb, "onkeyup", G2DatePicker_TextBox_OnKeyUp);
			//window.setTimeout("document.body.attachEvent('onclick',G2DatePicker_CloseFloatingCalendar);",0); //Will happen after the click event is processed.
			G2_DetachEvent(document,'onclick',G2DatePicker_CloseFloatingCalendar); //This will prevent closing the new calendar
			window.setTimeout("G2_AttachEvent(document,'onclick',G2DatePicker_CloseFloatingCalendar);",0); //Will happen after the click event is processed.
			var floatingDivIFrame = G2DOM.G2CreateElement('<IFRAME ID="floatingCalendarFrame" src="'+url+'" style="width:184px;height:189px;" FRAMEBORDER=0  SCROLLING=NO>');
			floatingDiv.appendChild(floatingDivIFrame);
			floatingDivIFrame.src = url //FIX for case 4468
			floatingDivIFrame.contentWindow.opener = window;
			floatingDivIFrame.contentWindow.g2opener = window; //FF refuses to set opener
			var wnd = window;			
			verifyObjectShown(floatingDiv);
			verifyObjectShown(floatingDivIFrame);
		}			
	}
}

function G2DatePicker_CloseFloatingCalendar()
{

	Debug.writeln('G2DatePicker_CloseFloatingCalendar');
	var oldCalendar = document.getElementById('floatingCalendarDiv');
	if (oldCalendar)
	{
		Debug.writeln('G2DatePicker_CloseFloatingCalendar - closed existing calendar.');
		if(oldCalendar.parentElement._g2calendar)
			oldCalendar.parentElement._g2calendar = null;
		oldCalendar.parentElement.removeChild(oldCalendar);	
		G2_DetachEvent(document,'onclick',G2DatePicker_CloseFloatingCalendar); //This will prevent closing the new calendar
		//Cacnel event bubbling so we wont get the click to open event
		if (event)
		{
			event.cancelBubble = true;
			event.returnValue = false;
		}
		return false;
		//document.body.detachEvent('onclick',G2DatePicker_CloseFloatingCalendar);
	}	
}



function G2DatePicker_updateDayOfWeek(sender)
{
    var lblDayOfWeekID = G2DatePicker_GetCachedProperty(sender, "lbldayofweekid");
    
    var lblDayOfWeek = sender.document.getElementById(lblDayOfWeekID);
	var date = G2DatePicker_GetDate(sender);//sender.getDate();
	if(date!=null)
	{
		//TODO: find this more accuratly.
		var iDay = date.getDay();
		var dayOfWeek = weekDays[iDay];
		lblDayOfWeek.innerText = dayOfWeek;
	}
	else
	{
		lblDayOfWeek.innerText = "";
	}
}

function G2DatePicker_SimulateValidation(datePicker)
{
	var targetElement;
	if(G2DatePicker_SeperateYearAndMonth(datePicker))
	{
		targetElement = G2DatePicker_GetListMonths(datePicker);
	}
	else
	{
		targetElement = G2DatePicker_GetListMonthYear(datePicker);
	}

	G2Validator_ValidateElementOnChange(targetElement);
}

//in rtl (hebrew) the date is reversed (when comes from the server or from calendar)
//when it is typed by the user it is already ok (thus disableRtl)
function G2DatePicker_IsRtl(datePicker)
{
    return (datePicker.isrtl == 'true' && datePicker.disableRtl != true);
}

function Calendar_UpdateDatePicker(datePickerId, strNewDate)
{
	//Parse the Date string
	var newDate = new Date(strNewDate);
	
	//Resolve the datePicker Control
	var datePicker = document.getElementById(datePickerId);
	
	//Set the date on the datePicker
	G2DatePicker_SetDate(datePicker, newDate, true);
	
	G2DatePicker_SimulateValidation(datePicker);
//	//Trigger the onchange event on the datePicker
//	window.opener.execScript(datePicker.onchange);
}



// Date functions
function Date_GetNumOfDaysInMonth(fullYear, month)
{
    if(!Date_IsValid(fullYear, month, 29))
        return 28
    if(!Date_IsValid(fullYear, month, 30))
        return 29
    if(!Date_IsValid(fullYear, month, 31))
        return 30;
        
    return 31;
}

function Date_IsValid(fullYear, month, day) 
{
	var test = new Date(fullYear,month,day);
	if ((test.getFullYear() == fullYear) && (month == test.getMonth()) &&  (day == test.getDate()))
		return true;
	else
		return false;
}



function Date_GetDateIfValid(fullYear, month, day, hours, minutes, seconds) 
{
	if(hours==null)
		hours = 0;
	if(minutes==null)
		minutes = 0;
	if(seconds==null)
		seconds = 0;
	var test = new Date(fullYear, month, day, hours, minutes, seconds);
	if (test.getFullYear() == fullYear && 
			month == test.getMonth() &&  
			day == test.getDate() &&
			hours == test.getHours() &&  
			minutes == test.getMinutes() &&  
			seconds == test.getSeconds() 
			)
		return test;
	else
		return null;
}


function Date_RemoveTime(date)
{
	var newDate = new Date(date.toDateString());
	return newDate;
}


function G2DatePicker_ShowDayOfWeek(datePicker)
{
	return G2DOM.G2GetAttribute(datePicker,"options").search("ShowDayOfWeek")!=-1;
}
function G2DatePicker_AllowNull(datePicker)
{
	return G2DOM.G2GetAttribute(datePicker,"options").search("AllowNull")!=-1;
}
function G2DatePicker_SeperateYearAndMonth(datePicker)
{
	return G2DOM.G2GetAttribute(datePicker,"options").search("SeperateYearAndMonth")!=-1;
}
function G2DatePicker_SeperateHourAndMinute(datePicker)
{
	return G2DOM.G2GetAttribute(datePicker,"options").search("SeperateHourAndMinute")!=-1;
}

function G2DatePicker_ShowTime(datePicker)
{
	return G2DOM.G2GetAttribute(datePicker,"options").search("ShowTime")!=-1;
}

function G2DatePicker_GetTimeControl(datePicker)
{
	return G2DatePicker_GetCachedProperty(datePicker, "listtime");
}

function G2DatePicker_GetHoursDropDown(datePicker)
{
	return G2DatePicker_GetCachedProperty(datePicker, "ddlhours");
}

function G2DatePicker_GetMinutesDropDown(datePicker)
{
	return G2DatePicker_GetCachedProperty(datePicker, "ddlminutes");
}

function G2DatePicker_GetListDays(datePicker)
{
	return G2DatePicker_GetCachedProperty(datePicker, "listdays");
}
function G2DatePicker_GetListMonthYear(datePicker)
{
	return G2DatePicker_GetCachedProperty(datePicker, "listmonthyear");
}
function G2DatePicker_GetListYears(datePicker)
{
	return G2DatePicker_GetCachedProperty(datePicker, "listyears");
}
function G2DatePicker_GetListMonths(datePicker)
{
	return G2DatePicker_GetCachedProperty(datePicker, "listmonths");
}

function G2_EmulateKeyPress(keyPressEvent)
{
	var e = keyPressEvent;
	var ch = String.fromCharCode(e.keyCode)
	if(ch=="")
		return;
	G2Event.stop(e);
	var range = document.selection.createRange();
	if(range.text.length>0)
	{
		document.selection.clear();
		range.text=ch;
	}
	else
	{
		range.text+=ch;
	}

}
function G2DatePicker_Mask(textbox, e)
{
	var oldText = textbox.value;
	G2_EmulateKeyPress(e);
	var text = textbox.value;
	if(text==oldText)
		return;
	var keyCode = e.keyCode;
//	var text = textbox.value;
//	var range = document.selection.createRange();
//	
	var pos = G2_GetCaretPosition(textbox);
//	var ch = String.fromCharCode(keyCode);
//	if(ch=="")
//		return;
//	G2Event.stop(e);
//	text = text.substr(0, pos)+ ch + text.substr(pos, text.length);
	text = String_RemoveAll(text, "/");
	for(var i=0;i<8;i++)
	{
		var ch = null;
		if(text.length>i)
			ch = text.charAt(i);
		if(i==2 || i==5)
		{
			if(ch!="/")
			{
				text = String_InsertAt(text, i, "/");
			}
		}
		else
		{
			if(ch==null)
				text = String_InsertAt(text, i, " ");
		}
	}
	text = text.substr(0, 8);
	
	var pos = G2_GetCaretPosition(textbox);
//	pos++;
	if(pos==2 || pos==5)
	{
		if(keyCode==Char.Backspace)
		{
			pos--;
			text = String_RemoveAt(text, pos);
			text = String_InsertAt(text, pos, " ");
		}
		else
		{
			pos++;
		}
	}
	else if(keyCode==Char.Tab)
	{
		pos = 0;
	}
	if(textbox.value!=text)
	{
		textbox.value = text;
		//Feature: blur when filled
	  if(pos==8)
	  {
	    G2_AutoSkip(textbox, true, e);
	  }
	  else
	  {
		  G2_SetCaretPosition (textbox, pos);
		}
		return true;
	}
	G2_SetCaretPosition (textbox, pos);
	window.status = textbox.value.length + ":["+textbox.value+"]";
	return false;
}


function G2DatePicker_TextBox_OnKeyPress(e)
{	
	var sender = G2Event.element(e);

	var keyCode = e.keyCode;
	if(keyCode==9 || keyCode==16) //tab, shift+tab
		return;
	var changed = false;
	changed = G2DatePicker_Mask(sender, e);
//	if(changed)
//	{
//		G2DatePicker_Changed(sender.DatePicker);
//	}
}

function G2DatePicker_TextBox_OnBlur(e)
{
	var sender = G2Event.element(e);
	var datePicker = sender.DatePicker;
	datePicker.disableRtl = true; 
	var date = G2DatePicker_GetDate(datePicker);
	datePicker.disableRtl = false;
	
	// if there was no change- return without ant action
	if(sender.currentDate == date)
		return;

	G2DatePicker_SetDate(datePicker, date);
}

function G2DatePicker_TextBox_OnFocus(e)
{
	
	var sender = G2Event.element(e);
	var datePicker = sender.DatePicker;
	var date = G2DatePicker_GetDate(datePicker);
	sender.currentDate = date;
	if(date!=null)
	{
		var format = "dd/MM/yy";
		sender.value = Date_ToString(date, format);
	}
	else
	{
		sender.value = "  /  /  ";
		if(datePicker.nullcssclass!=null)
			datePicker.className = datePicker.cssclass;
	}
	sender.select();
}









function getFirstDayOfWeek(year, month)
{
	if(typeof(year)=="object")
	{
		var date = year;
		var day = new Date(date.getFullYear(), date.getMonth(), 1).getDay();
		return day;
	}
	var day = new Date(year, month, 1).getDay();
	return day;
}

Calendar = function()
{
	this.suspendLayout();

	this.element = window.top.document.createElement("div");
	this.element._calendar = this;
	this.element.style.position = "absolute";
	this.element.className = "Calendar";
	G2_AttachEvent(this.element, "onselectstart", function(e)
	{
		G2Event.stop(e);
	});
	this.selectedDate = null;
	this._createTable();
	var caller = this;
	G2_AttachEvent(this.element, "onclick", function(e)
	{
		caller._element_onclick(e);
	});
	G2_AttachEvent(this.element, "ondblclick", function(e)
	{
		caller._element_onclick(e);
	});
	G2_AttachEvent(this.element, "onmouseover", function(e)
	{
		caller._element_onmouseover(e);
	});
	G2_AttachEvent(this.element, "onmouseout", function(e)
	{
		caller._element_onmouseout(e);
	});
	this.header = G2DOM.G2CreateElementFromHtml(Calendar._calendarHeaderTemplate, window.top.document);
	this.dateCaptionElement = G2DOM.GetChildElementById(this.header, "dateCaption");
	this.element.insertAdjacentElement("afterBegin", this.header);
	var now = new Date();
	this.today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
	this.maxDate = null;
	this.minDate = null;
	this.showDate(this.today);
}

if(document.body.dir == "rtl")
{
    Calendar._calendarHeaderTemplate =	[
    '				<table class="calendarHeaderTemplate" cellspacing="0" cellpadding="0" border="0">',
    '						<tbody>',
    '							<tr>',
    '								<td style="width: 15px" class="CalendarTitleBackg">',
    '									<div title="Go to the previous month" class="CalendarNavigator_PreviousMonthRTL" style="color: #234b86" href="javascript:void(0);" onclick="Calendar._previousMonth(event);" ondblclick="Calendar._previousMonth(event);"></div></td>',
    '								<td style="width: 120px" class="CalendarTitleBackg" align="center"  id="dateCaption" nowrap></td>',
    '								<td style="width: 15px" align="right" class="CalendarTitleBackg">',
    '									<div title="Go to the next month" class="CalendarNavigator_NextMonthRTL" href="javascript:void(0);" onclick="Calendar._nextMonth(event);" ondblclick="Calendar._nextMonth(event);"></div></td>',
    '							</tr>',
    '						</tbody>',
    '					</table>'
    ].join("");
}
else
{
    Calendar._calendarHeaderTemplate =	[
    '				<table class="calendarHeaderTemplate" cellspacing="0" cellpadding="0" border="0">',
    '						<tbody>',
    '							<tr>',
    '								<td style="width: 15px" class="CalendarTitleBackg">',
    '									<div title="Go to the previous month" class="CalendarNavigator_PreviousMonth" style="color: #234b86" href="javascript:void(0);" onclick="Calendar._previousMonth(event);" ondblclick="Calendar._previousMonth(event);"></div></td>',
    '								<td style="width: 120px" class="CalendarTitleBackg" align="center"  id="dateCaption" nowrap></td>',
    '								<td style="width: 15px" align="right" class="CalendarTitleBackg">',
    '									<div title="Go to the next month" class="CalendarNavigator_NextMonth" href="javascript:void(0);" onclick="Calendar._nextMonth(event);" ondblclick="Calendar._nextMonth(event);"></div></td>',
    '							</tr>',
    '						</tbody>',
    '					</table>'
    ].join("");
}

Calendar.prototype.setRelativeElement = function(element)
{
	this._relativeElement = element;
}
Calendar.prototype.setRelativeElementDock = function(dock)
{
	this._relativeElementDock = dock;
}

Calendar.prototype.render = function()
{
	this.resumeLayout();
}
Calendar.prototype.closePopup = function()
{
	G2PopupManager.closePopup(this.element);
	return;
}


Calendar.prototype.showPopup = function(e)
{
	G2PopupManager.openPopup(this.element, this._relativeElement, this._relativeElementDock, true);
	var w = this._relativeElement.document.parentWindow;
	var tw = window.top;
	//  the marked lines caused 8646
  //	if(tw!=w)
  //	  tw.Calendar = Calendar;
	return;
}

Calendar._getCalendar = function(e)
{
	var element = e.srcElement;
	while(element!=null)
	{
		if(element._calendar!=null)
			return element._calendar;
		element = element.parentElement;
	}
	return null;
}

Calendar._previousMonth = function(e)
{
	var cal = this._getCalendar(e);
	cal.showPreviousMonth(e);
}
Calendar._nextMonth = function(e)
{
	var cal = this._getCalendar(e);
	cal.showNextMonth(e);
}

Calendar.prototype._element_onclick = function(e)
{
	var cell = e.srcElement;
	if(cell.tagName=="TD" && cell.date!=null && this._canSelectDate(cell.date))
	{
		if (this.selectedDate-cell.date==0) 
			this.closePopup();
		else
			this.setSelectedDate(cell.date);
				
	}
	else if(cell==this._btnNext)
	{
		this.showNextMonth();
	}
	else if(cell==this._btnPrevious)
	{
		this.showPreviousMonth();
	}
}


Calendar.prototype.setMinDate = function(date)
{
	this.minDate = date==null ? null : new Date(date.getFullYear(), date.getMonth(), date.getDate());
	this._redraw();
}

Calendar.prototype.setMaxDate = function(date)
{
	this.maxDate = date==null ? null : new Date(date.getFullYear(), date.getMonth(), date.getDate());
	this._redraw();
}

Calendar.prototype._element_onmouseover = function(e)
{
	var cell = e.srcElement;
	if(cell.tagName=="TD" && cell.date!=null)
	{
		if(this._canSelectDate(cell.date))
		{
			G2_AddCssClass(cell, "CalendarDay_MouseOver");
		}
		else
		{
			G2_AddCssClass(cell, "CalendarDay_MouseOver_Disabled");
		}
	}
}

Calendar.prototype._element_onmouseout = function(e)
{
	var cell = e.srcElement;
	if(cell.tagName=="TD" && cell.date!=null)
	{
		G2_RemoveCssClass(cell, "CalendarDay_MouseOver");
		G2_RemoveCssClass(cell, "CalendarDay_MouseOver_Disabled");
	}
}

Calendar.prototype.getSelectedDate = function(date)
{
	return this.selectedDate;
}

Calendar.prototype.setSelectedDate = function(date)
{
	if(date!=null)
		date = new Date(date.getFullYear(), date.getMonth(), date.getDate()); //strip time
	if(this.selectedDate==date || this.selectedDate-date==0)
		return;
	this.selectedDate = date;
	this._redraw();
	this.fireEvent("SelectedDateChanged");
}


Calendar.prototype.showNextMonth = function()
{
	var date= this._shownDate;
	this.showDate(new Date(date.getFullYear(), date.getMonth()+1, 1));
}
Calendar.prototype.showPreviousMonth = function()
{
	var date = this._shownDate;
	this.showDate(new Date(date.getFullYear(), date.getMonth()-1, 1));
}

Calendar.prototype.showDate = function(date)
{
	date = new Date(date.getFullYear(), date.getMonth(), 1); //strip time and day
	if(this._shownDate==date)
		return;
	this._shownDate = date;
	this._redraw();
}
Calendar.prototype.suspendLayout = function()
{
	this._suspendLayout = true;
	this._layoutChanged = false;
}
Calendar.prototype.resumeLayout = function()
{
	this._suspendLayout = false;
	if(this._layoutChanged)
		this._redraw();
}

Calendar.prototype._redraw = function()
{
	if(this._suspendLayout)
	{
		this._layoutChanged = true;
		return;
	}
	var table = this.table;
	var date = this._shownDate;
	this.dateCaptionElement.innerText = Date_ToString(date, "yyyy MMMM");

	var selectedDate = this.getSelectedDate();
	var firstDayOfWeek = getFirstDayOfWeek(date);
	var currentDate = new Date(date.getFullYear(), date.getMonth(), 1-firstDayOfWeek);
	var row = table.rows[0];
	row.className = "CalendarDaysOfWeek";
	for(var j=0;j<7;j++)
	{
		var cell = row.cells[j];
		cell.innerText = G2_ShortDays[j];
	}

	for(var i=1;i<7;i++)
	{
		var row = table.rows[i];
		for(var j=0;j<7;j++)
		{
			var cell = row.cells[j];
			var styles = G2_ParseCssClasses(cell);
			styles.add("CalendarDay");
			cell.innerText = currentDate.getDate().toString();
			if(!this._canSelectDate(currentDate))
			{
				styles.add("CalendarDay_Disabled");
			}
			else
			{
				styles.remove("CalendarDay_Disabled");
			}
			if(currentDate.getMonth()!=date.getMonth())
			{
				styles.add("CalendarDay_Dimmed");
			}
			else
			{
				styles.remove("CalendarDay_Dimmed");
			}
			// compare only the ate component of the dateTime value
			
			if(selectedDate && currentDate && selectedDate.getYear()== currentDate.getYear() && selectedDate.getMonth()== currentDate.getMonth() && selectedDate.getDate()== currentDate.getDate())
			{
				styles.add("CalendarDay_Selected");
				styles.remove("CalendarDay_Today");
			}
			else
			{
				styles.remove("CalendarDay_Selected");
				if(currentDate-this.today==0)
				{
					styles.add("CalendarDay_Today");
				}
				else
				{
					styles.remove("CalendarDay_Today");
				}
			}
			styles.remove("CalendarDay_MouseOver");
			styles.remove("CalendarDay_MouseOver_Disabled");
			G2_SetCssClasses(cell, styles);

			cell.date = currentDate;
			currentDate = Date_AddDays(currentDate, 1);
		}
	}
}

Calendar.prototype._canSelectDate = function(date)
{
	// check the datePicker's excludedWeekDays
	if(this.datePicker.excludedweekdays != null &&
		this.datePicker.excludedweekdays.indexOf(date.getDay()) != -1)
		return false;

	if(this.minDate!=null && date-this.minDate<0)
		return false;
	if(this.maxDate!=null && date-this.maxDate>0)
		return false;
	return true;
}

Calendar.prototype._createTable = function()
{
	var table = window.top.document.createElement("table");
	this.table = table;
	table.className = "Calendar_Table";
	table.cellPadding = 0;
	table.cellSpacing = 0;
	table.border = 0;
	for(var i=0;i<7;i++)
	{
		var row = table.insertRow(-1);
		for(var j=0;j<7;j++)
		{
			var cell = row.insertCell(-1);
		}
	}
	this.element.innerHTML = "";
	this.element.appendChild(table);
}


Calendar.prototype.attachEvent = function(eventName, handler)
{
	if(this.events==null)
	{
		this.events = new Object();
	}
	if(this.events[eventName]==null)
		this.events[eventName] = [handler];
	else
		this.events[eventName].push(handler);
}
Calendar.prototype.fireEvent = function(eventName)
{
	if(this.events==null)
		return;
	
	var handlers = this.events[eventName];
	if(handlers==null)
		return;
	for(var i=0;i<handlers.length;i++)
	{
		handlers[i](this);
	}
}

function G2DateRangePicker_GetStartDateControl(dateRangePicker)
{
	if(dateRangePicker.StartDateControl==null)
	{
		dateRangePicker.StartDateControl = document.getElementById(dateRangePicker.startdatecontrolid);
	}
	return dateRangePicker.StartDateControl;
}

function G2DateRangePicker_GetEndDateControl(dateRangePicker)
{
	if(dateRangePicker.EndDateControl==null)
	{
		dateRangePicker.EndDateControl = document.getElementById(dateRangePicker.enddatecontrolid);
	}
	return dateRangePicker.EndDateControl;
}

//This function is unused, but make sure to send the SenderID and not the sender itself
function G2DateRangePicker_VerifyInit(senderID)
{
	G2DateRangePicker_Init(senderID);
}

//Modified by Alon - sender is the ID of the sender, not the sender itself (FF compatibility)
function G2DateRangePicker_Init(senderID)
{
	var sender = document.getElementById(senderID);
	if(!sender || sender.IsInited)
		return;
	sender.IsInited = true;	
	G2DOM.G2TransferAttributes(sender);	
	var start = G2DateRangePicker_GetStartDateControl(sender);
	var end = G2DateRangePicker_GetEndDateControl(sender);
	if(start==null || end==null)
		return;
	
	//Force initialization of the datepickers
	G2DatePicker_VerifyInit(start, true);
	G2DatePicker_VerifyInit(end, true);
	sender.nightmode = sender.nightmode!="false";
	sender.includehours = sender.includehours!="false";

	if(sender.mode=="Invisible")
	{
		sender.maxdays = parseInt(sender.maxdays);
		sender.mindays = parseInt(sender.mindays);
	}
	else
	{
		var nddDays = G2DateRangePicker_GetDaysNumericDropDown(sender);
		G2NumericDropDown_VerifyInit(nddDays);
		nddDays.onchange=function(){G2DateRangePicker_DaysChanged(sender);};
	}
	
	
//	sender.onpropertychange = "G2DateRangePicker_OnPropertyChanged(this);";

	start.G2OnSelectedDateChanged.push
	(
		function(e)
		{
			G2DateRangePicker_StartDateChanged(sender, e);
		}
	);
	end.G2OnSelectedDateChanged.push
	(
		function(e)
		{
			G2DateRangePicker_EndDateChanged(sender, e);
		}
	);
	
	G2DateRangePicker_EndDateChanged(sender);
}

function G2DateRangePicker_OnPropertyChanged(dateRangePicker)
{
	if(dateRangePicker.mode!="Invisible")
	{
		var nddDays = G2DateRangePicker_GetDaysNumericDropDown(dateRangePicker);
		if(dateRangePicker.disabled!=nddDays.disabled)
		{
			G2_RecursiveSetPropertyValue(dateRangePicker, "disabled", dateRangePicker.disabled);
		}
	}
}


function G2DateRangePicker_GetDaysNumericDropDown(dateRangePicker)
{
	if(dateRangePicker.listDaysControl==null)
	{
		dateRangePicker.listDaysControl = document.getElementById(dateRangePicker.listdayscontrolid);
	}
	return dateRangePicker.listDaysControl;
}

///Occurs when the DateRangePicker changed its days
function G2DateRangePicker_DaysChanged(dateRangeControl)
{
	if(dateRangeControl.updating)
		return;
	dateRangeControl.updating = true;
	var startDateControl = G2DateRangePicker_GetStartDateControl(dateRangeControl);
	var endDateControl = G2DateRangePicker_GetEndDateControl(dateRangeControl);
	var startDate = G2DatePicker_GetDate(startDateControl, true);
	var sDays = parseInt(G2DateRangePicker_GetDaysNumericDropDown(dateRangeControl).value);
	if(sDays!="")
	{
		var days = parseInt(sDays);
	    //if day mode - we should subtract 1 day
		if(!dateRangeControl.nightmode)
			days--;
		var endDate = Date_AddDays(startDate, days);
		G2DatePicker_SetDate(endDateControl, endDate, true);
	}
	dateRangeControl.updating = false;
}

///Occurs when one of the date controls (start/end) changes its date
function G2DateRangePicker_StartDateChanged(dateRangeControl, e)
{
	if(dateRangeControl.updating)
		return;
	dateRangeControl.updating = true;
	var startDateControl = G2DateRangePicker_GetStartDateControl(dateRangeControl);
	var endDateControl = G2DateRangePicker_GetEndDateControl(dateRangeControl);
	var startDate = G2DatePicker_GetDate(startDateControl);
	if(startDate!=null)
	{
		var endDate = G2DatePicker_GetDate(endDateControl);
		var days = G2DateRangePicker_CalculateDays(dateRangeControl, startDate, endDate);
		if(dateRangeControl.mode=="Invisible")
		{
			if(days<dateRangeControl.mindays)
			{
				var newDate = Date_AddDays(startDate, dateRangeControl.mindays);
				G2DatePicker_SetDate(endDateControl, newDate, true);
			}
			else if(days>dateRangeControl.maxdays)
			{
				var newDate = Date_AddDays(startDate, dateRangeControl.maxdays);
				G2DatePicker_SetDate(endDateControl, newDate, true);
			}
		}
		else
		{
			if(Date_EqualsWithoutTime(startDate, e.oldValue)) //only time has changed
			{
			  //include the hours while calculating the range ( i.e. more the 24 hours range will cause addition of 1 day )
				if(dateRangeControl.includehours)
				{
					var currentDays = G2DateRangePicker_GetDays(dateRangeControl);
					if(currentDays!=days) //happens when just the time has changed
					{
						G2DateRangePicker_SetDays(dateRangeControl, days);
					}
				}
			}
			else
			{
				var currentDays = G2DateRangePicker_GetDays(dateRangeControl);
				if(currentDays == null)
				{
					currentDays = days;
					G2DateRangePicker_InternalSetDays(dateRangeControl,currentDays);
				}
				Date_RemoveTime(startDate);
				Date_RemoveTime(endDate);
				var newDate;
				//if day mode - we should subtract 1 day
                if(dateRangeControl.nightmode)
					newDate = Date_AddDays(startDate, currentDays);
				else
				    newDate = Date_AddDays(startDate, currentDays - 1);
				   
				G2DatePicker_SetDate(endDateControl, newDate, true);
			}
		}
	}
	dateRangeControl.updating = false;
}

//case 7606:
//this function is called in case the day light saving turn date (summer to winter or vise versa) 
//happens to occur between start date and end date
//these are the time formats: "00:00:00 UTC+0100" or "00:00:00 UTC-0100"
function AddHoursAtDateLightSavingSwitch(endDate, startDate)
{
	var hoursToAdd = 0
	if(startDate != null && startDate.toTimeString().indexOf('+') > -1)
		hoursToAdd -= ExtractMissingHours(startDate, '+');
	if(startDate != null && startDate.toTimeString().indexOf('-') > -1)
		hoursToAdd += ExtractMissingHours(startDate, '-');
	if(endDate != null && endDate.toTimeString().indexOf('+') > -1)
		hoursToAdd += ExtractMissingHours(endDate, '+');
	if(endDate != null && endDate.toTimeString().indexOf('-') > -1)
		hoursToAdd -= ExtractMissingHours(endDate, '-');
	return hoursToAdd;
}

function ExtractMissingHours(inPutDate, sign)
{
	var numInputDate = Number(inPutDate.toTimeString().split(sign)[1])/100;
	if(!isNaN(numInputDate))
		return Number(sign + numInputDate);
	else 
		return Number(sign + 1);
}

function G2DateRangePicker_CalculateDays(dateRangeControl, startDate, endDate)
{
	var hoursToAdd = AddHoursAtDateLightSavingSwitch(endDate, startDate);
	
	// If not include hours - remove time to calculate the days
	if(!dateRangeControl.includehours)
	{
	    Date_RemoveTime(startDate);
		Date_RemoveTime(endDate);
	}
	if(dateRangeControl.nightmode)
		return DateRange_GetNights(endDate-startDate, hoursToAdd);
    return DateRange_GetDays(endDate-startDate, hoursToAdd);

}

function G2DateRangePicker_GetDays(dateRangeControl)
{
	var ndd = G2DateRangePicker_GetDaysNumericDropDown(dateRangeControl);
	var days = String_ToInt(ndd.value);
	return days;
}

function Date_EqualsWithoutTime(date1, date2)
{
	if(date1==null || date2==null)
		return date1==date2;
	return (date1.getFullYear()==date2.getFullYear() && date1.getMonth()==date2.getMonth() && date1.getDate()==date2.getDate());
}

function Date_Equals(date1, date2)
{
	if(date1==null || date2==null)
		return date1==date2;
	return date1.valueOf()==date2.valueOf();
}

function Date_RemoveTime(date)
{
	if(date)
		date.setHours(0, 0, 0, 0);
}

function G2DateRangePicker_EndDateChanged(dateRangeControl, e)
{
	if(dateRangeControl.updating)
		return;
	dateRangeControl.updating = true;
	var startDateControl = G2DateRangePicker_GetStartDateControl(dateRangeControl);
	var endDateControl = G2DateRangePicker_GetEndDateControl(dateRangeControl);
	var startDate = G2DatePicker_GetDate(startDateControl);
	var endDate = G2DatePicker_GetDate(endDateControl);
	
	if(endDate!=null && startDate!=null)
	{
		var days = G2DateRangePicker_CalculateDays(dateRangeControl, startDate, endDate);
		if(dateRangeControl.mode=="Invisible")
		{ 
//			//TODO: remove this code - we don't wan't to update the startDatePicker
//			if(days<dateRangeControl.mindays)
//			{
//				var newDate = Date_SubtractDays(endDate, dateRangeControl.mindays);
//				G2DatePicker_SetDate(startDateControl, newDate);
//			}
//			else if(days>dateRangeControl.maxdays)
//			{
//				var newDate = Date_SubtractDays(endDate, dateRangeControl.maxdays);
//				G2DatePicker_SetDate(startDateControl, newDate);
//			}
		}
		else
		{
			var nddDays = G2DateRangePicker_GetDaysNumericDropDown(dateRangeControl);
			nddDays.value = days;
		}
	}
	dateRangeControl.updating = false;
}

function G2DateRangePicker_SetDays(dateRangePicker, days)
{
	G2DateRangePicker_InternalSetDays(dateRangePicker, days);
	G2DateRangePicker_DaysChanged(dateRangePicker);
}

function G2DateRangePicker_InternalSetDays(dateRangePicker, days)
{
	var nddDays = G2DateRangePicker_GetDaysNumericDropDown(dateRangePicker);
	nddDays.value = days;
}

// JScript File
G2Dragger = function(cell)
{
	this.Cell = cell;
	this.SetBackgroundImage("Dragger.gif");
	this.SurfaceElement = cell.parentElement.parentElement.parentElement;
	G2_AttachEventWithCaller(this.Cell, "onmousedown", this.DragHandleElement_mousedown, this);
	G2_AttachEventWithCaller(this.Cell,"onmouseover", this.DragHandleElement_mouseover, this);
	G2_AttachEventWithCaller(this.Cell,"onmouseout", this.DragHandleElement_mouseout, this);
}

G2Dragger.EnableDrag = function(cell)
{
	cell._dragger = new G2Dragger(cell);
}

G2_DeclareClass(G2Dragger, "G2Dragger", null, 
{
	DragHandleElement_mousedown : function(e)
	{
		if(this.isDragging)
			this._EndDrag(e);
		else
			this._StartDrag(e);
	},
	_StartDrag : function(e)
	{
		this.isDragging = true;
		var mouseX = e.clientX;
		this.offsetX = mouseX-this.Cell.offsetLeft;
		this.Cell.setCapture(true);
		G2_AttachEventWithCaller(this.Cell, "onmousemove", this.DragHandleElement_mousemove, this);
		G2_AttachEventWithCaller(this.Cell, "onmouseup", this.DragHandleElement_mouseup, this);
	},
	_EndDrag : function()
	{
		this.Cell.releaseCapture();
		G2_DetachEventWithCaller(this.Cell, "onmousemove", this.DragHandleElement_mousemove, this);
		G2_DetachEventWithCaller(this.Cell, "onmouseup", this.DragHandleElement_mouseup, this);
		this.isDragging = false;
	},
	DragHandleElement_mousemove : function(e)
	{
		var prevCell = this.Cell.previousSibling;
		var width = e.clientX - prevCell.offsetLeft - this.offsetX;
		if(width < 0)
			width = 0;
		prevCell.style.width = width;	
	},
	DragHandleElement_mouseup : function(e)
	{
		this.SetBackgroundImage("Dragger.gif");
		if(this.isDragging)
			this._EndDrag();
	},
	DragHandleElement_mouseover : function(e)
	{
		this.SetBackgroundImage("Dragger_Over.gif");
	},
	DragHandleElement_mouseout : function(e)
	{
		this.SetBackgroundImage("Dragger.gif");
	},
	SetBackgroundImage : function(ImageName)
	{
		var virtualUrl = "/App_Themes/Setup/Images/Icons/" + ImageName;
		var rootAppPath = document.getElementById("G2_RootAppPath").value;
		var url = G2_MapPath(rootAppPath + virtualUrl);
		this.Cell.style.backgroundImage = "url(" + url + ")";
	}
});



G2DropDownList_HtmlSelectEmptyValue = "_NULL_";

function G2DropDownList_VerifySubmit(ddlControlId)
{
	var ddlControl = document.getElementById(ddlControlId);
	if(ddlControl!=null && ddlControl.disabled)
		ddlControl.disabled = false;
}

function G2DropDownList_VerifyInit(ddlControl)
{
	if(ddlControl.IsInited)
		return;
	if (!ddlControl)
	{
		G2_Warn("G2DropDownList_VerifyInit","ddlControl is null!");
		return;
	}
	G2DOM.G2TransferAttributes(ddlControl);
	ddlControl.IsInited = true;
	
	ddlControl.g2onload = []; //events array
	var changeScripts = ddlControl.g2onchange;
	ddlControl.g2onchange = []; //events array
	if(changeScripts!=null)
	{
		var func = eval(changeScripts);
//		if(typeof(func)!="function")
//			throw new Error("g2onchage requires a function name");
		ddlControl.g2onchange.push(func);
	}
	
	if(G2DropDownList_EnableClientSideLoading(ddlControl))
	{		
		G2DropDownList_LoadItems(ddlControl);//asynchornous
	}
	else
	{
		G2DropDownList_InternalLoad(ddlControl);
	}
	EnableSupportForPartialPostData(ddlControl);
  ddlControl.getValue = function()
  {
    if(this.value == G2DropDownList_HtmlSelectEmptyValue)
      return "";
    return this.value;
  }
}

function G2DropDownList_Load(ddlControlId)
{
	var ddlControl = document.getElementById(ddlControlId);
	if(ddlControl==null) //TODO: this might happen when a visible control is found in an invisible gridColumn
		return;
	G2DropDownList_VerifyInit(ddlControl);
}

function G2DropDownList_GetParentListControl(ddlControl)
{
	if(ddlControl.parentlistcontrol==null && ddlControl.parentlistcontrolid!=null)
	{
		ddlControl.parentlistcontrol = document.getElementById(ddlControl.parentlistcontrolid);
	}
	return ddlControl.parentlistcontrol;
}

function G2DropDownList_IsLoaded(ddlControl)
{
	return ddlControl.IsLoaded;
}
function G2DropDownList_InternalLoad(ddlControl)
{
	var allowLoad=true;
	var parentListControl = G2DropDownList_GetParentListControl(ddlControl);
	if(parentListControl!=null)
	{
		if(G2DropDownList_IsLoaded(parentListControl))
		{
			G2DropDownList_ApplyFilter(parentListControl, ddlControl);
			G2DropDownList_AttachToParentListControl(ddlControl, parentListControl);
		}
		else
		{
			allowLoad	 = false;
			parentListControl.g2onload.push
			(
				function()
				{
					G2DropDownList_ApplyFilter(parentListControl, ddlControl);
					G2DropDownList_AttachToParentListControl(ddlControl, parentListControl);
					G2DropDownList_OnLoad(ddlControl);
				}
			);
		}
	}
	if(allowLoad)
		G2DropDownList_OnLoad(ddlControl);
}
	
function G2DropDownList_AttachToParentListControl(ddlControl, parentListControl)
{
	parentListControl.g2onchange.push(
		function()
		{
			G2DropDownList_ApplyFilter(parentListControl, ddlControl);
		});
}

//	if(ddlControl.ChildFilteredControlIds!=null)
//	{
//		ddlControl.ChildFilteredControls = new Array();
//		var tokens = ddlControl.ChildFilteredControlIds.split(",");
//		for(var i=0;i<tokens.length;i++)
//		{
//			var token = tokens[i];
//			if(token.length>0)
//				ddlControl.ChildFilteredControls.push(document.getElementById(token));
//		}
//		G2DropDownList_ApplyChildFiltering(ddlControl);
//	}



//	if(ddlControl.UpdateValueOnControlId!=null)
//	{
//		ddlControl.UpdateValueOnControl = document.getElementById(ddlControl.UpdateValueOnControlId);
//		G2DropDownList_ApplySync(ddlControl);
//	}
//	if(allowLoad)
//	{
//		G2DropDownList_OnLoad(ddlControl);
//	}
//}


function G2DropDownList_OnLoad(ddlControl)
{
	ddlControl.IsLoaded=true;
	for(var i=0;i<ddlControl.g2onload.length;i++)
	{
		ddlControl.g2onload[i](ddlControl);
	}
}





function G2DropDownList_LoadItems(ddlControl)
{
	var stopper = new Stopper();
	stopper.start();
	//G2_Trace(ddlControl, "G2DropDownList_LoadItems: "+stopper.lap()+"ms");

	ddlControl.disabled = true;
	ddlControl.options.add(new Option("Loading", "Loading"), 0);
	var url = G2_MapPath("~/CachePage.ashx");
	G2_GetData
	(
		url+"?CacheDataKey="+ddlControl.CacheDataKey+
			"&DataTextField="+ddlControl.DataTextField+
			"&DataValueField="+ddlControl.DataValueField+
			"&ParentDataValueField="+ddlControl.ParentDataValueField+
			"&DataTextFormatString="+ddlControl.DataTextFormatString, 
		function(xmlhttp)
		{
			G2DropDownList_LoadItemsCallback(ddlControl, xmlhttp.responseText, stopper);
		},
		function(xmlhttp)
		{
		    if (document.getElementById(ddlControl.id) != null)
			    alert("could not load items for "+ddlControl.id+" "+xmlhttp.statusText+", "+xmlhttp.responeText);
		}

	);
}

function G2DropDownList_LoadItemsCallback(ddlControl, responseText, stopper)
{
	//G2_Trace(ddlControl, "G2DropDownList_LoadItemsCallback start");
	//G2_Trace(ddlControl, "G2DropDownList_LoadItemsCallback Eval Start");
	eval(responseText);
	//G2_Trace(ddlControl, "G2DropDownList_LoadItemsCallback Eval End");
	ddlControl.options.remove(0);
	ddlControl.disabled = false;
	G2DropDownList_VerifyNullItem(ddlControl);
	ddlControl.value = ddlControl.selectedvvalue;
	G2DropDownList_InternalLoad(ddlControl);
	//G2_Trace(ddlControl, "G2DropDownList_LoadItemsCallback end: "+stopper.lap()+"ms");
}

function G2DropDownList_VerifyNullItem(ddlControl)
{
	if(G2DropDownList_AllowNull(ddlControl))
	{
		var option = new Option(ddlControl.nulldisplaytext, ddlControl.nullvalue);
		ddlControl.options.add(option, 0);
	}
}


function G2DropDownList_Changed(ddlControl)
{
	if(ddlControl.g2onchange!=null)
	{
		G2_FireEventArray(ddlControl, ddlControl.g2onchange);
	}
	

//  if(ddlControl.g2onchange!=null)
//  {
//    eval(ddlControl.g2onchange+"('"+ddlControl.id+"');");
//  }
//	G2DropDownList_ApplyChildFiltering(ddlControl);
	if(ddlControl.UpdateValueOnControl!=null)
		G2DropDownList_ApplySync(ddlControl);
}

//function G2DropDownList_ApplyChildFiltering(ddlControl)
//{
//	if(ddlControl.ChildFilteredControls!=null)
//	{
//		for(var i=0;i<ddlControl.ChildFilteredControls.length;i++)
//		{
//			var childControl = ddlControl.ChildFilteredControls[i]
//			G2DropDownList_ApplyFilter(ddlControl, childControl);
//		}
//	}
//}

function G2DropDownList_ApplySync(ddlControl)
{
	ddlControl.UpdateValueOnControl.value = ddlControl.value;
}

function G2DropDownList_ApplyFilter(parentListControl, ddlControl)
{
//	var start = new Date();
	var stopper = new Stopper();
	stopper.start();
	//G2_Trace(ddlControl, "G2DropDownList_ApplyFilter - start");
	var parentId = parentListControl.value;

	var startIndex = G2DropDownList_GetRelevantStartIndex(ddlControl);
  // backup the list, only the first time
  if (ddlControl.OriginalOptions==null)
  {
		ddlControl.OriginalOptions = G2_CopyArray(ddlControl.options, startIndex);
		G2DropDownList_GroupOptions(ddlControl);
	
  }
	//G2_Trace(ddlControl, "G2DropDownList_ApplyFilter - group options");
  
  //Backup the selected valkue
  var selectedValue = ddlControl.value;

	//Perform Unfilter if needed  
 	if(ddlControl.nullvalue==parentId)
	{
		//optimization - do not clear and refill the combo again
		if(ddlControl.options.length<ddlControl.OriginalOptions.length)
		{
			ddlControl.options.length = startIndex;
			G2DropDownList_AddItems(ddlControl, ddlControl.OriginalOptions, stopper);
//			ddlControl.options.length = 0;
//			for (n=0;n<ddlControl.OriginalOptions.length;n++)
//			{
//				ddlControl.options.add(ddlControl.OriginalOptions[n]);
//			}
		}
		//G2_Trace(ddlControl, "G2DropDownList_ApplyFilter - group options End");
	}
	else //Perform filter
	{
		G2DropDownList_FilterParentDataValue(ddlControl, parentId, selectedValue, stopper);
  }
  
  if(ddlControl.value!=selectedValue)
  {
		G2DropDownList_Changed(ddlControl);
	}
	
//	var end = new Date();
	//G2_Trace(ddlControl, "G2DropDownList_ApplyFilter end");
}

//function G2DropDownList_FilterParentDataValue2(ddlControl, parentId, selectedValue)
//{
////	var j=0;
//	for(var i=0;i<ddlControl.OriginalOptions.length;i++)
//	{
//		var originalOption = ddlControl.OriginalOptions[i];
//		if(originalOption.pdv==null || originalOption.pdv==parentId)
//		{
//			if(!ddlControl.options.contains(originalOption))
//				ddlControl.options.add(originalOption);
////			if(ddlControl.options[j]!=originalOption)
////				ddlControl.options[j] = originalOption;
//				
//			if(originalOption.value==selectedValue)
//				ddlControl.value = selectedValue;

////			j++;
//		}
//	}
//	if(ddlControl.options.length != j+1)
//		ddlControl.options.length = j+1;
//}

function G2DropDownList_AddItems(ddlControl, items, stopper)
{
	for (n=0;n<items.length;n++)
	{
		var option = items[n];
		ddlControl.options.add(option);
//		if(option.value==selectedValue)
//			ddlControl.value = selectedValue;
	}
}

function G2DropDownList_FilterParentDataValue(ddlControl, parentId, selectedValue, stopper)
{
	var startIndex = G2DropDownList_GetRelevantStartIndex(ddlControl);

  ddlControl.options.length = startIndex;
//	Debug.writeln("G2DropDownList_ApplyFilter - added ungrouped options, took: "+stopper.lap()+"ms");

  var relevantOptions = ddlControl.GroupedOptions[parentId];
 	//G2_Trace(ddlControl, "G2DropDownList_ApplyFilter - found grouped options");
 	if(relevantOptions==null || relevantOptions.length==0)
 	{
 		G2DropDownList_AddItems(ddlControl, ddlControl.OriginalOptions, selectedValue, stopper);
 	}
	else//if(relevantOptions!=null)
  {
		G2DropDownList_AddItems(ddlControl, relevantOptions, selectedValue, stopper);
	}
	ddlControl.value = selectedValue;
	if(ddlControl.selectedIndex==-1 && ddlControl.options.length>0)
		ddlControl.selectedIndex=0;
	//G2_Trace(ddlControl, "G2DropDownList_ApplyFilter - added grouped options");

}


function G2DropDownList_GroupOptions(ddlControl)
{
	var stopper = new Stopper();
	stopper.start();
	//G2_Trace(ddlControl, "entering G2DropDownList_GroupOptions");

	var hashtable = new Object();
	var ungroupedOptions = new Array();
	var startIndex = G2DropDownList_GetRelevantStartIndex(ddlControl);
	for (var i=startIndex;i<ddlControl.OriginalOptions.length;i++)
	{
		var option = ddlControl.OriginalOptions[i];
		if(option.pdv==null)
		{
			ungroupedOptions.push(option);
		}
		else
		{
			var options = hashtable[option.pdv];
			if(options==null)
			{
				options = new Array();
				hashtable[option.pdv] = options;
			}
			options.push(option);
		}
	}
	ddlControl.GroupedOptions = hashtable;
	ddlControl.UnGroupedOptions = ungroupedOptions;
	//G2_Trace(ddlControl, "G2DropDownList_GroupOptions End");
}

function G2DropDownList_GetRelevantStartIndex(ddlControl)
{
	return G2DropDownList_AllowNull(ddlControl) ? 1 : 0;
}

function G2DropDownList_AllowNull(ddlControl)
{
	return ddlControl.AllowNull=="true";
}
function G2DropDownList_EnableClientSideLoading(ddlControl)
{
	var settings = ddlControl.settings;
	//G2DOM.G2GetAttribute(ddlControl,"Settings");
	return settings.search("EnableClientSideLoading")!=-1;
}


//
// Autocomplete with delayed thinktime
//
function G2DropDownList_AutoComplete(sender,event)
{
	if (event==null)
		event = window.event;
	var eventKeyCode = event.keyCode;
	var keyCode = parseInt(eventKeyCode,10);
	if (keyCode==9)
		return true; //Firefox needs it
	var key = MakeUpper(String.fromCharCode(keyCode));

	var now = new Date();
	if(sender.autoCompleteLastTime==null || now-sender.autoCompleteLastTime>1500)
	{
		//G2_Trace(sender, "starting autocomplete session with letter: "+key);
		sender.autoCompleteText = key;
	}
	else
	{
		//G2_Trace(sender, "continuing autocomplete session with letter: "+key);
		sender.autoCompleteText += key;
	}
	sender.autoCompleteLastTime = now;

	if(sender.autoCompleteTimerID!=null)
	{
		window.clearTimeout(sender.autoCompleteTimerID);
	}
	sender.autoCompleteTimerID = window.setTimeout(function(){G2DropDownList_FindAutoCompleteText(sender);}, 300);
	return false;
}

function G2DropDownList_FindAutoCompleteText(sender)
{
	//G2_Trace(sender, "Performing autocomplete search on "+sender.autoCompleteText);
	sender.autoCompleteTimerID = null;
	var text = sender.autoCompleteText;

	var index = -1;
	var s;
	for (var i = 0; i < sender.length; i++) 
	{
		s = MakeUpper(sender.item(i).text);
		s = s.substr(0, text.length);
		if (s == text) 
		{
			index = i;
			break;
		}
	}
	if (index != -1) 
	{
		sender.selectedIndex = index;
		G2_FireEvent(sender, "onchange");
		//dan-el: removed this line - because this method happens asynchronously, followup:
		//window.event.returnValue = false;
		//changed instead of sender.onchange()
		//to support the stupid implementation of validators in asp.net
		//		var dummyEvent = new Object();
		//		dummyEvent.srcElement = sender;
		//		if(sender.Validators!=null)
		//		{
		//			ValidatorOnChange(dummyEvent);
		//		}
		//		G2DropDownList_Changed(sender);
		//reverted back to the old implementation - validators may not work
//TODO: TEST - this condition doesn't work
//		if (sender.onchange)
//		{
//			//HACK - Fix the validators stupid microsoft implementation
//			//they're looking for an event object which doesn't exist right now
//			var s = sender.onchange.toString();
//			if(s.search("(event)")!=-1)
//			{
//				var newFuncString = s.replace("function anonymous()", "var func = function(event)");
//				newFuncString+=";new G2ReturnValue(func);";
//				var result = eval(newFuncString);
//				var dummyEvent = new Object();
//				dummyEvent.srcElement = sender;
//				result.value(dummyEvent);
//			}
//			else
//			{
//				sender.onchange();
//			}
//		}
	}	
	//we always return false - so it's hardcoded somewhere else
	//	return false;
}


//// G2DropDownList functions
//function G2DropDownList_filterListControl(parentId, listControlId)
//{

//  var ddlControl = document.getElementById(listControlId);
//	//  alert("filterListControl: id="+parentId+", control="+listControlId + "items: "+list.options.length);
//	

//  // backup the list, only the first time
//  if (ddlControl.OriginalOptions==null)
//  {
//		ddlControl.OriginalOptions = G2_CopyArray(ddlControl.options);
//		G2DropDownList_GroupOptions(ddlControl);
//	
//  }
//  
//  //Backup the selected valkue
//  var selectedValue = ddlControl.value;


//	//Perform Unfilter if needed  
// 	if(ddlControl.NullValue==parentId)
//	{
//		//optimization - do not clear and refill the combo again
//		if(ddlControl.options.length<ddlControl.OriginalOptions.length)
//		{
//			ddlControl.options.length = 0;
//			for (n=0;n<ddlControl.OriginalOptions.length;n++)
//			{
//				ddlControl.options.add(ddlControl.OriginalOptions[n]);
//			}
//		}
//	}
//	else //Perform filter
//	{
//	  ddlControl.options.length = 0;
//	  var relevantOptions = ddlControl.GroupedOptions.get(parentId);
//	  if(relevantOptions!=null)
//	  {
//			for (n=0;n<relevantOptions.length;n++)
//			{
//				var option = relevantOptions[n];
//				ddlControl.options.add(option);
//				if(option.value==selectedValue)
//					ddlControl.value = selectedValue;
//			}
//		}
//		if(ddlControl.UnGroupedOptions!=null)
//		{
//			for (n=0;n<ddlControl.UnGroupedOptions.length;n++)
//			{
//				var option = ddlControl.UnGroupedOptions[n];
//				ddlControl.options.add(option);
//				if(option.value==selectedValue)
//					ddlControl.value = selectedValue;
//			}
//		}

//  }
//  if(ddlControl.value!=selectedValue)
//  {
//		if(ddlControl.onchange!=null)
//			ddlControl.onchange();
//	}
//}


//// DEPRECATED
//// SoftWeek for listbox/combobox
//function onSelectKeyPress()
//{
//	var now = new Date();
//	if (now.valueOf() > keybdTick.valueOf()+1500 || window.event.srcElement.name != keybdElementName)
//		keybdBuf = "";		
//	keybdTick = now;		
//	keybdElementName = window.event.srcElement.name;
//	var keyCode = parseInt(window.event.keyCode,10);
//	keybdBuf += MakeUpper(String.fromCharCode(keyCode));
//	var index = -1, s;
//	for (var i = 0; i < window.event.srcElement.length; i++) {
//		s = MakeUpper(window.event.srcElement.item(i).text);
//		s = s.substr(0, keybdBuf.length);
//		if (s == keybdBuf) {
//			index = i;
//			break;
//		}
//	}
//	if (index != -1) {
//		window.event.srcElement.selectedIndex = index;
//		window.event.returnValue = false;
//		if (window.event.srcElement.onchange)
//			window.event.srcElement.onchange();
//	}	
//	return false;
//}


////Autocomplete (Taken from Util.js)
//var keybdBuf = "";
//var keybdTick = 0;
//var keybdElementName = "";
//function onSortSelectKeyPress(firstIndex)
//{
//	if(firstIndex==null)
//		firstIndex = 1;
//		
//	var now = new Date();
//	if (now.valueOf() > keybdTick.valueOf()+1500 || window.event.srcElement.name != keybdElementName)
//		keybdBuf = "";		
//	keybdTick = now;		
//	keybdElementName = window.event.srcElement.name;
//	var keyCode = parseInt(window.event.keyCode,10);
//	keybdBuf += MakeUpper(String.fromCharCode(keyCode));
//	var index = -1, s;
//	var lower = firstIndex;
//    var upper = window.event.srcElement.length-1;
//    var middle;
//    while (lower <= upper) {
//        middle = parseInt((lower+upper)/2,10);
//		s = MakeUpper(window.event.srcElement.item(middle).text);
//		s = s.substr(0, keybdBuf.length);
//        if (s == keybdBuf) {
//			index = middle;
//            break;
//        }
//		else if (s < keybdBuf)
//            lower = middle+1;
//        else
//            upper = middle-1;
//	}
//	if (index != -1) {
//		// Find the first occurance of key, in case of duplicate keys
//		var prevIndex = index;
//		index--;
//		while (index >= firstIndex) {
//			s = MakeUpper(window.event.srcElement.item(index).text);
//			s = s.substr(0, keybdBuf.length);
//			if (s == keybdBuf) {
//				prevIndex = index;
//				index--;
//			}
//			else
//				break;
//		}
//		index = prevIndex;
//		window.event.srcElement.selectedIndex = index;
//		window.event.returnValue = false;
//		if (window.event.srcElement.onchange)
//			window.event.srcElement.onchange();
//	}	
//	return false;
//}

function MakeUpper(s)
{
	var outStr, c;
	outStr = "";
	for (var i = 0; i < s.length; i++) {
		c = s.charCodeAt(i);
		if (c >= 97 && c <= 122)
			c -= 32;
		outStr += String.fromCharCode(c);
	}
	return outStr;
}


function G2Expander_Init(controlId)
{
	//Required for FF Compatibility
	var control = document.getElementById(controlId);
	if (!control)
	{
		G2_Warn("G2Expander_Init","control "+controlId+" was not found!");
		return;
	}
	G2DOM.G2TransferAttributes(control);
	var func = function(e)
	{
		G2Expander_OnClick(control, e);
	};
	G2_AttachEvent(control, "onclick", func);
	G2_AttachEvent(control, "ondblclick", func);
}

function G2Expander_OnClick(sender, e)
{
	G2Event.stop(e);
	G2DOM.G2TransferAttributes(sender); //For FF
	if(sender.isDisabled)
		return;
	if(sender.targetislazy=="true")
	{
		sender.targetislazy="false";
		__doPostBack(sender, "WakeUpLazyTarget", true);
	}
	else
	{
	
		if(sender.allowclose=="false")
			G2Expander_ShowHideControl(sender.targetid, sender.stateid, sender.id, true);
		else
			G2Expander_ToggleControl(sender.targetid, sender.stateid, sender.id);
	}
}

//G2Expander functions

function G2Expander_ShowHideControl(controlId, stateControlID, expanderID, show)
{     
  var control = document.getElementById(controlId);
  var stateControl = document.getElementById(stateControlID);
  var expander = document.getElementById(expanderID);
  stateControl.value = G2_ShowHideControl(control, show).toString();
  
  var newHtml = "";
  //Handle image
  var expanderChildren = expander.children;
  if(expanderChildren.length>0)
  {
    if(show)
      expanderChildren[0].src = expander.g2expandedimageurl;
    else
      expanderChildren[0].src = expander.g2imageurl;
    
    //newHtml+=expanderChildren[0].outerHTML;
  }
  
  if(show)
    newHtml+=expander.g2expandedtext;
  else
    newHtml+=expander.g2text;
    
	var txtNode = G2_FindNodeByNameValue(expander, "nodeType", 3);
	if(txtNode!=null)
	{
		txtNode.nodeValue = newHtml;
  }
    
  //expander.innerHTML = newHtml;
	var element = expander;
	if(show && expander.onexpanded!=null)
  {
			eval(expander.onexpanded);
	}
	else if(!show && expander.oncollapsed!=null)
  {
			eval(expander.oncollapsed);
	}
	
	if(show && control.onexpanded!=null)
  {
			eval(control.onexpanded);
	}
	else if(!show && control.oncollapsed!=null)
  {		
			eval(control.oncollapsed);
	}
}

function G2Expander_ToggleControl(controlId, stateControlID, expanderID)
{
  var stateControl = document.getElementById(stateControlID);
  
  if(stateControl.value == "false")
  {
    G2Expander_ShowHideControl(controlId, stateControlID, expanderID, true);
  }
  else
  {
		G2Expander_ShowHideControl(controlId, stateControlID, expanderID, false);
  }
}

function G2_ShowHideElementById(elementId, show)
{
  var element = document.getElementById(elementId);
  if(element!=null)
  {
		G2_ShowHideControl(element, show).toString();
  }
}


function G2Expander_ToggleElementVisibilityById(elementId)
{
	var element = $(elementId);
	if(element!=null)
		G2_ToggleElementVisibility(element);
}

function G2Expander_ToggleElementVisibility(targetElementId)
{
	var targetElement = $targetElementId;
	if(targetElement!=null)
		G2_ToggleElementVisibility(targetElement);
}

function G2ExpanderHelper_ToggleControl(controlId, stateControlID)
{
  var control = document.getElementById(controlId);
  var stateControl = document.getElementById(stateControlID);
  
  if(stateControl.value == "false")
  {
    stateControl.value = G2_ShowControl(control);
  }
  else
  {
    stateControl.value = G2_HideControl(control);
  }
}

function G2CheckBoxExpander_ToggleControl(e, controlId, stateControlID)
{
	var sender = G2Event.element(e);
	if (sender==null || sender.nodeType!=1 || sender.tagName.toLowerCase()!="input")
		return;
	G2ExpanderHelper_ToggleControl(controlId, stateControlID);
}

//selects all the visible 
function G2ExtendedCheckBoxList_SelectAllVisibleLookups(senderid)
{
	var sender = document.getElementById(senderid);
	if(sender==null)
		return;//TODO: warn
	G2_PerformRecursiveActionOnElement(sender, G2ExtendedCheckBoxList_RecursiveCheck, {checked:true});
}

function G2ExtendedCheckBoxList_RecursiveCheck(element, context)
{
	if(element.type=="checkbox")
	{
		element.checked = context.checked;
	}
}

//select none of the visible lookups
function G2ExtendedCheckBoxList_SelectNoneVisibleLookups(senderid)
{
	var sender = document.getElementById(senderid);
	if(sender==null)
		return;//TODO: warn
	G2_PerformRecursiveActionOnElement(sender, G2ExtendedCheckBoxList_RecursiveCheck, {checked:false});
}


G2ExpanderGroupManager = 
{
  groups : [],
  
  getGroup : function(groupname)
  {
    return this.groups[groupname];
  },
  addToGroup : function(groupname, expander)
  {
    if(this.groups[groupname]==null)
    {
      this.groups[groupname] = new Array();
    }
    var group = this.groups[groupname];
    group.push(expander);
    
    //Show first in group, hide the rest
    if(group.length==1)
      G2ExternalExpander_SetExpanded(expander, true, false);
    else
      G2ExternalExpander_SetExpanded(expander, false, false);
  }
};

function G2ExternalExpander_Init(id)
{
	var expander = document.getElementById(id);
	if(expander==null)
		return;
	G2DOM.G2TransferAttributes(expander);
	expander.targetcontrol = document.getElementById(expander.targetcontrolid);
	expander.expandedcontrol = document.getElementById(expander.expandedcontrolid);
	expander.collapsedcontrol = document.getElementById(expander.collapsedcontrolid);	
	G2_AttachEvent(expander.expandedcontrol, "onclick", 
		function(e)
		{
			G2ExternalExpander_Toggle(expander, e);
		});
		
	G2_AttachEvent(expander.collapsedcontrol, "onclick", 
		function(e)
		{
			G2ExternalExpander_Toggle(expander, e);
		});
  
  if(expander.groupname!=null)
    G2ExpanderGroupManager.addToGroup(expander.groupname, expander);
}

function G2ExternalExpander_Toggle(expander)
{
	// notify changes
	G2.notifyInputChanged(expander);
	if(expander.targetislazy=="true")
	{
		expander.targetislazy="false";
		__doPostBack(expander, "WakeUpLazyTarget", true);
	}
	else
	{
		var expanded = G2ExternalExpander_GetExpanded(expander);
		G2ExternalExpander_SetExpanded(expander, !expanded)
	}
}

function G2ExternalExpander_GetExpanded(expander)
{
	return expander.value=="true";
}

function G2ExternalExpander_SetExpanded(expander, value, affectGroup)
{
  if(expander.groupname!=null && value && (affectGroup!=false))
  {
   var group = G2ExpanderGroupManager.getGroup(expander.groupname);
   for(var i =0; i<group.length; i++)
   {
     var exp = group[i];
     if(exp==expander)
       continue;
     G2ExternalExpander_SetExpanded(exp, false, false);
   }
  }
   
	if(value)
	{
		expander.value="true";
		G2_ShowControl(expander.targetcontrol);
		G2_ShowControl(expander.expandedcontrol);
		G2_HideControl(expander.collapsedcontrol);
	}
	else
	{
		expander.value="false";
		G2_HideControl(expander.targetcontrol);
		G2_HideControl(expander.expandedcontrol);
		G2_ShowControl(expander.collapsedcontrol);
	}
}


function G2ClientExpander_OnClick(exp, e)
{
	if(exp.elementCache==null)
	{
		exp.elementCache = {};
		exp.expanded = true;
		exp.visibilityClientElementsIds = exp.visiblityclientids.split(",");
		exp.displayClientElementsIds = exp.displayclientids.split(",");
	}
	var show = !exp.expanded;
	exp.src = show ? exp.expandedimagesrc : exp.collapsedimagesrc;
	var display = show ? "" : "none";	
	var border = show ? "true" : "false";	
	
	//build mutual reference between the expander and its parent row
	if (exp.ParentTr == null)
	{
		exp.ParentTr = findControl(exp, "TemplateRow");
		exp.ParentTr.Expander = exp;
	}
		
	G2ClientExpander_SetStyleProperty(exp, exp.displayClientElementsIds, "display", display);	
	G2ClientExpander_SetStyleProperty(exp, exp.visibilityClientElementsIds, "border", border);		
	exp.expanded = show;
}

/*there are 2 cases for this expander:
	1.list of id's to display or hide.
	2.list of id's to show their border or not.
		for these id's we save their border style on a backup variable that holds element.style.cssText information
		in case the element has left border style and bottom border style(a node in the diagram) we hide only
		the bottom border
	special case:
	when opening an expander that has child expander that is closed(expanded = false),
	we have to change visibilty of child expander visibilityClientElementsIds, open the expander and switch
	its image (all the child expanders should be open)  */
function G2ClientExpander_SetStyleProperty(exp, idList, propertyName, value)
{
	var cache = exp.elementCache;
	for(var i=0;i<idList.length;i++)
	{
		var id = idList[i];
		var element = cache[id];
		if(element===undefined)
		{
			element = document.getElementById(id);
			cache[id] = element;
		}
		if(element!=null)
		{		
			if(propertyName == "display")
			{
				element.style[propertyName] = value;
				if (value=="" && element.Expander != null && !element.Expander.expanded)
				{
					G2ClientExpander_SetStyleProperty(element.Expander, element.Expander.visibilityClientElementsIds, "border", 'true');
					element.Expander.expanded = true;
					element.Expander.src = exp.expandedimagesrc;
				}
			}		
			else if(propertyName == "border")
			{
				if(element.cssBackup!=null)
        {
          element.style.cssText = element.cssBackup;
					element.cssBackup = null;
        }
        else
        {
         element.cssBackup = element.style.cssText;
         if(element.style.borderBottom != "" && element.style.borderLeft != "")
					element.style["borderBottom"] = "none 1px black";
         else
					element.style["border"] = "none 1px black";
        }        
			}
		}
	}
}
/*	
get the window's size, the FloatTable's size
and always changing the position of the FloatTable
according to the scrolling position
Written by Arnon
12.6.2005 
 */
window.onerror = null;
var slideTime = 800;
var ns6 = (!document.all && document.getElementById);
var ie4 = (document.all);
var ns4 = (document.layers);
var lang = 'ltr'; //hard coded for now

function layerObject(id,left) {
	if (ns6) {
		this.obj = document.getElementById(id).style;
		this.obj.left = left;
		return this.obj;
	}
	else if(ie4) {
		this.obj = document.all[id].style;
		if(lang=="rtl")
			this.obj.right = left;
		else
			this.obj.left = left+770;
		return this.obj;
	}
	else if(ns4) {
		this.obj = document.layers[id];
		this.obj.left = left;
		return this.obj;
   }
}
function layerSetup(tableHeight,tableWidth, PanelID) {
	var tblPosition
	if(pageWidth < 950)
		tblPosition = -5;
	else
		tblPosition = (pageWidth - 950)/2;
	floatLyr = new layerObject(PanelID, tblPosition);
	window.setInterval("main("+tableHeight+",'"+PanelID+"')", 10)
}
function floatObject() {
	if (ns4 || ns6) {
		findHt = window.innerHeight;
	} 
	else if(ie4) {
		findHt = document.documentElement.clientHeight;
   }
} 
function main(tableHeight, PanelID) {
	if (ns4) {
		this.currentY = document.layers[PanelID].top;
		this.scrollTop = window.pageYOffset;
		mainTrigger();
	}
	else if(ns6) {
		this.currentY = parseInt(document.getElementById(PanelID).style.top);
		this.scrollTop = scrollY;
		mainTrigger();
	} 
	else if(ie4) {
		var tableH = document.getElementById(PanelID);
		this.currentY = tableH.style.pixelTop;
		this.scrollTop = document.documentElement.scrollTop-5+(pageHeight/2)-tableH.clientHeight;
		mainTrigger(PanelID);
   }
}
function mainTrigger(PanelID) {
	
	var newTargetY = this.scrollTop + this.document.documentElement.clientHeight-(document.getElementById(PanelID).clientHeight)+20;
	//alert(document.documentElement.scrollLeft)	
	//alert(document.documentElement.clientHeight)	
	if ( this.currentY != newTargetY ) {
		if ( newTargetY != this.targetY ) {
			this.targetY = newTargetY;
			floatStart();
		}
	animator(PanelID);
   }
}
//starting the floating position
function floatStart() {
	var now = new Date();
	
	this.A = this.targetY - this.currentY;
	this.B = Math.PI / ( 2 * this.slideTime );
	this.C = now.getTime();
	if (Math.abs(this.A) > this.findHt) {
		this.D = this.A > 0 ? this.targetY - this.findHt : this.targetY + this.findHt;
		this.A = this.A > 0 ? this.findHt : -this.findHt;
	}
	else {
		this.D = this.currentY;
   }
   //alert("this.targetY " + this.targetY + " this.currentY " + this.currentY)
   //alert("this.A " + this.A + " this.B " + this.B + " this.C " + this.C + " this.D " + this.D)
}  
//try{
//	window.onresize = function (){
//	startShowFloat();
//	startDrag();
//	}
//}
//catch(e){}
//dragging the horizontal  the FloatTable according to the mose click
function animator(PanelID) {
	var now = new Date();
	
	var newY = this.A * Math.sin( this.B * ( now.getTime() - this.C ) ) + this.D;
	newY = Math.round(newY);
	//alert(newY)
	if (( this.A > 0 && newY > this.currentY ) || ( this.A < 0 && newY < this.currentY )) {
		if ( ie4 )
			document.getElementById(PanelID).style.pixelTop = newY;
		if ( ns4 )
			document.layers[PanelID].top = newY;
		if ( ns6 )
			document.getElementById(PanelID).style.top = newY + "px";
   }
}
function startShowFloat(PanelID) {
	var DivName = document.getElementById(PanelID);
	DivName.style.display = "block";
	if(ns6||ns4) {
		pageWidth = innerWidth;
		pageHeight = innerHeight;
		layerSetup();
		floatObject();
	}
	else if(ie4) {
		pageWidth = document.documentElement.clientWidth;
		pageHeight = document.documentElement.clientHeight;
		//alert(pageWidth + " - " + pageHeight)
		var tableSizes = document.getElementById(PanelID);
		layerSetup(tableSizes.clientHeight,tableSizes.clientWidth, PanelID);
		floatObject();
	}
}
function GetLayer(layer)
         {
         var ReturnLayer = null;
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)
              ReturnLayer = document.getElementById(layer);
           else
              eval('ReturnLayer = document.' + layer + ';');
           }
         else
           {
           eval('ReturnLayer = document.all.' + layer + ';');
           }
         return ReturnLayer; 
         }
         
function Layer(layer, x, y)
         {
         this.id = GetLayer(layer);         
         //Move(x, y, this.id);   
         this.ClickedX = 0;
         this.ClickedY = 0;
         }

function SetZ(z, layer)
         {
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)
              layer.style.zIndex = z;
           if(parseInt(navigator.appVersion) == 4)
              layer.zIndex = z;
           }
         else
           {
           layer.style.zIndex = z;
           }
         }

function GetZ(layer)
         {
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)
              return(parseInt(layer.style.zIndex));
           if(parseInt(navigator.appVersion) == 4)
              return(layer.zIndex);
           }
         else
           {
           return(layer.style.zIndex);
           }
         }         
		 
function GetX(layer)
         {
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)
              return(parseInt(layer.style.left));
           if(parseInt(navigator.appVersion) == 4)
              return(layer.left);
           }
         else
           {
           return(layer.style.pixelLeft);
           }
         }

function GetW(layer)
         {
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)             
              return(parseInt(layer.style.width));		     
           if(parseInt(navigator.appVersion) == 4)
              return(layer.clip.width);                      
           }
         else
           {
           if(navigator.appVersion.indexOf('MSIE 4') > 0)
              return(layer.style.pixelWidth);
           else
              return(layer.offsetWidth);
           }
         }
                           
function GetY(layer)
         {
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)
              return(parseInt(layer.style.top));
           if(parseInt(navigator.appVersion) == 4)
              return(layer.top);
           }
         else
           {
           return(layer.style.pixelTop);
           }
         }

function GetH(layer)
         {
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)             
              return(parseInt(layer.style.height));		     
           if(parseInt(navigator.appVersion) == 4)
              return(layer.clip.height);
           }
         else
           {           
           if(navigator.appVersion.indexOf('MSIE 4') > 0)		  
              return(layer.style.pixelHeight);
           else
              return(layer.offsetHeight);
           }
         }         
	       	 	
function Move(x, y, layer)
         {
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)
             {
            // layer.style.left = x;
             layer.style.top = parseInt(y)+"px";
             }
           if(parseInt(navigator.appVersion) == 4)
             {
             //layer.left = x;
             layer.top = parseInt(y)+"px";
             }
           }
         else
           {
           //layer.style.pixelLeft = x;

           if(document.documentElement.clientHeight<document.getElementById(layer.id).clientHeight)
						layer.style.pixelTop = y;
           }
         }

function PickUp(layer)
         {
         var CurrentZ = GetZ(Layers[layer].id);
         SetZ(Layers.length - 1, Layers[layer].id);
         var currentZ;
         for(var index = 0; index < Layers.length; index++)
            {
            currentZ = GetZ(Layers[index].id);
            if(currentZ >= CurrentZ && index != layer)
              {
              SetZ(currentZ - 1, Layers[index].id);
              }
            }
         }
       
function Selected(x, y, layer)
         {         
         if(navigator.appName == 'Netscape')
           {
           if(parseInt(navigator.appVersion) == 5)                             
              if(x > parseInt(layer.style.left) && x < parseInt(layer.style.left) + parseInt(layer.style.width) &&
                 y > parseInt(layer.style.top) && y < parseInt(layer.style.top) + parseInt(layer.style.height))
                 return(true);	                  
           if(parseInt(navigator.appVersion) == 4)		     
              if(x > layer.left && x < layer.left + layer.clip.width &&
                 y > layer.top && y < layer.top + layer.clip.height)
                 return(true);            
           }
         else
           {		     
           if(navigator.appVersion.indexOf('MSIE 4') > 0)
             {
             if(x > layer.style.pixelLeft && x < layer.style.pixelLeft + layer.offsetWidth &&
                y > layer.style.pixelTop && y < layer.style.pixelTop + layer.offsetHeight)		   
                return(true);
             }
           else
             {
             if(x > layer.style.pixelLeft && x < layer.style.pixelLeft + layer.offsetWidth &&
                y > layer.style.pixelTop && y < layer.style.pixelTop + layer.offsetHeight)		   
                return(true);		     
             }
           }
                    
         return(false);
         }       

function mouseDown(e) 
         {
         if ((navigator.appName == 'Netscape' && e.which!=1) || (navigator.appName == 'Microsoft Internet Explorer' && event.button!=1)) return true;
         var x = (navigator.appName == 'Netscape')? e.pageX : event.x+document.documentElement.scrollLeft;
         var y = (navigator.appName == 'Netscape')? e.pageY : event.y+document.documentElement.scrollTop;
         if (navigator.appName == 'Netscape' && e.target!=document) routeEvent(e);

         ClickedLayer = -1;
         	              
         //Check if a div was clicked on.	     	     
         for(var layer = 0; layer < Layers.length; layer++)
            {                       
            if(Selected(x, y, Layers[layer].id))
              {
              if(ClickedLayer == -1)
                {       
                Layers[layer].ClickedX = x - GetX(Layers[layer].id);
                Layers[layer].ClickedY = y - GetY(Layers[layer].id);
                ClickedLayer = layer;
                }
              else
                //If divs are overlapping, pick the one on top.
                if(GetZ(Layers[layer].id) > GetZ(Layers[ClickedLayer].id))
                  {
                  Layers[layer].ClickedX = x - GetX(Layers[layer].id);
                  Layers[layer].ClickedY = y - GetY(Layers[layer].id);
                  ClickedLayer = layer;
                  }
              }                         
            }
            
         if(ClickedLayer != -1)
           {
           PickUp(ClickedLayer);           
           }
                           
         if(ClickedLayer == -1) return true; 
         else return false;
         }
         
function mouseMove(e) 
         {
         var x = (navigator.appName == 'Netscape')? e.pageX : event.x+document.documentElement.scrollLeft;
         var y = (navigator.appName == 'Netscape')? e.pageY : event.y+document.documentElement.scrollTop;
         if (navigator.appName == 'Netscape' && e.target!=document) routeEvent(e);
						
         //If a div is selected,
         //make it follow the mouse cursor.
                           
         if(ClickedLayer != -1)
           {           
           Move(x - Layers[ClickedLayer].ClickedX, 
                y - Layers[ClickedLayer].ClickedY, 
	       Layers[ClickedLayer].id);
           }         
         
         if(ClickedLayer == -1) return true; 
         else return false;
         }
         
function mouseUp(e) 
         {
         var x = (navigator.appName == 'Netscape')? e.pageX : event.x+document.documentElement.scrollLeft;
         var y = (navigator.appName == 'Netscape')? e.pageY : event.y+document.documentElement.scrollTop;
         if (navigator.appName == 'Netscape' && e.target!=document) routeEvent(e);			         	         
           
         ClickedLayer = -1;
         
         return true; 
         }
// start the dragging
function startDrag(PanelID){ 
         ClickedLayer = -1;
         document.onmousedown = mouseDown;
         document.onmousemove = mouseMove;
         document.onmouseup = mouseUp;
         if(navigator.appName == 'Netscape') 
            document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);
            
         Layers = new Array(); 
         Layers[0] = new Layer(PanelID, 0, 0);      
}

// show and hide the the prices's table of the FloatTable
// also replace the display between the small icons
function ShowHideTable(tableName, PanelID)  {
	var tableLocator = document.getElementById(tableName);
	var tableOpacity = document.getElementById(PanelID);
	var imgRestore = document.getElementById("imgRestore");
	var imgMinimize = document.getElementById("imgMinimize");
	if(tableLocator.style.display == "none"){
		tableLocator.style.display = "block";
		tableOpacity.style.filter = "alpha(opacity=90)";
		imgRestore.style.display = "none";
		imgMinimize.style.display = "block";
	}
	else {
		tableLocator.style.display = "none";
		tableOpacity.style.filter = "alpha(opacity=80)";
		imgRestore.style.display = "block";
		imgMinimize.style.display = "none";
	}
}

//----------------------------------------------------------------------
//G2GridExpander functions
//----------------------------------------------------------------------

function G2GridExpander_Init(expanderControlId)
{
  var expander = document.getElementById(expanderControlId);
  G2GridExpander_OnChange(expander);
}

function G2GridExpander_OnChange(expanderControl)
{
  var rowsToShow = parseInt(expanderControl.value);
  G2GridExpander_ShowHideRows(expanderControl.G2TargetControl, rowsToShow);
  G2Page_AutoSize();
  
}


function G2GridExpander_ShowHideRows(controlId, rowsToShow)
{
  var table = document.getElementById(controlId);
  if(table==null || table.rows.length==0)
		return;

	//if header exists
	if(table.rows[0].cells[0].tagName.toUpperCase()=="TH")
	{
		//Ignore header
		rowsToShow++;
	}	
  //var tbody=table.children[0];
  for(var i=0; i<table.rows.length; i++)
  {
    if(i<rowsToShow)
      G2_ShowHideControl(table.rows[i], true);
    else
      G2_ShowHideControl(table.rows[i], false);
  }
}


function G2_WriteObject(obj, writer)
{
	if(obj==null)
		writer.push("null");
	else if(typeof(obj)=="object")
	{
		if(obj instanceof Array)
			G2_WriteArray(obj, writer);
		else
			G2_WriteJson(obj, writer);
	}
	else if (obj instanceof String)
	{
	  writer.push('"'+obj.toString()+'"');
	}
	else
		writer.push(obj.toString());
}

function G2_WriteJson(json, writer)
{
	writer.push("{");
	var first = true;
	for(var p in json)
	{
	  if (typeof(json[p])=="function")
	    continue;
	  if(first)
	    first = false;
	  else
	    writer.push(",\n");
	    
		writer.push(p+":");
		G2_WriteObject(json[p], writer);
	}
	writer.pop();
	writer.push("}");
}
function G2_WriteArray(array, writer)
{
	writer.push("[");
	for(var i=0;i<array.length;i++)
	{
		G2_WriteObject(array[i], writer);
		if(i!=array.length-1)
			writer.push(",\n");
	}
	writer.push("]");
}

Array.prototype.insert = function(index, item)
{
	this.splice(index, 0, item);	
}
// JScript File

function ParseNullableBoolean(s)
{
	if(s==null)
		return null;
	s = s.toLowerCase();
	if(s=="true")
		return true;
	if(s=="false")
		return false;
}

function G2Menu_Init(menuElementId)
{
    var menuElement = document.getElementById(menuElementId);
	if(menuElement==null)
		return;
	G2DOM.G2TransferAttributes(menuElement);
	var menu = {element:menuElement, IsMenu:true, SilentPostback:ParseNullableBoolean(menuElement.SilentPostback),IsContextMenu: menuElement.iscontextmenu=="true"};
	G2_AttachEvent(menu.element,"onclick",G2Menu_OnClick);
	G2_AttachEvent(document,"onclick",G2Menu_OnDocumentClick);
	var child1 = G2DOM.GetChildByProgid(menuElement, 'maindiv');
	var firstItemElement = G2DOM.GetChildByProgid(child1, 'menuitem');
		
	//var firstItemElement = menuElement.childNodes[1].childNodes[1];
	ForEachSibling(firstItemElement, G2Menu_CreateMenuItem, {menu:menu}, function(elem) {return elem.progid == 'menuitem';});
	
	menuElement.menu = menu;
	if (menu.IsContextMenu)
	{ //done at serverside
//		if(menuElement.g2contextmenutargetid!=null)
//		{
//			menu.contextMenuTargetElement = document.getElementById(menuElement.g2contextmenutargetid);
////			if(menu.contextMenuTargetElement!=null) 
////			{
////				menu.contextMenuTargetElement.contextMenu = menuElement.id;
////				G2_AttachEvent(menu.contextMenuTargetElement, "oncontextmenu", function()
////				{
////					G2Menu_ShowContextMenu(event);
////				});
////			}
//		}
	}
	else
	{
		G2Menu_Render(menu);
	}
}

function G2Menu_Close(menu)
{
	if(menu != null)
	{
		if(menu.activeItem!=null)
		{
			G2Menu_UnrenderMenuItemChildren(menu.activeItem);
			menu.activeItem = null;
		}
		if (menu.IsContextMenu)
		{
			G2Menu_UnrenderMenuItemChildren(menu);
		}
		menu.currentContextMenuTarget = null;
	}
	G2CurrentOpenMenu = null;
}


var G2CurrentOpenMenu;
function G2Menu_OnDocumentClick(event)
{
	if(G2CurrentOpenMenu!=null)
	{
		G2Menu_Close(G2CurrentOpenMenu);
	}
}

function G2Menu_GetMenuItemByPath(menu, path)
{
	var values = path.split(".");
	var menuItem = menu;
	for(var i=0;i<values.length;i++)
	{
		var value = values[i];
	    menuItem = menuItem.items.FirstOrDefault(function(t){return t.value==value;});
		if(menuItem==null)
			return null;
	}
	return menuItem;
}

function G2Menu_CreateMenuItem(menuItemElement, context)
{
    G2DOM.G2TransferAttributes(menuItemElement);
	var values = menuItemElement.path.split(".");
	var menuItem = context.menu;
	for(var i=0;i<values.length;i++)
	{
		var value = values[i];
		menuItem = G2Menu_CreateChildMenuItem(menuItem, value);
	}
	//menuItem.path = menuItemElement.path;
	menuItem.element = menuItemElement;
	menuItem.element.menuItem = menuItem;
	menuItem.SilentPostback = ParseNullableBoolean(menuItem.element.SilentPostback)
}

function G2Menu_CreateChildMenuItem(menuItem, value)
{
	if(menuItem.items==null)
	{
		menuItem.items = new Array();
	}
	var childMenuItem = Find(menuItem.items, function(item){return item.value==value;});
	if(childMenuItem==null)
	{
		childMenuItem = {value:value, parent:menuItem};
		menuItem.items.push(childMenuItem);
	}
	return childMenuItem;
}


function G2Menu_UnrenderMenuItemChildren(menuItem)
{
	if(menuItem.itemsTableElement!=null)
	{
		var table = menuItem.itemsTableElement;
		G2DOM.G2RemoveNode(menuItem.itemsTableElement);
		menuItem.itemsTableElement = null;
		ForEach(menuItem.items, G2Menu_UnrenderMenuItemChildren);
		G2_DetachEvent(table,"onmouseout",G2Menu_OnMouseOut);
		G2_DetachEvent(table,"onmouseover",G2Menu_OnMouseOver);
	}
}


function G2Menu_RenderMenuItemChildren(menu, menuItem)
{
	var firstLevel = menuItem.IsMenu;
	menuItem.activeItem = null;
	if(menuItem.items==null || menuItem.items.length==0)
		return;
	var table = document.createElement("table");
	menuItem.itemsTableElement = table;
	if(menu.element.staticmenucssclass!=null && firstLevel) //if first level
	{
		table.className = menu.element.staticmenucssclass;
	}
	else if(menu.element.dynamicmenucssclass!=null && !firstLevel) //if first level
	{
		table.className = menu.element.dynamicmenucssclass;
	}
	table.cellPadding = 0;
	table.cellSpacing = 0;
		//alert(" Orientation = "  + menu.element.Orientation  )

	var horizontal = menu.element.orientation=="Horizontal";
	var MenuPosition = menu.element.InvertedLayout; // display layout at the left or right of the element
	var horizontalChildren = horizontal && firstLevel;
	var row = null;
	if(horizontalChildren)
	{
		row = G2DOM.G2InsertRowToTable(table);
	}
	for(var i=0;i<menuItem.items.length;i++)
	{
		var item = menuItem.items[i];
		if(!horizontalChildren)
		{
			row = G2DOM.G2InsertRowToTable(table);
		}
		var cell = G2DOM.G2InsertCellToRow(row);
		cell.noWrap = true;
		cell.appendChild(item.element);
	}
	if(!firstLevel)
	{
		var isParentStaticMenuItem = menuItem.parent!=null && menuItem.parent==menu;
		var parentCell = menuItem.element.parentElement;
		if(menu.element.staticmenuitempopoutdock!=null && isParentStaticMenuItem)
		{
			G2_PlaceElementAbsolutlyNear(table, parentCell, menu.element.staticmenuitempopoutdock);
		}
		else
		{
			if(horizontal)
			{
				G2_PlaceElementAbsolutlyBelow(table, parentCell, MenuPosition);
			}
			else
			{
				G2_PlaceElementAbsolutlyBeside(table, parentCell, MenuPosition);
			}
		}
	}
	else
	{
		menuItem.element.appendChild(table);
	}
	G2_AttachEvent(table,"onclick", G2Menu_OnClick);
	G2_AttachEvent(table,"onmouseout",G2Menu_OnMouseOut);
	G2_AttachEvent(table,"onmouseover",G2Menu_OnMouseOver);


}



function G2Menu_Render(menu)
{
	G2Menu_RenderMenuItemChildren(menu, menu);
}

//	Treats the onclick event of menu2 type item
function G2Menu_OnMenuItemClick(menu, menuItem)
{
	//	Resets the background color so that the next click on the menu will not show the last selected item chosen.
	if(menuItem.element.enableoverstate == "true")			//	event should be applied on items only
		menuItem.element.className =menuItem.element.cls;
	if(menuItem.element.navigateurl!=null)
	{
		G2_Navigate(menuItem.element.navigateurl);
	}
	else if(menuItem.element.postback=="true")
	{
		var forceSilent = menuItem.SilentPostback;
		if(forceSilent==null)
		{
			forceSilent = menu.SilentPostback;
		}
		var argument = menuItem.element.path;
		if(menu.currentContextMenuTarget!=null)
			argument+="|"+menu.currentContextMenuTarget.id;
		__doPostBack(menu.element, argument, forceSilent);
	}
	G2Menu_Close(menu);
}

//	Treats the onmouseover event of menu2 type item
function G2MenuItem_OnMouseOver(el)
{
	//	Change the background color of an item to out color
	if(el.disabled != true)
		if(el.enableoverstate == "true")												//	event should be applied on items only
		{
			el.cls = el.className;
			if(el.className.endsWith("RTL"))
				el.className="G2Menu2DynamicMenuItem_RTLHover";
			else
				el.className = "G2Menu2DynamicMenuItemHover";
			if(el.cls == "G2MenuItemLink")												//	adminTools context menus don't need bold text
				el.style.fontWeight = "normal";
		}
}

function G2Menu_SetVisibleMenuItems(menu, menuItemsPaths)
{
	G2Menu_ForEachMenuItemByPaths(menu, menuItemsPaths, 
		function(t){t.element.style.display="";}, 
		function(t){t.element.style.display="none";});
}
function G2Menu_SetEnabledMenuItems(menu, menuItemsPaths)
{
	G2Menu_ForEachMenuItemByPaths(menu, menuItemsPaths, 
		function(t){t.element.disabled = false;}, 
		function(t){t.element.disabled=true;});
}


function G2Menu_ForEachMenuItemByPaths(menu, menuItemsPaths, selectedMenuItemFunc, notSelectedMenuItemFunc)
{
	var res = G2Menu_GetMenuItemsByPathsAndRest(menu, menuItemsPaths);
	if(selectedMenuItemFunc!=null)
		res.selected.ForEach(selectedMenuItemFunc);
	if(notSelectedMenuItemFunc!=null)
		res.notSelected.ForEach(notSelectedMenuItemFunc);
}

function G2Menu_GetMenuItemsByPathsAndRest(menu, menuItemsPaths)
{
	var selected = [];
	var notSelected = [];
	var menuItem = menu;
	var selectPaths = null;
	if(menuItemsPaths!=null)
		selectPaths = menuItemsPaths.split(",");
	_G2Menu_GetMenuItemsByPathsAndRest(menu, selectPaths, null, selected, notSelected);
	return {selected:selected, notSelected:notSelected};
}
function _G2Menu_GetMenuItemsByPathsAndRest(menuItem, selectPaths, currentPath, selected, notSelected)
{
	if(menuItem.items==null)
		return;
	for(var i=0;i<menuItem.items.length;i++)
	{
		var childMenuItem = menuItem.items[i];
		var childPath = currentPath==null ? childMenuItem.value : currentPath+"."+childMenuItem.value;
		if(selectPaths==null)
			notSelected.push(childMenuItem);
		else if(selectPaths=="*")
			selected.push(childMenuItem);
		else
		{
			var found = selectPaths.FirstOrDefault(function(t){return t.startsWith(childPath);});
			if(found!=null)
				selected.push(childMenuItem);
			else
				notSelected.push(childMenuItem);
		}
		_G2Menu_GetMenuItemsByPathsAndRest(childMenuItem, selectPaths, childPath, selected, notSelected);
	}
}


function G2Menu_OnMouseOver(event)
{
	if(closeMenuTimerId!=null)
	{
		window.clearTimeout(closeMenuTimerId);
		closeMenuTimerId = null;
	}
}

//	Treats the onmouseout event of menu2 type item
function G2MenuItem_OnMouseOut(el)
{
	//	Change the background color of an item to hover color
	if(el.disabled != true)
		if(el.enableoverstate == "true")											//	event should be applied on items only
			el.className = el.cls;
}

// hide the menu when leaving it
var closeMenuTimerId;
function G2Menu_OnMouseOut(event)
{
	if(G2CurrentOpenMenu!=null)
	{
		if(closeMenuTimerId!=null)
		{
			window.clearTimeout(closeMenuTimerId);
			closeMenuTimerId = null;
		}
		closeMenuTimerId = window.setTimeout(function(){G2Menu_Close(G2CurrentOpenMenu);}, 1500);
	}
}


function G2Menu_GetMenuByMenuElement(menuElementId)
{
	var element = $(menuElementId);
	if(element!=null)
		return element.menu;
	return null;
}

function G2Menu_GetMenuItem(element)
{
	while(element!=null && element.menuItem==null)
	{
		element = element.parentElement;
	}
	if(element==null)
		return null;
	var menuItem = element.menuItem;
	return menuItem;
}
function G2Menu_OnClick(event)
{
	G2Event.stop(event);
	var element = G2Event.element(event);
	if(element.disabled == true)
		return;
	var menuItem = G2Menu_GetMenuItem(element);
	if(menuItem==null)
		return;
	var menu = G2Menu_GetMenu(menuItem);
	G2Menu_OnClick2(menu, menuItem);
}
function G2Menu_ClickMenuItem(menuElementId, menuItemPath)
{
  	var menu = G2Menu_GetMenuByMenuElement(menuElementId);
	if(menu!=null)
	{
		var menuItem = G2Menu_GetMenuItemByPath(menu, menuItemPath);
		if(menuItem!=null)
		{
			window.setTimeout(function()
			{
				G2Menu_OnClick2(menu, menuItem);
			}, 0);
			return true;
		}
	}
	return false;
}

function G2Menu_OnClick2(menu, menuItem) //menuItem==the clicked menuItem
{
	if(G2CurrentOpenMenu!=null && G2CurrentOpenMenu!=menu)
		G2Menu_Close(G2CurrentOpenMenu);
	if(menuItem.items==null)
	{
		G2Menu_OnMenuItemClick(menu, menuItem);
	}
	else
	{
		if(menuItem.parent.activeItem!=null)
		{
			if(menuItem.parent.activeItem==menuItem)
				return;
			G2Menu_UnrenderMenuItemChildren(menuItem.parent.activeItem);
		}
		G2CurrentOpenMenu = menu;
		G2Menu_RenderMenuItemChildren(menu, menuItem);
		menuItem.parent.activeItem = menuItem;
	}
}
function G2Menu_GetMenu(menuItem)
{
	while(menuItem!=null && !menuItem.IsMenu)
	{
		menuItem = menuItem.parent;
	}	
	return menuItem;
}

function G2Menu_GetTarget(element)
{
	var menuItem = G2Menu_GetMenuItem(element);
	var menu = G2Menu_GetMenu(menuItem);
	if(menu!=null)
		return menu.currentContextMenuTarget;
	return null;
}

function G2Menu_GetTargetId(element)
{
	var target = G2Menu_GetTarget(element);
	if(target!=null)
		return target.id;
	return null;
}


function G2Menu_FindContextMenuElement(element)
{
	var initialElement = element;
	while(element!=null)
	{
		if (element.contextMenu != null)
		{
			return document.getElementById(element.contextMenu);
		}
		if (element.findContextMenu != null)			//found a "findContextMenu" property on one of the node tree
		{
			var f=element.findContextMenu;
			if (typeof(f)=="string")								//if this is a string, and not a function, evaluate it
				f = eval(f);
			var r = (typeof(f)=="function") ? f(initialElement) : f; 	//if this is a function, call it
			return (typeof(r)=="string") ? document.getElementById(r) : r; //if r is a string, find the node by its ID
		}	
		element = element.parentElement;
	}	
	return null;
}

function G2Menu_ShowContextMenu(event)
{
	G2Event.stop(event);
	var opener = event.srcElement;
	if(G2DOM.G2GetAttribute(opener,'disabled'))
		return;
	//Show the menu
	var menuElement = G2Menu_FindContextMenuElement(opener);	
	var menu = menuElement.menu;
	if(G2CurrentOpenMenu!=null)
	{
		if(G2CurrentOpenMenu!=menuElement)
			G2Menu_Close(G2CurrentOpenMenu);
		else
			return;	//Open, showing
	}	
	G2CurrentOpenMenu = menu;
	var target = opener;
	// find the element with the context menu
	while(target && !target.contextMenu)
	{
		target = target.parentElement;
	}
	menu.currentContextMenuTarget = target;
	if(target.g2oncontextmenu!=null)
	{
		var func = new Function("e", target.g2oncontextmenu);
		func.call(target, {menu:menu});
	}
	G2Menu_Render(menu);
	G2_FloatElement(menuElement,opener,"SE",false);
	G2_VerifyAbsoluteElementNotCropped(menuElement);
	//G2PopupManager.openPopup(menuElement, opener, "bl:tl", true)
}
// JScript File
//open message Popup
function G2_OpenMessagePopup(popUpID, openerData, event)
{
	//FF/IE adjustment 
	event = event || window.event;
   var oldAlertObj = document.getElementById(popUpID);
   // clone the Div and show the clone
   var alertObj = document.createElement("DIV");
   alertObj.innerHTML = oldAlertObj.innerHTML;
   alertObj.id = "AlertDiv";

  //return if already shown
	if (alertObj.style.display == 'block')
		return;
		
	//save opener data
	var hfObj = G2DOM.GetChildByProgid(oldAlertObj, 'hfMP');
	hfObj.value = openerData;
	
	// append messagePopup to the form and not to the body (case 11229)
	var container = document.forms[0];
	
	//show the popup div
	alertObj.style.display = 'block';
	
	// create a cover div 
	var coverDiv = G2_CreateModalCoverDiv(window);

	// append cover div to form
	if(container != null)
		container.appendChild(coverDiv);
	else
		document.getElementsByTagName("body")[0].appendChild(coverDiv);

	//set popup div position
	alertObj.style.position = 'absolute';
	if (event != null && event.type != "")
	{
	    alertObj.style.left = Math.max(0, document.documentElement.scrollLeft + event.clientX - (alertObj.scrollWidth) + 5 ) + "px";
	    alertObj.style.top = Math.max(0, document.documentElement.scrollTop + event.clientY - (alertObj.scrollHeight / 2)) + "px";
	}
	else //keep original position
	{
		alertObj.style.left = G2_GetX(alertObj);
		alertObj.style.top = G2_GetY(alertObj);
		
		// position popup in center of the screen
		if(alertObj.style.top == "0px" || alertObj.style.top == "0pt") // FireFox count with pt and IE with px
		{
			alertObj.style.top = (document.documentElement.scrollTop + (document.documentElement.scrollHeight / 2)) + "px";
			if(alertObj.style.left == "0px" || alertObj.style.left == "0pt")
				alertObj.style.left = (document.documentElement.scrollLeft + (document.documentElement.scrollWidth / 2)) + "px";
		}
	}
	alertObj.style.zIndex = 101;
	G2_AttachFrame(alertObj);
	
	if(!String.IsNullOrEmpty(oldAlertObj.relativecontrolid))
	{
		var relativeControl = document.getElementById(oldAlertObj.relativecontrolid);
		if(relativeControl!=null)
			G2_PlaceElementAbsolutlyNear(alertObj, relativeControl, oldAlertObj.relativecontroldocking, false, container);
	}
	else
	{
		// append element to form
		if(container != null)
			container.appendChild(alertObj);
		else
			document.body.appendChild(alertObj);
	}
	
	// verify that the popup is in the boreder of the screen
	G2_VerifyAbsoluteElementNotCropped(alertObj);
}

// remove message popup from the DOM
function G2_CloseMessagePopup(popUpID) 
{
	var alertObj = document.getElementById("AlertDiv");
	// remove the cloned Div
	var container = alertObj.parentElement;
	if (alertObj != null && container !=  null)
	{
		//alertObj.style.display = 'none';
		window.setTimeout(function () { container.removeChild(alertObj); }, 0);
	}
	
	// remove the cover Div
  var coverDiv = document.getElementById("CoverDiv");
  container = coverDiv.parentElement;
  if (coverDiv != null && container !=  null)
      container.removeChild(coverDiv);
  G2_DetachFrame(alertObj);
}

// set the message of the message popup
function G2_SetMessageNearButtons(popUpID, message)
{
	var popup = $(popUpID);
	if(!popup)
		return;
		
	var tdMessage = G2DOM.GetChildByProgid(popup, 'tdMessage');
	if(!tdMessage)
		return;
		
	tdMessage.innerText = message;
}

G2_DeclareFunctions(
{
    G2MultiSelect : function(child)
    {
        mainDiv = findControl(child, 'multiSelect');
        this.inputData = mainDiv.inputData;
        this.listSelected = mainDiv.listSelected;
        this.listUnselected = mainDiv.listUnselected;
        this.inputData = mainDiv.inputData;
        this.dataArray = this.inputData.value.split('#');
    },
    
    G2MultiSelect_ChangeSelection : function(row)
    {
        var multiSelect = new G2MultiSelect(row);
        var value = row.value;
        var wasSelected = row.selected;
        G2MultiSelect_SwitchSelectionValue(row);
        var listRemoveFrom = null;
        var listAppendTo = null;
        if (wasSelected == 'true')
        {
            listRemoveFrom = multiSelect.listSelected;
            listAppendTo = multiSelect.listUnselected;
            multiSelect.dataArray.RemoveItem(value);
        }
        else
        {
            listRemoveFrom = multiSelect.listUnselected;
            listAppendTo = multiSelect.listSelected;
            multiSelect.dataArray.push(value);
        }
        multiSelect.inputData.value = multiSelect.dataArray.join('#');   
        //remove row from remove from listRemoveFrom and try to append it
        //to listAppendTo
        var appended = false;
        var removeRunner = listRemoveFrom.firstChild;
        var appendRunner = listAppendTo.firstChild;
        //run on both list
        while (removeRunner != null && appendRunner != null)
        {
            if (removeRunner == row)
            {
                listRemoveFrom.removeChild(row);
                listAppendTo.insertBefore(row, appendRunner);
                appended = true;
                break;
           }
           removeRunner = removeRunner.nextSibling;
           appendRunner = appendRunner.nextSibling;
        }
        if (!appended) //append to the end
        {
            listRemoveFrom.removeChild(row);
            listAppendTo.appendChild(row);
        }
        verifyObjectShown(row);
     },
     
      G2MultiSelect_ChangeSelectionForAll : function(elem, action)
      {
         var multiSelect = new G2MultiSelect(elem); 
         var listRemoveFrom = null
         var listAppendTo = null;
         if (action == 'selectall')
         {
            listRemoveFrom = multiSelect.listUnselected;
            listAppendTo = multiSelect.listSelected;
         }
         else //action = 'selectnone'
         {
            listRemoveFrom = multiSelect.listSelected;
            listAppendTo = multiSelect.listUnselected;
         }
         var removeRunner = listRemoveFrom.firstChild;
         while (removeRunner != null)
         {
            var temp = removeRunner.nextSibling;
            listRemoveFrom.removeChild(removeRunner);
            listAppendTo.appendChild(removeRunner);
            G2MultiSelect_SwitchSelectionValue(removeRunner);
            if (action == 'selectall')
            {
                multiSelect.dataArray.push(removeRunner.value);
            }
            removeRunner = temp;
         }
         if (action == 'selectall')
             multiSelect.inputData.value = multiSelect.dataArray.join('#');  
          else
            multiSelect.inputData.value = "";
         
      },
      
      G2MultiSelect_Init : function(id)
      {
        var mainDiv =  $(id);
        if (mainDiv.initialized == 'true')
            return;
        mainDiv.initialized = 'true';
        mainDiv.inputData = G2DOM.GetChildByProgid(mainDiv,'inputData');
        mainDiv.listSelected = G2DOM.GetChildByProgid(mainDiv,'listSelected');
        mainDiv.listUnselected = G2DOM.GetChildByProgid(mainDiv, 'listUnselected');
        mainDiv.getValue = function(){ return this.inputData.value; }
     },
     
     G2MultiSelect_SwitchSelectionValue : function(elem)
     {
        if (elem.selected == 'false')
            elem.selected = 'true';
         else
            elem.selected = 'false';
     },
     
     G2MultiSelect_ValidateHasItems : function(elem)
     {
        // Check if there are selected items
				if(elem.listSelected.childNodes != null && elem.listSelected.childNodes.length > 0)
					return true;
					
				return false;
     }
    
});


// Validate that the selected values smaller than the max allowed value
function G2MultiSelect_ValidateMaxItems()
{
	var lbItems = this.targetcontrol;
	var max = this.MaxItems;
	
	if(lbItems.listSelected.childNodes == null || max == 0)
		return true;
		
	if (lbItems.listSelected.childNodes.length > max)
		return false;
	return true;
}
function G2NumericDropDown_Init(numericUpDownID)
{
	var numericUpDown = document.getElementById(numericUpDownID);
	if(numericUpDown==null)
		return;
	G2NumericDropDown_VerifyInit(numericUpDown);
}

function G2NumericDropDown_VerifyInit(numericUpDown)
{
	if(numericUpDown.IsInited)
		return;
	if (!numericUpDown)
	{
		G2_Warn("G2NumericDropDown_VerifyInit","numericUpDown is null");
		return;
	}
	numericUpDown.isInitializing = true;
	G2DOM.G2TransferAttributes(numericUpDown);
	numericUpDown.IsInited = true;
	numericUpDown.minvalue = parseInt(numericUpDown.minvalue);
	numericUpDown.maxvalue = parseInt(numericUpDown.maxvalue);
//	numericUpDown.renderItemsInline = numericUpDown.renderitemsinline=="true";
//	if(!numericUpDown.renderItemsInline)
	G2NumericDropDown_RefreshItems(numericUpDown);
	EnableSupportForPartialPostData(numericUpDown);
	numericUpDown.isInitializing = false;
}


//TODO: this can be optimized
function G2NumericDropDown_RefreshItems(numericUpDown)
{
	numericUpDown.options.length = 0;
	var option = null;
	if (numericUpDown.allownull)
	{
		option = new Option(numericUpDown.nulldisplaytext, numericUpDown.nullvalue);
		numericUpDown.options.add(option);
	}
	var i = numericUpDown.minvalue;
	while (i <= numericUpDown.maxvalue)
	{
		option = new Option(i.toString(), i.toString());
		numericUpDown.options.add(option);
		i++;
	}
	numericUpDown.value = numericUpDown.selectedvalue;
}

//G2NumericDropDown_RefreshItems_Async = function(numericUpDown)
//{
//	this.numericUpDown = numericUpDown;
//	this.cancelRequested = false;
//}
//G2_DeclareClass(G2NumericDropDown_RefreshItems_Async, "G2NumericDropDown_RefreshItems_Async",null, 
//{
//	cancel : function()
//	{
//		this.cancelRequested = true;
//	},
//	_doWork : function()
//	{
//		if(this.cancelRequested)
//			return;
//		if(!this.isFinished())
//		{
//			this.doWork();
//			var caller = this;
//			window.setTimeout(function()
//			{
//				caller._doWork();
//			}, 0);
//		}
//		else
//		{
//			this.finish();
//		}
//	},
//	invoke : function()
//	{
//		this.start();
//		this._doWork();
//	},
//	isFinished : function()
//	{
//		return !(this.index <=  this.numericUpDown.maxvalue);
//	},
//	start : function()
//	{
//		var numericUpDown = this.numericUpDown;
//		numericUpDown.options.length = 0;
//		if (numericUpDown.allownull)
//		{
//			var option = new Option("", HtmlSelectEmptyValue);
//			numericUpDown.options.add(option);
//		}
//		this.index = numericUpDown.minvalue;
//	},
//	doWork : function()
//	{
//		var numericUpDown = this.numericUpDown;
//		var i = this.index;
//		var option = new Option(i.toString(), i.toString());
//		numericUpDown.options.add(option);
//		this.index++;

//	},
//	finish : function()
//	{
//		this.numericUpDown.value = this.numericUpDown.selectedvalue;
//	}
//});


// This method set the range of the given numeric dropDownList.
function Select_SetRange(select, min, max)
{
  if(min==null)
		min = 1;
	if(max==null)
		max = 31;
	if(select==null)
		return;
		
	// remember the day selected
	var dayValue = select.value;
	
	// Clear the ddl
	select.length=0;
	
  // In case the select is empty
  if (select.options.length == 0)
  {
      for (var t = min; t <= max ; t++)
      {
          option = new Option(t, t);                
					select.options.add(option);
      }
  }
     
  // set the selected value
  if(!Select_ContainsValue(select, dayValue))
  {
    select.selectedIndex = 0;
  }
  else
  {
		select.selectedIndex = Select_IndexOfValue(select, dayValue);
  }
}

G2PopupWindow2 = function()
{
}



G2PopupWindow2.CloseCurrentPopup = function()
{
	var popup = this.GetCurrentPopup();
	if(popup!=null)
		return popup.Close();
}

G2PopupWindow2.GetCurrentPopup = function(win)
{
	win = win || window;
	var frame = win.frameElement;
	if(frame!=null)
		return frame.g2PopupWindow2;
	return null;
}

G2PopupWindow2.Open = function(id, varargs)
{
   	var pw = G2PopupWindow2.Get(id);
	if(pw!=null)
	{
		varargs = G2.ArgumentsFrom(arguments, 1);
		pw.Open.apply(pw, varargs);
	}
}
G2PopupWindow2.Close = function(id)
{
	var pw = G2PopupWindow2.Get(id);
	if(pw!=null)
	{
		pw.Close();
	}
}

G2PopupWindow2.OpenNew = function(url)
{
	var pw = new G2PopupWindow2();
	pw.url = url;
	pw.Open();
}

G2PopupWindow2.Get = function(hfid)
{
	var hf = $(hfid);
	if(hf.popupControl==null)
	{
		hf.popupControl = new G2PopupWindow2();
		hf.popupControl.ImportFromHf(hf);
	}
	return hf.popupControl;
}

G2PopupWindow2.CreateFrame = function(id)
{
    var resultFrame = null;
    var win = GetTopAvailableWindow();
    if (win.g2PopupWindowFrames == null)
        win.g2PopupWindowFrames = new Object();
    var availableFound = false;
    var frameToRemoveId = null;
    //try to find not used frame
    for (oldid in win.g2PopupWindowFrames)
    {
       var f = win.g2PopupWindowFrames[oldid];
       if (f.available)
       {
          availableFound = true;
          frameToRemoveId = oldid;
          //reuse frame
          resultFrame = f;
       }
    } 
    if (!availableFound)
    {
        resultFrame = G2_CreateIFrame(win.document);
    }
    if (frameToRemoveId != null)
    {
        delete win.g2PopupWindowFrames[frameToRemoveId];
    }
    resultFrame.available = false;
    win.g2PopupWindowFrames[id] = resultFrame;
    return resultFrame;   
}

//Get Frame for popup id
G2PopupWindow2.GetFrame = function(id)
{
    var result = null;
    var win = GetTopAvailableWindow();
    if (win.g2PopupWindowFrames != null)
      result = win.g2PopupWindowFrames[id];
    return result;
}

//Release frame used by a popup
G2PopupWindow2.ReleaseFrame = function(id)
{
    var frame = G2PopupWindow2.GetFrame(id);
    if (frame != null)
    {
        frame.available = true;
        frame.src = '';
        try
        {
            var frameDoc = frame.contentWindow.document;
		    frameDoc.open();
		    frameDoc.write("<html><body></body></html>");
		    frameDoc.close();
		}
		catch (e){}
		frame.width = "";
		frame.style.width = "";
        frame.height = "";
        frame.style.height = "";
        frame.scrolling = "auto";
        G2FrameManager.unregisterFrame(frame);
    }
}

function G2PopupWindow2_SetTitle(titleText)
{
	document.getElementById("7ae80179-c9a3-4fd3-89e5-a771d445f830").innerText=titleText;
}

G2_DeclareClass(G2PopupWindow2, "G2PopupWindow2", null, 
{
	ImportFromHf : function(hf)
	{
		this.hf = hf;
		this.Url = hf.url;
		this.CssClass = hf.cssclass;
		this.Title = hf.windowtitle;
		this.RelativeControlDocking = hf.relativecontroldocking;
		this.RelativeControlID = hf.relativecontrolid;
		this.NotifyClose = hf.notifyclose=="true";
		this.AutoSize = hf.autosize!="false";
		this.AutoSizeHeight = hf.autosizeheight!="false";
		this.AutoSizeWidth = hf.autosizewidth!="false";
		this.AllowMove = hf.allowmove!="false";
		this.IsModal = hf.ismodal!="false";
		this.FireCloseEventOnCloseIconClick = hf.firecloseeventoncloseiconclick=="true";
		this.WindowWidth = hf.windowwidth;
		this.WindowHeight = hf.windowheight;
		this.Scrolling = hf.scrolling;
		
		if (this.IsModal)
		{
			if (this.Url.indexOf('?') == -1)
				this.Url += "?IsPopup=True";
			else
				this.Url+="&IsPopup=True";
		}
	},
	Close : function(fireClosed, windowID, silent)
	{
	 	if(this.coverElement!=null && this.coverElement.parentElement!=null)
		{
			this.coverElement.removeNode(true);
		}
		G2_DetachFrame(this.element);
		this.element.removeNode(true);
		if(this.NotifyClose || fireClosed || this.FireCloseEventOnCloseIconClick)
		{
			__doPostBack(this.hf.name, "Close$"+windowID, silent);
		}
		G2PopupWindow2.ReleaseFrame(this.hf.id);
	},
	
	Open : function(args)
	{
	   	var win = GetTopAvailableWindow();
		var doc = win.document;
		var caller = this;
		var surface = doc.body;
		this.surfaceElement = surface;
//		var div = document.createElement("div");
//		div.innerHTML = "<table class='SerInfo_Table'><tr class='SerInfo_Header'><td class='SerInfo_Title'
		var table = G2_CreateTable(2, 1, true);
		table.className = "SerInfo_Table";
		table.style.width = "auto"; //override the css 100% (from old synthetic popup)
		table.rows[0].className = "SerInfo_Header";
		table.rows[0].cells[0].className = "SerInfo_Title";
		var element = table;
		this.element = element;
		//this.element.style.overflow = "auto";
		element.style.display = "none";
		 //div.appendChild(table);
	
		if(this.IsModal)
		{
			this.coverElement = doc.createElement('DIV');
			this.coverElement.className = "MessageBoxContainer";
			this.coverElement.style.left = "0px";
			this.coverElement.style.top = "0px";
			this.coverElement.style.width = surface.scrollWidth+"px";
			this.coverElement.style.height = surface.scrollHeight+"px";
			this.coverElement.style.position = "absolute";
		}
		
		var headerTable = G2_CreateTable(1, 2, true);
		headerTable.width = "100%";
		headerTable.style.cursor = "default";
		headerTable.rows[0].cells[1].align="right";
		headerTable.style.height = "25px";		
		table.rows[0].cells[0].appendChild(headerTable);
		
		//title
		var titleElement = doc.createElement("div");
		titleElement.id = "7ae80179-c9a3-4fd3-89e5-a771d445f830";
		titleElement.innerText = this.Title || " ";
		headerTable.rows[0].cells[0].appendChild(titleElement);

		//close
		var closeButtonElement = doc.createElement("span");
		closeButtonElement.className = "ClosePopupWindow";
		closeButtonElement.innerText = "X";
		closeButtonElement.onclick = function()
		{
			caller.Close(this.FireCloseEventOnCloseIconClick);
		};
		headerTable.rows[0].cells[1].appendChild(closeButtonElement);
		
		//element
		element.style.position = "absolute";
		element.style.pixelTop = 100+document.documentElement.scrollTop;
		element.style.pixelLeft = 100+document.documentElement.scrollLeft;
		//this.element.className = this.CssClass || "G2PopupWindow2";
		
		var url = this.Url;
		
		if(args!=null)
		{
			var queryString = [];
			for(var p in args)
			{
				queryString.push(p+"="+ encodeURIComponent(args[p]));
			}
			queryString = queryString.join("&");
			url = G2.AppendQueryString(url, queryString);
		}
		var frame = G2PopupWindow2.CreateFrame(this.hf.id);
		//this.frame.scrolling = "no";
		frame.frameBorder = "0";
		frame.width = "100%";
		
		frame.g2PopupWindow2 = this;
				
		if(this.AutoSize)
		{
	        frame.autosizeheight = "true";
	        frame.autosizewidth = "true";
	        frame.AutoSize = "true";
			if(!this.AutoSizeHeight)
				frame.autosizeheight = "false";
			if(!this.AutoSizeWidth)
				frame.autosizewidth = "false";
			G2FrameManager.registerFrame(frame);
		}
		else
		{
		    frame.autosizeheight = "false";
		    frame.autosizewidth = "false";
		    frame.AutoSize = "false";
		    
		    if(this.WindowWidth != null)
		    {
		        frame.width = this.WindowWidth;
		    }
    		
		    if(this.WindowHeight != null)
		    {
		        frame.height = this.WindowHeight;
		    }
		    G2FrameManager.registerFrame(frame);
		}
		table.rows[1].cells[0].appendChild(frame);
		if(this.AllowMove)
			G2Dragger.EnableDrag(table.rows[0], element, surface);
		
		surface.appendChild(this.element);
		if(!String.IsNullOrEmpty(this.RelativeControlID))
		{
			var relativeControl = document.getElementById(this.RelativeControlID);
			if(relativeControl!=null)
				G2_PlaceElementAbsolutlyNear(element, relativeControl, this.RelativeControlDocking,true);
		}
		G2_AttachEventWithCaller(frame, "onload", this.frame_onload, this);
		if(this.Scrolling == "false")
		   frame.scrolling = "no";
		frame.src = url;
		
      
    },
	frame_onload : function(e)
	{
		if(this.IsModal)
		{
			this.surfaceElement.insertBefore(this.coverElement, this.element);
		}
		this.element.style.display = 'block';
				
		G2_AttachFrame(this.element);
		var frame = G2PopupWindow2.GetFrame(this.hf.id);
		G2_DetachEventWithCaller(frame, "onload", this.frame_onload, this);
		
		// in case we use docking: verify popupWindow open within screen boundries
		if(!String.IsNullOrEmpty(this.RelativeControlID))
		{
			var element = this.element;
			VerifyPopupWindowNotCrooped(element);
		}
	}
});

// this method use setInterval to try to reposition the popup if it is out of boundries.
// the logic: keep trying to resize. after 3 times the resize action takes place and do nothing we stop.
// case 11147.
VerifyPopupWindowNotCrooped = function(element)
{
	var windowResizedCounter = 0;
	var refreshIntervalId = null;
	refreshIntervalId = setInterval(function()
		{
			// in case no action made in G2_VerifyAbsoluteElementNotCropped we add one 
			if(G2_VerifyAbsoluteElementNotCropped(element) == false)
				windowResizedCounter++;
			else
				if(refreshIntervalId != null) // clear interval on seccess 
					clearInterval(refreshIntervalId);

			if(refreshIntervalId != null && windowResizedCounter == 3)
			{
				clearInterval(refreshIntervalId);
			}
		}, 100);
}

G2Dragger = function(dragHandleElement, dragElement, surfaceElement)
{
	this.DragHandleElement = dragHandleElement;
	this.DragElement = dragElement;
	this.DragHandleElement.ondragstart = function(){return false;};
	this.SurfaceElement = surfaceElement || document.documentElement;
	G2_AttachEventWithCaller(this.DragHandleElement, "onmousedown", this.DragHandleElement_mousedown, this);
}

G2Dragger.EnableDrag = function(dragHandleElement, dragElement, surfaceElement)
{
	dragHandleElement._dragger = new G2Dragger(dragHandleElement, dragElement, surfaceElement);
}

G2_DeclareClass(G2Dragger, "G2Dragger", null, 
{
	DragHandleElement_mousedown : function(e)
	{
		if(this.isDragging)
			this._EndDrag(e);
		else
			this._StartDrag(e);
	},
	_StartDrag : function(e)
	{
		this.isDragging = true;
		var mouseX = G2.GetRelativeMouseX(e, this.SurfaceElement);
		var mouseY = G2.GetRelativeMouseY(e, this.SurfaceElement);
		this.offsetX = mouseX-this.DragElement.offsetLeft;
		this.offsetY = mouseY-this.DragElement.offsetTop;
		this.SurfaceElement.setCapture(true);
		G2_AttachEventWithCaller(this.SurfaceElement, "onmousemove", this.DragHandleElement_mousemove, this);
		G2_AttachEventWithCaller(this.SurfaceElement, "onmouseup", this.DragHandleElement_mouseup, this);
	},
	_EndDrag : function()
	{
		this.SurfaceElement.releaseCapture();
		G2_DetachEventWithCaller(this.SurfaceElement, "onmousemove", this.DragHandleElement_mousemove, this);
		G2_DetachEventWithCaller(this.SurfaceElement, "onmouseup", this.DragHandleElement_mouseup, this);
		this.isDragging = false;
	},
	DragHandleElement_mousemove : function(e)
	{
		var mouseX = G2.GetRelativeMouseX(e, this.SurfaceElement);
		var mouseY = G2.GetRelativeMouseY(e, this.SurfaceElement);
		if(mouseX<10)
			mouseX = 10;
		if(mouseY<10)
			mouseY = 10;
		var newX = mouseX-this.offsetX;
		var newY = mouseY-this.offsetY;
		this.DragElement.style.pixelLeft = newX;
		this.DragElement.style.pixelTop = newY;
	},
	DragHandleElement_mouseup : function(e)
	{
		if(this.isDragging)
			this._EndDrag();
	}
});

//Support for G2RadioButton.G2GroupName property
if( radioButtonGroups == null){
	var radioButtonGroups = new Object();
}

function registerRadioButton(radioButton)
{
	
	var groupName = radioButton.g2groupname;
	if(radioButtonGroups[groupName]==null)
	{
		radioButtonGroups[groupName] = new Array();
	}
	
	radioButtonGroups[groupName].push(radioButton);
}


function updateRadioButtonGroup(radioButton)
{
	
	G2RadioButton_VerifyCssClass(radioButton);
	if(!radioButton.checked)
		return;
		
	var groupName = radioButton.g2groupname;
	var radioButtonGroup = radioButtonGroups[groupName];
	
	for(var i=0;i<radioButtonGroup.length;i++)
	{
		var btn = radioButtonGroup[i];
		if(btn!=radioButton && btn.checked)
		{
			G2RadioButton_SetChecked(btn, false);
		}
	}
}

function G2RadioButton_GetLabel(radioButton)
{
	if(radioButton.nextSibling!=null && radioButton.nextSibling.htmlFor == radioButton.id)
		return radioButton.nextSibling;
	if(radioButton.previousSibling!=null && radioButton.previousSibling.htmlFor == radioButton.id)
		return radioButton.previousSibling;
	return null;
}

function G2RadioButton_VerifyCssClass(radioButton)
{
	var label = G2RadioButton_GetLabel(radioButton)
	if(label==null)
		return;
	
	if(radioButton.checkedcssclass!=null)
	{
		if(radioButton.checked)
			label.className = radioButton.checkedcssclass;
		else
			label.className = "";
	}
}

function G2RadioButton_SetChecked(radioButton, checked)
{
	radioButton.checked = checked;
	G2RadioButton_VerifyCssClass(radioButton);
}

function G2RadioButton_Init(radioButtonId)
{
	var radioButton = document.getElementById(radioButtonId);
	if(radioButton==null)
	{
		G2_Warn("G2RadioButton_Init","Cannot find the radiobutton with id "+radioButtonId);
		return;//TODO: Warn!!!
	}
	G2DOM.G2TransferAttributes(radioButton);
	if(radioButton.g2groupname!=null)
	{
		registerRadioButton(radioButton);
	}
	if(radioButton.fixautopostback=="True")
	{
		radioButton.wasChecked = radioButton.checked;
//		//TODO: this doesn't work for the label of the input
//		G2_AttachEvent(radioButton, "onmousedown", function(){G2RadioButton_OnMouseDown(radioButton)});
		G2_AttachEvent(radioButton, "onclick", function(){G2RadioButton_CheckPostBack(radioButton)});
	}
}


///
/// this method makes the asp.net AutoPostBack feature work alongside with our SilentPostBack feature
///
function G2RadioButton_CheckPostBack(sender, index)
{
	if(index!=null)
	{
		setTimeout("__doPostBack('"+sender.name+"$"+index.toString()+"','"+sender.value+"')", 0);
	}
	else
	{
	//TODO:couldn't optimize this because <label for> tag
		setTimeout(function() { __doPostBack(sender); }, 0);
	}
}



var G2TabControl_LastSelectedTab=""; // hold the last tab we selected in a tab control

function G2TabControl_Init(tabControlId)
{
		
	var tabControl = document.getElementById(tabControlId);
	G2DOM.G2TransferAttributes(tabControl);
	tabControl.tabs = [];
	if(tabControl.activetabid!=null)
	{
		var activeTab = document.getElementById(tabControl.activetabid);
		tabControl.tabs[tabControl.activetabindex] = activeTab;
		if(activeTab.parentElement!=null)
			G2_ShowControl(activeTab.parentElement);
		tabControl.ActiveTab = activeTab;
		G2TabControl_LastSelectedTab = tabControl.activetabid;
		
	}
}


function G2TabControl_SelectTab(tabControl, tab, tabIndex)
{
	if(tabControl.serverside=="true")
	{
		__doPostBack(tabControl, "TabClick:"+tabIndex, true);
		return;
	}
	if(tabControl.notifyserver=="true")
	{
		__doPostBack(tabControl, "TabClick:"+tabIndex, true);
	}
	tabControl.tabs[tabIndex] = tab;
	var firstCellChildren = tabControl.rows[0].cells[1].children;	
	var headerRow = firstCellChildren[0].rows[0];
	for(var i=0;i<headerRow.cells.length-1;i++) //we don't need to check the last cell - it is just for layout
	{
	
		var cell = headerRow.cells[i];
		var cellChildren = cell.children;
		var table = cellChildren[0];
		var from = "Selected"
		var to = "Addition";
		if(i==tabIndex)
		{
			from = "Addition";
			to = "Selected";
		}
		for(var j=0;j<table.rows[0].cells.length;j++)
		{
			var cell2 = table.rows[0].cells[j];
			cell2.className = cell2.className.replace(from, to);
		}
	}
	
	if(tabControl.ActiveTab!=null)
	{
		G2TabControl_HideTab(tabControl, tabControl.ActiveTab);
	}		
		
	G2TabControl_ShowTab(tabControl, tab);
	tabControl.ActiveTab = tab;
	G2TabControl_LastSelectedTab = tabControl.ActiveTab.id 
}

function G2TabControl_HideTab(tabControl, tab)
{
	if(tabControl.detachtabs == "true")
	{
		if(tab.parentElement!=null)
		{
			tab._TabParentElement = tab.parentElement;
			tab.removeNode(true);
		}
	}
	else if(tab.parentElement!=null)
	{
		G2_HideControl(tab.parentElement);
	}
}

function G2TabControl_ShowTab(tabControl, tab)
{
	if(tabControl.detachtabs == "true")
	{
		if(tab._TabParentElement!=null && tab.parentElement==null)
		{
			tab._TabParentElement.appendChild(tab);
			//G2_ShowControl(tab);
		}
	}
	if(tab.parentElement != null)
		G2_ShowControl(tab.parentElement);
}

function G2TabControl_OnTabClick(tabControlId, tabId, tabIndex)
{
	var tabControl = $(tabControlId);
	var tab = $(tabId);
	
	if(tabControl==null)
		return;
		
	// perform validation
	if(G2DOM.G2GetAttribute(tabControl,"causesvalidation")=="true")
	{
		if(typeof(G2Validation_PerformValidation)=="function" && G2Validation_PerformValidation(tabControl)==false) 
        return;
	}
	
	if(tab==null)
	{
		tab = tabControl.tabs[tabIndex];
		if(tab==null)
			return;
	}

	if(G2DOM.G2GetAttribute(tab, "g2enabled")=="false")
		return;
	if(tabControl.clientontabclickfunction!=null)
	{
		var f = tabControl.clientontabclickfunction + "(tabControl, tab, tabIndex);";
		var returnValue = eval(f);
		if(returnValue == false)
			return;
	}
	G2TabControl_SelectTab(tabControl, tab, tabIndex);
}

// return the last tab that we pressed on
function G2TabControl_GetLastSelectedTab()
{
		return G2TabControl_LastSelectedTab;
}
//----------------------------------------------------------------------
//G2TableExpander functions
//----------------------------------------------------------------------

function G2TableExpander_Init(expanderControlId)
{
  var expander = document.getElementById(expanderControlId);
  if (!expander)
  {
		G2_Warn("G2TableExpander_Init","expander is null");
		return;
  }
  G2DOM.G2TransferAttributes(expander);
  expander.targethasheader = expander.targethasheader=="True";
  expander.UseVisibility = expander.usevisibility=="true";
  G2TableExpander_OnChange(expander);
	if(expander.onclientinit!=null)
	{
		var event = {srcElement:expander};
		eval(expander.onclientinit);
  }
  
}

function G2TableExpander_OnChange(expander)
{
  var value = parseInt(expander.value);
  if(expander.expansiontype=="Row")
  {
		G2TableExpander_ShowHideRows(expander, value);
  }
  else if(expander.expansiontype=="Cell")
  {
		G2TableExpander_ShowHideCells(expander, value, true);
  }
}

function G2TableExpander_GetTargetTable(expander)
{
  var element = document.getElementById(expander.g2targetcontrol);
  if(element!=null)
	  element = G2_FindElementByTagName(element, "TABLE");
	return element;
}



function G2TableExpander_ShowHideCells(expander, cellsToShow)
{
  var table = G2TableExpander_GetTargetTable(expander);
  if(table==null || table.rows.length==0)
		return;

	var startFromRow=0;
	if(expander.targethasheader)
	{
		G2_ShowHideControl(table.rows[0], cellsToShow>0, expander.UseVisibility);
		startFromRow++;
	}

//	//if header exists
//	if(table.rows[0].cells[0].tagName.toUpperCase()=="TH")
//	{
//		//Ignore header
//		G2_ShowHideControl(table.rows[0], cellsToShow>0);
//	}	
  //var tbody=table.children[0];
  var index=0;
  for(var i=startFromRow; i<table.rows.length; i++)
  {
		var row = table.rows[i];
    for(var j=0; j<row.cells.length; j++)
	  {
			var cell = row.cells[j];
	    if(index<cellsToShow)
	      G2_ShowControl(cell, expander.UseVisibility);
		  else
			  G2_HideControl(cell, expander.UseVisibility);
			index++;
	  }

  }
}



function G2TableExpander_ShowHideRows(expander, rowsToShow)
{
  var table = document.getElementById(expander.g2targetcontrol);
  if(table==null || table.rows.length==0)
		return;

	if(expander.targethasheader)
		rowsToShow++;
//	//if header exists
//	if(table.rows[0].cells[0].tagName.toUpperCase()=="TH")
//	{
//		//Ignore header
//		rowsToShow++;
//	}	
  //var tbody=table.children[0];
  for(var i=0; i<table.rows.length; i++)
  {
    if(i<rowsToShow)
      G2_ShowControl(table.rows[i], expander.UseVisibility);
    else
      G2_HideControl(table.rows[i], expander.UseVisibility);
  }
}



var reKeyboardChars = /[\x00\x03\x08\x0D\x16\x18\x1A]/;
var reClipboardChars = /[cvxz]/i;
	var specialCopyKey = 17; //ctrl + q

G2_DeclareFunctions(
{
	G2TextBox_Init : function(textbox, e)
	{
		if(typeof(textbox)=="string")
			textbox = document.getElementById(textbox);
		if(textbox==null)
			return;
		if(textbox.g2IsInited)
			return;
		G2DOM.G2TransferAttributes(textbox);
		textbox.g2IsInited = true;
		if(textbox.value==textbox.nullvalue)
		{
			if(e && e.type=="focus" && e.srcElement==textbox)
				G2TextBox_OnFocus(e);
			else
				G2_AttachEvent(textbox, "onfocus", G2TextBox_OnFocus);
		}
		if(textbox.allowedinputregex!=null)
		{
			textbox.reValidChars = new RegExp(textbox.allowedinputregex);
			textbox.reValidString = new RegExp("^"+textbox.allowedinputregex+"*$");
			G2_AttachEvent(textbox, "onkeypress", G2TextBox_OnKeyPress);
			G2_AttachEvent(textbox, "onpaste", G2TextBox_OnPaste);
			G2_AttachEvent(textbox, "onchange", G2TextBox_OnChange);
		}
		if (textbox.allowedexpregex != null)
		{
			textbox.reValidExp = new RegExp(textbox.allowedexpregex);
		}
		if(textbox.inputmaskformat!=null && textbox.inputmask!=null)
		{
			G2_AttachEvent(textbox, "onkeypress", G2TextBox_InputMask_OnKeyPress);
			G2_AttachEvent(textbox, "onkeydown", G2TextBox_InputMask_OnKeyDown);
			if(textbox.value=="")
				textbox.value = textbox.inputmaskformat;
		}
	
		if(textbox.convertlowertoupper=="true")
		{
			textbox.convertlowertoupper = true;
			//text-transform: uppercase
		}
		
		textbox.getValue = G2TextBox_GetValue;
		G2TextBox_SetOriginalValue(textbox);
		//textbox.originalValue = G2TextBox_GetValue(textbox);
		textbox.g2PerformUndo = G2TextBox_PerformUndo;
		textbox.g2SetOriginalValue = G2TextBox_SetOriginalValue;
		textbox.g2IsDirty = G2TextBox_IsDirty;

		EnableSupportForPartialPostData(textbox);
	},
	G2TextBox_IsDirty : function(textbox)
	{
		textbox = textbox || this;
		return textbox.originalValue!=G2TextBox_GetValue(textbox);
	},
	G2TextBox_PerformUndo : function()
	{
		G2TextBox_SetValue(this, this.originalValue);
		//G2.undoNotifyInputChanged(this);
	},
	G2TextBox_SetOriginalValue : function(textbox)
	{
		textbox = textbox || this;
		textbox.originalValue = G2TextBox_GetValue(textbox);
		G2.undoNotifyInputChanged(textbox);
	},

	G2TextBox_GetValue : function(textbox)
	{
		textbox = textbox || this;
		return (textbox.convertlowertoupper) ? textbox.value.toUpperCase() : textbox.value;
	},

	G2TextBox_SetValue : function(textbox, value)
	{
		if(textbox.value!=value)
			textbox.value = value;
	},

	G2TextBox_OnAllowedInputError : function(textbox)
	{
		if(textbox.allowedinputerrormessage!=null && textbox.allowedinputerrormessage!="")
			alert(textbox.allowedinputerrormessage);
	},

	G2TextBox_OnFocus : function(e) 
	{
		var tb = e.srcElement;
		if(tb.value==tb.nullvalue)
		{
			tb.value = "";
		}
		if (tb.cssclass)
			G2_ReplaceCssClass(tb, tb.cssclass, tb.nullcssclass);
		else
			tb.cssclass = "";
	},
	G2TextBox_MoveCursorToEnd : function(textbox, e)
	{
		textbox.select();
		var range = document.selection.createRange();
		range.collapse(false);
		range.select();
	},
	G2TextBox_InputMask_OnKeyPress : function(e)
	{
		var pos = G2_GetCaretPosition(e.srcElement);
		var input = e.srcElement;
		if(input.inputmask.charAt(pos)=="P" && e.keyCode!=input.inputmaskformat.charCodeAt(pos))
		{
			var ee = document.createEventObject(e);
			ee.keyCode = input.inputmaskformat.charCodeAt(pos);
			EmulateKeyPress(ee, "overwrite");
			EmulateKeyPress(e, "overwrite");
			G2Event.stop(e);
		}
		else
		{
			if(input.inputmask.charAt(pos)=="D")
			{
				var ch = String.fromCharCode(e.keyCode);
				if(!/[0-9]/.test(ch))
				{
					G2Event.stop(e);
					return;
				}
			}
			if(TryEmulateKeyboardEvent(e, "overwrite"))
				G2Event.stop(e);
		}
	},
	G2TextBox_InputMask_OnKeyDown : function(e)
	{
		var pos = G2_GetCaretPosition(e.srcElement);
		var input = e.srcElement;
		if(e.keyCode==Char.Backspace)
		{
			if(pos==0)
			{
				G2Event.stop(e);
				return;
			}
			var ee = document.createEventObject(e);
			if(input.inputmask.charAt(pos-1)=="P")
			{
				ee.keyCode = Char.ArrowLeft;
				EmulateKeyboardEvent(ee);
				pos--;
			}

			EmulateKeyboardEvent(e);
			G2Event.stop(e);
			ee.keyCode = input.inputmaskformat.charCodeAt(pos-1);
			EmulateKeyPress(ee);
			ee.keyCode = Char.ArrowLeft;
			EmulateKeyDown(ee);
		}
		else if(e.keyCode==Char.Delete)
		{
			if(document.selection.createRange().text.length!=5)
				G2Event.stop(e);
		}
	},

	//mask functions
	G2TextBox_OnKeyPress : function(objEvent) 
	{
		var keyCode, strKey, textbox;  
		
		if (isIE) 
		{
			keyCode = objEvent.keyCode;
			textbox = objEvent.srcElement;
		} 
		else 
		{
			keyCode = objEvent.which;
			textbox = objEvent.target;
		}

		/*if(textbox.convertlowertoupper && Char.IsLower(keyCode))
		{
			keyCode = Char.ToUpperKeyCode(keyCode);
			if (isIE)
				objEvent.keyCode = keyCode; //Is this really necassary ?
		}*/
		strKey = String.fromCharCode(keyCode);
		if (textbox.convertlowertoupper)
				strKey = strKey.toUpperCase(); //This is handled at the server and visually as well.
			
		if (G2TextBox_IsInputValid(textbox, textbox.getValue())) 
		{
			textbox.validValue = textbox.getValue();
			if (!G2TextBox_IsKeyValidInMask(textbox, strKey) && !reKeyboardChars.test(strKey) && !checkClipboardCode(objEvent, strKey, keyCode)) 
			{
				G2TextBox_OnAllowedInputError(textbox);
				objEvent.returnValue = false;
				G2Event.stop(objEvent);				
	//			alert("Invalid Character Detected!\nKeyCode = " + keyCode + "\nCharacter =" + strKey);
				return false;
			}
		} 
		else 
		{
			G2TextBox_OnAllowedInputError(textbox);
	//		alert("Invalid Data");
			textbox.value = textbox.validValue;
			objEvent.returnValue = false;
			G2Event.stop(objEvent);			
			return false;
		}
	},

	checkClipboardCode : function(objEvent, strKey, keyCode) 
	{
		var x = false;
		if (isMoz)
  				x = objEvent.ctrlKey && reClipboardChars.test(strKey);
  		else
  		{
  				//in IE we don't need to test ctrl xcv (event does not happen) - we DO need to test for ctrl-q
  				if(keyCode == specialCopyKey)
  						return true;
  		}
		objEvent.returnValue = x;
		return x;
	},

	G2TextBox_IsKeyValidInMask : function(textbox, key)
	{
		if(textbox.reValidChars==null)
			return true;
		return textbox.reValidChars.test(key);
	},

	G2TextBox_IsInputValid : function(textbox, text)
	{
		if(textbox.reValidString==null)
			return true;
		var isValid = textbox.reValidString.test(text) || text.length == 0;
		return isValid;
	},


	G2TextBox_OnChange : function(objEvent) 
	{
		var textbox;
		if (isIE) 
		{
  		textbox = objEvent.srcElement; 
		} 
		else 
		{
  		textbox = objEvent.target;
		}

		if (!G2TextBox_IsInputValid(textbox, textbox.getValue())) 
		{
			G2TextBox_OnAllowedInputError(textbox);
			textbox.value = textbox.validValue || "";
			textbox.focus();
  		textbox.select(); 
		} 
		else 
		{
			textbox.validValue = textbox.getValue();
		}
		textbox._isDirty = true;
	},

	G2TextBox_OnPaste : function(objEvent) 
	{
		var strPasteData = window.clipboardData.getData("Text");
		var textbox = objEvent.srcElement;
		if (!G2TextBox_IsInputValid(textbox, strPasteData)) 
		{
			G2TextBox_OnAllowedInputError(textbox);
			textbox.focus();
			objEvent.returnValue = false;
			return false;
		}
	},
	
	G2TextBox_SizeLimit : function(thisEl,maxLength)
	{
	    if(thisEl.value.length > (maxLength - 1) )	      
	      window.event.keyCode = 0;	      
	},		
    
    G2TextBox_SizeLimitOnUp : function(thisEl,maxLength)
	{
	    if(thisEl.value.length > maxLength)	      
	        thisEl.value = thisEl.value.substring(0, maxLength);
	},
	
	G2TextBox_FormatAmount : function(thisEl)
	{
		if (thisEl.convertnulltozero == "False" && thisEl.value == "")
			return;
		
		var num = new Number(thisEl.value);	
		if (!isNaN(num))    
			thisEl.value = num.toFixed(2);
	},
	
	//avoid blanks when AllowedInputType="WholeNumbers"
	G2TextBox_AvoidBlack : function(thisEl)
	{
		if(thisEl.value == "")
			thisEl.value = "0";
	},
	
	G2TextBox_CheckExpression : function (objEvent, thisEl)
	{
		if(thisEl.reValidExp==null)
			return true;
		var isValid = thisEl.reValidExp.test(thisEl.value);
		if (!isValid)
		{
			G2TextBox_OnAllowedInputError(thisEl);
			thisEl.focus();
			objEvent.returnValue = false;
			G2Event.stop(objEvent);			
		}
		return isValid;
	},
	G2TimePicker_OnBlur : function(e)
	{
		var input = e.srcElement;
		var s = input.value;
		if(s!=input.inputmaskformat)
		{
			var hh = s.substr(0, 2);
			var mm = s.substr(3, 2);
			var hour = String_ToInt(hh);
			var minute = String_ToInt(mm);
			if(hour<0 || hour>23 || minute<0 || minute>59)
			{
				if(input.invalidtimeerrormessage!=null)
				{
					alert(input.invalidtimeerrormessage);
				}
				input.value = input.inputmaskformat;
			}
		}
	},
	G2PasswordBox_GetNullText : function(pb)
	{
		return pb.nextSibling.innerText;
	},
	G2PasswordBox_SetNullText : function(pb, value)
	{
		pb.nextSibling.innerText = value;
	},
	G2PasswordBox_OnFocus : function(e) 
	{
		var pb = e.srcElement;
		if(G2PasswordBox_GetNullText(pb)==pb.nullvalue)
		{
			G2PasswordBox_SetNullText(pb, "")
		}
//		if(pb.className==pb.nullcssclass)
//		{
//			pbclassName = pb.cssclass || "";
//		}
	},

	G2PasswordBox_Init : function(pb, e)
	{
		G2TextBox_Init(pb, e);
		if(G2PasswordBox_GetNullText(pb)==pb.nullvalue)
		{
			if(e.type=="focus" && e.srcElement==pb)
				G2PasswordBox_OnFocus(e);
			else
				G2_AttachEvent(pb, "onfocus", G2PasswordBox_OnFocus);
		}

		
	}
	
});



function EmulateKeyboardEvent(e, mode)
{
	if(!TryEmulateKeyboardEvent(e, mode))
		throw new Error();
}

function EmulateKeyPress(e, mode)
{
	if(!TryEmulateKeyPress(e, mode))
		throw new Error();
}
function EmulateKeyDown(e, mode)
{
	if(!TryEmulateKeyDown(e, mode))
		throw new Error();
}


//e = event / json like event. srcElement, keyCode, shiftState, etc...
//mode = insert / overwrite
function TryEmulateKeyboardEvent(e, mode)
{
	if(e.type=="keydown")
		return TryEmulateKeyDown(e, mode);
	else if(e.type=="keypress")
		return TryEmulateKeyPress(e, mode);
	return false;
}

function TryEmulateKeyPress(e, mode)
{
	mode = mode || "insert";
	if(e.srcElement!=null && e.srcElement.document.activeElement!=e.srcElement)
		e.srcElement.setActive();
	var range = document.selection.createRange();
	if(range.text.length>0)
		document.selection.clear();
	else if(mode=="overwrite")
		range.moveEnd("character", 1)
	range.text = String.fromCharCode(e.keyCode);
	return true;
}

function TryEmulateKeyDown(e, mode)
{
	mode = mode || "insert";
	if(e.srcElement!=null && e.srcElement.document.activeElement!=e.srcElement)
		e.srcElement.setActive();
	var range = document.selection.createRange();
	if(e.keyCode==Char.Backspace)
	{
		range.moveStart("character", -1);
		range.select();
		document.selection.clear();
		return true;
	}
	else if(e.keyCode==Char.Delete)
	{
		range.moveEnd("character", +1);
		range.select();
		document.selection.clear();
		return true;
	}
	else if(e.keyCode==Char.ArrowLeft)
	{
		range.move("character", -1);
		range.select();
		return true;
	}
	else if(e.keyCode==Char.ArrowRight)
	{
		range.move("character", +1);
		range.select();
		return true;
	}
	return false;
}

G2TreeNode3_Init = function(id)
{
	var node = document.getElementById(id);
	if(node==null)
		return;
	node.expander = document.getElementById(node.expanderid);
	node.childrenContainer = document.getElementById(node.childrencontainerid);
	if(node.expander!=null && node.childrenContainer!=null)
	{
		node.expander.onclick = function()
		{
			node.childrenContainer.style.display = node.childrenContainer.style.display=="none" ? "" : "none";
		};
	}
}

G2_DeclareFunctions(
{
	GetTreeView : function(element)
	{
		while(element!=null)
		{
			if(element._treeView!=null)
				return element._treeView;
			element = element.parentElement;
		}
		return null;
	},
	GetTreeNode : function(element)
	{
		1;
		while(element!=null)
		{
			if(element._treeNode!=null)
				return element._treeNode;
			element = element.parentElement;
		}
		return null;
	},
	
	G2TreeNode2_Init : function(treeNodeId)
	{
		var treeNodeElement = document.getElementById(treeNodeId);
		if(treeNodeElement!=null)
		{
			var tn = new TreeNode(treeNodeElement);
		}
	},
		
	TreeView_Init : function(treeViewId)
	{
		var tvElement = document.getElementById(treeViewId);
		var treeView = new TreeView(tvElement);
	}
});

//
// TreeView client control (works with G2TreeView2)
//	
TreeView = function(tvElement)
{
	this.treeViewElement = tvElement;
	this.treeViewElement._treeView = this;
	var child = this.treeViewElement.firstChild;
	while(child!=null)
	{
		var childNode = new TreeNode(child);
		child = child.nextSibling;
	}
	var caller = this;
	G2_AttachEvent(this.treeViewElement, "onmouseover", function(){caller._onmouseover();});
	G2_AttachEvent(this.treeViewElement, "onmouseout", function(){caller._onmouseout();});
}
	
G2_DeclareClass(TreeView, "TreeView", null, 
{
	_onmouseover : function()
	{
		var el = event.srcElement;
		if(G2_ContainsCssClass(el, "NodeText"))
		{
			G2_AddCssClass(el, "NodeText_MouseOver");
		}
	},
	_onmouseout : function()
	{
		var el = event.srcElement;
		if(G2_ContainsCssClass(el, "NodeText"))
		{
			G2_RemoveCssClass(el, "NodeText_MouseOver");
		}
	},
	getSelectedNode : function()
	{
		return this.selectedNode;
	},

	setSelectedNode : function(node, dopostback)
	{
		if(this.selectedNode!=null)
		{
			this.selectedNode.nodeTextElement.className = "NodeText";
			this.selectedNode = null;
		}
		if(node!=null)
		{
			this.selectedNode = node;
			G2_AddCssClass(node.nodeTextElement, "NodeText_Selected");
			if(dopostback)
			{
				window.setTimeout(function()
				{
					__doPostBack(node.nodeElement, null, true);//always silent for now
				}, 0);
			}
		}
	},

	getNodeStateIcon : function(node)
	{
		if(!node.hasChildNodes())
		{
			return this.treeViewElement.g2iconsfolderurl+"/NoExpand.gif";
		}
		return this.treeViewElement.g2iconsfolderurl+"/"+node.state+".gif";
	}
});


TreeNode = function(element)
{
	this.nodeElement = element;
	this.nodeElement._treeNode = this;
	this.nodeContentElement = this.getChildElementById("NodeContent");
	this.nodeStateElement = this.getChildElementById("NodeState");
	this.nodeChildrenElement = this.getChildElementById("NodeChildren");
	this.nodeTextElement = this.getChildElementById("NodeText");
	this.nodeHiddenTextElement = this.getChildElementById("NodeHiddenText");
	this.nodeIconElement = this.getChildElementById("NodeIcon");
	this.nodeStateIconElement = this.getChildElementById("NodeStateIcon");
	this.state = this.nodeStateElement.value.indexOf("expanded:true")!=-1 ? "expanded" : "collapsed";
	EnableSupportForPartialPostData(this.nodeStateElement);
	EnableSupportForPartialPostData(this.nodeHiddenTextElement);
	if(this.nodeElement.g2isselected)
		this.getTreeView().selectedNode = this;
	this.initChildNodes();
}
	
G2_DeclareClass(TreeNode, "TreeNode", null, 
{
	getChildElementById : function(id)
	{
		var x = G2DOM.GetChildElementById(this.nodeElement, "_"+this.nodeElement.id+"__"+id);
		return x;
	},
	
	initChildNodes : function()
	{
		var child = this.nodeChildrenElement.firstChild;
		while(child!=null)
		{
			var childNode = new TreeNode(child);
			child = child.nextSibling;
		}
	},
	
	hasChildNodes : function()
	{
		return this.nodeChildrenElement.childNodes.length>0;
	},

	addChildNode : function(node)
	{
		this.nodeChildrenElement.appendChild(node.nodeElement);
	},
	
	toggle : function()
	{
		if(this.state=="expanded")
			this.collapse();
		else
			this.expand();
	},
	
	
	expand : function()
	{
		this.state = "expanded";
		this.nodeChildrenElement.style.display = "";
		this.nodeStateIconElement.src = this.getTreeView().getNodeStateIcon(this);
		this.nodeStateElement.value	= this.nodeStateElement.value.replace("expanded:false", "expanded:true");
	},
	
	collapse : function()
	{
		this.state = "collapsed";
		this.nodeChildrenElement.style.display = "none";
		this.nodeStateIconElement.src = this.getTreeView().getNodeStateIcon(this);
		this.nodeStateElement.value	= this.nodeStateElement.value.replace("expanded:true", "expanded:false");
	},
	
	getTreeView : function()
	{
		return GetTreeView(this.nodeElement);
	},
	
	stateIcon_onclick : function()
	{
		this.toggle();
	},
	
	endEdit : function()
	{
		G2_RemoveCssClass(this.nodeTextElement, "NodeText_Edit");
		this.nodeHiddenTextElement.value = this.nodeTextElement.innerText; //save
		this.nodeTextElement.contentEditable = false;
		G2_DetachEvent(this.nodeTextElement, "onblur", this.nodeTextElement_onblur);
	},

	nodeTextElement_onblur : function()
	{
		var node = GetTreeNode(event.srcElement);
		if(node!=null)
			node.endEdit();
		else
		{
			G2_Trace("couldn't find node");
		}
	},

	beginEdit : function()
	{
		G2_AddCssClass(this.nodeTextElement, "NodeText_Edit");
		this.nodeTextElement.contentEditable = true;
		this.nodeTextElement.focus();
		G2_AttachEvent(this.nodeTextElement, "onblur", this.nodeTextElement_onblur);
	},
	
	node_onclick : function()
	{
		if(this.getTreeView().getSelectedNode()==this)
		{
			this.beginEdit();
		}
		else
		{
			this.getTreeView().setSelectedNode(this, true);
		}
	},
	
	node_oncontextmenu : function()
	{
		this.getTreeView().setSelectedNode(this, false);
	}
	
	
	
});
G2Validators = new Object();

function G2BaseValidator_Init(validatorID)
{
	var validator = document.getElementById(validatorID);
	if(validator==null || validator.isInited)
	{
		Debug.writeln("Validator was not found: "+validator);
		return;
	}
	G2Validators[validatorID] = validator;
	validator.isInited = true;
	G2DOM.G2TransferAttributes(validator);
	if (validator.isvalid=="false")
		validator.isvalid = false;
		
	if(validator.targetcontrolid!=null)
	{
		var target = document.getElementById(validator.targetcontrolid);
		if(target!=null)
		{
			validator.targetcontrol = target;
			if(target.validators==null)
				target.validators = new Array();
			target.validators.push(validator);
			if(validator.clientvalidationfunction!=null)
			{
				eval("validator.validate="+validator.clientvalidationfunction+";");
			}
			else
			{
				validator.validate = G2CustomValidator_Validate;
			}
			if(validator.extrainitializationfunction!=null)
			{
				eval(validator.extrainitializationfunction+"(validator);");
			}
		} 
		else 
			Debug.writeln("Validator's target was not found: "+validator.targetcontrolid);
	}
}


function G2CompareValidator_Init(validator)
{
	if(validator.controltocompare!=null)
	{
		validator.controltocompare = document.getElementById(validator.controltocompare);
		if (!validator.controltocompare)
			Debug.writeln("Validator's target was not found: "+validator.controltocompare);
	} else Debug.writeln("Validator's target was not specified: "+validator.id);
}


function G2CustomValidator_Validate()
{
	return true;
}

function G2RegularExpressionValidator_Validate()
{
	var value = G2Validation_GetControlValue(this.targetcontrol);
	if(value==null || value.toString()=="" || this.ignorevalue==value) //this is like asp.net RE validators
		return true;
  var rx = new RegExp(this.validationexpression);
  var matches = rx.exec(value);
  return (matches != null && value == matches[0]);
}

function G2CompareValidator_Validate()
{
	var value1 = G2Validation_GetControlValue(this.targetcontrol);
	var value2 = null;
	if(this.controltocompare!=null)
	{
		value2 = G2Validation_GetControlValue(this.controltocompare);
	}
	else if(this.valuetocompare!=null)
	{
		value2 = this.valuetocompare;
	}
	if(this.type!=null)
	{
		value1 = G2Validation_ConvertValue(value1, this.type);
		value2 = G2Validation_ConvertValue(value2, this.type);
	}
	return G2CompareValidator_Compare(value1, value2, this.operator);
}

function G2Validation_ConvertValue(value, targetType)
{
	if(targetType=="double")
	{
		if(typeof(value)=="number")
			return value;	
		var x = parseFloat(value);
		if(isNaN(x))
			return null;
		return x;
	}
	else if(targetType=="integer")
	{
		if(typeof(value)=="number")
			return value;	
		var x = parseInt(value);
		if(isNaN(x))
			return null;
		return x;
	}
	else
	{
		throw new Error("convertion not (yet) supported between the value "+value+" and the targetType "+targetType);
	}
}

function G2CompareValidator_Compare(x, y, operator)
{
    if(x==null || y==null)
      return true;
	if(x instanceof Date && y instanceof Date)
	{
		x = x.valueOf();
		y = y.valueOf();
	}
  switch (operator) 
  {
    case "NotEqual":
        return (x!=y);
    case "GreaterThan":
        return (x>y);
    case "GreaterThanEqual":
        return (x>=y);
    case "LessThan":
        return (x<y);
    case "LessThanEqual":
        return (x<=y);
    default:
        return (x==y);
  }
}



function G2Validation_GetControlValue(control)
{
	if (control==null)
	{
		Debug.writeln("G2Validation_GetControlValue: Control was not found");
		return null;
	}
		
	if(typeof(control.getValue)=="function")
		return control.getValue();
	return control.value || G2DOM.G2GetAttribute(control,'value');
}

function G2Validation_GetControlNullValue(control)
{
	if (control==null)
		return Debug.writeln("G2Validation_GetControlValue: Control was not found");
		
	if(typeof(control.getNullValue)=="function")
		return control.getNullValue();
	return control.nullvalue || G2DOM.G2GetAttribute(control,'nullvalue');
}

function G2RequiredFieldValidator_Validate()
{
	var targetcontrol = this.targetcontrol;	
	return G2RequiredFieldValidator_ValidateControl(targetcontrol);
	
}

function G2RequiredFieldValidator_ValidateControl(targetcontrol)
{
	//TODO: Check why (targetcontrol.document != document)
	targetcontrol = targetcontrol.document.getElementById(targetcontrol.id);
	var value = G2Validation_GetControlValue(targetcontrol);
	if(value==null || value=="")
		return false;
	var nullValue = G2Validation_GetControlNullValue(targetcontrol);
	if(nullValue!=null)
	{
		return value!=nullValue;
	}
	return true;
}

function G2Validation_Validate(validator, context)
{
	
	if(validator.enabled=="false")
	{
		return;
	}
	var control = validator.targetcontrol;
	if(control==null)
	{
		Debug.writeln("validator was not attached to element "+validator.id);
		return;
	}

	if(validator.parentElement==null)
	{
		if (validator.id && validator.id != "")
			validator = $(validator.id);
		if (validator == null || validator.parentElement==null)
			return;//this happens when updating the validator in silentpostback. TODO: perform clean up when changing outerHTML
	}
	context.validators.push(validator);
	var isvalid = validator.validate();
	validator.isvalid = isvalid;
	G2_ShowHideControl(validator, !isvalid);
	if(context.isvalid && !isvalid)
	{
		context.isvalid = false;
	}
}

function G2Validation_PerformValidation(sender)
{
	G2DOM.G2TransferAttributes(sender);
	if(sender.causesvalidation!="false")
	{
		var options = new Object();
		options.validatehiddencontrols = sender.validatehiddencontrols=="true";
		options.validatedisabledcontrols = false;
		return G2Validation_ValidateControlsById(sender.validatecontrolsids, options);
	}
	return true;
}

//
// performs recursive validation on each control sent in the client controlIDs
// controlIds - string - comma seperated client element ids, can be null or empty - if null or empty
// an entire page validation will occur
// options may be a jsObject with these features: 
//		validatehiddencontrols - true/false
//		ShowMessageBox - true/false
function G2Validation_ValidateControlsById(controlIds, options)
{
	var context = new Object();
	context.validators = new Array();
	context.isvalid = true;
	context.options = options==null ? new Object() : options;
	if(options.ShowMessageBox==null)
		options.ShowMessageBox = true;
	if(options.validatehiddencontrols==null)
		options.validatehiddencontrols = false;
		
	if(controlIds!=null && controlIds.length>0)
	{
		controls = G2FindControlsById(controlIds);
//		for(var validatorId in G2Validators)
//		{
//			var validator = document.getElementById(validatorId);
//			
//		}
		for(var i=0,j=controls.length;i<j;i++)
		{			
			G2Validation_ValidateAllFromElement(controls[i], context);
			//G2Validation_ValidateControl(controls[i], context);
		}
	}
	else
	{
		G2Validation_ValidateAllFromElement(document.body, context);
		//G2Validation_ValidateControl(document.body, context);
	}
	if(!context.isvalid && options.ShowMessageBox)
	{
		G2Validation_ShowErrorsInMessageBox(context.validators);
	}
	return context.isvalid;
}

function G2Validation_ShowErrorsInMessageBox(validators)
{
	var errors = new Array();
	for(var i=0;i<validators.length;i++)
	{
		var validator = validators[i];
		if(!validator.isvalid)
		{
			errors.push(validator.errormessage);
		}
	}
	alert(errors.join("\n"));
}

//
// performs recursive validation on a certain client control (html element)
// this function needs validationContext to run with.
function G2Validation_ValidateControl(control, context, implicit)
{
	if(implicit && control.explicitvalidation) //a flag set on an element that wants to stop recursive validation
		return;
	if(!context.options.validatehiddencontrols)
	{ 
		var checkParents = !context.checkedAllParentVisibility;
		if(checkParents)
			context.checkedAllParentVisibility = true;
		if(!G2_IsElementVisible(control, checkParents))
			return;
	}
	if(control.validators!=null)
	{
		for(var i=0;i<control.validators.length;i++)
		{
			G2Validation_Validate(control.validators[i], context);
		}
		return;
	}
	else
	{
		if(control.tagName=="SELECT") //so we won't check the items in the combo
			return;
		
		control = control.firstChild;
		while(control!=null)
		{
			G2Validation_ValidateControl(control, context, true);
			control = control.nextSibling;
		}
	}
	
}
function G2_IsChildOf(child, element)
{
	var parent = child;
	while(parent!=null)
	{
		if(parent==element)
			return true;
		parent = parent.popupParentElement || parent.parentNode;
	}
	return false;
}
//
// performs recursive validation on a certain client control (html element)
// this function needs validationContext to run with.
function G2Validation_ValidateAllFromElement(rootElement, context)
{
	for(var validatorId in G2Validators)
	{
		var validator = G2Validators[validatorId];
		if(validator.parentElement==null)//stale validator, continue (TODO: Remove from list)
		{
		   continue;
		}	
		if(rootElement.explicitvalidation && rootElement!=validator.targetcontrol) //a flag set on an rootElement that wants to stop recursive validation
			continue;
		if(rootElement==document.body || G2_IsChildOf(validator.targetcontrol, rootElement))
		{
			var startControl = validator.targetcontrol; //control for the visibility check
			if (startControl == null) //no target control (e.g. custom validator, use parent of the validator)
				startControl = validator.parentNode;
			if(!context.options.validatehiddencontrols && !G2_IsElementVisible(startControl, true))
			{ 
				continue;
			}			
			if(!context.options.validatedisabledcontrols && validator.targetcontrol != null && validator.targetcontrol.isDisabled)
				continue;
			G2Validation_Validate(validator, context);
		}		
	}

}

//returns false if the returning date equals the departure date and
//the returning hour is later rhan the departure hour
function ValidatePartOfDay()
{
	var rootNode = $("mainTableId");
	var partOfDayTo = G2DOM.GetChildByProgid(rootNode,"partOfDayTo");
	var partOfDayFrom = G2DOM.GetChildByProgid(rootNode,"partOfDayFrom");
	var returningDate = G2DOM.GetChildByProgid(rootNode,"returningDate");
	var departurDate = G2DOM.GetChildByProgid(rootNode,"departurDate");
	
	if(	departurDate.value == returningDate.value &&
			partOfDayTo.selectedIndex != 0 && partOfDayFrom.selectedIndex != 0 &&
			partOfDayTo.selectedIndex < partOfDayFrom.selectedIndex)
		return false;
	else
		return true;
}
/*********************************************
 * FlightSegmentForm Validators Region Start *
 *********************************************/
var ddlLeavingFrom, ddlGoingTo;

function LoadG2ComboDdlFromTo()
{
    var hiddenFields = document.getElementsByTagName("INPUT");
    for (var i=0; i<hiddenFields.length; i++)
    {
        if(hiddenFields[i].type != null)
        {
            if (hiddenFields[i].type == "hidden" && hiddenFields[i].id.substring(hiddenFields[i].id.length-22,hiddenFields[i].id.length)=="ddlLeavingFrom_TBValue")
                ddlLeavingFrom = hiddenFields[i];
            if (hiddenFields[i].type == "hidden" && hiddenFields[i].id.substring(hiddenFields[i].id.length-18,hiddenFields[i].id.length)=="ddlGoingTo_TBValue")
                ddlGoingTo = hiddenFields[i];            
        }
    }
}
//following 4 are used in the MultiSelection Logic, to avoid validation failure
//unless all segments are filled. (case 9009). shayd.
var MultiSelectionDestinations = 0;
var MultiSelectionDestinationsCounter = 0;
var MultiSelectionValidDestinations = 0;
var MultiSelectionView = null;

//returns true and fills variables if in multiselection mode, else false. run-once type.
function IsMultiSelection()
{
	if(MultiSelectionDestinations==undefined)
		MultiSelectionDestinations=0;
	if (MultiSelectionView == null)
	{
		var multi = GetElementByProgId();
		if (multi == undefined || multi == null)
		{
			MultiSelectionView = false;
		}
		else
		{
			MultiSelectionDestinations = multi.rows.length;
			MultiSelectionView = true;
		}
	}
	return MultiSelectionView;
}

//returns the G2DataList-generated "DataListMultiSelection" Table if in
//multiselection mode, else returns null.
function GetElementByProgId()
{
	var Tables = document.getElementsByTagName("TABLE");
	for (var i=0; i<Tables.length; i++)
	{
		if (Tables[i].progid == "DataListMultiSelection")
		{
			return Tables[i];
		}
	}
	return null;
}

function customValidatorValidateNotAllRouting_ClientValidate(source, args)
{
    LoadG2ComboDdlFromTo();
    
    var ddlLeavingFrom = $(window.ddlLeavingFromID);
		var ddlGoingTo = $(window.ddlGoingToID);
		if(!ddlLeavingFrom || !ddlGoingTo)
			return true;
    
    if (ddlLeavingFrom.value == "0" || ddlGoingTo.value == "0")
    {
				//if another validation fails, the counter is already at 4, and further validations will
				//fail although in multi-selection mode. this forces it to start validating from 0 each time.
				if(MultiSelectionDestinationsCounter==4)
				{
					MultiSelectionDestinationsCounter = 0;
					MultiSelectionValidDestinations = 0;
				}
				/* if we're in multiselection mode don't fail validation for each segment, some may         *
				 * be null, but if at least 2 are filled we search for the filled segments (server-side)    *
				 * case 9009: allow choosing 2 or more flights in multi-selection, not just max (4). shayd. */
				if(IsMultiSelection() && ( MultiSelectionDestinationsCounter < MultiSelectionDestinations || MultiSelectionValidDestinations >= 2 ))
				{
						MultiSelectionDestinationsCounter++;
						return true;
				}
				else
				{
					  return false;
	      }
	  }
    else
    {
				MultiSelectionDestinationsCounter++;
				MultiSelectionValidDestinations++;
        return true;
    }
}

function customValidatorValidateAllRouting_ClientValidate(source, args)
{
    LoadG2ComboDdlFromTo();
    
		var ddlLeavingFrom = $(window.ddlLeavingFromID);
		var ddlGoingTo = $(window.ddlGoingToID);
		if(!ddlLeavingFrom || !ddlGoingTo)
			return true;
		
    if ((ddlLeavingFrom.value != "0" && ddlGoingTo.value == "0") || (ddlLeavingFrom.value == "0" && ddlGoingTo.value != "0"))
        return false;
    else
        return true;
}
/*******************************************
 * FlightSegmentForm Validators Region End *
 *******************************************/
/***************************************************************************
			Synthetic Popup
 **************************************************************************/

G2_DeclareFunctions({
	// SyntheticModalDialogShow
	//	Called by common.js/G2PopupWindow_Open() to show synthetic poups
	SyntheticModalDialogShow : function(url,name,features,h,w,wndargs)
	{
		//Prevent two popups from showing at the same time (on top of each other)	
		if (G2SyntheticPopup.IsPopupShowing())		
			return;
			
		wndargs.h= isNaN(h) ? 0 : h;
		wndargs.w = isNaN(w) ? 0 : w;
		wndargs.src = url;
		wndargs.ifrmId = "IFRM";	
		
		if (G2SyntheticPopup.CanReusePopup())
		{
			document.popup = document._popup;
			document._popup = null;
			document.popup.reInitialize(wndargs);		
		}
		else
		{
			document.popup = new G2SyntheticPopup(wndargs);
			//Register to the top window's unload event to free used resources
			G2_AttachEvent(window,'unload',G2SyntheticPopup.windowUnload);
		}
		document.popup.closeClientFunction = wndargs.closeClientFunction;
		document.popup.setVisibility("hidden");
		document.popup.blurBackground();
		document.popup.setShowWatchdog(50);
		document.popup.hookToExternalEvents();
		
	},
	
	G2_GetOpeningWindow : function(forClosing)
	{
		if (window.document.popup)
			return window;
		if (window.document._popup && !forClosing) //when we look for a document that has a popup, in order to close it, don't count documents with closed popups
			return window;
		return window.parent || window.top;
	},
	
	// Closes the synthetic popup
	//  Called by common.js/G2_ClosePopupWindow() 
	G2_CloseSyntheticPopupWindow : function(      
									openerFunctionScript_functionToCall,										//A function name that will be called
									result,																									//Popup's result
									firePopupClosedOnOpener,																//When true, G2_FirePopupClosed will be called on the top window
									fireCloseScript_functionToCall,													//Unused (for compatibility with G2_ClosePopupWindow)
									fireCloseScript_windowID,																//Closed popup's window ID
									fireCloseScript_forceSilentPopupClosedOnOpener)					//For compatibility with G2_ClosePopupWindow
	{
    var op = G2_GetOpeningWindow(true);
    
    parentDoc = op.document;
    
    //Explicit close function
		if (op.document.popup && !String.IsNullOrEmpty(op.document.popup.closeClientFunction))
		{
			var openerFunction = op[op.document.popup.closeClientFunction];
      if (openerFunction && typeof(openerFunction)=="function")
				openerFunction.call(op,result);
		}
		//Close function from parameter	
		if (!String.IsNullOrEmpty(openerFunctionScript_functionToCall))
    {
			var openerFunction = op[openerFunctionScript_functionToCall];
      if (openerFunction && typeof(openerFunction)=="function")
				openerFunction.call(op,result);
    }			 
    
		if (firePopupClosedOnOpener)
		{
			op.setTimeout(function() //setTimeout is required, because otherwise an error occurs (window is already destroyed)
			{
        op.G2_FirePopupClosed.call(op,fireCloseScript_windowID,result,fireCloseScript_forceSilentPopupClosedOnOpener,G2_GetOpeningWindow().document.popup.uniqueID);
        if (parentDoc.body.closeSyntheticPopup)
					parentDoc.body.closeSyntheticPopup();
      },0);
    }
    else
    {
			if (parentDoc.body.closeSyntheticPopup)
				parentDoc.body.closeSyntheticPopup();
    }
		return;    
	}
});


////
//// G2SyntheticPopup class
////
G2SyntheticPopup = function(prms)
{
	this.defaultTitle = "";

	//Create modal container and add iframe
	this.controls = this.CreateModalContainer(prms);
	
	// Create Iframe and add to modal's content cell
	this.createIframe(prms);
	
	//Avoid reInitialize re-setting the src for the first time
	prms.src = prms.ifrmId = null;

	this.reInitialize(prms);
}

G2_DeclareClass(G2SyntheticPopup, "G2SyntheticPopup", null, 
{
	createIframe : function(prms)
	{
		var ifrm = this.controls.ifrm = G2_CreateIFrame();
		ifrm.frameBorder = "0";	
		ifrm.style.height = "20px";
		ifrm.src = prms.src;	
		ifrm.scrolling = ((prms.scroll && prms.scroll=="1") ? "yes" : "no");
		this.controls.content.appendChild(ifrm);
		ifrm.style.width = "100%";
		ifrm.style.height = "100%";
		ifrm.style.backgroundColor = "#ffffff";
		ifrm.style.allowTransparency = false;
		this.defaultTitle = "";
		prms.src = prms.ifrmId = null;
	},

	isCloseButtonShown : function()
	{
		return this.controls.closeBtnCell!=null;
	},

	//
	// Creates a close button
	//
	createCloseButton : function()
	{
		if (this.isCloseButtonShown())
			return; //already shown
			
		var closeBtnCell = document.createElement('TD');
		this.controls.topcellTableRow.appendChild(closeBtnCell);
		closeBtnCell.style.textAlign = this.getTitleDirection();
		closeBtnCell.innerHTML="<a href='#' class='ClosePopupWindow' >X</a>";
		G2_AttachEvent(closeBtnCell,"onclick",G2_ClosePopupWindow);
		this.controls.closeBtnCell = closeBtnCell;
	},

	//
	// Hides the close button
	//
	hideCloseButton : function()
	{
		if (this.isCloseButtonShown())
		{
			var closeBtnCell = this.controls.closeBtnCell;
			this.controls.closeBtnCell = null;
			
			G2_DetachEvent(closeBtnCell,"onclick",G2_ClosePopupWindow);
			closeBtnCell.parentElement.removeChild(closeBtnCell);		
		}
	},

	//
	// Re-initializes the popup for reuse
	//
	reInitialize : function (prms)
	{
		if (prms.src)
			this.controls.ifrm.src = prms.src;
		if (prms.ifrmId)
				this.controls.ifrm.id = prms.ifrmId;
				
		this.visible = false;
		this.controls.ifrm._resized = false;
		this.leftMargin =			prms.leftMargin!=null		? prms.leftMargin		: 30;
		this.rightMargin =		prms.rightMargin!=null	? prms.rightMargin	: 30;
		this.topMargin = 			prms.topMargin!=null		? prms.topMargin		: 30;
		this.bottomMargin = 	prms.bottomMargin!=null ? prms.bottomMargin : 30;
		if (prms.scroll!=null)
			this.showScrollBars = (prms.scroll=="1");
		this.controls.ifrm.setAttribute("scrolling",(this.showScrollBars ? "yes" : "no"));
		this.fixedHeight =		(prms.h && prms.h!=0) ? prms.h : 0;
		this.fixedWidth =			(prms.w && prms.w!=0) ? prms.w : 0;			
		this.minW = (prms.minW && prms.minW!=0) ? prms.minW : 100;
		this.minH = (prms.minH && prms.minH!=0) ? prms.minH : 0;
		this.uniqueID = prms.uniqueID;
		this.horzMargin = prms.horzMargin;
		this.vertMargin = prms.vertMargin;
		this.backgroundBlurred = false;	
		this.fadeSteps = prms.fade ? 20 : 1;
		this.setTitle(prms.title || this.defaultTitle);
		this.coverAllWindow(document);
		
		// Add Close button if needed
		if (prms.closeBtn)
			this.createCloseButton();
		else 
			this.hideCloseButton();
	},

	//
	// Sets the popup's visibility
	//
	setVisibility : function(viz)
	{
		if(viz=="hidden")
		{
		  if (isIE)
			  this.controls.coverIframe.style.zIndex = -101;
			this.controls.contentTbl.style.zIndex = -102;
		}
		else
		{
		  if (isIE)
			  this.controls.coverIframe.style.zIndex = "";//101;
			this.controls.contentTbl.style.zIndex = "";//102;
		}
	},

	// 
	// Attaches the popup to the DOM and displays it
	//
	show : function()
	{
		//If already visible
		if (this.visible)
			return;
		this.clearShowWatchdog();
		this.visible = true;
		this.blurBackground();
		if (isIE) //Required only for IE to fix window z-index bugs
		{
		  document.body.appendChild(this.controls.coverIframe);
		  this.controls.coverIframe.style.display = "block";
  	} 
		document.body.appendChild(this.controls.contentTbl);
		this.controls.contentTbl.style.display = "block";
		
	},

	//
	// Detaches the popup from the DOM. Sets the Iframe content to about:blank
	//
	hide : function()
	{
		if (!this.visible)
			return;
		this.visible = false;
		this.clearShowWatchdog();
		this.controls.ifrm.src="about:blank";
		this.controls.ifrm.id="";	
		//Removes the covering DIV element that blurs the window
		if (this.controls.coverDiv.parentElement!=null)
			document.body.removeChild(this.controls.coverDiv);
		G2DOM.G2EnableSelects();
		//Remove popup's components from the DOM
		document.body.removeChild(this.controls.contentTbl);
		if (isIE) //Required only for IE to fix window z-index bugs
		  document.body.removeChild(this.controls.coverIframe);
	},

	//
	// Sets the popup's title
	//
	setTitle : function(newTitle)
	{
		this.controls.title.innerText = newTitle;
	},

	//
	// Attaches the cover DIV to the DOM so it will cover the opening document
	//
	blurBackground : function()
	{
		if (this.backgroundBlurred)
			return;
		this.backgroundBlurred = true;
		document.body.appendChild(this.controls.coverDiv);
		G2DOM.G2DisableSelects();
		this.controls.coverDiv.style.display = "block";
	},

	//
	// Makes sure the window is covered and blurred
	//
	coverAllWindow : function(doc)
	{
			//doc is specified because the popup may not be attached yet to a document (just a document fragment)
			var parentDoc = doc || this.controls.coverDiv.document.parent || document;
			docHeight = Math.max (parentDoc.documentElement.offsetHeight, parentDoc.documentElement.scrollHeight);
			docWidth = Math.max ( parentDoc.documentElement.offsetWidth,  parentDoc.documentElement.scrollWidth );
			this.controls.coverDiv.style.height = docHeight+"px";			
			this.controls.coverDiv.style.pixelWidth = docWidth;
			this.controls.coverDiv.style.width = docWidth+"px"; //Don't change to pixelWidth
	},
	
	////
	//// Dynamic creation of the popup
	////
	getTitleDirection : function()
	{
		return (document.body.dir == "rtl") ? titleDirection = "left" : "right";
	},
	
	//
	// Creates the popup and returns it components
	//
	CreateModalContainer : function(prms)
	{
			//	Popup title closing 'X' should be aligned to the side depending on the alignment of page
			var titleDiretion;
			
				
			var h=parseInt(prms.h),w=parseInt(prms.w),title=prms.title;
			var showCloseBtn = prms.closeBtn==true;
			var ret = {};
			var coverDiv = document.createElement('DIV');
			coverDiv.className = "MessageBoxContainer";
			coverDiv.style.left = "0px";
			coverDiv.style.top = "0px";
			docHeight = Math.max (window.document.documentElement.offsetHeight,document.documentElement.scrollHeight);
			docWidth = Math.max ( window.document.documentElement.offsetWidth, document.documentElement.scrollWidth);
			coverDiv.style.height = docHeight+"px";
			coverDiv.style.width = "100%"; //docWidth+"px";
			//coverDiv.style.zIndex="100";
			coverDiv.style.position="absolute";
			ret.coverDiv = coverDiv;

			var marginHeight = (docHeight - h) / 2;
			var marginWidth = (docWidth - w) / 2;
			
			//For overcoming comboboxes from the opening page hiding the title area (IE only)
			if (isIE)
			{
			  var coverIframe = G2_CreateIFrame(0, false);
			  ret.coverIframe = coverIframe;
			}
			var contentTbl = document.createElement('TABLE');
			contentTbl.cellSpacing = "0";
			contentTbl.cellPadding = "0";
			var topRow = contentTbl.insertRow(-1);
			var topCell = topRow.insertCell(-1);
			var mainRow = contentTbl.insertRow(-1);
			var mainCell = mainRow.insertCell(-1);
			topRow.className = "SerInfo_Header";
			topCell.className = "SerInfo_Title";
			
			//topCell.innerHTML="<table cellspacing='0' cellpadding='0' border='0' style='width:100%'></table>";
			var topCellTable = document.createElement('TABLE');
			topCell.appendChild(topCellTable);
			topCellTable.cellspacing = 0;
			topCellTable.cellpadding = 0;
			topCellTable.border = "0px";
			topCellTable.style.width='100%';
			var topcellTableRow = topCellTable.insertRow(-1);
			var titleCell = topcellTableRow.insertCell(-1);		
			titleCell.innerText="";
			ret.title = titleCell;
			ret.topcellTableRow = topcellTableRow;

			contentTbl.className = "SerInfo_Table";		
			contentTbl.style.display="none";				
			contentTbl.style.left = marginWidth+"px";
			contentTbl.style.top = (GetScrollTop()+marginHeight)+"px";
			contentTbl.style.width=w+"px";
			contentTbl.style.height=h+"px";
			contentTbl.style.zIndex=102;
			contentTbl.style.position="absolute";
			
			if (isIE)
			{
			  coverIframe.style.display = "none"; //will be shown afterwards
			  coverIframe.style.left = marginWidth+"px";
			  coverIframe.style.top = (GetScrollTop()+marginHeight)+"px";
			  coverIframe.style.width = (contentTbl.style.pixelWidth+2)+"px";
			  coverIframe.style.height = (contentTbl.style.pixelHeight+2)+"px";
			  //coverIframe.style.zIndex = 101;
			  coverIframe.style.position="absolute";		
			}
			
			ret.contentTbl = contentTbl;
			ret.content = mainCell;
					
			return ret;
	},
	
	////
	//// Autosize logic  
	////
	//
	// If there are scheduled calls to watchdogTimeout, this will cancel them
	//
	clearShowWatchdog : function()
	{
		if (this.showWatchdog)
		{
				window.clearTimeout(this.showWatchdog);
				this.showWatchdog = 0;
		}
	},
	
	//
	// Schedules a call to watchdogTimeout, with the specified timeout
	//
	setShowWatchdog : function(timeout)
	{
		//Ensure no other timeouts are set
		this.clearShowWatchdog();		
		this.showWatchdog = window.setTimeout(this.watchdogTimeout,timeout);
	},
	
	//
	// During the autosize loop, this is called once in a while to check if the document finished loading itself
	// If it fails, it calls setShowWatchdog
	//
	watchdogTimeout : function()
	{
		var me = document.popup;
		if (!me)
			return;

		autoSized = false;
		try
		{
			autoSized = me.autoSize.call(me);
		}
		catch(e)
		{	
			Debug.writeln(e.message);		
		}
			me.setShowWatchdog(300); //keep re-scheduling
	},
	
	collectMetrics : function()
	{
		var returnValue = 
		{
			clientWidth : document.documentElement.clientWidth,
			clientHeight : document.documentElement.clientHeight,
			fixedSize : true
		}
	
		returnValue.Hmargin =  returnValue.clientWidth*this.horzMargin/100;
		returnValue.Vmargin = returnValue.clientHeight*this.vertMargin/100;
		
		returnValue.maxH = returnValue.clientHeight -(2 * returnValue.Vmargin);
		returnValue.maxW = returnValue.clientWidth  -(2 * returnValue.Hmargin);
		
		if (this.fixedHeight)
		{
			returnValue.fixedHeight = returnValue.minH = this.fixedHeight;
			returnValue.maxH = Math.min(returnValue.fixedHeight,returnValue.maxH);
		}	
		else
		{
			returnValue.minH = this.minH;			
			returnValue.fixedSize = false;
		}
		
		if (this.fixedWidth)
		{
			returnValue.fixedWidth = returnValue.minW = this.fixedWidth;
			returnValue.maxW = Math.min(returnValue.fixedWidth,returnValue.maxW);
		}	
		else
		{
			returnValue.minW = this.minW;
			returnValue.fixedSize = false;
		}
		
		for(var i in returnValue)
		{
			if (typeof(returnValue[i])=="number")
				returnValue[i] = Math.round(returnValue[i]);
		}
		return returnValue;
	},
	
	//
	// Autosizes the popup to fit its content.
	// If a fixed size was specified,
	//
	autoSize : function()
	{
		//Make sure the popup is attached to the DOM
		if (!this.visible)
			this.show();
		var metrics = this.collectMetrics();
			
		var retTop=0, innerDocument = this.controls.ifrm.Document;;
		if(innerDocument!=null && innerDocument.documentElement!=null)
			retTop = innerDocument.documentElement.scrollTop;
		var contentSize;
		if (metrics.fixedSize)
		{
			metrics.contentSize = {w: metrics.fixedWidth, h: metrics.fixedHeight };
		}			
		else
		{
			//Prepare data for autosize
			metrics.contentSize = G2SyntheticPopup.autoSizeIframe(this.controls.ifrm,metrics.minW,metrics.minH,metrics.maxW,metrics.maxH);
		}
		//Check if autosized failed
		if (metrics.contentSize.w > 0 && metrics.contentSize.h > 0)
		{
			this.afterResize(metrics);
			if(innerDocument!=null && innerDocument.documentElement!=null)
			{
				innerDocument.documentElement.scrollTop = retTop;
			}	
			return true;
		}
		else
		{
			if (metrics.contentSize.sameSize)	//Iframe is already in the required size, just make sure it's shown
			{
				this.setVisibility(true);
			}
			return false;
		}	
	},
	//Re-adjusts the container (header etc.) after the iframe has been resized
	afterResize : function(metrics)
	{		
		//
		try
		{
			if (this.controls.ifrm.Document!=null && this.controls.ifrm.Document.title!=null && this.controls.title.innerText==this.defaultTitle)
			{
				this.setTitle(this.controls.ifrm.Document.title);
			}
		}
		catch(err)
		{
		}	
		
		//
		// Position popup at the center of the parent window
		//
		var x = Math.max(0.5*(metrics.clientWidth-metrics.contentSize.w),metrics.Hmargin);
		var y = Math.max(0.5*(metrics.clientHeight-metrics.contentSize.h),metrics.Vmargin);
		var popupW = metrics.clientWidth - 2*x;
		var popupH = metrics.clientHeight - 2*y;
		
		this.controls.contentTbl.style.left = x+"px";
		this.controls.contentTbl.style.top = (y + GetScrollTop())+"px";
		if (isIE)
		{
		  this.controls.coverIframe.style.left = this.controls.contentTbl.style.left;
		  this.controls.coverIframe.style.top = this.controls.contentTbl.style.top;
		}
		this.controls.contentTbl.style.width = (popupW+(isMoz?2:0))+"px";
		this.controls.contentTbl.style.height = (popupH+20+(isMoz?6:0))+"px";
		if (isIE)
		{
		  this.controls.coverIframe.style.width = (popupW+2)+"px";
		  this.controls.coverIframe.style.height = (popupH+20)+"px";
		}
		this.controls.content.firstChild.style.width = popupW+"px";
		this.controls.content.firstChild.style.height = popupH+"px";
		
		if (isMoz)
		{
			this.controls.content.style.width = popupW+"px";
			this.controls.content.style.height = popupH+"px";
		}
		this.setVisibility("visible");
		return true;
	},
	hookToExternalEvents : function()
	{
		G2_AttachEvent(G2_GetOpeningWindow(),'onresize', G2SyntheticPopup.windowResizeHandler);
		document.body.hideSyntheticPopup = G2SyntheticPopup.bodyHideSyntheticPopup;
		document.body.closeSyntheticPopup = G2SyntheticPopup.closeSyntheticPopup;	
	},
	unhookFromExternalEvents : function()
	{
		G2_DetachEvent(G2_GetOpeningWindow(),'onresize', G2SyntheticPopup.windowResizeHandler);
		document.body.hideSyntheticPopup = null;
		document.body.closeSyntheticPopup = null;
	}
}
);

//// 
//// STATIC METHODS
////

//
// Checks if a popup window is already opened
//
G2SyntheticPopup.IsPopupShowing = function()
{
	return document.popup!=null;
}

//
// Checks if a popup was previously open and it can now be resued
//
G2SyntheticPopup.CanReusePopup = function()
{
	return document._popup!=null;
}

G2SyntheticPopup.EnsureInRange = function(val,min,max)
{
	if (min)
		val = Math.max(val, min);
	if (max)
		val = Math.min(val, max);
	return val;
}

// Adjusts the IFrame to fit its contents. Also takes into considerations
// Min & Max size limitations.
// Returned value is the new iframe size as a JSON object with fields h & w.
// If an error is encounterd, h and w will be 0.
G2SyntheticPopup.autoSizeIframe = function(ifrm, minWidth, minHeight, maxWidth, maxHeight )
{
	if (typeof(ifrm)=='string')
		ifrm = document.getElementById(ifrm);	

	var innerDocument = ifrm.Document;				
	var retWidth=0, retHeight=0, resized = false;
	
	if (!ifrm._resized)
	{
		ifrm.style.width = "10px";
		ifrm.style.height = "10px";
	}
	if (innerDocument==null || innerDocument.documentElement==null || innerDocument.documentElement.scrollWidth==0 || innerDocument.documentElement.scrollHeight==0)
	{	return {h: 0, w: 0};	}
	
	try
	{		
			var w = innerDocument.documentElement.filters; //Fixed IE7 layout bug (doesn't happen in IE6).
	
			retWidth = innerDocument.documentElement.scrollWidth;
			if (retWidth < 20) {	return {h: 0, w: 0};	}
			retWidth = G2SyntheticPopup.EnsureInRange(retWidth,minWidth,maxWidth);
			if (isMoz && ifrm.scrolling=="yes")
			  retWidth += 17; //Scrollbars
			if (ifrm.style.pixelWidth != retWidth)
			{						
				ifrm.style.width = retWidth+"px";	
				resized = true;
			}
			
			
			
			var reqHeight = retHeight = innerDocument.documentElement.scrollHeight;
			if (retHeight < 10) {	return {h: 0, w: 0};	}
			retHeight = G2SyntheticPopup.EnsureInRange(retHeight,minHeight,maxHeight);			
			if (isMoz && ifrm.scrolling=="yes")
			  retHeight += 17; //Scrollbars
			if (ifrm.style.pixelHeight != retHeight)
			{
				ifrm.style.height = retHeight+"px";	
				resized = true;
			}
			
			if (reqHeight > retHeight)
			{				
				if (IE7)
				{
					//Then we'll have vertical scrollbars. but in that case, the horizontal will be added too
					//Repeat the width calculations again
					var scrollbarWidth = innerDocument.documentElement.scrollWidth-innerDocument.documentElement.clientWidth;
					retWidth = retWidth+scrollbarWidth;
				} 
				retWidth = G2SyntheticPopup.EnsureInRange(retWidth,minWidth,maxWidth);
				if (ifrm.style.pixelWidth != retWidth)
				{			
					ifrm.style.width = retWidth+"px";	
					resized = true;
				}				
			}
			if (!resized) {	return {h: 0, w: 0, sameSize:true};	}			
			ifrm._resized=true;
			if (innerDocument.popup!=null) innerDocument.popup.coverAllWindow();
		
	}
	catch(e)
	{
	}		
	return {h: retHeight, w: retWidth};
}

////
//// External event handlers
////

//
// Called from the top window whenever it is resized
//
G2SyntheticPopup.windowResizeHandler = function()
{
	var doc = G2_GetOpeningWindow().document;
	if (doc==null || doc.popup==null)
		return;
		
	doc.popup.coverAllWindow();
}

//
// Sets the popup's visibility to hidden
//
G2SyntheticPopup.bodyHideSyntheticPopup = function()
{
	var doc = G2_GetOpeningWindow().document;
	if (doc==null || doc.popup==null)
		return;
	doc.popup.setVisibility("hidden");
}

//
// Closes the page's synthetic popup
//
G2SyntheticPopup.closeSyntheticPopup = function()
{
	var doc = G2_GetOpeningWindow().document;
	if (doc==null || doc.popup==null)
		return;
		
	//The try...catch was added due to a javaScript 'Permission denied' error due to Cross-site scripting (case 9273)
	//This happens when we try to open a popup that redirects to a different site for payment ( such as RomCard interface )
	try
	{
		//Fix for windows that are posting back and closing themselves at the same time
		//This is handled at __doPostBack
		if (doc.popup.controls.ifrm.Document!=null)
			doc.popup.controls.ifrm.Document.isPostingFromAClosedPopup = true;
	}
	catch(err){}
	
	var docpopup = doc._popup = doc.popup;	
	G2_GetOpeningWindow().setTimeout(G2SyntheticPopup.hideSyntheticPopup,0);
	doc.popup.setVisibility("hidden");
	doc.popup.unhookFromExternalEvents();
	doc.popup.controls.ifrm.src="about:blank";
	doc.popup = null;
}

// 
// Hides the popup window. (Attached to the top document)
//
G2SyntheticPopup.hideSyntheticPopup = function()
{
	var doc = G2_GetOpeningWindow().document;
	if (doc==null || doc._popup==null)
		return;
	var docpopup = doc._popup;
	docpopup.hide();
}

//
// Top window's unload handler. Frees used resources.
//
G2SyntheticPopup.windowUnload = function()
{	
	var doc = G2_GetOpeningWindow().document;
	if (doc==null)
		return;
	if (doc._popup)
	{
		doc._popup.controls = null;
		doc._popup==null;
	}
	if (doc.popup)
	{
		doc.popup.controls = null;
		doc.popup==null;
	}
}

// JScript File

//this function handls the manipulation of cell visibility by a dropdown
//on the tables header
//trID - the ID of the current row of cells
//sortByID - the ID of the input hidden tag that holds the sorted by string
//tableID - the ID of the table
//selectedIndex - the sort by string
//selectedIndex - the selected index in the ddl
//Displays = an array of 'progid's of thr relevant cells
//markup example in AccountTransactions.ascx
function modifyDisplay(trID, sortByID, tableID, selectedText, selectedIndex, Displays)
{
	var repTable = document.getElementById(tableID);
	var child = repTable.rows[1];
	
	if(document.getElementById(sortByID) != null)
		document.getElementById(sortByID).value = selectedText;
		
	while(child != null)
	{
		if( child.id.indexOf(trID) != -1)//change all lines but the sub totals lines
	  {
			//loop over the columns for each dropdown item
			for(i=0;i<Displays.length ; i++)
			{
				
				var displayCell = G2DOM.GetChildByProgid(child, Displays[i]);
				if(displayCell != null)
				{
					if(i == selectedIndex)
						displayCell.style.display = "";
					else
						displayCell.style.display = "none";
				}
			}			
		}
		child = child.nextSibling;
	}
}


// TableSorter is a generic object that can sort table rows at the client side
// The sorted rows need to have a similar structure. 
// The TableSorter provides additional features such as header rows that will not be sorted, reverse sorting, and caching
// 
// the TableSorter can sort the table by multiple keys, that are embedded in the markup as attributes.
// The sort key format is     [sortKeyName]="<value type, string is default>[:<element property. default is innerText>]"
//     e.g   byName="true" means that the table will be sorted by the innerText of the element that had the attribute
//           byDate="date" means that the table will be sorted by the innerText of the element, according to is date value
//
// Available key types are string, currency, number and date.
// * When a table row has sortwith="PreviousRow", that row will join to the previous row group (by default, each row is in a singleton).

// for use in the method 'dateFromString' when converting month name to its number
var ascendingMode = false;

var months = [];
months['jan'] = '01';
months['feb'] = '02';
months['mar'] = '03';
months['apr'] = '04';
months['may'] = '05';
months['jun'] = '06';
months['jul'] = '07';
months['aug'] = '08';
months['sep'] = '09';
months['oct'] = '10';
months['nov'] = '11';
months['dec'] = '12';

G2_DeclareFunctions(
{
	
	// Set the sign on the header of the sorted row
	SetCollSign : function(imgId, tableId)
	{
		
		var imgElement = $(imgId);
		var table = $(tableId);
		
		if (!imgElement || !table)
			return;
			
		// in the spacial case of supplier reconciliation the header of the repeater has a different structure
		if (table.suppliermode)
		{
			table = G2_FindElementByTagName(table.firstChild, "TABLE"); // get the table with the template header cells
			
			if (!table) // validation
				return;
		}

		// go over all imgs and do visible=flase
		var firstRow = G2DOM.GetRowByIndex(table, 0);
		var cell = firstRow.firstChild;
		while(cell)
		{

			var img = G2_FindElementByTagName(cell, "IMG");

			if (img != null && img.className != 'G2ComboBox_Widget')
			{
				if (String.EndsWith(img.id, 'imgBottomTopRight') || String.EndsWith(img.id, 'imgBottomTopLeft') ||
				String.EndsWith(img.id, 'imgUserNameHelp'))
				{
					cell = cell.nextSibling;
					continue;
				}	
				if (img.id == imgId)
				{
					if (img.style["display"] == "inline")
					{
						if(ascendingMode)
							ascendingMode = false;
						else
							ascendingMode = true;
					}
					else
					{
						img.style["display"] = "inline";
						ascendingMode = false;
					}
				}
				else
				{
					img.style["display"] = "none";
				}
			}
			cell = cell.nextSibling;
		}
	
		var theme = G2_PageTheme();
		
		var rootAppPath = document.getElementById("G2_RootAppPath").value;
			
		if (ascendingMode)
			imgElement.src = rootAppPath + "/App_Themes/" + theme + "/Images/AdministrationTools/tables/Arrow_Down.gif";
		else
			imgElement.src = rootAppPath + "/App_Themes/" + theme + "/Images/AdministrationTools/tables/Arrow_Up.gif";
	},
	
	SetInitCollSign : function(imgId)
	{
		// set sorting symbol on loading
		var imgElement = $(imgId);
		
		imgElement.style["display"] = "block";
		imgElement.src = "../App_Themes/Grey/Images/AdministrationTools/tables/Arrow_Up.gif";
	}
});

TableSorter = function(tblId,headerRows,footerRows)
{
	this.tbl = document.getElementById(tblId);	
	this.headerRows = headerRows!=null ? headerRows : 0;
	this.footerRows = footerRows!=null ? footerRows : 0;
	if (this.tbl.sorter)
		this.relations = this.tbl.sorter.relations;
	else
		this.relations = {};
	this.preloadKeys();	
	this.tbl.sorter = this;
}

G2_DeclareClass(TableSorter, "TableSorter", null, 
{
	LTrim : function( value ) 
	{	
		var re = /\s*((\S+\s*)*)/;
		return value.replace(re, "$1");	
	},

	// Removes ending whitespaces
	RTrim : function( value ) 
	{	
		var re = /((\s*\S+)*)\s*/;
		return value.replace(re, "$1");	
	},

	// Removes leading and ending whitespaces
	trim : function( value ) 
	{	
		if (!value || value==null)
			value = this;
		return this.LTrim(this.RTrim(value));	
	},

	// Sorts the table by the key name. The reverse parameter has a default value of false.
	// Sort string is in the format <keyName1> [ASC/DESC],<keyName2> [ASC/DESC] (ASC is the default)
	sort : function(keyNames,reverse)
	{
		var parts,keyRelations=[],keyRelation,keyOrder;
		//Support for more than one 
		if (keyNames.indexOf(',')!=-1)
			keyNames = keyNames.split(',');
			
		if (keyNames instanceof Array)
		{
			for (var i=0;i<keyNames.length;i++)
			{
				parts = this.trim(keyNames[i]).split(' ');
				if (parts.length==1)
				{
					parts.push(reverse ? 'DESC' : 'ASC');
				}	
				keyRelation = this.getKeyRelation(parts[0]);
				keyOrder = parts[1].toUpperCase() == 'ASC';
				keyRelations.push({name:parts[0], keyRelation : keyRelation, keyOrder : keyOrder});
			}
		} else keyRelations.push({name: keyNames, keyRelation : this.getKeyRelation(keyNames), keyOrder : reverse!=true });
		
		this.sortTable(keyRelations);
	},

	// Finds the sort key in the first data row.
	// This method is recursive. if the key is not found in the give node, it searches in its children.
	findKeyHierarchy : function(node,keyName)
	{
		if (keyName in node)
		{
			var keyTypeValue = node[keyName];
			var keyTypeValueParts =keyTypeValue.split(':'); 
			var keyType = keyTypeValueParts[0];
			
			var keyValue = "innerText";
			if (keyTypeValueParts.length>1)
			{
				keyValue = keyTypeValueParts[1];								
			}
			
			// TODO: remove the use of 'firstChild' chain
			if (keyValue == "combo")
				keyValue = "firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.value";
			else if (keyValue == "checkbox")
				keyValue = "firstChild.checked";
			
			switch(keyType.toLowerCase())
			{
				case "number":
					return keyValue+")%parseInt(";
				case "numberallowcancel":
					return keyValue+")%me.numOrCancelFromString("
				case "doctype":
					return keyValue+")%me.fromDocType("	
				case "currency":
					return keyValue+".substr(3))%parseInt(";		
				case "date":
					return keyValue+")%me.dateFromString("		
				default:
					return keyValue+"%";
					break;
			}
		}
			
		//Not found - search in children
		for(var c = node.firstChild,i=0;c;c = c.nextSibling,i++)
		{		
			var t = this.findKeyHierarchy(c,keyName);
			if (t)
				return "childNodes["+i+"]."+t; 
		}
		return null;
	},

	// cover the case we have a column of numbers plus some of the cells are with a string value.
	// an example for this case can be found in ui_net\AdministrationTools\Reports\CashierReport.ascx
	numOrCancelFromString : function (s)
	{
			var result = parseInt(s);
			if (isNaN(result))
				result = -1;
				
			return result;
	},

	// Converts a date to a string that can be sorted lexicographically.
	dateFromString : function(s)
	{
			if (!s || s == " ")
				return "";
			var dateParts = s.split('/');
			if (dateParts.length!=3)
					dateParts = s.split('-');				
			var day = parseInt(dateParts[0].substr(dateParts[0].indexOf('0')+1));
			if (isNaN(day))
			{
				day = parseInt(dateParts[0]);
			}

			var month = parseInt(dateParts[1].substr(dateParts[1].indexOf('0')+1));
			// in case the month is in a form of string such as 'dec' for december.
			if (isNaN(month))
				month = months[dateParts[1].toLowerCase()];

			var year = parseInt(dateParts[2].substr(dateParts[2].indexOf('0')+1));
			if (year<50)
				year += 2000;
			else 
				year += 1900;

			// if the day is smaller then 10 then add a left digit for competability in the comparer values
			var dayStr = day.toString();
			if (day < 10)
				dayStr = "0" + dayStr;

			var str = year.toString() + month.toString() + dayStr;
			return str;
	 },

	 // Converts a document type to a number that can be sorted.
	fromDocType : function(s)
	{
		var dateParts = s.split(' ');
		if (String_StartsWith(s,"R"))
			return parseInt(dateParts[1]);
		else
			return -1;
	},

	// Finds the sort key relation to each data row.
	// This method is cached, so successive calls with the same keyName will be immediately fetched.
	getKeyRelation : function(keyName)
	{
		if (this.relations[keyName])
			return this.relations[keyName];
		if (this.tbl.rows[this.headerRows])
		{
			var keyRelation = this.findKeyHierarchy(this.tbl.rows[this.headerRows],keyName);
			if (!keyRelation)
				return null;
			var keyRelationParts = keyRelation.split("%"); 
			this.relations[keyName] = keyRelationParts[1]+keyRelationParts[0];	
			return this.relations[keyName];
		}
		return "";
	},
	
	preloadKeys : function()
	{	
		var t = this.tbl.sortKeys;
		if (!t)
			return;
		t = t.split(',');
		for (var i=0;i<t.length;i++)
		{
			this.getKeyRelation(this.trim(t[i]));
		}
	},

	// Internal.
	// Sorts the table according to the key relation and a boolean value (default:false) for reversing the order
	sortTable : function(sortData)
	{
		
		//Retrieves sort key #i for row r
		var getRowKey = function(r,i)
		{
			if (r.rowKeys == null)
				r.rowKeys = {};
			var rel = sortData[i];	
			var relationName = rel.name;
			if (r.rowKeys[relationName])
			{
				try
				{
					// try to convert to lower so the sorting will not be case sensitive
					return r.rowKeys[relationName].toLowerCase();
				}
				catch(exception)
				{
					return r.rowKeys[relationName];
				}
			}
			var keyRelation = rel.keyRelation;				
			with(r)
			{
				try
				{
					// try to convert to lower so the sorting will not be case sensitive
					return rowKeys[relationName] = eval(keyRelation).toLowerCase();
				}
				catch(exception)
				{
					return rowKeys[relationName] = eval(keyRelation);
				}				
			}
		}		
		
		//compares two rows, according to the sort order
		var comparer = function(a,b)
		{
			a = a[0]; //get the first row of the row group
			b = b[0]; //same 
			
			var key1,key2,sortPart;
			for (var i=0,j=sortData.length;i<j;i++)
			{	
				key1 = getRowKey(a,i);
				key2 = getRowKey(b,i);

				if (key1==key2)
				{
					if (i==j-1)
						return 0;
					else
						continue;
				}	
				else 			
				{
					if (sortData[i].keyOrder)
						return (key1>key2) ? 1 : -1;
					else
						return (key1<key2) ? 1 : -1;
				}	
			}
		}

		var allRowGroups = [];
		var rowsNum = this.tbl.rows.length;
		var row = G2DOM.GetRowByIndex(this.tbl, 0); // get first row
		var i = 0;
		while (row) //for (var i=0,j=rowsNum;i<j;i++)
		{
			if (i < this.headerRows || i > (rowsNum - this.footerRows - 1))
			{
			}
			else
			{
				//var row = this.tbl.rows[i];
				if (row.sortwith=="PreviousRow")
				{
					var lastRowGroup = allRowGroups.pop();
					lastRowGroup.push(row);
					allRowGroups.push(lastRowGroup);
				}
				else
					allRowGroups.push([row]);	//push the row as a singleton
			}
			i++;
			row = row.nextSibling;
		}
		if (allRowGroups.length==0)
			return;
			
		var me = this;
		allRowGroups.sort(comparer);	
		var originalBody = allRowGroups[0][0].parentElement; //TBody

		var rowOffset = this.headerRows;
		for (var i=0,j=allRowGroups.length;i<j;i++)
		{	
			var rowGroup = allRowGroups[i];
			for (var i1=0,j1=rowGroup.length;i1<j1;i1++)
			{
				originalBody.moveRow(rowGroup[i1].rowIndex,rowOffset);
				rowOffset++;				
			}
		}	
	}	

});


sortTable = function(tblId,sortKey,reverse,headerRows,footerRows)
{
	var table = $(tblId);
	if (!table)
		alert('Table was not found');
	if (table.sorter==null)
		table.sorter = new TableSorter(tblId,parseInt(eval(headerRows) || eval(table.headerRows) || 1),parseInt(eval(footerRows) || eval(table.footerRows) || 0));	
	else
	{
		table.sorter.headerRows = eval(headerRows) || eval(table.headerRows) || 1;
		table.sorter.footerRows = eval(footerRows) || eval(table.footerRows) || 0;
	}
		
	table.sorter.sort(sortKey,reverse);
}
