﻿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)
                return; 
            else 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)
                adr = elem.getAttribute("adr");
            if(adr != null)
                break;
            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;
    },
    
	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>
	    if(this._selectedItems != null && this._selectedItems.length > 0)
	    {
	        for(var i in this._selectedItems)
            {
                var item = this._selectedItems[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)
	    {
                this._control._hoverItem(item, val);
                itemFlags.setHovered(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*********************************/

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();