/**
 ******************************************************************************
 * (c) Copyright 2001-2008. EMC Corporation.  All Rights Reserved.
 ******************************************************************************
 *
 * Project        Lister
 * File           dynamicAction.js
 * Description    the javascript responsible for handling dynamic
 *                action links and buttons - requires locate.js
 * Created on     23rd May 2001
 * Tab width      3
 *
 ******************************************************************************
 *
 * PVCS Maintained Data
 *
 * Revision       $$
 * Modified on    $$
 *
 * Log at EOF
 *
 ******************************************************************************
 */
wdk.DYNAMICACTION = new Object();
wdk.DYNAMICACTION.ACTION_MULTISELECT_PREFIX = "actionmultiselectcheckbox_";
wdk.DYNAMICACTION.DESKTOP_LOOKFEEL = false;
 //DAM: branched from webtop 5.2.0.24. Revision 28

// global row highlight colour
var ROW_HIGHLIGHT_COLOUR = "#b5c4d9";              // Standard format

/* @deprecated NS 7+ has no problem with # color literals. All browsers can use the standard format */
var ROW_HIGHLIGHT_COLOUR_IE = "#b5c4d9";              // IE format
var ROW_HIGHLIGHT_COLOUR_NS = "rgb(205, 209, 213)";     // NS7.1 format
var ROW_HIGHLIGHT_COLOUR_NS_OLD = "rgb(205, 209, 213)";     // Older NS format

// global constant for Dynamic settings
var DYNAMIC_GENERIC = 0;
var DYNAMIC_SINGLESELECT = 1;
var DYNAMIC_MULTISELECT = 2;
var DYNAMIC_GENERICNOSELECT = 3;

/**
 * @deprecated Use ClientInfo JS Object for client side detection
 */
var isNav = (navigator.appName == "Netscape");
var isMac = (navigator.platform.toLowerCase().indexOf("mac")!=-1)
var isMacIE = isMac&&!isNav;

// dynamic helper
function isGeneric(dynamic)
{
   return ( (dynamic == DYNAMIC_GENERIC) || (dynamic == DYNAMIC_GENERICNOSELECT) );
}

// init helper
function init(name, value)
{
   if (typeof(eval(name)) == "undefined")
   {
      eval(name + "=" + value);
   }
}

// array of action controls
init("getTopLevelWnd().g_actionControls", "[]");

// lookup table for menu items
init("getTopLevelWnd().pmLookup", "[]");

/**
 * Action control constructor
 *
 * @param strControlId     the control id (E.g. 'menuitem_checkin')
 * @param strActionId      the associated action (E.g. 'checkin')
 * @param source           reference to containing frame
 * @param bShowIfDisabled  whether to show the control when action disabled
 * @param bShowIfInvalid   whether to show the control when action invalid
 * @param eDynamicMode     type of dynamic behaviour (0=generic, 1=singleselect, 2=multiselect)
 * @param bIsMenu          true if this item is a dynamic menu item, false otherwise
 * @param callbackFunction the client side callback function for inline action
 */
function ActionControl(strControlId,strActionId,source,bShowIfDisabled,bShowIfInvalid,eDynamic,bIsMenu,callbackFunction)
{
   this.m_strControlId = strControlId;
   this.m_strActionId = strActionId;
   this.m_bShowIfDisabled = bShowIfDisabled;
   this.m_bShowIfInvalid = bShowIfInvalid;
   this.m_eDynamic = eDynamic;
   this.m_source = source;
   this.m_actionState = -1;
   this.m_bIsMenu = bIsMenu;
   this.m_strCallbackFunction = callbackFunction;
}

ActionControl.prototype.toString = function()
{
   return "ActionControl [" +
      "id=" + this.m_strControlId +
      ", actionId=" + this.m_strActionId +
      ", showIfDisabled=" + this.m_bShowIfDisabled +
      ", showIfInvalid=" + this.m_bShowIfInvalid +
      ", dynamic=" + this.m_eDynamic  +
      ", actionState=" + this.m_actionState +
      ", menu=" + this.m_bIsMenu +
      ", source=" + this.m_source +
      "]";
}

/**
 * Shows an action control enabled
 *
 * @param control The action control
 */
function showControlEnabled(control)
{
   if ( control.m_bIsMenu == false )
   {
      // standard control
      if (isDispatchableWindow(control.m_source))
      {
         setControlVisibility(control, true, false);
      }
   }
   else
   {
      // menu item
      var menuItem = getTopLevelWnd().pmLookup[control.m_strControlId];
      menuItem.isEnabled = true;
      menuItem.isVisible = true;
   }
}

/**
 * Shows an action control disabled
 *
 * @param control The action control
 */
function showControlDisabled(control)
{
   if ( control.m_bIsMenu == false )
   {
      // standard control
      if ( isDispatchableWindow(control.m_source) )
      {
         setControlVisibility(control, false, true);
      }
   }
   else
   {
      // menu item
      var menuItem = getTopLevelWnd().pmLookup[control.m_strControlId];
      menuItem.isEnabled = false;
      menuItem.isVisible = true;
   }
}

/**
 * Hides an action control
 *
 * @param control The action control
 */
function hideControl(control)
{
   if ( control.m_bIsMenu == false )
   {
      // standard control
      if ( isDispatchableWindow(control.m_source) )
      {
         setControlVisibility(control, false, false);
      }
   }
   else
   {
      // menu item
      var menuItem = getTopLevelWnd().pmLookup[control.m_strControlId];
      menuItem.isVisible = false;
   }
}

/**
 * Set the visibility of the enabled and disabled parts of the dynamic action control
 *
 * @param control       The action control
 * @param showEnabled   True to show the enabled part, false to hide it
 * @param showEnabled   True to show the disabled part, false to hide it
 */
function setControlVisibility(control, showEnabled, showDisabled)
{
   var span1 = control.m_source.document.getElementById(control.m_strControlId + "_1");
   var span2 = control.m_source.document.getElementById(control.m_strControlId + "_2");

   // display as 'inline' if any parent node is set as inline
   var span1DisplayState = 'block';
   var node = null;
   if (span1 != null)
   {
      node = span1.parentNode;
   }
   while (node != null)
   {
      if (node.tagName == 'DIV' && node.style.display.indexOf('inline') !=-1)
      {
         span1DisplayState = 'inline';
         break;
      }
      node = node.parentNode;
   }

   // hide/show the enabled part of the control
   if (span1 != null && span2 != null)
   {
       if (showEnabled == true)
       {
          span1.style.display = span1DisplayState;
       }
       else
       {
          span1.style.display = 'none';
       }

       // hide/show the disabled part of the control
       if (showDisabled == true)
       {
          span2.style.display = span1DisplayState;
       }
       else
       {
          span2.style.display = 'none';
       }
   }
}

/**
 * Update an action control
 *
 * @param control The action control
 * @param actionState   the new action state (0=unexecutable, 1=executable, 2=invalid)
 */
function updateControl(control, actionState)
{
   if (control.m_actionState != actionState)
   {
      control.m_actionState = actionState;

      if (actionState == 1)
      {
         showControlEnabled(control);
      }
      else if (actionState == 0)
      {
         if (control.m_bShowIfDisabled)
         {
            showControlDisabled(control);
         }
         else
         {
            hideControl(control);
         }
      }
      else if (actionState == 2)
      {
         if (control.m_bShowIfInvalid)
         {
            showControlDisabled(control);
         }
         else
         {
            hideControl(control);
         }
      }
   }
}

/**
 * Registers an action control - so that it can be dynamically updated
 *
 * @param strControlId     the control id (E.g. 'menuitem_checkin')
 * @param strActionId      the associated action (E.g. 'checkin')
 * @param source           reference to containing frame
 * @param bShowIfDisabled  whether to show the control when action disabled
 * @param bShowIfInvalid   whether to show the control when action invalid
 * @param eDynamicMode     type of dynamic behaviour (0=generic, 1=singleselect, 2=multiselect)
 * @param bIsMenu          true if this item is a dynamic menu item, false otherwise
 * @param callbackFunction the name of the client side callback function
 */
function registerActionControl(strControlId,strActionId,source,bShowIfDisabled,bShowIfInvalid,eDynamic,bIsMenu,callbackFunc)
{

   // create action control adding it to the action control list
   var actionControl = new ActionControl(strControlId,strActionId,source,bShowIfDisabled,bShowIfInvalid,eDynamic,bIsMenu,callbackFunc);
   getTopLevelWnd().g_actionControls[ strControlId ] = actionControl;
}

/**
 * Unregisters all registered action controls
 */
function unregisterActionControls()
{
    if( (g_clientInfo.isPlatform(ClientInfo.MACOS)
            && g_clientInfo.isBrowser(ClientInfo.MSIE))
               && typeof getTopLevelWnd().g_actionControls =="undefined" )
    {
      //on MAC IE:
      //for some reason the array is destroyed by the window so
      //don't bother to reset it
     }
    else
    {
      getTopLevelWnd().g_actionControls = [];
    }
}


//////////////////////////////////////////////////////
// Multislect functions

/**
 * get selection as string of '1' and '0' characters
 */
function getMultiselectSelection()
{
   var strSelection = "";
   while (true)
   {
      // TODO: Refactor for Row selection
      var id = "actionmultiselectcheckbox_" + strSelection.length;
      var checkbox = window.document.getElementById(id);
      if (checkbox == null)
      {
         break;
      }

      if (checkbox.checked)
      {
         strSelection = strSelection + "1";
      }
      else
      {
         strSelection = strSelection + "0";
      }
   }

   return strSelection;
}

/**
 * Update a checkbox's row highlight colour
 *
 * @param checkbox Checkbox element
 */
function updateCheckboxRowHighlightColour(checkbox)
{
   // locate row
   var row = checkbox.parentNode;
   while (row != null && row.tagName != "TR")
   {
      row = row.parentNode;
   }

   // set colour
   if (row != null && wdk.dom.hasClass(row, "selectable") == false)
   {
      if (checkbox.checked)
      {
         // ensure row is highlighted
         if (row.isHighlighted != true)
         {
            row.oldColour = row.style.backgroundColor;
            row.isHighlighted = true;
            row.style.backgroundColor = ROW_HIGHLIGHT_COLOUR;
         }
      }
      else
      {
         // ensure row is not highlighted
         if (row.isHighlighted == true)
         {
            row.style.backgroundColor = (row.oldColour) ? row.oldColour : "";
            row.isHighlighted = false;
         }
      }
   }
}

/**
 * Called when the user clicks on a ActionMultiselectCheckbox control
 *
 * @param checkbox Checkbox clicked upon
 */
function onActionMultiselectCheckboxClick(checkbox)
{
   updateCheckboxRowHighlightColour(checkbox);
   updateDynamicControls();
}

/**
 * Called when the user clicks on a ActionMultiselectCheckAll control
 */
function onActionMultiselectCheckAllClick()
{   // determine whether to select or deselect checkboxes
   var bSelectCheckboxes = false;

   for (var index = 0; true; index++)
   {
      var id = wdk.DYNAMICACTION.ACTION_MULTISELECT_PREFIX + index;
      var checkbox = window.document.getElementById(id);
      if (checkbox == null)
      {
         break;
      }

      if (checkbox.checked == false)
      {
         bSelectCheckboxes = true;
      }
   }

   // check/uncheck all checkboxes
   for (var index = 0; true; index++)
   {
      var id = wdk.DYNAMICACTION.ACTION_MULTISELECT_PREFIX + index;
      var checkbox = window.document.getElementById(id);
      if (checkbox == null)
      {
         break;
      }

      if (checkbox.checked != bSelectCheckboxes)
      {
         checkbox.checked = bSelectCheckboxes;
      }
      updateCheckboxRowHighlightColour(checkbox);
   }

   // update dynamic actions
   updateDynamicControls();
}

/**
 * update dynamic action controls
 *
 * @param refresh flag
 */
function updateDynamicControls()
{
   // invoke via timer
   window.setTimeout("_updateDynamicControls()",10);
}

function _updateDynamicControls()
{
   // get checkbox selection and count
   var selection = [];
   var nSelected = 0;

   while (true)
   {
      var id = wdk.DYNAMICACTION.ACTION_MULTISELECT_PREFIX + selection.length;
      var checkbox = window.document.getElementById(id);
      if (checkbox == null)
      {
         break;
      }

      if (checkbox.checked)
      {
         nSelected++;
      }

      selection[selection.length] = checkbox.checked;

      // ensure row is highlighted appropriatly
      updateCheckboxRowHighlightColour(checkbox);
   }

   // Set the state of the the select all checkbox, if it exists
   var selectAll = window.document.getElementById("actionmultiselectcheckall");
   if (selectAll != null)
   {
      selectAll.checked = (selection.length == nSelected);
   }

   _updateControlStatesFromSelection(selection, nSelected);
}

function _updateControlStatesFromSelection(selection, nSelected)
{
   // determine whether the selection spans more than one group
   var bSelectionSpansGroups = false;
   var group = -1;
   for (var iItem = 0; iItem < multiselectGroupTbl.length; iItem++ )
   {
      if (selection[ iItem ])
      {
         if (multiselectGroupTbl[ iItem ] != group)
         {
            if (group != -1)
            {
               bSelectionSpansGroups = true;
               break;
            }
            group = multiselectGroupTbl[ iItem ];
         }
      }
   }

   // update multiselect and generic action controls - based on selection
   var actionControls = getTopLevelWnd().g_actionControls;
   for ( var ctrlIndx in actionControls )
   {
      var control = actionControls[ctrlIndx];
      // get the control state
      var controlState = null;
      if (isGeneric(control.m_eDynamic) == true)
      {
         controlState = getGenericActionState(control.m_strActionId);
      }
      else
      {
         controlState = getMultiselectActionState(control.m_strActionId, selection);
         if (controlState == 1 && bSelectionSpansGroups == true)
         {
            controlState = 0;
         }
      }

      // override control state
      if ((nSelected > 0) && (controlState == 1) && (control.m_eDynamic == DYNAMIC_GENERICNOSELECT))
      {
         controlState = 0;
      }

      if ((nSelected > 1) && (controlState == 1) && (control.m_eDynamic == DYNAMIC_SINGLESELECT))
      {
         controlState = 0;
      }

      // update control
      updateControl(control, controlState);
   }

   // SAFARI BUG WORKAROUND :
   // Safari does not paint/render updates to DIV visibility/display state if the updates occur when the window is not the
   // currently loading/active window. The window is only repainted after certain events (e.g. mouseover) are fired
   // on the frame

   // As a workaorund, we fire the event below for Safari, which can be picked up by affected windows and used to
   // call repaintDynamicControlWindow(), which will cause the window screen to redraw and show the updated DIV state.

   if (g_clientInfo.isBrowser(ClientInfo.SAFARI) == true)
   {
      fireClientEvent("onRepaintDynamicControlWindow");
   }
}

/**
 * Helper Method to be used as a workaround for a SAFARI BUG which results in
 * Dynamic Control Frames not being repainted if updateDynamicControls is called when
 * the Dynamic Control Frame is not the currently loading/active frame.
 */
function repaintDynamicControlWindow()
{
   if (!window._bRepainted && window.scrollBy)
   {
      // Calling window.scrollBy should cause the frame to repaint
      // itself without the risk of any other sideeffects
      window.scrollBy(0,0);
      window._bRepainted = true;
   }
}


/**
 * return whether generic action is executable
 *
 * @param strActionId Action id
 * @return Multiselected action state
 *    0 - Action not executable
 *    1 - Action is executable
 *    2 - Action is not valid
 */
function getGenericActionState(strActionId)
{
   for ( var iAction = 0; iAction < genericActionIdTbl.length; iAction++ )
   {
      if ( strActionId == genericActionIdTbl[ iAction ] )
      {
         return genericActionExecuteTbl[ iAction ];
      }
   }
   return 0;
}


/**
 * return whether multiselect action is executable
 *
 * @param strActionId Action id
 * @param selection Current selection
 * @return Multiselected action state
 *    0 - Action not executable
 *    1 - Action is executable
 *    2 - Action is not valid
 */
function getMultiselectActionState(strActionId, selection)
{
   var iexecutable = 0; // not executable

   // locate action
   for ( var iAction = 0; iAction < multiselectActionIdTbl.length; iAction++ )
   {
      if ( strActionId == multiselectActionIdTbl[ iAction ] ) // action found
      {
         // first check for invalid actions
         var allItemsAreInvalid = true;
         var itemIsInvalid = false;
         for (var iItem = 0; iItem < multiselectActionExecuteTbl[ iAction ].length; iItem++ )
         {
            if (selection[ iItem ])
            {
               if (multiselectActionExecuteTbl[ iAction ][ iItem ] == 2)
               {
                  // invalid
                  itemIsInvalid = true;
               }
            }

            if (multiselectActionExecuteTbl[ iAction ][ iItem ] != 2)
            {
               // Not all item are valid
               allItemsAreInvalid = false;
              }
         }

         if (itemIsInvalid == true)
         {
            // invalid
            if (allItemsAreInvalid == true)
            {
               return 2;
            }
            else
            {
               return 0;   // treat the invalid item as "disabled"
            }
         }

         // All items are invalid.
         if (allItemsAreInvalid)
            return 2;

         // now determine action executability
         for (var iItem = 0; iItem < multiselectActionExecuteTbl[ iAction ].length; iItem++ )
         {
            if (selection[ iItem ])
            {
               if (multiselectActionExecuteTbl[ iAction ][ iItem ] == 1)
               {
                  // executable
                  iexecutable = 1;
               }
               else
               {
                  // if any of the actions is not executable for a selected item then
                  // it cannot be used as a multi-select action
                  return 0;
               }
            }
         }

         break;
      }
   }

   return iexecutable;
}

/**
 * fire dynamic action event
 *
 * @param strControlId     the action control id
 */
function fireDynamicActionEvent(strControlId)
{
   // find frame containing multiselect control
   var multiselectWnd = findMultiselectWindow();
   // call appropriate post action event function
   if (multiselectWnd != null)
   {
      // locate control
      var actionControl = null;
      var actionControls = getTopLevelWnd().g_actionControls;
      for ( var ctrlIndx in actionControls )
      {
         var control = actionControls[ctrlIndx];
         if ( control.m_strControlId == strControlId )
         {
            actionControl = control;
            break;
         }
      }

      // get action id and function
      var strActionId = actionControl.m_strActionId;
      var strCallbackFunc = actionControl.m_strCallbackFunction;
      var invocation = getInvocation(actionControl, multiselectWnd);
      var strUseModalPopup = "" + invocation.getUseModalPopup();
      var strPopupWindowSize = invocation.getPopupWindowSize();
      var strRefreshParentWindow = invocation.getRefreshParentWindow();
      
      var strFunction = null;
      if (isGeneric(actionControl.m_eDynamic) == true)
      {
         strFunction = "postGenericActionEvent";
      }
      else
      {
         strFunction = "postMultiselectActionEvent";
      }

      multiselectWnd[strFunction](strActionId, strCallbackFunc, strUseModalPopup, strPopupWindowSize, strRefreshParentWindow);
   }
}


/**
 * Find multiselect frame (contains postMultiselectActionEvent function)
 *
 * @param containerFrame       the object whose frames we are examining
 *
 * @return the found frame path
 */
function findMultiselectFrame(containerFrame)
{
   var framePath = null;

   for (var iChildFrame = 0; iChildFrame < containerFrame.frames.length; iChildFrame++)
   {
      var childFrame = containerFrame.frames[iChildFrame];
      // Test for cross-frame scripting before attempting to access window's properties.
      if (isAccessibleWindow(childFrame))
      {
         var evt = childFrame.postMultiselectActionEvent;
         if ( evt != null && typeof(evt) != "undefined")
         {
            framePath = "frames[" + iChildFrame + "]";
            break;
         }
      }
   }

   if (framePath == null)
   {
      for (var iChildFrame = 0; iChildFrame < containerFrame.frames.length; iChildFrame++)
      {
         var childFramePath = findMultiselectFrame(containerFrame.frames[iChildFrame]);
         if (childFramePath != null)
         {
            framePath = "frames[" + iChildFrame + "]." + childFramePath;
            break;
         }
      }
   }

   return framePath;
}

var g_multiselectWindow = null;
/**
 * Register multiselect top window (contains postMultiselectActionEvent function)
 *
 */
function registerMultiselectTopWindow(wnd)
{
   g_multiselectWindow = wnd;
}

/**
 * Unregister multiselect top window (contains postMultiselectActionEvent function)
 *
 */
function unregisterMultiselectTopWindow()
{
   g_multiselectWindow = null;
}

/**
 * Find multiselect window (contains postMultiselectActionEvent function)
 *
 * @return the wnd found
 */
function findMultiselectWindow()
{
   var wndFound = null;

   // find frame containing multiselect control
   var wnd = g_multiselectWindow ? g_multiselectWindow : getTopLevelWnd();

   var multiselectFrame = findMultiselectFrame(wnd);
   
   if (multiselectFrame != null)
   {
      wndFound = eval("getTopLevelWnd()." + multiselectFrame);
   }
   else if (multiselectFrame == null && typeof(window.postMultiselectActionEvent) != "undefined" && window.postMultiselectActionEvent != null)
   {
      // the action controls are used without a frame.
      wndFound = window;
   }

   return wndFound;
}


/**
 * set the window.unload handler.
 * This method is called via the FormTag as part of the form initialization.
 */
function setOnActionMultiselectWindowUnloadHandler()
{
   if (typeof(s_fWindowUnloadHandlerSet) == 'undefined')
   {
      s_fWindowUnloadHandlerSet = true;
      s_fnWindowUnload = window.onunload;
      window.onunload = onActionMultiselectWindowUnload;
   }
}

/**
 * Called when a window containing the controls are unloaded.
 * This window.unload handler is set by the FormTag as part of the form initialization.
 */
function onActionMultiselectWindowUnload()
{
   if( !(g_clientInfo.isPlatform(ClientInfo.MACOS) && g_clientInfo.isBrowser(ClientInfo.MSIE)) )
   {
      // Disable all controls.
      var actionControls = getTopLevelWnd().g_actionControls;
      for ( var ctrlIndx in actionControls )
      {
         var control = actionControls[ctrlIndx];
         // disable all controls
         updateControl(control, 2);
      }

      // call the default unload hander, set via FormTag.
      if (typeof(s_fnWindowUnload) != "undefined" && s_fnWindowUnload != null)
      {
         if (typeof s_fnWindowUnload == 'function')
         {
            eval(s_fnWindowUnload);
         }
         else if (typeof s_fnWindowUnload == 'string' && s_fnWindowUnload.indexOf("(") > 0)
         {
            eval(s_fnWindowUnload);
         }
         else
         {
            eval(s_fnWindowUnload + '();');
         }
      }
   }
}

/**
 * Check if action control is executable
 *
 * @param strControlId     the control id
 * @return true, if the control is executable; false, otherwise. 
 */
function isActionControlExecutable(strControlId)
{
   if (typeof(strControlId) == "undefined" || strControlId == null || strControlId == "")
   {
      return false;  // not very likely, but just in case
   }

   var actionControls = getTopLevelWnd().g_actionControls;
   for ( var ctrlIndx in actionControls )
   {
      var control = actionControls[ctrlIndx];
      if (control.m_strControlId == strControlId)
      {
         if (control.m_actionState == 1) // (0=unexecutable, 1=executable, 2=invalid)
         {
            return true;
         }
         else
         {
            return false;
         }
      }
   }

   return true; // non-dynamic action control (not registered with g_actionControls)
}

/**
 * PRIVATE : This function integrates the datagrid with the action multiselect framework
 */
function bindDynamicActionsToDatagrid(datagridCtrl, ctrlClass)
{
   if (datagridCtrl)
   {
      /** PRIVATE INNER FUNCTIONS **/
      function getProxyCheckbox(datagrid, idx)
      {
         var checkbox = null;
         var row = datagrid.getItemNode(idx);
         if (row)
         {
            var selector = wdk.dom.getElementsByClassName(row, ctrlClass);
            if (selector.length > 0)
            {
               checkbox = selector[0];
            }
         }
         return checkbox;
      }

      function updateDatagridFromDynamicActions(event)
      {
         var datagrid = event.datagrid;
         var domElement = datagrid.m_domElem;
         var itemCount = datagrid.getRowCount();
         var selection = datagrid.selection;
         for (var i = 0; i < itemCount; i++)
         {
            var checkbox = getProxyCheckbox(datagrid, i);
            if (checkbox != null && checkbox.checked)
            {
               selection.setSelected(i, true);
            }
         }
         datagrid.addEventListener("select", updateDynamicActionsFromDatagrid);
      }

      function updateDynamicActionsFromDatagrid(event)
      {
         var datagrid = event.datagrid;
         var itemCount = datagrid.getRowCount();
         var selection = datagrid.selection;
         for (var i = 0; i < itemCount; i++)
         {
            var checkbox = getProxyCheckbox(datagrid, i);
            if (checkbox != null && (checkbox.checked != selection.isSelected(i)))
            {
               checkbox.checked = selection.isSelected(i);
            }
         }
         _updateDynamicControls();
      }

      datagridCtrl.addEventListener("init", updateDatagridFromDynamicActions);
      wdk.DYNAMICACTION.DESKTOP_LOOKFEEL = true;
   }
}

/**
 * the invocation for a dynamic action ctrol
 */
wdk.DYNAMICACTION.invocation = function()
{
   this.m_strPopupSizeName = null;
   this.m_strRefreshParentWindow = null;
   this.m_fUseModalPopup = false;

   /**
    * get the popup window size
    * @return the size; e.g, "small"
    */
   this.getPopupWindowSize = function()
   {
      return this.m_strPopupSizeName;
   }

   /**
    * internally called to set a setting from data rendered by a tag handle.
    */
   this.setPopupWindowSize = function(strPopupWindowSize)
   {
      this.m_strPopupSizeName = strPopupWindowSize ;
   }

   /**
    * get the refresh parent setting
    * @return the value; e.g, "onok"
    */
   this.getRefreshParentWindow = function()
   {
      return this.m_strRefreshParentWindow;
   }

   /**
    * internally called to set a setting from data rendered by a tag handle.
    */
   this.setRefreshParentWindow = function(strRefreshParentWindow)
   {
      this.m_strRefreshParentWindow = strRefreshParentWindow;
   }

   /**
    * get the use modal flag
    * @return the value (true or false)
    */
   this.getUseModalPopup = function()
   {
      return this.m_fUseModalPopup;
   }

   /**
    * internally called to set a setting from data rendered by a tag handle.
    */
   this.setUseModalPopup = function(fUseModalPopup)
   {
      this.m_fUseModalPopup = fUseModalPopup;
   }
}

// index for the array containing the available action invocation settings.
wdk.DYNAMICACTION.INVOCATION_USEMODALPOPUP_INDEX = 0;
wdk.DYNAMICACTION.INVOCATION_MODALPOPUPWINDOWSIZE_INDEX = 1;
wdk.DYNAMICACTION.INVOCATION_REFRESHPARENTWINDOW_INDEX = 2;

// static and ordered values of invocation setting.
wdk.DYNAMICACTION.INVOCATION_MODALPOPUP_USEMODALPOPUP = [false, true];

// ordered values of the invocation settings dynamically reset by ActionMultiselectTag.
wdk.DYNAMICACTION.INVOCATION_MODALPOPUPWINDOWSIZE = [];
wdk.DYNAMICACTION.INVOCATION_REFRESHPARENTWINDOW = [];

/**
 * get the invocation of an action control
 * @param actionControl  the action control
 * @param multiselectWnd the datagrid window
 * @return an instance of wdk.DYNAMICACTION.invocation
 */
function getInvocation(actionControl, multiselectWnd)
{
   if (multiselectWnd == null || typeof(multiselectWnd.availableActionInvocationSettings) == 'undefined')
   {
      return null;
   }
   
   var invocation = new multiselectWnd.wdk.DYNAMICACTION.invocation();
   var arrayProperties = readFromMultiSelectData(actionControl, multiselectWnd);
   if (arrayProperties != null)
   {
      readModalPopupWindowSize(invocation, arrayProperties, multiselectWnd);
      readRefreshParentWindow(invocation, arrayProperties, multiselectWnd);
      readUseModalPopup(invocation, arrayProperties, multiselectWnd);
   }

   return invocation;

   /**
    * read the data from the javascripts generated by the mulitiselect control tag handler
    * @param actionControl  the action control
    * @param multiselectWnd the datagrid window
    * @return an array containing the invocation properties.
    */
   function readFromMultiSelectData(actionControl, multiselectWnd)
   {
      var arrayProperties = null;
      if (isGeneric(actionControl.m_eDynamic) == true)
      {
         for ( var iAction = 0; iAction < multiselectWnd.genericActionIdTbl.length; iAction++ )
         {
            if (actionControl.m_strActionId == multiselectWnd.genericActionIdTbl[ iAction ] )
            {
               var idxSetting = multiselectWnd.genericActionInvocationTbl[iAction];
               arrayProperties = multiselectWnd.availableActionInvocationSettings[idxSetting];
               break;
            }
         }
      }
      else
      {
         // find the index for the first selected item
         // for consistency we will use the invocation properties of the first selected property.
         var idxFirstSelectedItem = -1, nItemCount=0;
         while (true)
         {
            var id = wdk.DYNAMICACTION.ACTION_MULTISELECT_PREFIX + nItemCount;
            var checkbox = multiselectWnd.document.getElementById(id);
            if (checkbox == null)
            {
               break;
            }

            if (checkbox.checked)
            {
               idxFirstSelectedItem = nItemCount;
               break;
            }
            nItemCount++;
         }

         if (idxFirstSelectedItem > -1)
         {
            for ( var iAction = 0; iAction < multiselectWnd.multiselectActionIdTbl.length; iAction++ )
            {
               if ( actionControl.m_strActionId == multiselectWnd.multiselectActionIdTbl[ iAction ] ) // action found
               {
                  var idxSetting = multiselectWnd.multiselectActionInvocationTbl[iAction][idxFirstSelectedItem];
                  arrayProperties = multiselectWnd.availableActionInvocationSettings[idxSetting];
                  break;
               }
            }
         }
      }

      return arrayProperties;
   }

   /**
    * set window size from the array object obtained from readFromMultiSelectData
    * @param invocation  the target
    * @param arrayProperties the properties
    * @param multiselectWnd the datagrid window
    */
   function readModalPopupWindowSize(invocation, arrayProperties, multiselectWnd)
   {
      var idxValue = arrayProperties[multiselectWnd.wdk.DYNAMICACTION.INVOCATION_MODALPOPUPWINDOWSIZE_INDEX];
      if (idxValue >= 0 && idxValue < multiselectWnd.wdk.DYNAMICACTION.INVOCATION_MODALPOPUPWINDOWSIZE.length)
      {
         invocation.setPopupWindowSize(multiselectWnd.wdk.DYNAMICACTION.INVOCATION_MODALPOPUPWINDOWSIZE[idxValue]);
      }
   }

   /**
    * set refresh parent window from the array object obtained from readFromMultiSelectData
    * @param invocation  the target
    * @param arrayProperties the properties
    * @param multiselectWnd the datagrid window
    */
   function readRefreshParentWindow(invocation, arrayProperties, multiselectWnd)
   {
      var idxValue = arrayProperties[multiselectWnd.wdk.DYNAMICACTION.INVOCATION_REFRESHPARENTWINDOW_INDEX];
      if (idxValue >= 0 && idxValue < multiselectWnd.wdk.DYNAMICACTION.INVOCATION_REFRESHPARENTWINDOW.length)
      {
         invocation.setRefreshParentWindow(multiselectWnd.wdk.DYNAMICACTION.INVOCATION_REFRESHPARENTWINDOW[idxValue]);
      }
   }

   /**
    * set the use modal flag from the array object obtained from readFromMultiSelectData
    * @param invocation  the target
    * @param arrayProperties the properties
    * @param multiselectWnd the datagrid window
    */
   function readUseModalPopup(invocation, arrayProperties, multiselectWnd)
   {
      var idxValue = arrayProperties[multiselectWnd.wdk.DYNAMICACTION.INVOCATION_USEMODALPOPUP_INDEX];
      if (idxValue >= 0 && idxValue < multiselectWnd.wdk.DYNAMICACTION.INVOCATION_MODALPOPUP_USEMODALPOPUP.length)
      {
         invocation.setUseModalPopup(multiselectWnd.wdk.DYNAMICACTION.INVOCATION_MODALPOPUP_USEMODALPOPUP[idxValue]);
      }
   }
}

reregisterClientEventHandler(null, "datagridcreated", bindDynamicActionsToDatagrid);
reregisterClientEventHandler(null, "updateDynamicControls", updateDynamicControls);
// end
