﻿Type.registerNamespace("Infragistics.Web.UI");

/****************************************** Behavior **********************************************/
$IG.Behavior = function(element)
{
	/// <summary>Base class for behavior.</summary>
	/// <param name="element" type="Object" mayBeNull="false">Reference to html element.</param>
	$IG.Behavior.initializeBase(this, [element]);
	this._props = [];
}

$IG.Behavior.prototype =
{
	initialize: function()
	{
		/// <summary>Initializes instance of Behavior.</summary>
		$IG.Behavior.callBaseMethod(this, 'initialize');
		if (this._addHandlers)
			this._addHandlers();
	},

	get_owner: function()
	{
		/// <summary>Gets owner object of this behavior.</summary>
		/// <returns type="Object" mayBeNull="true">Reference to owner.</returns>
		return this._owner;
	},
	set_owner: function(value)
	{
		/// <summary>Sets owner object for this behavior. Internal use only.</summary>
		/// <param name="value" type="Object">Reference to owner.</param>
		this._owner = value;
	},

	dispose: function()
	{
		/// <summary>Disposes object and event handlers.</summary>
		ig_ui_timer(this, true);
		var elem = this.get_element();
		if (elem)
			$clearHandlers(elem);
		$IG.Behavior.callBaseMethod(this, 'dispose');
	},

	/* main control where behavior belongs to (not a member object like Header in WebDialogWindow, but WebDialogWindow) */
	get_control: function()
	{
		/// <summary>Gets owner control of this behavior.</summary>
		/// <returns type="Object" mayBeNull="true">Reference to control.</returns>
		return this._control;
	},
	set_control: function(value)
	{
		/// <summary>Sets owner control for this behavior. Internal use only.</summary>
		/// <param name="value" type="Object">Reference to control.</param>
		this._control = value;
	},

	/* prefix for some event dependant on control-owner (like ResizerMouseOver, HeaderMouseDown) */
	_prefix: '',

	/* VS all below came from igExtenderBase.js */
	getTargetElement: function()
	{
		/// <summary>Gets target html element of this behavior.</summary>
		/// <returns type="Object" mayBeNull="true">Reference to html element.</returns>
		var e = this._targetElem;
		if (!e)
			e = this._targetElem = this.get_element();
		return e;
	},
	get_targetHtmlElementID: function()
	{
		/// <summary>Gets id of target html element of this behavior.</summary>
		/// <returns type="String" mayBeNull="true">Id of html element.</returns>
		return this._elemID;
	},
	set_targetHtmlElementID: function(val)
	{
		/// <summary>Sets id of target html element.</summary>
		/// <param name="val" type="String">Id of element.</param>
		if (this._elemID)
			return;
		this._elemID = val;
		this._targetElem = document.getElementById(val);
	},
	get_stateID: function()
	{
		/// <summary>Gets id of html element used to persist state to server. Internal use only.</summary>
		/// <returns type="String" mayBeNull="true">Id of html element.</returns>
		return this._stateID;
	},
	set_stateID: function(val)
	{
		/// <summary>Sets id of html element used to persist state to server. Internal use only.</summary>
		/// <param name="val" type="String">Id of element.</param>
		if (!this._stateID)
			this._stateID = val;
	},
	get_stateValue: function()
	{
		/// <summary>Gets value of persistant state. Internal use only.</summary>
		/// <returns type="String" mayBeNull="true">Value which can be passed to server.</returns>
		return this._stateValue;
	},
	set_stateValue: function(val, save)
	{
		/// <summary>Sets value of persistant state. Internal use only.</summary>
		/// <param name="val" type="String">Value which can be passed to server.</param>
		/// <param name="save" type="Boolean">Request to pass value to server.</param>
		this._stateValue = val;
		if (!this._stateID || !save)
			return;
		var e = document.getElementById(this._stateID);
		if (e)
			e.value = val;
	},
	_get_: function(i)
	{
		return this._props[i];
	},
	_set_: function(i, val, evtName)
	{
		this._props[i] = val;
		if (evtName)
			$util.addClientEvent(this, evtName, val);
	},
	/* 1st param - name of event to fire */
	/* 2nd param - null, or Xxx prefix of XxxEventArgs, or instance of EventArgs */
	/* 3rd param - original event of browser */
	/* additional params to match with order of XxxEventArgs._props array */
	/* return: null or instance of XxxEventArgs */
	/* Examples: this._raiseClientEvent('click', null, e); will raise "click" event and args will be: new Infragistics.Web.UI.CancelEventArgs(); and e will define value returned by _args.get_browserEvent() */
	/* this._raiseClientEvent('resizing', 'Resize', e, null, 1, 2, 3, 4); will raise "resizing" event and args will be: new Infragistics.Web.UI.ResizeEventArgs(); and 1 will define value returned by _args.get_height(), and 2: _args.get_height() */
	_raiseClientEvent: function()
	{
		if (this._control)
			return this._control._raiseClientEvent(arguments);
		var args = arguments[1];
		var fnc = this.get_events().getHandler(arguments[0]); /* arguments[0] - name of event */
		var str = args && args.substring;
		if (!fnc)/* if 2nd param is EvtArgs object, then return that object as it is */
			return str ? null : args;
		if (str)
			eval('try{args = new Infragistics.Web.UI.' + args + 'EventArgs();}catch(ex){args = null;}');
		var i = 1, len = arguments.length;
		if (!args)/* if EventArgs is missing or invalid, then create default args */
			args = (len < 3) ? new Sys.EventArgs() : new $IG.EventArgs();
		/* if it is our EventArgs object, then initialize its properties */
		if (args._props) while (++i < len)
			args._props[i - 2] = arguments[i];
		/* fire event (notify listeners) */
		fnc(this, args);
		if (args._props)/* if it is our EventArgs object, then delete reference to browser event */
			delete args._props[0];
		return args;
	}
}
$IG.Behavior.registerClass('Infragistics.Web.UI.Behavior', Sys.UI.Behavior);
/****************************************** End Behavior OBJECT ***********************************************************/

/****************************************** UI BEHAVIORS OBJECT *************************************/
$IG.UIBehaviorsObject = function(control, collection)
{
	///<summary>
	/// This class is for Internal Use Only.
	/// A behavior that controls Selection, Hovering, Dragging, and Dropping, for a specified ObjectColection.
	///</summary> 
	this._control = control;
	this._collection = collection;
	this._selectedItems = [];
	this._handlers = { "mousedown": this.handleEvent, "mouseover": this.handleEvent, "mouseout": this.handleEvent };
	var flags = control._getFlags();
	var draggable = flags.getDraggable();
	var droppable = flags.getDroppable();
	if ((draggable || droppable) && $IG.DragDropBehavior)
	{
		var ddb = new $IG.DragDropBehavior();
		var events = ddb.get_events();
		if (draggable)
		{
			ddb.addSourceObject(control);
			events.addDragStartHandler(Function.createDelegate(this, this.dragStart));
		}
		if (droppable)
		{
			ddb.addTargetObject(control, true);
			events.addDropHandler(Function.createDelegate(this, this.drop));
			events.addDragCancelHandler(Function.createDelegate(this, this.dragCancel));
			events.addDragMoveHandler(Function.createDelegate(this, this.dragMove));
			events.addDragEnterHandler(Function.createDelegate(this, this.dragEnter));
			events.addDragLeaveHandler(Function.createDelegate(this, this.dragLeave));
		}
		events.addDragEndHandler(Function.createDelegate(this, this.dragEnd));
		this._ddb = ddb;
	}

	$addHandlers(control.get_element(), this._handlers, this);
}

$IG.UIBehaviorsObject.prototype =
{
	handleEvent: function(e)
	{
		///<summary>
		/// Handles all targeted browser events that are being listened to on the control's root element.
		/// It then determines if it should cause a behavior to occur. It it concludes that a behavior should occur, then
		/// it raises the correct functionality. 
		///</summary> 
		var item = this.getItemFromElem(e.target);
		if (item)
		{
			/* SJZ 9/11/07 - If a control is a templated control, then this event can fire for both
			* the parent control, and the child control. So we need to make sure that we're firing
			* the event for the correct control*/
			if (item._owner != this._control) /*5th of january 2010 bug fix 27186 A.B*/
				return;
				
			if (e.type == "mouseover")
				this.hover(item, e);
			else if (e.type == "mouseout")
				this.unhover(item, e);
			else if (e.type == "mousedown")
			{
				this.select(item, e);
		    }
		}
	},

	getItemFromElem: function(elem)
	{
		///<summary>
		/// If there is an item asociated with the element, or a parent of the element, the item is returned.
		/// Otherwise null is returned.
		///</summary>
		var item = null;
		var adr = null;
		while (elem)
		{
			if (elem.getAttribute)
			{
				this.initElemAttr(elem);
				adr = elem.getAttribute("adr");
			}
			if (adr != null)
			    break;

			if(elem.nodeName == "DIV")
			{
			    var controlClass;
			    // all IG controlls have this type of CSS class applied.
			    var regex = new RegExp("ig_\w*Control");
			    if(!$util.isNullOrUndefined(elem.getAttribute))
			    {
			        controlClass = ($util.IsIE7 ? elem.getAttribute("className") : elem.getAttribute("class"));
			    }
			    if(!$util.isNullOrUndefined(controlClass) &&
                   regex.test(controlClass))
			    {
			        /*  L.T. 30-April-2010, 31084
			            Sometimes the control may contain a template of another IG control.
			            When the mouse is over some element of the inner control, we try to
			            find the adr, but we cross the control boundary and go and take adr
			            attribute of the parent control. Which should not happen! */
			        return null;
			    }
			}
			elem = elem.parentNode;
		}
		if (elem != null)
		{
			item = elem._object;
			if (item == null)
			{
				item = this._collection._createObject(adr, elem);
				if (item == null)
					item = elem._object;
			}
		}
		return item;
	},
	
	initElemAttr: function(elem)
	{
		///<summary>
		/// Allows controls using UI behaviors to initialize element attributes if needed, for example when lazy loading of items is implemented.
		///</summary>
	},

	select: function(item, e)
	{
		///<summary>
		/// If an item is selectable and enabled, it adds the item to it's internal selected items list, and
		/// calls the _selectItem method off of the associated control.
		///</summary>
		var itemFlags = item._getFlags();
		var selectable = itemFlags.getSelectable(this._control);
		var enabled = itemFlags.getEnabled(this._control);

		if (selectable && enabled)
		{
			if (this._control._shouldSelect != null && e)
				if (!this._control._shouldSelect(item, e))
					return;
			var old = this._selectedItems[0];
			if (old != item)
			{
				if (old)
				{
					old._getFlags().setSelected(false);
					this._control._selectItem(old, false);
				}
				this._selectedItems[0] = item;
				itemFlags.setSelected(true);
				this._control._selectItem(item, true);
			}
		}
		if (e)
		{
			this._mouseDown = true;
			$util.cancelEvent(e);
		}
	},

	unSelectAll: function()
	{
		///<summary>
		/// Removes the item from the internal selected items list, and 
		/// calls the _selectItem method off of the associated control, with a parameter of false
		///</summary>
		var items = this._selectedItems;
		var i = items ? items.length : 0;
		while (i-- > 0)
		{
			var item = items[i];
			item._getFlags().setSelected(false);
			this._control._selectItem(item, false);
		}
		this._selectedItems = [];
	},

	getSelectedItems: function()
	{
		///<summary>
		/// Returns an array of all selected items.
		///</summary>
		return this._selectedItems;
	},

	hover: function(item, e)
	{
		///<summary>
		/// Calls the associated control's _shouldHover method first. 
		/// If it returns true, or the control doesn't implement _shouldHover, then
		/// the _hoverItem method is called on the control with a parameter of true.
		///</summary>
		if (this._control._shouldHover != null && e)
			if (!this._control._shouldHover(item, e))
				return;
		this._hover(item, true);
	},

	unhover: function(item, e)
	{
		///<summary>
		/// Calls the associated control's _shouldHover method first. 
		/// If it returns true, or the control doesn't implement _shouldHover, then
		/// the _hoverItem method is called on the control with a parameter of false.
		///</summary>
		if (this._control._shouldHover != null && e)
			if (!this._control._shouldHover(item, e))
				return;
		this._hover(item, false);
	},

	setDragDropNotification: function(notify)
	{
		///<summary>
		/// Sets whether or not the control should be notified for each element that is dragged
		/// over in the control, or if it should just be notified the first time the mouse enters the control.
		///</summary>
		this._controlDDNotification = notify;
	},

	dragStart: function(behavior, evntArgs)
	{
		///<summary>
		/// Handles the DragStart event off the DragDropBehavior and passes the 
		/// information to the control, if the control implements the __dragStart method. 
		///</summary> 
		if (this._control.__dragStart)
		{
			var manager = evntArgs.get_manager();
			var elem = manager.get_sourceElement();
			var item = this.getItemFromElem(elem);
			if (item != null)
			{
				manager.set_dataObject(item);
				this._control.__dragStart(this, item, behavior, evntArgs);
			}
			else
				evntArgs.set_cancel(true);
		}
	},

	dragEnter: function(behavior, evntArgs)
	{
		///<summary>
		/// Handles the DragEnter event off the DragDropBehavior and passes the 
		/// information to the control, if the control implements the __dragEnter method. 
		///</summary> 
		this._fireDragDropEvnt(this._control.__dragEnter, behavior, evntArgs, true);
	},

	dragLeave: function(behavior, evntArgs)
	{
		///<summary>
		/// Handles the DragLeave event off the DragDropBehavior and passes the 
		/// information to the control, if the control implements the __dragLeave method. 
		///</summary> 
		this._fireDragDropEvnt(this._control.__dragLeave, behavior, evntArgs, false);
	},

	dragMove: function(behavior, evntArgs)
	{
		///<summary>
		/// Handles the DragMove event off the DragDropBehavior and passes the 
		/// information to the control, if the control implements the __dragMove method. 
		///</summary> 
		this._fireDragDropEvnt(this._control.__dragMove, behavior, evntArgs, false);
	},

	dragCancel: function(behavior, evntArgs)
	{
		///<summary>
		/// Handles the DragCancel event off the DragDropBehavior and passes the 
		/// information to the control, if the control implements the __dragCancel method. 
		///</summary> 
		if (this._control.__dragCancel)
			this._control.__dragCancel(this, behavior, evntArgs);
	},

	dragEnd: function(behavior, evntArgs)
	{
		///<summary>
		/// Handles the DragEnd event off the DragDropBehavior and passes the 
		/// information to the control, if the control implements the __dragEnd method. 
		///</summary>
		this._fireDragDropEvnt(this._control.__dragEnd, behavior, evntArgs, false);
	},

	drop: function(behavior, evntArgs)
	{
		///<summary>
		/// Handles the Drop event off the DragDropBehavior and passes the 
		/// information to the control, if the control implements the __drop method. 
		///</summary>
		this._fireDragDropEvnt(this._control.__drop, behavior, evntArgs, false);
	},

	_fireDragDropEvnt: function(method, behavior, evntArgs, cancelable)
	{
		if (method)
		{
			method = Function.createDelegate(this._control, method);
			var item = this.getItemFromElem(evntArgs.get_manager().get_targetElement());
			if (item != null || (item == null && this._controlDDNotification))
				method(this, item, behavior, evntArgs);
			else if (cancelable)
				evntArgs.set_cancel(true);
		}
	},

	_hover: function(item, val)
	{
		var itemFlags = item._getFlags();
		var hoverable = itemFlags.getHoverable(this._control);
		var enabled = itemFlags.getEnabled(this._control);

		if (hoverable == $IG.DefaultableBoolean.True && enabled == $IG.DefaultableBoolean.True)
		{
			itemFlags.setHovered(val);
			this._control._hoverItem(item, val);
		}
	},

	dispose: function()
	{
		///<summary>
		/// Disposes of any objects created by the behavior.
		///</summary>
		if (this._ddb)
			this._ddb.dispose();
		$clearHandlers(this._control.get_element());
	}


};
$IG.UIBehaviorsObject.registerClass("Infragistics.Web.UI.UIBehaviorsObject");
/******************************************END UI BEHAVIORS OBJECT*********************************/


/****************************************** NotifySizeChangedBehavior **********************************/

$IG.NotifySizeChangedBehavior = function(element, handler, interval, trackZeroDimensions)
{	
	this._handlers = [];
	this._element = element;
	if (interval != null)
		this._interval = interval;
	else
		this._interval = 100;

	this._trackZeroDimensions = trackZeroDimensions;
	if (element != null)
	{
		this._prevOffsetHeight = this._element.offsetHeight;
		this._prevOffsetWidth = this._element.offsetWidth;
	}

	if (handler != null)
		this.addResizeHandler(handler);
}

$IG.NotifySizeChangedBehavior.prototype =
{
	addResizeHandler: function(handler)
	{
		if (handler != null)
		{
			if ($util.IsIE)
			{
				this._onResizeHandler = Function.createDelegate(this, this._onTick);
				$addHandler(this._element, "resize", this._onResizeHandler);
			}
			else if (this._intervalId == null)
				this._intervalId = window.setInterval(Function.createDelegate(this, this._onTick), this._interval);
			this._handlers.push(handler);
		}
	},

	removeResizeHandler: function(handler)
	{
		Array.remove(this._handlers, handler);
		if (this._handlers.length == 0)
		{
			window.clearInterval(this._intervalId);
			this._intervalId = null;
		}
	},

	dispose: function()
	{
		if (this._onResizeHandler)
		{
			$removeHandler(this._element, "resize", this._onResizeHandler);
			this._onResizeHandler = null;
		}
		else if (this._intervalId != null)
			window.clearInterval(this._intervalId);

		this._handlers = null;
		this._element = null;
	},

	_onTick: function()
	{
		var elem = this._element, handlers = this._handlers;
		var i = handlers ? handlers.length : 0;
		if (!elem || i < 1)
			return;
		var height = elem.offsetHeight, width = elem.offsetWidth;
		if ((!height && !width) || (height == 0 && width == 0) || (height == this._prevOffsetHeight && width == this._prevOffsetWidth))
		{
			if (this._trackZeroDimensions && (height == 0 && width == 0))
			{				
				this._prevOffsetHeight = elem.offsetHeight;
				this._prevOffsetWidth = elem.offsetWidth;
			}
			return;
		}
		var e = { oldOffsetHeight: this._prevOffsetHeight, oldOffsetWidth: this._prevOffsetWidth,
			offsetHeight: height, offsetWidth: width,
			clientHeight: elem.clientHeight, clientWidth: elem.clientWidth, element: elem
		};
		while (i-- > 0)
			handlers[i](e);
		this._prevOffsetHeight = elem.offsetHeight;
		this._prevOffsetWidth = elem.offsetWidth;
	}
};
$IG.NotifySizeChangedBehavior.registerClass("Infragistics.Web.UI.NotifySizeChangedBehavior");

/****************************************** END NotifySizeChangedBehavior **********************************/

/****************************************** NotifySizeChangedFromZeroBehavior **********************************/

$IG.NotifySizeChangedFromZeroBehavior = function(element, handler, interval)
{
	this._handlers = [];
	this._element = element;
	if (interval != null)
		this._interval = interval;
	else
		this._interval = 100;

	if (element != null)
	{
		this._prevOffsetHeight = this._element.offsetHeight;
		this._prevOffsetWidth = this._element.offsetWidth;
	}
	
	if (handler != null)
		this.addResizeHandler(handler);
}

$IG.NotifySizeChangedFromZeroBehavior.prototype =
{
	addResizeHandler: function(handler)
	{
		if (handler != null)
		{
			if ($util.IsIE && !$util.IsIEStandards)
			{
				this._onResizeHandler = Function.createDelegate(this, this._onTick);
				$addHandler(this._element, "resize", this._onResizeHandler);
			}
			else if (this._intervalId == null)
				this._intervalId = window.setInterval(Function.createDelegate(this, this._onTick), this._interval);
			this._handlers.push(handler);
		}
	},

	removeResizeHandler: function(handler)
	{
		Array.remove(this._handlers, handler);
		if (this._handlers.length == 0)
		{
			window.clearInterval(this._intervalId);
			this._intervalId = null;
		}
	},

	dispose: function()
	{
		if (this._onResizeHandler)
		{
			$removeHandler(this._element, "resize", this._onResizeHandler);
			this._onResizeHandler = null;
		}
		else if (this._intervalId != null)
			window.clearInterval(this._intervalId);

		this._handlers = null;
		this._element = null;
	},

	_onTick: function()
	{
		var elem = this._element, handlers = this._handlers;
		var i = handlers ? handlers.length : 0;
		if (!elem || i < 1)
			return;
		var height = elem.offsetHeight, width = elem.offsetWidth;
		
		if ((!height && !width) || (height == 0 && width == 0) || (height == this._prevOffsetHeight && width == this._prevOffsetWidth)
			|| (this._prevOffsetWidth != 0 && this._prevOffsetHeight != 0))
		{
			if (height == 0 && width == 0)
			{				
				this._prevOffsetHeight = elem.offsetHeight;
				this._prevOffsetWidth = elem.offsetWidth;
			}
			return;
		}
		var e = { oldOffsetHeight: this._prevOffsetHeight, oldOffsetWidth: this._prevOffsetWidth,
			offsetHeight: height, offsetWidth: width,
			clientHeight: elem.clientHeight, clientWidth: elem.clientWidth, element: elem
		};
		while (i-- > 0)
			handlers[i](e);
		this._prevOffsetHeight = elem.offsetHeight;
		this._prevOffsetWidth = elem.offsetWidth;
	}
};
$IG.NotifySizeChangedFromZeroBehavior.registerClass("Infragistics.Web.UI.NotifySizeChangedFromZeroBehavior");

/****************************************** END NotifySizeChangedFromZeroBehavior **********************************/

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();