/**
 ******************************************************************************
 *
 * Confidential Property of Documentum, Inc.
 * (c) Copyright Documentum, Inc. 2001-2003.
 * All Rights reserved.
 * May not be used without prior written agreement
 * signed by a Documentum corporate officer.
 *
 ******************************************************************************
 *
 * Project        Lister
 * File           dynamicAction.js
 * Description    the javascript responsible for handling dynamic
 *                action links and buttons
 * Created on     23rd May 2001
 * Tab width      3
 *
 ******************************************************************************
 *
 * PVCS Maintained Data
 *
 * Revision       $$
 * Modified on    $$
 *
 * Log at EOF
 *
 ******************************************************************************
 */

 //DAM: branched from webtop 5.2.0.24. Revision 28

// global row highlight colour
var ROW_HIGHLIGHT_COLOUR_IE = "#b6c7e6";              // IE format
var ROW_HIGHLIGHT_COLOUR_NS = "rgb(182, 199, 230)";     // NS7.1 format
var ROW_HIGHLIGHT_COLOUR_NS_OLD = "rgb(182,199,230)";     // Older NS format

// global constant for Dynamic settings
var DYNAMIC_GENERIC = 0;
var DYNAMIC_SINGLESELECT = 1;
var DYNAMIC_MULTISELECT = 2;
var DYNAMIC_GENERICNOSELECT = 3;
   //dam
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
 */
function ActionControl(strControlId,strActionId,source,bShowIfDisabled,bShowIfInvalid,eDynamic,bIsMenu)
{
   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;
}

/**
 * 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");

   // hide/show the enabled part of the control
   if (span1 != null && span2 != null)
   {
       if (showEnabled == true)
       {
          span1.style.display = 'block';
       }
       else
       {
          span1.style.display = 'none';
       }

       // hide/show the disabled part of the control
       if (showDisabled == true)
       {
          span2.style.display = 'block';
       }
       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
 */
function registerActionControl(strControlId,strActionId,source,bShowIfDisabled,bShowIfInvalid,eDynamic,bIsMenu)
{

   // create action control adding it to the action control list
   var actionControl = new ActionControl(strControlId,strActionId,source,bShowIfDisabled,bShowIfInvalid,eDynamic,bIsMenu);
   getTopLevelWnd().g_actionControls[ getTopLevelWnd().g_actionControls.length ] = actionControl;
}

/**
 * Unregisters all registered action controls
 */
function unregisterActionControls()
{

    if(isMacIE && 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)
   {
      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)
   {
      if (checkbox.checked)
      {
         // ensure row is highlighted
         var rowHighlightColor = ROW_HIGHLIGHT_COLOUR_IE;
         if (g_isIE == false)
         {
            rowHighlightColor = ROW_HIGHLIGHT_COLOUR_NS;
         }
         //Also account for older Netscape versions (this test will be fine on IE too)
         if ((row.style.backgroundColor != rowHighlightColor) && (row.style.backgroundColor != ROW_HIGHLIGHT_COLOUR_NS_OLD))
         {
            row.oldColour = row.style.backgroundColor;
            row.style.backgroundColor = rowHighlightColor;
         }
      }
      else
      {
         // ensure row is not highlighted
         if (typeof(row.oldColour) != "undefined" && row.style.backgroundColor != row.oldColour)
         {
            row.style.backgroundColor = row.oldColour;
         }
      }
   }
}

/**
 * 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 = "actionmultiselectcheckbox_" + 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 = "actionmultiselectcheckbox_" + 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 = "actionmultiselectcheckbox_" + 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);
   }

   // update multiselect and generic action controls - based on selection
   for ( var iControl = 0; iControl < getTopLevelWnd().g_actionControls.length; iControl++ )
   {
      var control = getTopLevelWnd().g_actionControls[ iControl ];

      // 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);
      }

      // 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);
   }
}


/**
 * 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;
      for ( var iControl = 0; iControl < getTopLevelWnd().g_actionControls.length; iControl++ )
      {
         var control = getTopLevelWnd().g_actionControls[ iControl ];
         if ( control.m_strControlId == strControlId )
         {
            actionControl = control;
            break;
         }
      }

      // get action id and function
      var strActionId = actionControl.m_strActionId;

      var strFunction = null;
      if (isGeneric(actionControl.m_eDynamic) == true)
      {
         strFunction = "postGenericActionEvent";
      }
      else
      {
         strFunction = "postMultiselectActionEvent";
      }

      multiselectWnd.eval(strFunction + "('" + strActionId + "')");
   }
}


/**
 * 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++)
   {
      if (( containerFrame.frames[iChildFrame].postMultiselectActionEvent != null ) &&
          ( typeof containerFrame.frames[iChildFrame].postMultiselectActionEvent != "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;
}

/**
 * Find multiselect window (contains postMultiselectActionEvent function)
 *
 * @return the wnd found
 */
function findMultiselectWindow()
{
   var wndFound = null;

   // find frame containing multiselect control
   var multiselectFrame = findMultiselectFrame(getTopLevelWnd());

   if (multiselectFrame != null)
   {
      wndFound = getTopLevelWnd().eval(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(!isMacIE)
   {
      // Disable all controls.
      for ( var iControl = 0; iControl < getTopLevelWnd().g_actionControls.length; iControl++ )
      {
         var control = getTopLevelWnd().g_actionControls[ iControl ];

         // disable all controls
         updateControl(control, 2);
      }

      // call the default unload hander, set via FormTag.
      if (typeof(s_fnWindowUnload) != "undefined" && s_fnWindowUnload != null)
      {
         eval(s_fnWindowUnload + "();");
      }
   }
}

// end
