/// <reference name="MicrosoftAjax.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/0_igControlMain.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/2_igCollections.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/3_igUIBehaviors.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/4_igEnums.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/5_igObjects.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/7_igClientStateManager.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/8_igCallback.js" />
/// <reference path="../../../../Infragistics.Web.UI/Scripts/9_igPropertyManagers.js" />
/// <reference path="../../../../Infragistics.Web.UI/SharedScripts/igAnimation.js" />
/// <reference path="../../../../Infragistics.Web.UI/SharedScripts/igDragDrop.js" />
/// <reference path="../../../../Infragistics.Web.UI/SharedScripts/igDropDown.js" />
/// <reference path="../../../../Infragistics.Web.UI/SharedScripts/igLayoutPane.js" />
/// <reference path="../../../../Infragistics.Web.UI/SharedScripts/igResizeBehavior.js" />
/// <reference path="igDataMenuItem.js" />
/// <reference path="igWebDataMenu.js" />

Type.registerNamespace('Infragistics.Web.UI');
var $IG = Infragistics.Web.UI;
/*
 * WebDataMenu will be using $IG.Orientation enumeration defined in the main Scripts for aikido,
 * which are all loaded in the RunBot base class.
 */
 
/******************************************DataMenuProps ENUM************************************/
$IG.DataMenuProps = new function()
{
    this.Enabled = [$IG.NavControlProps.Count + 1, 0];
    this.EnableExpandOnClick = [$IG.NavControlProps.Count + 2, 0];
    this.IsContextMenu = [$IG.NavControlProps.Count + 3, false];
    this.Count = $IG.NavControlProps.Count + 4;
};
/******************************************END DataMenuProps ENUM********************************/

/******************************************DataMenuItemProps ENUM************************************/
$IG.DataMenuItemProps = new function()
{
    this.Expanded = [$IG.NavItemProps.Count + 0, 0];
    this.ClientLevel = [$IG.NavItemProps.Count + 1, 0];
    this.HoverCssClass = [$IG.NavItemProps.Count + 2, ''];
    this.IsSeparator = [$IG.NavItemProps.Count + 3, false];
    this.Clicked = [$IG.NavItemProps.Count + 4, 0];
    this.Count = $IG.NavItemProps.Count + 5;
};
/******************************************END DataMenuItemProps ENUM********************************/

/******************************************DataMenuGroupSettingsProps ENUM************************************/
$IG.DataMenuGroupSettingsProps = new function()
{
    this.OffsetX = [$IG.DataMenuItemProps.Count + 0, 0];
    this.OffsetY = [$IG.DataMenuItemProps.Count + 1, 0];
    this.Height = [$IG.DataMenuItemProps.Count + 2, 0];
    this.Width = [$IG.DataMenuItemProps.Count + 3, 0];
    this.Orientation = [$IG.DataMenuItemProps.Count + 4, 0];
    this.ExpandDirection = [$IG.DataMenuItemProps.Count + 5, 0];
    this.EnableAnimation = [$IG.DataMenuItemProps.Count + 6, 0];
    this.AnimationType = [$IG.DataMenuItemProps.Count + 7, 0];
    this.AnimationDuration = [$IG.DataMenuItemProps.Count + 8, 0];
    this.AnimationEquationType = [$IG.DataMenuItemProps.Count + 9, 0];
    this.ItemsFullAddress = [$IG.DataMenuItemProps.Count + 10, 0];
    this.Count = $IG.DataMenuItemProps.Count + 11;
};
/******************************************DataMenuGroupSettingsProps ENUM************************************/
$IG.DataMenuItemSettingsProps = new function()
{
    this.CssClass = [$IG.DataMenuGroupSettingsProps.Count + 0, ""];
    this.DisabledCssClass = [$IG.DataMenuGroupSettingsProps.Count + 1, ""];
    this.HoverCssClass = [$IG.DataMenuGroupSettingsProps.Count + 2, ""];
    this.ImageUrl = [$IG.DataMenuGroupSettingsProps.Count + 3, ""];
    this.Target = [$IG.DataMenuGroupSettingsProps.Count + 4, ""];
    this.NavigateUrl = [$IG.DataMenuGroupSettingsProps.Count + 5, ""];
    this.SelectedCssClass = [$IG.DataMenuGroupSettingsProps.Count + 6, ""];
    this.ImageToolTip = [$IG.DataMenuGroupSettingsProps.Count + 7, ""];
    this.Count = $IG.DataMenuGroupSettingsProps.Count + 8;
};

/****************************************** DataMenuAnimationType ENUM********************************/
$IG.DataMenuAnimationtype = new function()
{
    this.OpacityAnimation = 0;
    this.ExpandAnimation = 1;
}

/****************************************** ExpandDirection ENUM********************************/
$IG.MenuExpandDirection = new function()
{
    this.Auto = 0;
    this.Up = 1;
    this.Down = 2;
    this.Left = 3;
    this.Right = 4;
}

/****************************************** DataMenuItemSettings **************************************/
$IG.DataMenuItemSettings = function(element, props, control)
{
    /// <summary>
    /// A DataMenuItemSettings object that represents the common item settings
    /// </summary>
    var csm = new $IG.ObjectClientStateManager(props[0]);
    $IG.DataMenuItemSettings.initializeBase(this, ["itemSettings", element, props, control, csm]);
    this.initialize();   
}

$IG.DataMenuItemSettings.prototype = 
{
    initialize:function()
	{	    
        ///<summary>
        ///Initializes the DataMenuItemSettings object 
        ///</summary>
		$IG.DataMenuItemSettings.callBaseMethod(this, 'initialize');
	},
	
    get_CssClass: function()
    {
        ///<summary>
        ///Returns/gets the CssClass of the object.
        ///</summary>
        return this._get_value($IG.DataMenuItemSettingsProps.CssClass);
    },
    
    get_DisabledCssClass: function()
    {
        ///<summary>
        ///Returns/gets the CssClass of the object.
        ///</summary>
        return this._get_value($IG.DataMenuItemSettingsProps.DisabledCssClass);
    },
    
    get_HoverCssClass: function()
    {
        ///<summary>
        ///Returns/gets the CssClass of the object.
        ///</summary>
        return this._get_value($IG.DataMenuItemSettingsProps.HoverCssClass);
    },
    
    get_SelectedCssClass: function()
    {
        ///<summary>
        ///Returns/gets the CssClass of the object.
        ///</summary>
        return this._get_value($IG.DataMenuItemSettingsProps.SelectedCssClass);
    },
    
    
    get_ImageUrl: function()
    {
        ///<summary>
        ///Returns/gets the CssClass of the object.
        ///</summary>
        return this._get_value($IG.DataMenuItemSettingsProps.ImageUrl);
    },
    
    get_NavigateUrl: function()
    {
        ///<summary>
        ///Returns/gets the CssClass of the object.
        ///</summary>
        return this._get_value($IG.DataMenuItemSettingsProps.NavigateUrl);
    },
    
    get_Target: function()
    {
        ///<summary>
        ///Returns/gets the CssClass of the object.
        ///</summary>
        return this._get_value($IG.DataMenuItemSettingsProps.Target);
    }
}

$IG.DataMenuItemSettings.registerClass('Infragistics.Web.UI.DataMenuItemSettings', $IG.ObjectBase);
/****************************************** DataMenuGroupSettings **************************************/
$IG.DataMenuGroupSettings = function(element, props, control)
{
    /// <summary>
    /// A DataMenuGroupSettings object that represents the group settings
    /// </summary>
    var csm = new $IG.ObjectClientStateManager(props[0]);
    $IG.DataMenuGroupSettings.initializeBase(this, ["groupSettings", element, props, control, csm]);
    this.initialize();   
}

$IG.DataMenuGroupSettings.prototype =
{
    initialize:function()
	{	    
        ///<summary>
        ///Initializes the DataMenuGroupSettings object 
        ///</summary>
		$IG.DataMenuGroupSettings.callBaseMethod(this, 'initialize');
	},

    get_offsetX: function()
    {
        ///<summary>
        ///Returns/gets the offsetX of the object.
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.OffsetX);
    },
    get_offsetY: function()
    {
        ///<summary>
        ///Returns/gets the offsetX of the object.
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.OffsetY);
    },
    get_height: function()
    {
        ///<summary>
        ///Returns/gets the Height of the object.
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.Height);
    },
    get_width: function()
    {
        ///<summary>
        ///Returns/gets the Width for the object.
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.Width);
    },
    get_orientation: function()
    {
        ///<summary>
        ///Returns/gets the Orientation for the object.
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.Orientation);
    },    
    get_expandDirection: function()
    {
        ///<summary>
        ///Returns/gets the ExpandDirectrion for the object.
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.ExpandDirection);
    },
    
    get_enableAnimation: function()
    {
        ///<summary>
        ///Gets the boolean EnableAnimation property
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.EnableAnimation);
    },
    
    get_animationDuration: function()
    {
        ///<summary>
        ///Gets the int AnimationDuration property 
        ///Represents the desired duration of animation effect in milliseconds
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.AnimationDuration);        
    },
    
    get_animationType: function()
    {
        ///<summary>
        ///Gets the int AnimationType property 
        ///Represents the desired animation effect: Opacity or Expand
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.AnimationType);        
    },
    
    get_animationEquationType: function()
    {
        ///<summary>
        ///Gets the int AnimationEquationType
        ///Default to EaseInOut
        ///</summary>
        return this._get_value($IG.DataMenuGroupSettingsProps.AnimationEquationType);        
    },
    
    get_itemsFullAddress: function()
    {
        return this._get_value($IG.DataMenuGroupSettingsProps.ItemsFullAddress);        
    }
    
}

$IG.DataMenuGroupSettings.registerClass('Infragistics.Web.UI.DataMenuGroupSettings', $IG.ObjectBase);
/******************************************END DataMenuGroupSettings ********************************/
/****************************************** WebDataMenu ********************************/

$IG.WebDataMenu = function(element)
{
	$IG.WebDataMenu.initializeBase(this, [element]);    
}

$IG.WebDataMenu.prototype =
{
	_thisType:'menu',
    __animation:$IG.DataMenuAnimations,
    _menuGroupSettings:$IG.DataMenuGroupSettings,
    _itemSettings:$IG.DataMenuItemSettings,
    _selectedItem:$IG.DataMenuItem,
    _hoveredItem:$IG.DataMenuItem,
    _activeItem:$IG.DataMenuItem,
    _itemsGroupSettings:null,
    _focusElement:null,
    __controlActive:false,
    __form:null,
    __submit:null,
    __defaultContextHandler:null,
    __defaultMouseUpHandler:null,
	initialize:function()
	{	    
		this._visibleItems = new Array();
		this.__currentFocusedItem = null;
        this._selectedItem = null;
        this._activeItem = null;
        this._hoveredItem = null;
		this._itemSettings = new $IG.DataMenuItemSettings(this._element, this._objectsManager.get_objectProps(0), this);
		this._objectsManager.register_object(0, this._itemSettings);	
		this._menuGroupSettings = new $IG.DataMenuGroupSettings(this._element, this._objectsManager.get_objectProps(1), this);
		this._objectsManager.register_object(1, this._menuGroupSettings);		
		var itemsGroupSettingsCount = parseInt(this._get_clientOnlyValue("gsc"));
		
		if(itemsGroupSettingsCount > 0)
		{
		    this._itemsGroupSettings = new Array();
		    for(var i = 0; i < itemsGroupSettingsCount ; i++)
		    {
		        var gc = new $IG.DataMenuGroupSettings(null, this._objectsManager.get_objectProps(i+2), this);
                this._objectsManager.register_object(i+2, gc);
                this._itemsGroupSettings[i] = gc;
                gc = null;
		    }
		}
		
		$IG.WebDataMenu.callBaseMethod(this, 'initialize');		
		
		this._sizer = document.createElement("DIV");
		this._sizer.style.position = 'absolute';
		this._sizer.style.visibility = 'hidden';
		this._sizer.zIndex = 0;
		this._sizer.className = this._element.className;
		
		if(this.get_isContextMenu())
		{
		    var el = this._element;
		    this._element.parentNode.removeChild(el);
		    document.body.appendChild(el);
		}
		
		this.__createFocusEl();
		
        if (this._focusElement != null)
        {
            this._onFocusFn = Function.createDelegate(this, this._onFocusHandler);
            $addHandler(this._focusElement, 'focus', this._onFocusFn);
            this._onBlurFn = Function.createDelegate(this, this._onBlurHandler);
            $addHandler(this._focusElement, 'blur', this._onBlurFn);
        }		
		
        this._onKeydownFn = Function.createDelegate(this, this._onKeydownHandler);
        $addHandler(this.get_element(), 'keydown', this._onKeydownFn);
        
        if(this.getItems().getItem(0) != null && typeof(this.getItems().getItem(0)) != undefined)
        {
            if(this._menuGroupSettings.get_orientation() == $IG.Orientation.Vertical)
                this._resizeSeparators(this.getItems().getItem(0), this.getItems().getItem(0)._element.offsetWidth, "1px", 1);
            else
                this._resizeSeparators(this.getItems().getItem(0), "1px", this.getItems().getItem(0)._element.offsetHeight, 1);
        }   
		this._raiseClientEvent('Initialize', 'DataMenuItemCancel', null, null, null);
	},
	
	__createFocusEl:function()
	{       
	    var inputEl = document.createElement("INPUT");
	    inputEl.style.position = "absolute";
	    inputEl.style.top = "1px";
	    inputEl.style.left = "1px";
	    inputEl.style.border = "0px none";
	    inputEl.style.background = "transparent";
	    inputEl.style.width = "1px";
	    inputEl.style.height = "1px";
	    inputEl.style.zIndex = "0";
	    /* 2009-07-14 AS set this style property to suppress Safari/Chrome outlining */
	    inputEl.style.outline = "none";
	    inputEl.setAttribute("type", "button");
	    // inputEl.setAttribute("tabindex", "-1");
	    // A.T. 2009-10-08 Fix for bug #22847
	    inputEl.setAttribute("tabIndex", this._get_clientOnlyValue("tabIndex"));
	    this._element.setAttribute("tabIndex", "-1");
	    inputEl.value = "";
	    this._element.appendChild(inputEl);
	    this._focusElement = inputEl;    
	},
	
    _onFocusHandler: function(browserEvent)
    {
        var el = this.get_element();
        this.__controlActive = true;
        var aItem = this._activeItem;
        if (aItem == null)
        {
            aItem = this.getItems().getItem(0);
        }
        /* AS 4/13/2009 Fixing Bug#16392 - here we may have no items, so let's just exit */
        if(aItem == null) return;
        this.__setActiveItem(aItem, false);
        aItem.open();
    },
    
    _onBlurHandler: function()
    {
        if (this.__cancelBlur)
        {
            this.__cancelBlur = false;
        }
        else
        {
            var el = this.get_element();
            this.__controlActive = false;
            if (this._activeItem != null)
            {
                this._activeItem.set_active(false);                
            }
            if(this.get_isContextMenu()) setTimeout(Function.createDelegate(this, this.__hideAll), 100);
                else this._timeoutID = setTimeout(Function.createDelegate(this, this.__hideAll), 1000);             
        }
    },
    		    
    dispose:function()
	{        
	    this.__clearAnimations();
	    $clearHandlers(this.get_element());
		$IG.WebDataMenu.callBaseMethod(this, 'dispose');
	},
	
 
    _focusEventElement: function(blurBeforeFocus)
    {
        var fe = this._focusElement;
        if (fe && fe.focus)
        {
            if (blurBeforeFocus) fe.blur();
            fe.focus();
        }
    },
    
    showAt:function(x, y, browserEvent)
	{
        ///<summary>
        /// Shows the menu at specified position
        ///</summary>
        ///<param name="x">The value for X-Axis where to show the menu</param>
        ///<param name="y">The value for Y-Axis where to show the menu</param>
        ///<param name="browserEvent">The borwser event object, to calculate position, if X,Y or both are empty</param>
        this.__defaultContextHandler = document.oncontextmenu;
        this.__defaultMouseUpHandler = document.body.onmouseup;
        
        var f = function() { return false; };
        //window.oncontextmenu = f;
        document.oncontextmenu = f;
        document.body.onmouseup = f;
                
	    if(typeof(x) == "undefined" || x == null)
	    {
	        if(browserEvent != null && typeof(browserEvent) != "undefined")
	        {
	            try {x = browserEvent.clientX + 2;}catch(e){x = 0;}
	        }
	        else
	        {
	            if(window.event) x = window.event.clientX;
	            else if(window.Event) { try{x = window.Event.clientX + 2;} catch(e){x = 0;} }
	            else x = 0;
	        }
	    }
	    if(typeof(y) == "undefined" || y == null)
	    {
	    	if(browserEvent != null && typeof(browserEvent) != "undefined")
	        {
	            try {y = browserEvent.clientY + 2;}catch(e){y = 2;}
	        }
	        else
	        {
	            if(window.event) y = window.event.clientY;
	            else if(window.Event) { try{y = window.Event.clientY + 2;} catch(e){y = 2;} }
	            else y = 0;
	        }
	    } 
	    var pageDims = this.__calcPageDimensions();
	    y += pageDims.ScrollTop;
	    x += pageDims.ScrollLeft;
	    this._element.style.position = "absolute";
	    this._element.style.zIndex = "12000";
	    this._element.style.top = y + "px";
	    this._element.style.left = x + "px";
	    if(this._menuGroupSettings.get_orientation() == $IG.Orientation.Horizontal)
	    {
            this._sizer.style.display = "block";
            this._sizer.style.visibility = "visible";
            this._sizer.style.position = "absolute";
            this._sizer.style.border = "solid";
            this._sizer.style.left = "-4000px";
            this._sizer.style.width = "2000px";
            this._sizer.appendChild(this._element);
            this._element.style.visibility = "visible";
            this._element.style.display = "block";
            document.body.appendChild(this._sizer);                     
            var elBounds = Sys.UI.DomElement.getBounds(this._element);            
            this._element.style.visibility = "hidden";
            document.body.appendChild(this._element);
            document.body.removeChild(this._sizer);
            this._element.style.width = elBounds.width + 'px';     
            /* remove unused variable */
            delete elBounds;
	    }
	    
	    this.__clearActiveItem();	    
	    this._element.style.display = "block";
	    this._element.style.visibility = "visible";
	    /* this is required due to absolute positioning of container when menu is ContextMenu */
	    this._element.style.overflow = "visible";
	    var that = this;
	    var f = function () { that._focusEventElement(false); };
	    window.setTimeout(f, 1);
	},
	
	hide:function()
	{
      ///<summary>
      /// Hides the menu if IsContextMenu is enabled
      ///</summary>
      if(this.get_isContextMenu)
      {
        document.oncontextmenu = this.__defaultContextHandler;
        document.body.onmouseup = this.__defaultMouseUpHandler;
              
	    this._element.style.display = "none";
	    this._element.style.visibility = "hidden";  
	  }
	},
	
	_addHandlers:function()
	{
	    $IG.WebDataMenu.callBaseMethod(this, '_addHandlers');
	    this._registerHandlers(["keyup", "keypress", "mousedown"]);
	},
	
    getItems:function()
	{
	    /// <summary>
        /// The collection of DataMenuItem objects in the WebDataMenu.
        /// </summary>
	    return this._itemCollection;
	},
	
    get_isContextMenu: function()
    {
        ///<summary>
        ///Gets the boolean IsContextMenu
        ///Default to false
        ///</summary>
        if(this._get_value($IG.DataMenuProps.IsContextMenu) < 1)
            return false;        
        return true;    
    },
    	
    get_enableExpandOnClick: function()
    {
        ///<summary>
        ///Gets the boolean EnableExpandOnClick
        ///Default to false
        ///</summary>
        if(this._get_value($IG.DataMenuProps.EnableExpandOnClick) < 1)
            return false;        
        return true;    
    },

	get_selectedItem:function()
	{
	    /// <summary>
        /// Returns the currently selected item. If there is no selection returns null.
        /// </summary>
	    return this._selectedItem;
	},
	
	get_activeItem:function()
	{
        ///<summary>
        /// Gets the currently active item
        ///</summary>
	    return this._activeItem;
	},
	
	__clearActiveItem:function()
	{
	    if(this._activeItem != null)
	    {
	        this._activeItem.set_active(false);      
	        this._selectItem(this._activeItem, false);
	        this._activeItem = null;
	    }
	},
	
	__setActiveItem:function(item, force)
    {
        if(this._activeItem != null)
        {
            this._activeItem.set_active(false);
        }
        /* AS 4/13/2009 Fixing Bug#16392 - here we may have no items, so let's just exit */
        if(item == null) return;
        item.set_active(true, force);
        this._activeItem = item;
    },
    
	// called by the Aikido behaviors 
    _selectItem:function(item, val)
    {
        if(!item.get_isSeparator())
            this.__selectItem(item, val);
    },
    
    __selectItem:function(item, val, force)
    {
        var selAddr = (this._selectedItem != null) ? this._selectedItem._address : "";
        var realForce = (force != null && typeof(force) != "undefined") ? force : false;
        if( val && ( item._address != selAddr || realForce ) )
        {
            /* we are selecting and we are selecting something  *
             * that is different than the current selection     */
            var args = this._raiseClientEvent('ItemSelecting', 'DataMenuItemCancel', null, null, item);
            var cancel = args ? args.get_cancel() : false;
            if (!cancel) 
            {
                this._raiseClientEvent('ItemSelected', 'DataMenuItemCancel', null, null,item);
                this.__unselectAll(this.getItems()._items);
                item.set_selected(true);
                this._selectedItem = item;
            }
            /* AS 2009-05-08 #17462 Canceling ItemSelecting does not actually deselects item
                hence it is already selected by Aikido Behavior
             */
            else
            {
                item.set_selected(false);
            }
        }
        else if (!val)
        {
            item.set_selected(false);
        }
    },
	
	__unselectAll: function(items)
	{
	    /*
	    *   TODO: In future when develop multiple selection be aware of that
	    */
	    for (var i = 0; i < items.length; i++)
	    {
	        if(items[i] == null || typeof(items[i]) == "undefined") continue;
	        items[i].set_selected(false);
	        if(items[i].hasChildren)
	        {
	            this.__unselectAll( items[i].getItems()._items );
	        }
	    }
	},
	
	__hideElement: function(subgroup, item)
	{
          args = this._raiseClientEvent('ItemCollapsing', 'DataMenuItemCancel', null, null, item);
          if (args && args.get_cancel())
            return;	
	      this.__clearAnimations();
	      if (subgroup!=null)
	      {
            subgroup.style.display = 'none';
            subgroup.style.visibility = 'hidden';
            this._raiseClientEvent('ItemCollapsed', 'DataMenuItemCancel', null, null, item);         
          }
	},
	
    __calcPageDimensions:function()
    {
        /* detectoverflow on the bottom
         * note that it is very important that we account for the body scrollTop as well !!!
         */
        var pageHeight = 0;
        var pageScrollTop = 0;
        var pageWidth = 0;
        var pageScrollLeft = 0;
        var pageScrollWidth = document.body.scrollWidth;
        var pageScrollHeight = document.body.scrollHeight;        
        if (document.compatMode == "BackCompat") {
            pageHeight = document.body.clientHeight;
            pageScrollTop = document.body.scrollTop + document.body.parentNode.scrollTop;
            pageWidth = document.body.clientWidth;
            pageScrollLeft = document.body.scrollLeft + document.body.parentNode.scrollLeft;
        } else {
            /* quirks */
            pageHeight = window.innerHeight;
            pageScrollTop = window.pageYOffset;
            pageWidth = window.innerWidth;
            pageScrollLeft = window.pageXOffset;
            if ($util.IsIE) {
                pageHeight = document.documentElement.clientHeight;
                pageScrollTop = document.documentElement.scrollTop;
                pageWidth = document.documentElement.clientWidth;
                pageScrollLeft = document.documentElement.scrollLeft;
                pageScrollHeight = document.documentElement.scrollHeight;
                pageScrollWidth = document.documentElement.scrollWidth;
            }
        }
        var dims = new Object();
        dims.Width = pageWidth;
        dims.Height = pageHeight;
        dims.ScrollLeft = pageScrollLeft;
        dims.ScrollTop = pageScrollTop;
        dims.ScrollWidth = pageScrollWidth;
        dims.ScrollHeight = pageScrollHeight;
        dims.X = pageScrollWidth - pageScrollLeft;
        dims.Y = pageScrollHeight - pageScrollTop;
        dims.MaxX = dims.ScrollLeft + dims.Width;
        dims.MaxY = dims.ScrollTop + dims.Height;
        return dims;
    },
    		
    _resizeSeparators:function(item, width, height, roots)
    {
        /// <summary>
        /// used to resize menu separators
        /// </summary>
        width -= 2;
        height -= 2;
	    var childItem = this.getItems().getItem(0);
	    var grpSettings = this._menuGroupSettings;
	    if(typeof(roots)=="undefined" || roots == null)
	    {
	        childItem = item.get_childItem(0);
	        grpSettings = item.get_itemsGroupSettings();
	    }
        while(childItem != null)
        {
            if(childItem.get_isSeparator())
            {
                if(grpSettings.get_orientation() == $IG.Orientation.Vertical)
                {
                    childItem._element.style.width = width + 'px';
                    var nItem = childItem.get_nextItem();
                    /* dirty hack to make separators work */
                    if(nItem != null && !nItem.get_isSeparator() && nItem._element.style.marginTop == "")
                    {
                        nItem._element.style.marginTop = "1px";                    
                    }
                }
                else
                {
                    childItem._element.style.height = height + 'px';                    
                }
            }
            childItem = childItem.get_nextItem();
        }
    },
	__showElement:function(sg, item, isFromKeyboard)
	{
	    /* sg - the subgroup to animate - this is reference to DOM UL element */
	    /* item - the item that is displaying element, may be null, Then we are displaying menu */
	    /* isFromKeyBoard - to indicate whether that event occurs after keyboard navigation */
	    if(sg == null || typeof(sg) == "undefined" || sg.style.display != 'none')
	        return false;
	    if(item != null && typeof(item) != "undefined")
	    {
	        /* raise event only if it is item event */
            args = this._raiseClientEvent('ItemExpanding', 'DataMenuItemCancel', null, null, item);
            if (args && args.get_cancel())
                 return false;           
        }
        /* Get page dimensions */     
        var pageDims = this.__calcPageDimensions();             
        /* Obtain reference to the Item's element for convenience */
        var itemElement = item.get_element();             
        /* Get orientation that the displaying sub-menu should have */
        var orientation = item.get_itemsGroupSettings().get_orientation();       
        
        var bounds = Sys.UI.DomElement.getBounds(itemElement);
        sg.style.position = 'absolute';
        sg.style.display = 'block';
        sg.style.visibility = 'hidden';
        sg.style.zIndex="10000";
        if(sg.style.width == ""
        && item.get_itemsGroupSettings().get_orientation() == $IG.Orientation.Horizontal )
        {
            /* calculate required width only if necessary */
            this._sizer.style.display = "block";
            this._sizer.style.visibility = "visible";
            this._sizer.style.position = "absolute";
            this._sizer.style.border = "solid";
            this._sizer.style.left = "-4000px";
            this._sizer.style.width = "2000px";
            this._sizer.appendChild(sg);
            sg.style.visibility = "visible";
            document.body.appendChild(this._sizer);                     
            var sgBounds = Sys.UI.DomElement.getBounds(sg);            
            sg.style.visibility = "hidden";
            itemElement.appendChild(sg);
            document.body.removeChild(this._sizer);
            sg.style.width = sgBounds.width + 'px';     
            /* remove unused variable */
            delete sgBounds;
        }
        this._resizeSeparators(item, sg.offsetWidth, item._element.offsetHeight);       
        /* Set to 0, to calculate new margins. Some scrolling might have appeared */                   
        sg.style.marginTop = "0px";
        sg.style.marginLeft = "0px";
        var x=0,y=0;
        if(item.get_orientation() == $IG.Orientation.Vertical || ( item._get_level() == 1 && this.get_orientation() == $IG.Orientation.Vertical) )
        {
            x += bounds.width;
        }
        else
        {
	        y += bounds.height;
        }
        
        var p0 = Sys.UI.DomElement.getLocation(itemElement);
        var p1 = Sys.UI.DomElement.getLocation(sg);
        x += p0.x - p1.x;
        y += p0.y - p1.y;
        
        if(!$util.IsIE && item._get_level() > 1)
        {
            scrolls = item.calcScrolls();
            x += scrolls.Left;
            y += scrolls.Top;
        }
        
        /* Consider the offsets given by group settings */
        x += item.get_itemsGroupSettings().get_offsetX();
        y += item.get_itemsGroupSettings().get_offsetY();
        
        sg.style.marginTop = y + 'px';
        sg.style.marginLeft = x + 'px';   
        
        
        var expandDirection = item.get_itemsGroupSettings().get_expandDirection();
        var sgBounds = Sys.UI.DomElement.getBounds(sg);            
        var itemsBounds = Sys.UI.DomElement.getBounds(itemElement);            
        var switched = false;
        
        if(expandDirection == $IG.MenuExpandDirection.Auto)
        {
            /* Auto Position */
            if( (sgBounds.x + sgBounds.width) > pageDims.MaxX)
            {
                var substractX = 0;
                if(item.get_itemsGroupSettings().get_orientation() == $IG.Orientation.Horizontal)
                    substractX = (sgBounds.x + sgBounds.width) - pageDims.MaxX;                   
                else
                    { substractX = itemsBounds.width + sgBounds.width; switched = true; }
                x -= substractX;
            }
        
            if( (sgBounds.y + sgBounds.height) > pageDims.MaxY )
            {
                var substractY = 0;
                if(item.get_itemsGroupSettings().get_orientation() == $IG.Orientation.Horizontal)
                    { substractY = itemsBounds.height + sgBounds.height; switched = true }
                else
                    substractY = (sgBounds.y + sgBounds.height) - pageDims.MaxY;
                y -= substractY;
            }
        }
        else if(item.get_orientation() == $IG.Orientation.Horizontal)
        {
            /* Item is rendered horizontally, so submenus have meaning expanding under, or above */
            switch(expandDirection)
            {
                case $IG.MenuExpandDirection.Down:
                    /* default do nothing */
                break;
                case $IG.MenuExpandDirection.Up:
                    substractY = itemsBounds.height + sgBounds.height;
                    y -= substractY;
                    switched = true;
                break;
            }
        }
        else if(item.get_orientation() == $IG.Orientation.Vertical)
        {
            /* Item is rendered vertically, so submenus have meaning expanding left, or right */
            switch(expandDirection)
            {
                case $IG.MenuExpandDirection.Left:
                    substractX = itemsBounds.width + sgBounds.width;  
                    x -= substractX;
                    switched = true;
                break;
                case $IG.MenuExpandDirection.Right:
                    /* default do nothing */
                break;
            }    
        }
        
        sg.style.marginTop = y + 'px';
        sg.style.marginLeft = x + 'px';            
        
        delete sgBounds;
        delete itemsBounds;
        delete expandDirection;
        delete pageDims;
        delete p0;
        delete p1;
              
       
       this._visibleItems[item._get_address()] = item;
       if(item.get_itemsGroupSettings().get_enableAnimation())
       {
            this.__animate(sg,item,isFromKeyboard, switched);
       }
       else
       {
           sg.style.visibility='visible';
           this._raiseClientEvent("ItemExpanded", "DataMenuItemCancel", null, null, item); 
       }
       return true;
	},
	
	__isInScrolledContainer:function()
	{
	    var isScrolled = false;
        var parent = this.get_element().parentNode;
        while(parent != null && parent.nodeName != "BODY")
        {
            if(parent.clientHeight < parent.scrollHeight
                || parent.clientWidth < parent.scrollWidth )
               {
                    isScrolled = true;
                    break;
               }
               parent = parent.parentNode;
        }
	    return isScrolled;
	},
	
	__isInFixedContainer:function()
	{
	    var isFixed = false;
        var parent = this.get_element().parentNode;
        if(parent.nodeName == "BODY" && this.get_element().style.position != "static") return true;
        while(parent != null && parent.nodeName != "BODY")
        {
            if ( parent.style.position != "static" )
            {
                    isFixed = true;
                    break;
            }
            parent = parent.parentNode;
        }
	    return isFixed;
	},
	
	__focusLink: function(item, fromParent)
	{
	    clearTimeout(this._timeoutID);
	    var isChild = false;
	    if(fromParent != null && typeof(fromParent) != "undefined")
	    {
	        if(fromParent) isChild = true;
	    }
	    if (item !=null && !item.get_isSeparator())
	    {
	        if(this._activeItem != null && !isChild )
	        {
	            $util.removeCompoundClass(this._activeItem.get_element(), this._activeItem.get_stateCssClass("Active"));
	        }
	        this.__hideUpLevelItems(item);
	        //$util.addCompoundClass(item.get_element(), item.get_stateCssClass("Active"));
	        this._activeItem = item;
	        this.__setActiveItem(this._activeItem);
        }
	},
	
    _onMousedownHandler: function(elem, adr, event)
    {
        /* do nothing if not initilized yet! may occur on postback, after disposing */
        if (!this.get_isInitialized()) return false;
        var item = this.getItems()._getObjectByAdr(adr);
        if(this.get_isContextMenu() && !this.get_enableExpandOnClick())
        {
            window.setTimeout(Function.createDelegate(this, this.hide), 100);
        }
        if(this.get_enableExpandOnClick())
        {
            if( this.__showElement(item._get_subgroup(), item, false) )
                this.__hideUpLevelItems(item);
        }
        if(item != "undefined" && item != null && item._getFlags().getEnabled(this))
        {
            item._toggleClicked();
            var args = this._raiseClientEvent("ItemClick", "DataMenuItemCancel", null, null, item, item._get_address());
            this.__focusLink(item);
            if(args && args.get_cancel() == true)
            {
                return false;
            }
        }

    },
	
	_onKeydownHandler: function(event)
    {
        /* do nothing if not initilized yet! may occur on postback, after disposing */
        if (!this.get_isInitialized()) return false;
        var shouldPreventDefault = true;
        var item = (this._activeItem) ? this._activeItem : this.getItems().getItem(0);
        /* AS 4/13/2009 Fixing Bug#16392 - here we may have no items, so let's just exit */
        if(item == null) return;
        this.__setActiveItem(item);
        args = this._raiseClientEvent("KeyDown", "DataMenuItemCancel", null, null, item);
        if (args && args.get_cancel()) 
        {
            return false;
        }        
        switch(event.keyCode)
        {
            case Sys.UI.Key.space:
            {
                this.__selectItem(item, !item.get_selected(), true);
                shouldPreventDefault = false;
                break;
            }
            case Sys.UI.Key.left:
                {
                    if(item.get_orientation() == $IG.Orientation.Horizontal)
                    {
                        this.__focusPrevious(item);   
                    }    
                    else
                    {
                        this.__focusParent(item);
                    }
                    break;
                }
            case Sys.UI.Key.right:
                {   
                    /* 1. If the item is horizontally oriented -> focus next */
                    if(item.get_orientation() == $IG.Orientation.Horizontal)
                    {
                        this.__focusNext(item);   
                    }    
                    /* 2. If the item is vertically oriented and has child itmes -> focus child */
                    else if( item.get_orientation() == $IG.Orientation.Vertical && item.hasChildren() )
                    {
                        this.__focusChild(item);   
                    }
                    /* 2. If the item is vertically oriented and has no child itmes -> focus parent */
                    else if(item.get_orientation() == $IG.Orientation.Vertical && !item.hasChildren())
                    {
                        this.__focusParent(item);
                    }
                    break;
                }
            case Sys.UI.Key.enter:
                {
                    item._toggleClicked();
                    var args = this._raiseClientEvent("ItemClick", "DataMenuItemCancel", null, null, item);
                    if(args && args.get_cancel() == true)
                    {
                        return false;
                    }
                    this.__selectItem(item, true, true);
                    this.__focusLink(item);
                    var iLink = item.get_anchorElement();
                    if(iLink != null && typeof(iLink)!="undefined")
                    {
            	        var formElement = document.createElement("FORM");
	                    formElement.style.position = "absolute";
	                    formElement.style.top = "-1000px";
	                    formElement.style.left = "-1000px";
	                    var submitEl = document.createElement("INPUT");
	                    submitEl.type = "SUBMIT";
	                    formElement.appendChild(submitEl);
	                    document.body.appendChild(formElement);
    	                    
                        formElement.action = iLink.href;
                        formElement.target = iLink.target;
                        submitEl.focus();
                        submitEl.click();
                        
                        document.body.removeChild(formElement);
                        formElement.removeChild(submitEl);
                        delete formElement;
                        delete submitEl;
                        /*
                        var that = this;
                        var fn = new function() { document.body.focus(); that._onFocusHandler(); } ;
                        window.setTimeout(fn,100);
                        */
                    }                     
                    shouldPreventDefault = true;
                    break;
                }
            case Sys.UI.Key.esc:
                {
                    /* close the whole menu (hide all items) ? */
                    this.__hideAll();
                    /* focus first item */
                    var firstItem = this.getItems()._getObjectByIndex(0);
                    this.__focusLink(firstItem);
                    break;
                }
            case Sys.UI.Key.tab:
            case Sys.UI.Key.space:
                {
                    /* release the focus */
                    shouldPreventDefault = false;
                    break;
                }
            case Sys.UI.Key.up:
                {
                    /* 1. if item is vertically oriented -> focus previous */
                    if(item.get_orientation() == $IG.Orientation.Vertical)
                    {
                        this.__focusPrevious(item);
                    }
                    else if (item.hasChildren())
                    {
                        this.__focusChild(item);
                    }
                    else
                    {
                        this.__focusParent(item);
                    }
                    break;
                }
            case Sys.UI.Key.down:
                {
                    if(item.get_orientation() == $IG.Orientation.Vertical)
                    {
                        this.__focusNext(item);
                    }
                    else if (item.hasChildren())
                    {
                        this.__focusChild(item);
                    }
                    else
                    {
                        this.__focusParent(item);
                    }
                    break;
                }
            default:
                break;
        }
        
        if(shouldPreventDefault)
        {
          $util.cancelEvent(event);
        }
        
    },
    
	__focusParent : function (item)
	{
	    /* get the parent of the item
	     * hide the item's container            
	     * focus on the parent of the item 
	     */
	    var parent = item.get_parentItem();
	    /* restore normal CSS class */
	    if(parent != null)
	    {
	        item.set_selected(false);
	        var subgroup = parent._get_subgroup();
	        this.__hideElement(subgroup, item);
	        this.__focusLink(parent);
	        item.restore_style();
	    }	
	},
	
	__focusChild : function(item)
	{
	    /* get the item            
	     * get the first child of the item
	     * open the container of the first child of the item (child collection UL)
	     * focus on the first child
	     */
	    /* var firstChild = item.get_childItem(0); */
	    var firstChild = item;
	    if(firstChild != null)
	    {
	        item.set_selected(false);
	        var subgroup = firstChild._get_subgroup();
	        if ( this.__showElement(subgroup, firstChild, true) )
	            /* AS 28/4/2009 appeared while working on 16496 */
	            this.__focusLink(firstChild.get_childItem(0, true), true);
	    }	    
	},
		
	__focusPrevious : function(item)
	{
        /* get the current item
         * get the previous sibling
         * focus on the previous sibling
         * if the current item is the first in the menu item collection, 
         *  focus on the last one (wrap around)
         */
        item.set_selected(false);
        item.restore_style();
        var parentItem = item.get_parentItem();
        var collection;
        if (parentItem == null)
            collection = this.getItems();
        else
            collection = parentItem.getItems();
        var index = collection.get_indexOf(item);
        index--;
        if (index < 0 )
            index = collection._items.length-1;
        var prevItem = this.__findPrevItem(collection, item); //collection._items[index];
        this.__focusLink(prevItem);	
	},
	
	__findPrevItem:function(collection, item)
	{
        var index = collection.get_indexOf(item);
        var initialIndex = index;
        index--;
        if (index < 0 )
            index = collection._items.length-1;	    
        var nextItem = collection._items[index]	        
	    while(!nextItem._getFlags().getEnabled(this) || nextItem.get_isSeparator())
	    {
	        nextItem = collection._items[index];
	        if(index == initialIndex || nextItem == item) break;
	        index--;
	        if(index < 0) index = collection._items.length-1;
	    }
	    return nextItem;            
	},
	
	__focusNext: function(item)
	{
	    /* get the current item
	     * get the next sibling 
	     * focus on the next sibling 
	     * if the current item is the last in the menu item collection, 
	     * focus on the first one (wrap around)
	     */
	    item.set_selected(false);
        item.restore_style();
	    var parentItem = item.get_parentItem();
	    var collection;
	    if(parentItem == null)
	        collection = this.getItems();
	    else
	        collection = parentItem.getItems();
	    var nextItem = this.__findNextItem(collection, item);//collection._items[index];
	    this.__focusLink(nextItem);	
	},
	
	__findNextItem:function(collection, item)
	{
	    var index = collection.get_indexOf(item);
	    var initialIndex = index;
	    index++;
	    if(index >= collection._items.length)
	        index = 0;
        var nextItem = collection._items[index]	        
	    while(!nextItem._getFlags().getEnabled(this) || nextItem.get_isSeparator())
	    {
	        nextItem = collection._items[++index];
	        if(index == initialIndex || nextItem == item) break;
	        if(index >= collection._items.length) index = 0;
	    }
	    return nextItem;
	},
	
    _onKeyupHandler: function(elem,adr,event)
	{	
	},
	
	_onKeypressHandler: function(elem,adr,event)
	{
	    /*
        var item = this.getItems()._getObjectByAdr(adr);
        if(item != "undefined" && item != null)
        {
            this._raiseClientEvent("KeyPress", "DataMenuItemCancel", null, null, item);
        }
        */
	},	
	
	_createItem:function(element, adr)
    {
        this._itemCollection._addObject($IG.DataMenuItem, element, adr);
    },

	
    _setupCollections:function()
    {
        this._itemCollection = this._collectionsManager.register_collection(0,$IG.DataMenuItemCollection);
        this._collectionsManager.registerUIBehaviors(this._itemCollection);
    },
    
    __hideAll:function()
    {
        /* AS 20080825 Animations 
        */
        clearTimeout(this._timeoutID);
        this.__clearAnimations();
        /* get sub menus and recursively set display none 
        */
        for(var key in this._visibleItems)
        {
            if(this._visibleItems[key] != null
               && typeof(this._visibleItems[key]) != "undefined" 
               && typeof(this._visibleItems[key]) != "function" 
            )
            {  
                args = this._raiseClientEvent("ItemCollapsing", "DataMenuItemCancel", null, null, this._visibleItems[key]);
                if(args && args.get_cancel())
                    continue;                
                this._visibleItems[key].set_expanded(false);
                this._visibleItems[key].set_hover(false);
                var subgroup = this._visibleItems[key]._get_subgroup();
                if (subgroup!=null && subgroup.style.display!='none')
                {
                    subgroup.style.display = 'none';
                    subgroup.style.visibility = 'hidden';
                }
                this._raiseClientEvent("ItemCollapsed", "DataMenuItemCancel", null, null, this._visibleItems[key]);
                this._visibleItems[key] = null;
                delete this._visibleItems[key];                      
            }
        }        
        if(this.get_isContextMenu())
        {
            this.hide();
        }
    },
    
    __hideUpLevelItems: function(currentItem)
    {
        var currSubGroup = currentItem._get_subgroup();
        var currentLevel = currentItem._get_level();
        
        for (var key in this._visibleItems)
        {
            if(this._visibleItems[key] != null
               && typeof(this._visibleItems[key]) != "undefined" 
               && this._visibleItems[key] != currentItem
               && typeof(this._visibleItems[key]) != "function"
            )
            {
                var level = this._visibleItems[key]._get_level();
                if (level >= currentLevel)
                {
                    if(currentItem.isDescendant(this._visibleItems[key]))
                        continue;        
                    args = this._raiseClientEvent("ItemCollapsing", "DataMenuItemCancel", null, null, this._visibleItems[key]);
                    if(args && args.get_cancel())
                        continue;    
                    this._visibleItems[key].set_expanded(false);
                    this._visibleItems[key].set_hover(false);            
                    var subgroup = this._visibleItems[key]._get_subgroup();
                    if (subgroup!=null && subgroup.style.display!='none' && subgroup != currSubGroup)
                    {
                        subgroup.style.display = 'none';
                        subgroup.style.visibility = 'hidden';
                    }
                    this._raiseClientEvent("ItemCollapsed", "DataMenuItemCancel", null, null, this._visibleItems[key]);
                    delete this._visibleItems[key];
                }                
            }
        }
    },
    
    /* Called by Aikido Core to detect if _hoverItem() should be called */
    _shouldHover: function(item, e)
    {
        /* do nothing if not initilized yet! may occur on postback, after disposing */
        if (!this.get_isInitialized()) return false;
        e.cancelBubble = true;
        /* do not fire events for item which is separator */
        if(item.get_isSeparator()) return false;
        
        if(e.type=="mouseover")
        {
            /* return true only if the item state is not flagged*/
            if(item._getFlags().getHovered()) return false;
                else return true;
        }
        else if(e.type=="mouseout") // && e.target.nodeName == "LI")
        {
            /* first check if the item is hovered, otherwise do not throw the event */
            if(!item._getFlags().getHovered()) return false;
             
            /* return true only of pointer is going out of DOM Element */
            return $util.isOut(e, item._element);
        }
        return false;
    },
    
    /* Called by Aikido Core */
    _hoverItem:function(item, shouldHover)
    {
        var subgroup = item._get_subgroup();
        if (shouldHover)
        {
            
            if(this._hoveredItem != null && this._hoveredItem._get_address() != item._get_address())
            {
                /* IE fix. Sometimes it is misscalculating dimesions, so _shouldHover returns false when unhovering */
                this._hoveredItem._getFlags().setHovered(false);
                this._hoveredItem.restore_style();
            }
            /** An item is HOVERed **/
            this._raiseClientEvent("ItemHovered", "DataMenuItemCancel", null, null, item);            

            /** Consider clearing this interval only if item is part of displayed sub-group **/
            clearTimeout(this._timeoutID); 
            if (subgroup!=null && !this.get_enableExpandOnClick()) 
            {
                if(this.__showElement(subgroup, item, false))
                    item.set_expanded(true);
            }   
            if(!this.get_enableExpandOnClick())
                this.__hideUpLevelItems(item);         
            this._hoveredItem = item;
        } else {
           /** An item is unHOVERed **/        
           /* record previous item
            * this.__previousItem = item;
            */
           /* item.restore_style(); */
           this._hoveredItem = null;
           this._raiseClientEvent("ItemUnhovered", "DataMenuItemCancel", null, null, item);            
           this._timeoutID = setTimeout(Function.createDelegate(this, this.__hideAll), 1000); 
        }
        item.set_hover(shouldHover);
    },
    
    /* AS20080825 Working on Animations */
    __animate:function(elem,item, isFromKeyboard, switched)
    {
        /* $IG.DataMenuAnimations = function(control, dmItem, orientation, animationSettings, isFromKB) */
        if(!this.get_menuGroupSettings().get_enableAnimation() 
            && !this._get_itemsGroupSettins(item._get_address()).get_enableAnimation())
        {
            return;
        }
        this.__clearAnimations();
        this.__animation = new $IG.DataMenuAnimations(this, item, elem, isFromKeyboard);
        //this.__animation.onStop = this._animationEnded;
        this.__animation.play();    
        /* TODO: Raise come kind of event on animation end so ItemExpanded could be fired */
    },

    _animationEnded:function(item)
    {
        this._raiseClientEvent("ItemExpanded", "DataMenuItemCancel", null, null, item);                
        this._visibleItems[item._get_address()] = item;
        this.__clearAnimations();
    },

    __clearAnimations:function()
    {
        if(this.__animation != null)
        {
            try { this.__animation.clearAnimation(); } catch(e){}
            this.__animation = null;
        }
    },

    get_menuGroupSettings: function()
    {
        ///<summary>
        /// Returns the groupSettings for the menu
        ///</summary>
        if(this._menuGroupSettings == null || typeof(this._menuGroupSettings) == "undefined")
        {
		    this._menuGroupSettings = new $IG.DataMenuGroupSettings(this._element, this._objectsManager.get_objectProps(1), this);
		    this._objectsManager.register_object(1, this._menuGroupSettings);            
        }
        return this._menuGroupSettings;
    },
    
    get_orientation: function()
    {
        ///<summary>
        /// Returns an integer value which indicates the orientation.
        ///</summary>
        return this.get_menuGroupSettings().get_orientation()
    },
    
    _get_itemsGroupSettins: function(fullAddress)
    {
        if(this._itemsGroupSettings == null || this._itemsGroupSettings.length < 1)
            return null;
        for(var i = 0; i< this._itemsGroupSettings.length; i++)
        {
            if(this._itemsGroupSettings[i].get_itemsFullAddress() == fullAddress)
            {
                return this._itemsGroupSettings[i];
            }
        }
        return null;
    },
    
    removeItem:function(item)
    {
        var adr = item._get_address();
        var cbo = this._callbackManager.createCallbackObject();
        cbo.serverContext.type = cbo.clientContext.type = "remove";
        cbo.serverContext.address = adr;
        cbo.clientContext.item = item;
        this._callbackManager.execute(cbo);
    },
    
    addItem:function(txt, parentItem)
    {
        var adr = "";
        if(parentItem != null && typeof(parentItem) != "undefined")
            adr = parentItem._get_address();
        var cbo = this._callbackManager.createCallbackObject();
        cbo.serverContext.type = cbo.clientContext.type = "add";
        cbo.serverContext.address = adr;
        cbo.serverContext.text = txt;
        cbo.clientContext.parentItem = parentItem;
        this._callbackManager.execute(cbo);        
    },
    
    removeItem:function(item)
    {
        var cbo = this._callbackManager.createCallbackObject();
        cbo.serverContext.type = cbo.clientContext.type = "remove";
        cbo.serverContext.address = item._get_address();
        var parentItem = item.get_parentItem();
        cbo.clientContext.parentItem = parentItem;
        this._callbackManager.execute(cbo);            
    },
    
    _responseComplete: function(callbackObject, responseObject)
    {
        switch(callbackObject.serverContext.type)
        {
            case "add":
                var html = responseObject.context[0];
                var parentItem = callbackObject.clientContext.parentItem;
                var element = this.get_element().getElementsByTagName("UL")[0];
                if(parentItem != null && typeof(parentItem) != "undefined")
                {
                    element = parentItem.get_element();
                }
                else
                {    
                    element = document.createElement("LI");
                    this.get_element().getElementsByTagName("UL")[0].appendChild(element);
                }
                
                var helperEl = document.createElement("DIV");
                helperEl.innerHTML = html;
                element.id = helperEl.firstChild.id;
                element.className = helperEl.firstChild.className;
                element.innerHTML = helperEl.firstChild.innerHTML;
                delete helperEl;
                
                var itemsCount = responseObject.context.length;
                for (var i = 1; i < itemsCount; i++)
                {
                    var response = eval(responseObject.context[i]);
                    var adr = response[0];
                    var props = response[1];
                    this._itemCollection._csm.set_itemProps(adr, props);
                }
                
                $util._initAttr(element);
                this._ensureItem(element, element.getAttribute("adr"));
            break;
            case "remove":
                var html = responseObject.context[0];
                /* var rendered = responseObject.context[1]; */
                var itemsCount = responseObject.context.length;
                for (var i = 2; i < itemsCount; i++)
                {
                    var response = eval(responseObject.context[i]);
                    var adr = response[0];
                    var props = response[1];
                    this._itemCollection._csm.set_itemProps(adr, props);
                }
                var parentItem = callbackObject.clientContext.parentItem;
                var element = this.get_element();
                if(parentItem != null && typeof(parentItem) != "undefined")
                {
                    element = parentItem.get_element();
                    var helperEl = document.createElement("DIV");
                    helperEl.innerHTML = html;
                    element.id = helperEl.firstChild.id;
                    element.className = helperEl.firstChild.className;
                    element.innerHTML = helperEl.firstChild.innerHTML;
                    delete helperEl;
                    $util._initAttr(element);
                    this._ensureItem(element, element.getAttribute("adr"));
                }
                else
                {
                    element.innerHTML = html;
                }
            break;
        }
        
        
        this.getItems()._items = [];
        var children = this.get_element().getElementsByTagName("LI");
               
        for (i = 0; i < children.length; i++)
        {
            var child = children[i];
            $util._initAttr(child);
            this._ensureItem(child, child.getAttribute("adr"));
        }                             

    },
    
    _ensureItem: function(e, adr)
    {
        var item = this._itemCollection._getObjectByAdr(adr);
        if (item == null || e != null)
            item = this._itemCollection._addObject($IG.DataMenuItem, e, adr);
        return item;
    }

}

$IG.WebDataMenu.registerClass('Infragistics.Web.UI.WebDataMenu', $IG.NavControl);
/******************************************DataMenuItemCollection*******************************/
///<summary>
///Used internally to construct the DataMenuItemCollections of the DataWebMenu
///</summary>
$IG.DataMenuItemCollection = function(control, clientStateManager, index, manager)
{
    $IG.DataMenuItemCollection.initializeBase(this, [control, clientStateManager, index, manager]);
}

$IG.DataMenuItemCollection.prototype = 
{
    _createNewCollection:function()
    {
        var nodes = new $IG.DataMenuItemCollection(this._control, this._csm, this._index, this._manager);
        nodes._ownerNode = this;
        return nodes;
    },

    getItem:function(index)
    {
        ///<summary>
        ///Returns the Item at the specified index or FullAddress 
        ///</summary>
        if(index.toString().indexOf(".") >= 0)
        {
            var indeces = index.toString().split(".");
            var itemsCollection = this._control.getItems();
            var item = null;
            for(var i = 0; i < indeces.length; i++)
            {
                item = itemsCollection.getItem(indeces[i]);
                if(item != null)
                   itemsCollection = item.getItems();
                else 
                   break;
                if(itemsCollection == null || typeof(itemsCollection) == "undefined")    
                    break;
            }
            return item;
        }
        else
        {
            if(index >= 0 && index < this.get_length())
                return this._items[index];
        }
        return null;
    },
    
    getChildrenCount: function()
    {
        if(this._items != null && typeof(this._items) != "undefined" && typeof(this._items.length) != "undefned" )
            return this._items.length;
        return 0;
    }
}
$IG.DataMenuItemCollection.registerClass('Infragistics.Web.UI.DataMenuItemCollection', $IG.NavItemCollection);
/******************************************End DataMenuItemCollection****************************/
/************************************ DataMenuItemCancelEventArgs *******************************/
$IG.DataMenuItemCancelEventArgs = function()
{
    ///<summary>
    ///Used internally to constuct cancelable event arguments to be passed to DataTree event handlers 
    ///</summary>
    $IG.DataMenuItemCancelEventArgs.initializeBase(this);
}

$IG.DataMenuItemCancelEventArgs.prototype =
{
    /* this._props: 0-event, 1-postBackAction, 2-item */
    ///<summary>
    ///Returns the Node object for this event. 
    ///</summary>
    getItem: function() { return this._props[2]; },
    dispose: function()
	{
		/// <summary>Disposes object.</summary>
		this._props[0] = null;
		this._props[1] = null;
		this._props[2] = null;
	},

    _getPostArgs: function()
    {
        return ':' + this.getItem()._get_address();
    }
}
$IG.DataMenuItemCancelEventArgs.registerClass('Infragistics.Web.UI.DataMenuItemCancelEventArgs', $IG.CancelEventArgs);

/******************************** End DataMenuItemCancelEventArgs *******************************/

$IG.DataMenuAnimations = function(control, dmItem, elem, isFromKB)
{
    $IG.DataMenuAnimations.initializeBase(this);
    this._dmItem = dmItem;
    this._groupSettings = control._get_itemsGroupSettins(this._dmItem._get_address());
    this._orientation = this._groupSettings.get_orientation();
    this._control = control;
    this._isFromKB = isFromKB;
    this._elementToAnimate = elem;
    //var subGroup = dmItem._get_subgroup();
    //$IG.DataMenuAnimations.initializeBase(this, [subGroup]);
}

$IG.DataMenuAnimations.prototype = 
{
    _groupSettings:$IG.DataMenuGroupSettings,
    _dmItem:$IG.DataMenuItem,
    _orientation:0,
    _control:$IG.WebDataMenu,
    _isFromKB:false,
    _animation:null,
    _elementToAnimate:null,
    
    //events
    add_onStop: function(handler) {
        /// <summary>Adds a event handler for the onStop event.</summary>
        /// <param name="handler" type="Function">The handler to add to the event.</param>
        this.get_events().addHandler("onStop", handler);
    },
    remove_onStop: function(handler) {
        /// <summary>Removes a event handler for the onStop event.</summary>
        /// <param name="handler" type="Function">The handler to remove from the event.</param>
        this.get_events().removeHandler("onStop", handler);
    },
    // methods
    get_item: function()
    {
		///<summary>
		/// Returns the DataMenuItem object 
		/// that is animating its shild submenu
		///</summary>      
        return this._dmItem;
    },    
    
    clearAnimation : function()
    {
		///<summary>
		/// Clears the Animation, if any
		///</summary>              
		if(this._animation != null)
		{
		    try { this._animation.stop(); } catch(e){};
		}
		this._animation = null;
    },
    
    play: function()
    {
		///<summary>
		/// animates the object according to the
		/// AnimationSettings provided
		///</summary>      
		//this.clearAnimation();
		var item = this._dmItem;
		var menu = this._control;
		var that = this;
        if(this._groupSettings.get_animationType() == 
            $IG.DataMenuAnimationtype.ExpandAnimation)
        {
            /* Initialize the expandAnimator object */
            this._animation = 
                new $IG.DataMenuExpandAnimator(this._control, this._elementToAnimate, this._dmItem, this._isFromKB);                  
            this._animation.onEnd = function() { that.onStop(item, menu); };
            this._animation.play(this._groupSettings.get_animationDuration(),this._groupSettings.get_animationEquationType(),true);                
            window.setTimeout(function(){that._dmItem._get_subgroup().style.visibility = "visible";}, 100);
            //this._dmItem._get_subgroup().style.visibility = "visible";
        }
        else if(this._groupSettings.get_animationType() ==
            $IG.DataMenuAnimationtype.OpacityAnimation)
        {
            /* Initialize the opacityAnimator object */
            /* AS 4/28/2009 Bug#17106 applying equationtype to opacity animation also */
            this._animation = new $IG.OpacityAnimation(this._elementToAnimate, this._groupSettings.get_animationEquationType());
            this._animation.set_duration(this._groupSettings.get_animationDuration());
            this._animation.onEnd = function() { that.onStop(item, menu); };            
            this._animation.play(0, 100, true);
            this._dmItem._get_subgroup().style.visibility = "visible";
        }
    },
    
    dispose: function() 
    {
        // clear any playing animation
        this.clearAnimation();
        // be sure to call base.dispose()
        $IG.DataMenuAnimations.callBaseMethod(this, 'dispose');
    },
    
    onStop:function(item, menu)
    {
        menu._animationEnded(item);
    }
}

$IG.DataMenuAnimations.registerClass("Infragistics.Web.UI.DataMenuAnimations", Sys.Component);

/******************************************Animating****************************/
$IG.DataMenuExpandAnimator = function(control, element, containingItem, isFromKB)
{
    this._containingItem = containingItem;
    this._orientation = containingItem.get_orientation();
    this._control = control;
    this._isFromKB = isFromKB;
    $IG.DataMenuExpandAnimator.initializeBase(this, [element]);
}

$IG.DataMenuExpandAnimator.prototype =
{
    /** Overrides **/
    ///<summary>
    /// Initialize the animation
    ///</summary>
    _init: function()
    {
        this._oldStyle = this._element.style;
        var bounds = Sys.UI.DomElement.getBounds(this._element);
        this._begin = 0;
        this._currentValue = 0;
        this._animatingContainer = document.createElement("div");
        this._animatingContainer.style.position = "absolute";        
        this._animatingContainer.style.display = "block";
        this._animatingContainer.style.visibility = "visible";
        if(this._orientation == $IG.Orientation.Vertical || this._containingItem._get_level() > 1)
        {
            this._end = bounds.width;
            this._animatingContainer.style.width = "0px";
            this._animatingContainer.style.height = bounds.height + "px";            
        }
        else
        {
            this._end = bounds.height;
            this._animatingContainer.style.width = bounds.width + "px";
            this._animatingContainer.style.height = "0px";
        }
        this._animatingContainer.style.marginLeft = this._element.style.marginLeft; //left = (bounds.width - this._containingItem._element.style.borderWidth) +"px";
        this._animatingContainer.style.marginTop = this._element.style.marginTop;
        this._animatingContainer.style.overflow = "hidden";
        this._animatingContainer.style.border = "0px none";
        this._containingItem._element.appendChild(this._animatingContainer);
        this._animatingContainer.appendChild(this._element);
        this._element.style.position = "relative";
        this._element.style.marginLeft = "0px";
        this._element.style.marginTop = "0px";
    },

    _next: function()
    {
        /* AS 4/28/2009 Bug#17106 accounting equationtype */
        this._currentValue = $IG.DataMenuExpandAnimator.callBaseMethod(this, "_calc", [this._equationType, this._time, this._begin, this._end, this._duration]);
        if(this._orientation == $IG.Orientation.Vertical || this._containingItem._get_level() > 1)
        {
            this._animatingContainer.style.width = this._currentValue + "px";
        }
        else
        {
            this._animatingContainer.style.height = this._currentValue + "px";
        }
        if( (this._begin < this._end && this._currentValue >= this._end) 
            || (this._begin > this._end && this._currentValue <= this._end) 
            )
        {
                this.stop();
        }
    },

    play: function(duration, equationType, unattach)
    {
        if(!this.get_isAnimating())
        {
            this.set_duration(duration);
            this._equationType = equationType;
            $IG.DataMenuExpandAnimator.callBaseMethod(this, "play");
        }
    },

    stop: function()
    {
        this._containingItem._element.appendChild(this._element);
        this._containingItem._element.removeChild(this._animatingContainer);
        this._element.style.position="absolute";
        this._element.style.marginLeft = this._animatingContainer.style.marginLeft;
        this._element.style.marginTop = this._animatingContainer.style.marginTop;
        if(this._isFromKB)
            this._control.__focusLink(this._containingItem.get_childItem(0, true));
        $IG.DataMenuExpandAnimator.callBaseMethod(this, "stop");        
    },

    get_item : function()
    {
        return this._containingItem;
    }
}
$IG.DataMenuExpandAnimator.registerClass("Infragistics.Web.UI.DataMenuExpandAnimator", $IG.AnimationBase);


if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();