/*****************************************************************************/
/* dcwebmail.2.12.js                                                              */
/*                                                                           */
/* DC WebMail JavaScript Common Functions                                    */
/*                                                                           */
/*****************************************************************************/

/*****************************************************************************/
/* makeUnsafe                                                                */
/*                                                                           */
/* Converts the input parameter to an unsafe string.                         */
/*                                                                           */
/* This function scans through the input string, looking for % characters.   */
/* If it finds one, it interprets the next two characters as a hex ASCII     */
/* code and translates the three characters "%xx" into the single equivalent */
/* ASCII character.                                                          */
/*                                                                           */
/* Parameters: inStr - input string                                          */
/*                                                                           */
/* Returns:    translated string                                             */
/*****************************************************************************/
function makeUnsafe(inStr)
{
  var outStr = "";
  var hexDigits = "0123456789abcdef";
  for (var ii=0; ii<inStr.length; ii++)
  {
    var nextChar = inStr.charAt(ii);
    if (nextChar == "\%")
    {
      var outChar = (hexDigits.indexOf(inStr.charAt(ii+1)) * 16)
                  + (hexDigits.indexOf(inStr.charAt(ii+2)) * 1);
      nextChar = String.fromCharCode(outChar);
      ii += 2;
    }
    outStr = outStr + nextChar;
  }
  return(outStr);
}

/*****************************************************************************/
/* makeUnsafeHTML                                                            */
/*                                                                           */
/* Converts the input parameter to an unsafe string by unescaping any        */
/* standard HTML escape codes (of the form &#nnn;). No explicit check for    */
/* end of string is made when searching for escape code. The string.charAt   */
/* method returns an empty string if it's argument is outside the string, so */
/* the code functionality will not be affected.                              */
/*                                                                           */
/* Parameters: inStr - input string                                          */
/*                                                                           */
/* Returns:    outStr - translated string                                    */
/*****************************************************************************/
function makeUnsafeHTML(inStr)
{
  var outStr = "";
  var codeFound = false;
  var currentCode = "";
  var charCode = null;
  var nextChar = "";

  for (var ii=0; ii<inStr.length; ii++)
  {
    currentCode = "";
    codeFound = false;
    nextChar = inStr.charAt(ii);
    if (nextChar == "&" && (inStr.charAt(ii+1) == "#"))
    {
       currentCode = currentCode + "&#";
       ii += 2;
       nextChar = inStr.charAt(ii);
       if (isDigit(nextChar) && (inStr.charAt(ii+1) == ";"))
       {
          currentCode = currentCode + nextChar + ";";
          codeFound = true;
          ii++;
       }
       else if (isDigit(nextChar) && isDigit(inStr.charAt(ii+1)) && (inStr.charAt(ii+2) == ";"))
       {
          currentCode = currentCode + nextChar + inStr.charAt(ii+1) + ";";
          codeFound = true;
          ii += 2;
       }
       else if (isDigit(nextChar) && isDigit(inStr.charAt(ii+1)) && isDigit(inStr.charAt(ii+2)) && (inStr.charAt(ii+3) == ";"))
       {
          currentCode = currentCode + nextChar + inStr.charAt(ii+1) + inStr.charAt(ii+2) + ";";
          codeFound = true;
          ii += 3;
       }
    }

    if (codeFound == true)
    {
       charCode = currentCode.substring(2,currentCode.length-1);
       nextChar = String.fromCharCode(charCode);
    }
    else
    {
       outStr = outStr + currentCode;
    }

    outStr = outStr + nextChar;
  }
  return(outStr);
}

/*****************************************************************************/
/* makeSafeHTML                                                              */
/*                                                                           */
/* Converts the input string into a safe HTML version. It converts all       */
/* non-alphanumeric characters into &#dd; where dd is the decimal            */
/* representation of the character                                           */
/*                                                                           */
/* Parameters: inStr - the input String                                      */
/*                                                                           */
/* Returns   : outSrtr - the translated string.                              */
/*****************************************************************************/
function makeSafeHTML(inStr)
{
  var outStr    = "";
  var lnextChar = "";

  if (inStr != null)
  {
    for (var li = 0; li < inStr.length; li++)
    {
      /***********************************************************************/
      /* Get the next character.                                             */
      /***********************************************************************/
      lnextChar = inStr.charAt(li);

      /***********************************************************************/
      /* Check if it is a permitted character.                               */
      /***********************************************************************/
      if ( ((lnextChar >= '0') && (lnextChar <= '9')) ||
           ((lnextChar >= 'A') && (lnextChar <= 'Z')) ||
           ((lnextChar >= 'a') && (lnextChar <= 'z')) )
      {
        /*********************************************************************/
        /* If the character is alphanumeric, append it to the output string. */
        /*********************************************************************/
        outStr = outStr + lnextChar;
      }
      else
      {
        /*********************************************************************/
        /* Append the escape code rather than the character.                 */
        /*********************************************************************/
        outStr = outStr + "&#";
        outStr = outStr + lnextChar.charCodeAt(0).toString();
        outStr = outStr + ";";
      }
    }
  }

  return(outStr);
}

/*****************************************************************************/
/* Help                                                                      */
/*                                                                           */
/* Opens a new window and displays the helplink in it                        */
/*                                                                           */
/* Parameters: helpLink - URL of the help page to open                       */
/*                                                                           */
/* Returns: nowt                                                             */
/*****************************************************************************/
function Help(helpLink)
{
  window.open(helpLink, commonjs1, "width=400,height=500,scrollbars=yes,dependent=yes,resizable=yes");
}

/*****************************************************************************/
/* pageIndex:                                                                */
/*                                                                           */
/* Output a page index HTML fragment.  This is used to navigate large lists  */
/* of  data.                                                                 */
/*                                                                           */
/* Parameters: baseurl - used to access the various pages                    */
/*                       the page number is appended to this URL when        */
/*                       generating links to each page.                      */
/*             thispage - page number of the current page                    */
/*             totalpages - the total number of pages in the set.            */
/*             prevstr - "Prev" string                                       */
/*             nextstr - "Next" string                                       */
/*                                                                           */
/* Notes:      Use plain spaces rather than &nbsp after each link as we need */
/*             the list of pages to wrap if it gets too long.                */
/*****************************************************************************/
function pageIndex(baseurl, thispage, totalpages, prevstr, nextstr)
{
  if (totalpages <= 1)
  {
    return;
  }

  if (thispage != 1)
  {
    document.write("<a href=\"" + baseurl + (thispage - 1) + "\">" + prevstr + "</a> ")

    for (var i = 1; i < thispage; i++)
    {
      document.write("<a href=\"" + baseurl + i + "\">" + i + "</a> ")
    }
  }

  document.write("<b>" + thispage + "</b> ")

  if (thispage != totalpages)
  {
    for (var i = thispage + 1 ; i <= totalpages; i++)
    {
      document.write("<a href=\"" + baseurl + i + "\">" + i + "</a> ")
    }

    document.write("<a href=\"" + baseurl + (thispage + 1) + "\">" + nextstr + "</a> ")
  }
}

/*****************************************************************************/
/* selectMatchingRadio                                                       */
/*                                                                           */
/* Scan a list of radio buttons, looking for the one that matches the value  */
/* check the matching radio button.                                          */
/*                                                                           */
/* Parameters: radioarray - array of radio buttons to scan.                  */
/*             value      - the value to select.                             */
/*****************************************************************************/
function selectMatchingRadio(radioarray, value)
{
  if (radioarray.length != null)
  {
    for (var i=0; i < radioarray.length; i++)
    {
      if (radioarray[i].value.toLowerCase() == value.toLowerCase())
      {
        radioarray[i].checked = true;
      }
    }
  }
  else
  {
    /*************************************************************************/
    /* Not an array - only one radio button, so check it if the value        */
    /* matches.                                                              */
    /*************************************************************************/
    if (radioarray.value.toLowerCase() == value.toLowerCase())
    {
      radioarray.checked = true;
    }
  }
}

/*****************************************************************************/
/* selectMatchingOption                                                      */
/*                                                                           */
/* Scan a list of select options, looking for the one that matches the value */
/* select the matching option.                                               */
/*                                                                           */
/* Parameters: selectset  - the select object to modify.                     */
/*             value      - the value to select.                             */
/*****************************************************************************/
function selectMatchingOption(selectset, value)
{
  for (var i=0; i < selectset.options.length; i++)
  {
    if (selectset.options[i].value.toLowerCase() == value.toLowerCase())
    {
      selectset.options[i].selected = true
    }
  }
}

/*****************************************************************************/
/* getSelectedRadio                                                          */
/*                                                                           */
/* Scan a list of radio buttons, looking for the checked one.  Return the    */
/* radio array element matching this value.                                  */
/*                                                                           */
/* Parameters: radioarray - array of radio buttons to scan.                  */
/*****************************************************************************/
function getSelectedRadio(radioarray)
{
  for (var i=0; i < radioarray.length; i++)
  {
    if (radioarray[i].checked)
    {
      return radioarray[i]
    }
  }
}

/*****************************************************************************/
/* getSelectValue                                                            */
/*                                                                           */
/* returns the value of the selected option in the given select.  (It        */
/* assumes only one value can be selected.)                                  */
/*                                                                           */
/* Parameters:                                                               */
/*   selection  - the select object to scan                                  */
/*****************************************************************************/
function getSelectValue(selection)
{
  for (var i = 0; i < selection.options.length; i++)
  {
    if (selection.options[i].selected)
    {
      return selection.options[i].value
    }
  }
}

/*****************************************************************************/
/* These functions implement utilities used by the notification settings     */
/* pages.                                                                    */
/*                                                                           */
/* The types array gives a list of all the notification types.               */
/*****************************************************************************/
var types = new Array("email", "voice", "fax")

/*****************************************************************************/
/* submitNotificationForm                                                    */
/*                                                                           */
/* Submit the target form after massaging its parameters.                    */
/*                                                                           */
/* tgtform  - the form to manipulate                                         */
/* update   - set true if this is an update operation.                       */
/* complete - set true if the modification operation is complete.            */
/*****************************************************************************/
function submitNotificationForm(tgtform, update, complete)
{
  tgtform.Update.value   = update;
  tgtform.Complete.value = complete;

  for (var i = 0; i < types.length; i++)
  {
    var srcstr = "tgtform.chkumnotify" + types[i]
    var srcitm = eval(srcstr)
    var srcval

    for (var j = 0; j < srcitm.length; j++)
    {
      if (srcitm[j].checked)
      {
         srcval = srcitm[j].value
         break
      }
    }

    if (srcval == "all")
    {
      eval("tgtform.umnotify" + types[i] + "urgent").value = "true"
      eval("tgtform.umnotify" + types[i] + "normal").value = "true"
    }
    else if (srcval == "urgent")
    {
      eval("tgtform.umnotify" + types[i] + "urgent").value = "true"
      eval("tgtform.umnotify" + types[i] + "normal").value = "false"
    }
    else
    {
      eval("tgtform.umnotify" + types[i] + "urgent").value = "false"
      eval("tgtform.umnotify" + types[i] + "normal").value = "false"
    }
  }
  tgtform.submit()
}

/*****************************************************************************/
/* initialiseNotificationForm                                                */
/*                                                                           */
/* Massage the widgets on the form to match the parameters in the directory. */
/*                                                                           */
/* tgtform  - the form to manipulate                                         */
/*****************************************************************************/
function initialiseNotificationForm(tgtform)
{
  for (var i = 0; i < types.length; i++)
  {
    var target
    var ugt = eval("tgtform.umnotify" + types[i] + "urgent.value")
    var nml = eval("tgtform.umnotify" + types[i] + "normal.value")

    if (ugt == "true")
    {
      if (nml == "true")
      {
         target = "all"
      }
      else
      {
         target = "urgent"
      }
    }
    else
    {
      target = "none"
    }

    selectMatchingRadio(eval("tgtform.chkumnotify" + types[i]), target)
  }
}

/*****************************************************************************/
/* Methods used by the DisplayConfMsgbox pages.                              */
/*                                                                           */
/* submitDCMBForm                                                            */
/*                                                                           */
/* submits a display conf_msgbox form                                        */
/*                                                                           */
/* Parameters:                                                               */
/*                                                                           */
/* update   - set true if this is an update operation.                       */
/* complete - set true if the modification operation is complete.            */
/* commit   - set true if this is an update that should be committed to the  */
/*            directory.                                                     */
/*****************************************************************************/
function submitDCMBForm(update, complete, commit)
{
  //---------------------------------------------------------------------------
  // IE is bugged in that it POSTs the HTML contents of the sound recording
  // buttons unless we explicitly disable them.
  //---------------------------------------------------------------------------
  if (document.MF._record)
  {
    document.MF._record.disabled = true;
  }
  if (document.MF._play)
  {
    document.MF._play.disabled = true;
  }
  if (document.MF._stop)
  {
    document.MF._stop.disabled = true;
  }

  document.MF.Update.value=update;
  document.MF.Commit.value=commit;
  document.MF.Complete.value=complete;
  document.MF.submit();
}

/*****************************************************************************/
/* Method: checkAutoSelection                                                */
/*                                                                           */
/* It sets the internal attributes identified by root and the attrprefix to  */
/* match the values of the autoset checkboxes.                               */
/*                                                                           */
/* Parameters:                                                               */
/*                                                                           */
/* root       - The root parameter to set.  The value of this attribute is   */
/*              set if a single hidden parameter is set.                     */
/* attrprefix - prefix used to identify the autoset parameters to scan, and  */
/*              the hidden parameters to modify.                             */
/*                                                                           */
/*****************************************************************************/
function checkAutoSelection(root, attrprefix)
{
  var elements = document.MF.elements

  for (var i = 0 ; i < elements.length; i++)
  {
    if (elements[i].name.indexOf(attrprefix) == 0)
    {
      var target = eval("document.MF." + elements[i].name.substring(7))

      if (elements[i].checked)
      {
        target.value = "yes"
        root.value = "yes"
      }
      else
      {
        target.value = "no"
      }
    }
  }
}

/*****************************************************************************/
/* initialiseAutoSelection                                                   */
/*                                                                           */
/* Set the values of the autoset parameters to reflect the state of the      */
/* hidden attribute values.                                                  */
/*****************************************************************************/
function initialiseAutoSelection ()
{
  var elements = document.MF.elements

  for (var i = 0 ; i < elements.length; i++)
  {
    if (elements[i].name.indexOf("autoset_") == 0)
    {
      var source = eval("document.MF." + elements[i].name.substring(7));
      if (source.value == "yes")
      {
        elements[i].checked = true
      }
    }
  }
}

/*****************************************************************************/
/* disableNotificationForm                                                   */
/*                                                                           */
/* Disable the components of a notification form.                            */
/*****************************************************************************/
function disableNotificationForm (tgtform)
{
  if (tgtform.notifyhotlist != null)
  {
    tgtform.notifyhotlist.disabled = true;
  }
  for (var i = 0; i < types.length; i++)
  {
    var radioname = eval("tgtform.chkumnotify" + types[i])

    for (var j = 0; j < radioname.length; j++)
    {
      radioname[j].disabled=true
    }
  }
}

/*****************************************************************************/
/* enableNotificationForm                                                    */
/*                                                                           */
/* Enable the components of a notification form.                             */
/*****************************************************************************/
function enableNotificationForm (tgtform)
{
  if (tgtform.notifyhotlist != null)
  {
    tgtform.notifyhotlist.disabled = false;
  }

  for (var i = 0; i < types.length; i++)
  {
    var radioname = eval("tgtform.chkumnotify" + types[i])

    for (var j = 0; j < radioname.length; j++)
    {
      radioname[j].disabled=false
    }
  }
}


/*****************************************************************************/
/* getInvalidNicknameChars                                                   */
/*                                                                           */
/* Searches a given nickname for invalid characters and returns a string     */
/* containing the invalid characters that have been found.                   */
/*****************************************************************************/
function getInvalidNicknameChars (nickname)
{
   var validCharacters = "1234567890ABCDEFGHIJKLMOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,()~.`!0 @";
   var checkCharacter;
   var invalidCharacter = "";

   for (var i=0; i<nickname.length; i++)
   {
     checkCharacter = "" + (nickname.substring(i, i+1)).toLowerCase();
     if (validCharacters.indexOf(checkCharacter) == "-1")
     {
       /**********************************************************************/
       /* We've found a character that isn't in the valid character set, so  */
       /* add it to the list.                                                */
       /**********************************************************************/
       invalidCharacter = invalidCharacter + checkCharacter;
     }
   }
   return (invalidCharacter);
}

/*****************************************************************************/
/* checkEmailAddress                                                         */
/*                                                                           */
/* Check that a given email address is valid.                                */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* email      A string containing the email address to check                 */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if the email address is valid, false otherwise.                      */
/*****************************************************************************/

function checkEmailAddress(email)
{
   var linvalidEmailCharacters = "<>()[]\\,;\": ";
   var checkCharacter;
   var lreturn = true;
   var elength = email.length
   for (var i=0; i < email.length; i++)
   {
     checkCharacter = "" + (email.substring(i, i+1));
     if (linvalidEmailCharacters.indexOf(checkCharacter) != -1)
     {
       lreturn = false;
     }
     if ((email.charCodeAt(i) < 32) || ( email.charCodeAt(i) > 126))
     {
       lreturn = false;
     }
   }

   if ((email.indexOf("@") == -1) ||
                                (email.indexOf("@") != email.lastIndexOf("@")))
   {
     lreturn = false;
   }

   if (email.indexOf(".") == -1)
   {
     lreturn = false;
   }

   if (email.indexOf("@") == 0 || email.indexOf("@") == (elength-1))
   {
     lreturn = false;
   }

   if (email.indexOf(".") == 0 || email.lastIndexOf(".") == (elength-1))
   {
     lreturn = false;
   }

   return lreturn;
}

/*****************************************************************************/
/* generateCMBLineTypeString                                                 */
/*                                                                           */
/* Generates the name of the type of phone line corresponding to the         */
/* following indexes:                                                        */
/*                                                                           */
/*   0 -> Primary Landline                                                   */
/*   1 -> Landline                                                           */
/*   2 -> Cellular (Wireless)                                                */
/*****************************************************************************/
function generateCMBLineTypeString (index)
{
   switch (index)
   {
   case 0:
      document.write(dc2js1);
      break;
   case 1:
      document.write(dc2js2);
      break;
   case 2:
      document.write(dc2js3);
      break;
   }
}

/*****************************************************************************/
/* getCMBLineTypeString                                                      */
/*                                                                           */
/* Returns the name of the type of phone line corresponding to the           */
/* following indexes:                                                        */
/*                                                                           */
/*   0 -> Primary Landline                                                   */
/*   1 -> Landline                                                           */
/*   2 -> Cellular (Wireless)                                                */
/*   3 -> Extension (SFM)                                                    */
/*   4 -> Group (PFM)                                                        */
/*****************************************************************************/
function getCMBLineTypeString (index)
{
  var linetype;

  switch (index)
  {
  case 0:
     linetype = dc2js4;
     break;
  case 1:
     linetype = dc2js2;
     break;
  case 2:
     linetype = dc2js5;
     break;
  case 3:
     linetype = dc2js6;
     break;
  case 4:
     linetype = dc2js7;
     break;
  }

  return(linetype)
}

/*****************************************************************************/
/* generateCMBGreetingList                                                   */
/*                                                                           */
/* Generates the list of greetings for a CMB, based on:                      */
/*                                                                           */
/*   current mailbox type (1 - PFM, 2- SFM, 0 - IM)                          */
/*   phone line type (Primary landline, Landline, Cellular)                  */
/*   greetings recorded (comma separated list)                               */
/*   cmb phone number                                                        */
/*   name of currently active greeting                                       */
/*   whether this (wireless) line is unitialized                             */
/*   whether the auto-attendant function is active (PBM only).               */
/*****************************************************************************/
function generateCMBGreetingList (mbxtype,
                                  linetype,
                                  greetings,
                                  cmbnumber,
                                  activegreetingstr,
                                  uninitialized,
                                  autoattendant)
{
   var numattrs        = 6;

   /**************************************************************************/
   /* Constants for the greeting types.                                      */
   /**************************************************************************/
   var attr_SAP        = 0;
   var attr_name       = 1;
   var attr_allcalls   = 2;
   var attr_extended   = 3;
   var attr_family     = 4;
   var attr_business   = 5;

   var attrvalue       = new Array("SameAsPrimary",
                                   "SpokenName",
                                   "AllCalls",
                                   "Extended_Absence",
                                   "GroupMailbox",
                                   "AutoAttendant");
   var optstr          = new Array(dc2js8,
                                   dc2js9 + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
                                   dc2js10,
                                   dc2js11,
                                   dc2js22,
                                   dc2js22);
   var optavail        = new Array(0,1,0,0,0,0);
   var numopts         = 1;
   var activegreeting  = 0;

   if (uninitialized == 1)
   {
      optavail[attr_allcalls] = 0;
      numopts = 0;
   }
   else
   {
      if (activegreetingstr == "")
      {
         activegreeting = 1;
      }
      else
      {
         for (var i = 0; i < numattrs; i++)
         {
            if (activegreetingstr == attrvalue[i])
            {
               activegreeting = i;
            }
         }
      }

      switch (mbxtype)
      {
      case 0:
      case 3:
      case 5:
         /********************************************************************/
         /* Individual mailbox, Individual Business mailbox and Secondary    */
         /* Business Mailbox.  Deliberate fall through as all have same      */
         /* options.                                                         */
         /********************************************************************/
         switch (linetype)
         {
         case 1:
         case 2:
            /*****************************************************************/
            /* Landline and Wireless.  We want SameAsPrimary here in         */
            /* addition to the Personal and Extended_Absence.  Deliberate    */
            /* fall-through.                                                 */
            /*****************************************************************/
            optavail[attr_SAP] = 1;
            numopts++;
         case 0:
            /*****************************************************************/
            /* Primary Landline.                                             */
            /*****************************************************************/
            optavail[attr_allcalls] = findSubString(greetings,attrvalue[attr_allcalls],numopts);
            if (optavail[attr_allcalls] == 1) {numopts++};
            optavail[attr_extended] = findSubString(greetings,attrvalue[attr_extended],numopts);
            if (optavail[attr_extended] == 1) {numopts++};
            break;
         }
         break;
      case 1:
         /********************************************************************/
         /* Primary Family mailbox aka Group mailbox.                        */
         /********************************************************************/
         switch (linetype)
         {
         case 0:
            /*****************************************************************/
            /* Primary Landline.                                             */
            /*****************************************************************/
            optavail[attr_family] = findSubString(greetings,attrvalue[attr_family],numopts);
            if (optavail[attr_family] == 1) {numopts++};
            break;
         case 1:
         case 2:
            /*****************************************************************/
            /* Landline and Wireless.  Deliberate fall-through.              */
            /*****************************************************************/
            optavail[attr_allcalls] = findSubString(greetings,attrvalue[attr_allcalls],numopts);
            if (optavail[attr_allcalls] == 1) {numopts++};
            optavail[attr_extended] = findSubString(greetings,attrvalue[attr_extended],numopts);
            if (optavail[attr_extended] == 1) {numopts++};
            optavail[attr_SAP] = 1;
            numopts++;
            break;
         default:
            /*****************************************************************/
            /* Error!                                                        */
            /*****************************************************************/
            error = 1;
            break;
         }
         break;
      case 2:
         /********************************************************************/
         /* Secondary Family mailbox aka Shared Mailbox.                     */
         /********************************************************************/
         switch (linetype)
         {
         case 0:
            /*****************************************************************/
            /* Primary Landline.                                             */
            /*****************************************************************/
            optavail[attr_allcalls] = findSubString(greetings,attrvalue[attr_allcalls],numopts);
            if (optavail[attr_allcalls] == 1) {numopts++};
            optavail[attr_extended] = findSubString(greetings,attrvalue[attr_extended],numopts);
            if (optavail[attr_extended] == 1) {numopts++};
            break;
         case 1:
            /*****************************************************************/
            /* Landline.                                                     */
            /*****************************************************************/
            optavail[attr_SAP] = 1;
            optavail[attr_name] = 0;
            numopts = 1;
            break;
         case 2:
            /*****************************************************************/
            /* Wireless line.  There are two possibilities here:             */
            /*                                                               */
            /* - SFM wireless line, in which case we want to display the     */
            /*   greetings options                                           */
            /* - PFM wireless line, in which case we only display 'Same As   */
            /*   Primary'                                                    */
            /*                                                               */
            /* The second is true if the greetings available is given only   */
            /* as 'SameAsPrimary'                                            */
            /*****************************************************************/
            if (greetings == attrvalue[attr_SAP])
            {
               /**************************************************************/
               /* PFM wireless line.                                         */
               /**************************************************************/
               optavail[attr_SAP] = 1;
               optavail[attr_name] = 0;
               numopts = 1;
            }
            else
            {
               /**************************************************************/
               /* SFM wireless line.                                         */
               /**************************************************************/
               optavail[attr_allcalls] = findSubString(greetings,attrvalue[attr_allcalls],numopts);
               if (optavail[attr_allcalls] == 1) {numopts++};
               optavail[attr_extended] = findSubString(greetings,attrvalue[attr_extended],numopts);
               if (optavail[attr_extended] == 1) {numopts++};
               optavail[attr_SAP] = 1;
               numopts++;
            }
            break;
         default:
            /*****************************************************************/
            /* Error!                                                        */
            /*****************************************************************/
            error = 1;
            break;
         }
         break;
      default:
         /********************************************************************/
         /* Error!                                                           */
         /********************************************************************/
         error = 1;
         break;
      case 4:
         /********************************************************************/
         /* Primary Business mailbox.                                        */
         /********************************************************************/
         switch (linetype)
         {
         case 0:
            /*****************************************************************/
            /* Primary Landline.  If the auto-attendant feature is turned    */
            /* on, present the group greeting option.  If not, present the   */
            /* personal greeting options for the mailbox.                    */
            /*****************************************************************/
            if (autoattendant == 1)
            {
            optavail[attr_business] = findSubString(greetings,attrvalue[attr_business],numopts);
            if (optavail[attr_business] == 1) {numopts++};
            }
            else
            {
               optavail[attr_allcalls] = findSubString(greetings,attrvalue[attr_allcalls],numopts);
               if (optavail[attr_allcalls] == 1) {numopts++};
               optavail[attr_extended] = findSubString(greetings,attrvalue[attr_extended],numopts);
               if (optavail[attr_extended] == 1) {numopts++};
            }
            break;
         case 1:
         case 2:
            /*****************************************************************/
            /* Landline and Wireless. Deliberate fall-through.               */
            /*****************************************************************/
            optavail[attr_allcalls] = findSubString(greetings,attrvalue[attr_allcalls],numopts);
            if (optavail[attr_allcalls] == 1) {numopts++};
            optavail[attr_extended] = findSubString(greetings,attrvalue[attr_extended],numopts);
            if (optavail[attr_extended] == 1) {numopts++};
            optavail[attr_SAP] = 1;
            numopts++;
            break;
         default:
            /*****************************************************************/
            /* Error!                                                        */
            /*****************************************************************/
            error = 1;
            break;
         }
         break;
      }
   }

   generateGreetingsDropDown(numopts,
                             numattrs,
                             optavail,
                             optstr,
                             attrvalue,
                             activegreeting,
                             "cmbset_" + cmbnumber + "_umactivegreetingid");
}

/*****************************************************************************/
/* generatePTNGreetingList                                                   */
/*                                                                           */
/* Generates the list of greetings for a PTN. Called only when the PFM is in */
/* Group Mailbox enabled mode (i.e. generateCMBGreetingList will give a list */
/* containing some or all of {'System Greeting', 'Family Greeting'})         */
/*                                                                           */
/*   greetings recorded (comma separated list)                               */
/*   name of currently active greeting                                       */
/*****************************************************************************/
function generatePTNGreetingList (greetings, activegreetingstr)
{
   var numattrs        = 3;

   /**************************************************************************/
   /* Constants for the greeting types.                                      */
   /**************************************************************************/
   var attr_name       = 0;
   var attr_allcalls   = 1;
   var attr_extended   = 2;

   var attrvalue       = new Array("SpokenName",
                                   "AllCalls",
                                   "Extended_Absence");
   var optstr          = new Array(dc2js9 + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
                                   dc2js10,
                                   dc2js11);
   var optavail        = new Array(1,0,0);
   var numopts         = 1;
   var activegreeting  = 0;

   /**************************************************************************/
   /* We define which is the currently active greeting by setting up         */
   /* activegreeting to be an index into the value arrays defined above.     */
   /* This index defaults to 1 (i.e. the SpkenName AKA System Greeting)      */
   /**************************************************************************/
   if (activegreetingstr == "")
   {
      activegreeting = 0;
   }
   else
   {
      for (var i = 0; i < numattrs; i++)
      {
         if (activegreetingstr == attrvalue[i])
         {
            activegreeting = i;
         }
      }
   }

   /**************************************************************************/
   /* Check which greetings are recorded (i.e. are present in the greetings  */
   /* inpu argument) and add the available ones to the list to be displayed. */
   /**************************************************************************/
   optavail[attr_allcalls] = findSubString(greetings,attrvalue[attr_allcalls],numopts);
   if (optavail[attr_allcalls] == 1) {numopts++};
   optavail[attr_extended] = findSubString(greetings,attrvalue[attr_extended],numopts);
   if (optavail[attr_extended] == 1) {numopts++};

   generateGreetingsDropDown(numopts,
                             numattrs,
                             optavail,
                             optstr,
                             attrvalue,
                             activegreeting,
                             "ptn_activegreetingid");

}

/*****************************************************************************/
/* generateGreetingsDropDown                                                 */
/*                                                                           */
/* takes the output from the generate???List functions, along with the name  */
/* of the parameter to which the drop down relates, and turns it into a      */
/* drop-down list with the correct member selected                           */
/*                                                                           */
/* numopts  - Number of values recorded (i.e. available to be displayed)     */
/* numattrs - Number of possible values this parameter could take            */
/* optavail - Array of 1s and 0s defining which greetings are available      */
/* optstr   - Array of the display names for each greeting                   */
/* attrvalue - Array of the actual values submitted for each greeting.       */
/* activegreeting - the index into the arrays of the selected greeting.      */
/* xiparameterName - The parameter name that will be submitted on the        */
/*                   request with the value of this <SELECT> dropdown        */
/*****************************************************************************/
function generateGreetingsDropDown(numopts,
                                   numattrs,
                                   optavail,
                                   optstr,
                                   attrvalue,
                                   activegreeting,
                                   xiparameterName)
{

   /**************************************************************************/
   /* Check how many options there are to display.                           */
   /**************************************************************************/
   if (numopts == 0)
   {
      /***********************************************************************/
      /* No options.  This is valid, e.g. for a as yet unprovisioned         */
      /* wireless line.                                                      */
      /***********************************************************************/
      document.write("&nbsp;");
   }
   else if (numopts == 1)
   {
      /***********************************************************************/
      /* Only one, no need for a list.                                       */
      /***********************************************************************/
      for (var i = 0; i < numattrs; i++)
      {
         if (optavail[i] == 1)
         {
            document.write(optstr[i]);
         }
      }
   }
   else
   {
      document.write("<SELECT CLASS=\"umsselect\" name=" + xiparameterName + ">");
      for (var i = 0; i < numattrs; i++)
      {
         if (optavail[i] == 1)
         {
            if (activegreeting == i)
            {
               document.write("<OPTION value=" + attrvalue[i] + " SELECTED>" + optstr[i] + "</OPTION>");
            }
            else
            {
               document.write("<OPTION value=" + attrvalue[i] + ">" + optstr[i] + "</OPTION>");
            }
         }
      }
      document.write("</SELECT>");
   }
}

/*****************************************************************************/
/* generateCMBNumber                                                         */
/*                                                                           */
/* Generates either the phone number passed in, or "<Add new Phone #>" if    */
/* the number ends with the special string "-1".                             */
/*                                                                           */
/*****************************************************************************/
function generateCMBNumber (number,
                            variant,
                            uninitialized)
{
   if (uninitialized == 1)
   {
      document.write("&lt;" + dc2js12 + "&gt;");
   }
   else
   {
      document.write(presentTelephone(number, variant));
   }
}

/*****************************************************************************/
/* generateSFMKey                                                            */
/*                                                                           */
/* Generates the 'Key Pressed from Group Mailbox to reach this Shared        */
/* Mailbox' value.                                                           */
/*                                                                           */
/*****************************************************************************/
function generateSFMKey (linetype,
                         url,
                         key)
{
   if (linetype == 0)
   {
      /***********************************************************************/
      /* Primary landline.  This case wants the url link.                    */
      /***********************************************************************/
      if (key == "")
      {
         document.write("&nbsp;");
      }
      else
      {
         document.write("<a href=\"" + url + "\"><u>" + key + "</u></a>");
      }
   }
   else
   {
      /***********************************************************************/
      /* No url.                                                             */
      /***********************************************************************/
      if (key == "")
      {
         document.write("&nbsp;");
      }
      else
      {
         document.write(key);
      }
   }
}

/*****************************************************************************/
/* findSubString                                                             */
/*                                                                           */
/* Searches (case-insensitive) for a substring in a string.  Returns 1 if    */
/* successful, 0 if not.                                                     */
/*****************************************************************************/
function findSubString (str,
                        substr)
{
   var found = 0;
   var re = new RegExp(substr);
   if (!(str.search(re) == -1))
   {
      found = 1;
   }
   return(found);
}

/*****************************************************************************/
/* generateSMBActive                                                         */
/*                                                                           */
/* Generates an option list for the active status of a submailbox (aka       */
/* shared mailbox).                                                          */
/*                                                                           */
/*   mailbox count, PFM -> 0                                                 */
/*   submailbox naming attribute                                             */
/*   'blocked' attribute                                                     */
/*    'blockedstatusdescr' attribute                                         */
/*                                                                           */
/*****************************************************************************/
function generateSMBActive (mbcount,
                            namingattr,
                            blocked,
                            blockedstatusdescr)
{
   if (mbcount == 0)
   {
      document.write(dc2js13);
   }
   else
   {
      if (blockedstatusdescr.toLowerCase() == dc2js14)
      {
         document.write("<SELECT CLASS=\"umsselect\" name=dis_local_" + namingattr + "_umblocked DISABLED>");
         document.write("<OPTION value=yes SELECTED>" + dc2js15 + "</option>");
      }
      else
      {
         document.write("<SELECT CLASS=\"umsselect\" name=sfm_" + namingattr + "_umblocked id=sfm_" + namingattr + "_umblocked>");

         if (blocked == "no")
         {
            document.write("<OPTION value=no SELECTED>" + dc2js13 + "</option>");
            document.write("<OPTION value=yes>" + dc2js15 + "</option>");
         }
         else
         {
            document.write("<OPTION value=no>" + dc2js13 + "</option>");
            document.write("<OPTION value=yes SELECTED>" + dc2js15 + "</option>");
         }
      }
      document.write("</SELECT>");
   }
}

/*****************************************************************************/
/* updateInHoursTrigger                                                      */
/*                                                                           */
/* Updates and returns value for the multi-valued attribute inHoursTriggerA, */
/* based on the old notification address and a new one, plus the device type */
/* prefix.                                                                   */
/*                                                                           */
/*****************************************************************************/
function updateInHoursTrigger (newaddress,
                               oldaddress,
                               inhourstrigger,
                               hotlistchecked,
                               prefix)
{
   var tmpstr = "";
   var newtrigger = inhourstrigger;
   var indexnew;
   var indexold;
   var index1;
   var index2;
   var oldentry = "";
   var newentry = "";

   /**************************************************************************/
   /* Build up full inHoursTriggerA values from the old and new notification */
   /* addresses.                                                             */
   /**************************************************************************/
   if (oldaddress != "")
   {
      oldentry = prefix + "=" + oldaddress;
   }

   if (newaddress != "")
   {
      newentry = prefix + "=" + newaddress;
   }

   if ((hotlistchecked) && (newaddress != ""))
   {
      /***********************************************************************/
      /* Key contact notifications to newaddress are enabled.  Check whether */
      /* the old and new entries are present in the attribute                */
      /* inHoursTriggerA.                                                    */
      /***********************************************************************/
      indexold = findIndex(inhourstrigger, oldentry);
      indexnew = findIndex(inhourstrigger, newentry);

      if (indexnew == -1)
      {
         if (indexold == -1)
         {
            /*****************************************************************/
            /* Add the newentry address to the end.                          */
            /*****************************************************************/
            if (inhourstrigger.length != 0)
            {
               tmpstr = ";;";
            }

            tmpstr += newentry;
            newtrigger = inhourstrigger + tmpstr;
         }
         else
         {
            /*****************************************************************/
            /* Old present, but not new - replace existing entry.            */
            /*****************************************************************/
            index2 = inhourstrigger.indexOf(";;", indexold);
            tmpstr = inhourstrigger.substring(0, indexold);
            tmpstr += newentry;

            if (index2 != -1)
            {
               tmpstr += inhourstrigger.substring(index2,
                                                  inhourstrigger.length);
            }

            newtrigger = tmpstr;
         }
      }
   }
   else
   {
      /***********************************************************************/
      /* Key contact notifications are disabled or no new address has been   */
      /* supplied.  Check whether the old entry is present in the attribute  */
      /* inHoursTriggerA and then remove it.                                 */
      /***********************************************************************/
      index1 = findIndex(inhourstrigger, oldentry)

      if (index1 != -1)
      {
         index2 = inhourstrigger.indexOf(";;", index1);

         if (index2 == -1)
         {
            /*****************************************************************/
            /* No entries in inHoursTriggerA after this one - copy           */
            /* everything before it.                                         */
            /*****************************************************************/
            tmpstr = inhourstrigger.substring(0, (index1 - 2));
         }
         else if (index1 == 0)
         {
            /*****************************************************************/
            /* This one is the first entry - copy everything after it.       */
            /*****************************************************************/
            tmpstr = inhourstrigger.substring((index2 + 2),
                                              inhourstrigger.length);
         }
         else
         {
            /*****************************************************************/
            /* This one is in the middle - copy entries before and after.    */
            /*****************************************************************/
            tmpstr = inhourstrigger.substring(0, index1);
            tmpstr += inhourstrigger.substring((index2 + 2),
                                               inhourstrigger.length);
         }

         newtrigger = tmpstr;
      }
   }

   return newtrigger;
}

/*****************************************************************************/
/* findIndex                                                                 */
/*                                                                           */
/* Returns the index of a string, -1 if it is not present, or if the string  */
/* requested is blank.                                                       */
/*****************************************************************************/
function findIndex (string,
                    substring)
{
   if (substring == "")
   {
      return -1;
   }
   else
   {
      return string.indexOf(substring);
   }
}

/*****************************************************************************/
/* selectHotList                                                             */
/*                                                                           */
/* Sets up the hotlist parameter based on the notification address, device   */
/* prefix and inhourstrigger attribute.                                      */
/*****************************************************************************/
function selectHotList (parameter,
                        trigger,
                        address,
                        prefix)
{
   var fulladdress = prefix + "=" + address;

   if ((address != "") &&
       (trigger != "") &&
       (trigger.indexOf(fulladdress) != -1))
   {
      parameter.checked = true;
   }
   else
   {
      parameter.checked = false;
   }
}

/*****************************************************************************/
/* isBlank                                                                   */
/*                                                                           */
/* Determines whether a given string solely contains whitespace.             */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* s The string to check.                                                    */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if the string only contains whitespace, false otherwise.             */
/*                                                                           */
/*****************************************************************************/
function isBlank(s)
{
  for (var i = 0; i < s.length; i++)
  {
    var c = s.charAt(i);

    if (!isWhitespace(c))
    {
      return false;
    }

  }

  return true;
}

/*****************************************************************************/
/* isLetter                                                                  */
/*                                                                           */
/* Determines whether a given character is a letter (a-zA-Z)                 */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* c The character to check.                                                 */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if the character is a letter, false otherwise.                       */
/*                                                                           */
/*****************************************************************************/
function isLetter (c)
{   return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}

/*****************************************************************************/
/* isDigit                                                                   */
/*                                                                           */
/* Determines whether a given character is a digit (0-9)                     */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* c The character to check.                                                 */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if the character is a digit, false otherwise.                        */
/*                                                                           */
/*****************************************************************************/
function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}

/*****************************************************************************/
/* isLetterOrDigit                                                           */
/*                                                                           */
/* Determines whether a given character is a letter (a-zA-Z) or a digit      */
/* (0-9)                                                                     */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* c The character to check.                                                 */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if the character is a letter or a digit, false otherwise.            */
/*                                                                           */
/*****************************************************************************/
function isLetterOrDigit (c)
{   return (isLetter(c) || isDigit(c))
}

/*****************************************************************************/
/* isWhitespace                                                              */
/*                                                                           */
/* Determines whether a given character is whitespace (\n\r\t )              */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* c The character to check.                                                 */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if the character is whitepsace, false otherwise.                     */
/*                                                                           */
/*****************************************************************************/
function isWhitespace(c)
{
    return ((c == "\n") || (c == "\r") ||(c == "\t") || (c == " "));
}

/*****************************************************************************/
/* isNumeric                                                                 */
/*                                                                           */
/* Determines whether a given string solely contains a positive integer.     */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* s The string to check.                                                    */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if the string is a positive integer, false otherwise.                */
/*                                                                           */
/*****************************************************************************/
function isNumeric(s)
{   var i;

    for (i = 0; i < s.length; i++)
    {
        var c = s.charAt(i);

        if (! (isDigit(c) ) ) return false;
    }

    return true;
}

/**PROC+**********************************************************************/
/* Name:      trim                                                           */
/*                                                                           */
/* Purpose:   Remove lerading & trailing whitespace.                         */
/*                                                                           */
/* Returns:   Trimmed string.                                                */
/*                                                                           */
/* Params:    IN     myField      - string to trim whitespace from           */
/*                                                                           */
/**PROC-**********************************************************************/

function trim(myField)
{
  while (isWhitespace(myField.charAt(0)))
  {
    myField = myField.slice(1,myField.length);
  }
  while (isWhitespace(myField.charAt((myField.length-1))))
  {
    myField = myField.slice(0,(myField.length-1));
  }
  return myField;
}

/**PROC+**********************************************************************/
/* Name:      presentTelephone                                               */
/*                                                                           */
/* Purpose:   DCL-written procedure to present telephone numbers.            */
/*                                                                           */
/* Returns:   US: A presentable telephone number in the format NPA-NXX-XXXX. */
/*            UK: The unmodified telephone number.                           */
/*                                                                           */
/* Params:    IN     number       - the telephone number                     */
/*                                                                           */
/**PROC-**********************************************************************/

function presentTelephone(number, variant)
{
  var retval = number;

  if ((number.length == 10) && (isNumeric(number)) && (variant != "UK"))
  {
    retval = number.substring(0, 3) + "-" + number.substring(3, 6) + "-" + number.substring(6);
  }

  return retval;
}

/**PROC+**********************************************************************/
/* Name:      unpresentTelephone                                             */
/*                                                                           */
/* Purpose:   DCL-written procedure to remove the presentation from          */
/*            telephone numbers.                                             */
/*                                                                           */
/* Returns:   A string of numbers - the telephone number in plain format.    */
/*                                                                           */
/* Params:    IN     number       - telephone number with optional spacing   */
/*                                  characters.                              */
/*                                                                           */
/**PROC-**********************************************************************/
function unpresentTelephone(number)
{
  var retval = "";
  var spacerChars="() -";
  for (var i = 0; i < number.length; i++)
  {
    if (spacerChars.indexOf(number.charAt(i)) == -1)
    {
      retval = retval +  number.charAt(i);
    }
  }
  return retval;
}

/**PROC+**********************************************************************/
/* Name:      formatDate                                                     */
/*                                                                           */
/* Purpose:   Format email/fax/voicemail recieved date so that AM/PM are     */
/*            converted to am/pm.                                            */
/*                                                                           */
/* Returns:   Converted date string                                          */
/*                                                                           */
/* Params:    IN     dateString   - the original date string                 */
/*                                                                           */
/**PROC-**********************************************************************/

function formatDate(dateString)
{
  var len = dateString.length;

  if (len > 2)
  {
    var ampm = dateString.substring(len - 2);

    if (ampm == "AM" || ampm == "PM")
    {
      dateString = dateString.substring(0, len - 2) + ampm.toLowerCase();
    }
  }

  return dateString;
}


/*****************************************************************************/
/* isValidIPAddress                                                          */
/*                                                                           */
/* Determines whether a string is a valid IP address or not.                 */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* s  The string to check                                                    */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* True or false.                                                            */
/*****************************************************************************/
function isValidIPAddress(s)
{
   var isIPAddress = false;
   var subStrings = s.split('.');
   var numericCount = 0;

   for (var i = 0; i < subStrings.length; i++)
   {
      if (isNumericIPAddrElement(subStrings[i]))
      {
         numericCount++;
      }
   }

   if ((subStrings.length == 4) && (numericCount == 4))
   {
      isIPAddress = true;
   }

   return (isIPAddress);
}

function isNumericIPAddrElement(s)
{
   if (isNumeric(s))
   {
      var num = parseInt(s);
      if ( (num >= 0) && (num <= 255) )
      {
        return true;
      }
   }
   return false;
}


/*****************************************************************************/
/* isDomain                                                                  */
/*                                                                           */
/* Determines whether a string is a valid domain name.  Note though, it      */
/* only checks the characters and whether there is at least one '.' in the   */
/* string.                                                                   */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* s   the string to check                                                   */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* True or false                                                             */
/*****************************************************************************/
function isDomain(s)
{
   var echars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.[]"

   if (!hasOnlyGoodChars(s, echars))
   {
     return false;
   }

   var i = 1;
   var sLength = s.length;

   while ((i < sLength) && (s.charAt(i) != "."))
   {
     i++;
   }

   if ((i >= sLength - 1) || (s.charAt(i) != "."))
   {
     return false;
   }

   return true;
}

/*****************************************************************************/
/* hasOnlyGoodChars                                                          */
/*                                                                           */
/* Checks the string passed in against a list of 'good' characters.          */
/*                                                                           */
/* Parameters                                                                */
/*                                                                           */
/* string     string to test                                                 */
/* goodlist   string containing the 'good' characters.                       */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* If any of the characters in 'string' are not in 'goodlist', return false  */
/* else return true.                                                         */
/*****************************************************************************/
function hasOnlyGoodChars(string, goodlist)
{
   for (var i =0; i <= string.length -1; i++)
   {
      if (goodlist.indexOf(string.charAt(i)) == -1)
      {
         return false;
      }
   }
   return true;
}

/*****************************************************************************/
/* hasBadChars                                                               */
/*                                                                           */
/* Checks the string passed in against a list of 'bad' characters.           */
/*                                                                           */
/* Parameters                                                                */
/*                                                                           */
/* string     string to test                                                 */
/* badlist    string containing the 'bad' characters.                        */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* If any of the characters in 'string' are in 'badlist', return true        */
/* else return false.                                                        */
/*****************************************************************************/
function hasBadChars(string, badlist)
{
  /***************************************************************************/
  /* Detect characters from the bad set appearing in the string.             */
  /***************************************************************************/
  for (var ii=0; ii < string.length; ii++)
  {
    var cc = string.charAt(ii);
    if (badlist.indexOf(cc) != -1)
    {
      return true;
    }
  }

  return false;
}

/*****************************************************************************/
/* isGoodServer                                                              */
/*                                                                           */
/* Checks whether the passed string represents a good DNS name/IP address    */
/* for a remote machine.                                                     */
/*                                                                           */
/* Parameters                                                                */
/*                                                                           */
/* s          string to test                                                 */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true/false                                                                */
/*                                                                           */
/* Notes                                                                     */
/*                                                                           */
/* First checks whether the string is all numeric - if so we treat it as an  */
/* IP address.  If not, we treat it as a DNS name.  Then call on to the      */
/* relevant functions above.                                                 */
/*****************************************************************************/
function isGoodServer(string)
{
   var echars = "0123456789."

   if (!hasOnlyGoodChars(string, echars))
   {
      /***********************************************************************/
      /* Treat as a DNS name, as it has one or more characters that are not  */
      /* 1-9 or '.'                                                          */
      /***********************************************************************/
      return (isDomain(string));
   }
   else
   {
      /***********************************************************************/
      /* Treat as IP address.                                                */
      /***********************************************************************/
      return (isValidIPAddress(string));
   }
}

/*****************************************************************************/
/* compareCoS                                                                */
/*                                                                           */
/* Does a case insensitive string comparison of the two parameters,          */
/* returning the result.                                                     */
/*                                                                           */
/*****************************************************************************/
function compareCoS(a, b)
{
  a = a.toUpperCase()
  b = b.toUpperCase()

  if (a == b)
  {
    retval = true;
  }
  else
  {
    retval = false;
  }

  return(retval)
}

/*****************************************************************************/
/* isBrowserNetscape                                                         */
/*                                                                           */
/* Work out whether the browser is Netscape or not.                          */
/*                                                                           */
/* Parameters                                                                */
/*                                                                           */
/* userAgent  the browser user agent string                                  */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true   if the browser is Netscape                                         */
/* false  otherwise                                                          */
/*****************************************************************************/
function isBrowserNetscape(userAgent)
{
  var agent      = userAgent.toLowerCase();
  var isNetscape = agent.indexOf('mozilla') != -1 &&
                   agent.indexOf('compatible') == -1 &&
                   agent.indexOf('opera') == -1 &&
                   agent.indexOf('webtv') == -1;

  return isNetscape;
}

/*****************************************************************************/
/* isBrowserIE                                                               */
/*                                                                           */
/* Work out whether the browser is IE or not.                                */
/*                                                                           */
/* Parameters                                                                */
/*                                                                           */
/* userAgent  the browser user agent string                                  */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true   if the browser is IE                                               */
/* false  otherwise                                                          */
/*****************************************************************************/
function isBrowserIE(userAgent)
{
  var agent = userAgent.toLowerCase();
  var isIE  = agent.indexOf('msie') != -1;

  return isIE;
}

/*****************************************************************************/
/* isBrowserFirefox                                                          */
/*                                                                           */
/* Work out whether the browser is Firefox or not.                           */
/*                                                                           */
/* Parameters                                                                */
/*                                                                           */
/* userAgent  the browser user agent string                                  */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true   if the browser is Firefox                                          */
/* false  otherwise                                                          */
/*****************************************************************************/
function isBrowserFirefox(userAgent)
{
  var agent = userAgent.toLowerCase();
  var isFirefox  = agent.indexOf('firefox') != -1;

  return isFirefox;
}

/*****************************************************************************/
/* isBrowserSupported                                                        */
/*                                                                           */
/* Checks whether the browser being used is supported by WebMail. Returns    */
/* true if it is, false otherwise.                                           */
/*                                                                           */
/* Examples:                                                                 */
/*                                                                           */
/* IE 5.01    userAgent  mozilla/4.0 (compatible; msie 5.01; windows nt)     */
/* IE 5.5 SP2 userAgent  mozilla/4.0 (compatible; msie 5.5; windows nt 5.0)  */
/* IE 6.0     userAgent  mozilla/4.0 (compatible; msie 6.0; windows nt 5.0)  */
/* NN 6.2     userAgent  mozilla/5.0 (windows; ...) ... netscape6/6.2        */
/* NN 7.0     userAgent  mozilla/5.0 (windows; ...) ... netscape7/7.02       */
/*                                                                           */
/* IE 5.01    appVersion 4.0 (compatible; msie 6.0; windows nt 5.0)          */
/* IE 5.5 SP2 appVersion 4.0 (compatible; msie 5.5; windows nt 5.0)          */
/* IE 6.0     appVersion 4.0 (compatible; msie 5.01; windows nt)             */
/* NN 6.2     appVersion 5.0 (windows; en-us)                                */
/* NN 7.02    appVersion 5.0 (windows; en-us)                                */
/*                                                                           */
/*****************************************************************************/
function isBrowserSupported()
{
  var agent = navigator.userAgent.toLowerCase();
  var appver = navigator.appVersion.toLowerCase();

  /***************************************************************************/
  /* Do we think it's Netscape Navigator?                                    */
  /***************************************************************************/
  if (isBrowserNetscape(agent))
  {
    /*************************************************************************/
    /* Do we think it's Firefox?                                             */
    /*************************************************************************/
    if (isBrowserFirefox(agent))
    {
      return true;
    }

    var nnpos = agent.indexOf('netscape');
    var slpos = agent.indexOf('/', nnpos);

    var fullVersion = parseFloat(agent.substring(slpos + 1));
    var majorVersion = parseInt(fullVersion);
    var minorVersion = (fullVersion - majorVersion) * 100;

    /*************************************************************************/
    /* If at least Navigator 6.2.                                            */
    /*************************************************************************/
    if ((majorVersion > 6) || (majorVersion == 6 && minorVersion > 19))
    {
      return true;
    }
  }
  /***************************************************************************/
  /* Do we think it's Microsoft Internet Explorer?                           */
  /***************************************************************************/
  else if (isBrowserIE(agent))
  {
    var iepos = appver.indexOf('msie');
    var scpos = appver.indexOf(';', iepos);

    var fullVersion = parseFloat(appver.substring(iepos + 5, scpos));
    var majorVersion = parseInt(fullVersion);
    var minorVersion = (fullVersion - majorVersion) * 100;

    var ie3 = (majorVersion < 4);
    var ie4 = (majorVersion == 4);
    var ie5 = (majorVersion == 5) && (minorVersion <= 49);
    var ie55 = (majorVersion == 5) && (minorVersion > 49);

    var minorVers = navigator.appMinorVersion.toLowerCase();

    var ie55sp1 = (ie55) && (minorVers.indexOf('sp1') != -1);
    var ie55sp2 = (ie55) && (minorVers.indexOf('sp2') != -1);
    var ie55sp3 = (ie55) && (minorVers.indexOf('sp3') != -1);

    ie55 = (ie55 && !ie55sp1 && !ie55sp2 && !ie55sp3);
    var ie6 = (majorVersion == 4) && (agent.indexOf('msie 6') != -1);
    var ie55sp2up = (!ie3 && !ie4 && !ie5 && !ie55 && !ie55sp1);

    /*************************************************************************/
    /* If at least Internet Explorer 5.5 SP2.                                */
    /*************************************************************************/
    if (ie55sp2up)
    {
       return true;
    }
  }

  /***************************************************************************/
  /* Incompatible browser.                                                   */
  /***************************************************************************/
  return false;
}

/*****************************************************************************/
/* countLangs                                                                */
/*                                                                           */
/* Counts the number of languages available to the user and returns this     */
/* number.                                                                   */
/*                                                                           */
/* Parameters: langString  - input string                                    */
/*                                                                           */
/* Returns:    numberLangs - number of languages available                   */
/*****************************************************************************/
function countLangs(langString)
{
  var langList = langString.split(";;");
  var numberLangs = langList.length;

  return(numberLangs);
}

/*****************************************************************************/
/* checkFriendlyName                                                         */
/*                                                                           */
/* Check that a friendly name is valid.                                      */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* userid     A string containing the friendly name (without @domain)        */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* true if valid, false otherwise.                                           */
/*****************************************************************************/
function checkFriendlyName(userid)
{
  var rc = false;

  /***************************************************************************/
  /* Test length bounds.                                                     */
  /***************************************************************************/
  if (userid.length < 3 || userid.length > 18)
  {
    /*************************************************************************/
    /* Length is not in bounds so reject.                                    */
    /*************************************************************************/
    alert(dc2js19);
  }
  else if (!userid.match(/^[\w\.\-]+$/))
  {
    // We failed to match a full string of WORD characters [a-zA-Z0-9_] or dot or dash
    alert(dc2js20);
  }
  else if (userid.match(/^[\d\-\+\(\)]+$/))
  {
    // This regular expression is equivalent to the server side one in
    //   parseEmailAddresses in wmcesess
    // We matched a string that looks like a phone number
    //  - digits, dashes, pluses and brackets (though actually the pluses and
    //  brackets will have been prevented by the earlier test)
    alert(dc2js21);
  }
  else
  {
    rc = true;
  }

  return rc;
}

/*****************************************************************************/
/* getCookieValue                                                            */
/*                                                                           */
/* Retrieve cookie value or "".                                              */
/*                                                                           */
/* Arguments                                                                 */
/*                                                                           */
/* cookieName Name of cookie                                                 */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* Cookie value or "".                                                       */
/*****************************************************************************/

function getCookieValue(cookieName)
{
  var allCookies = document.cookie;
  var position = allCookies.indexOf(cookieName + "=");

  if (position == -1)
  {
    return "";
  }
  else
  {
    var start = position + cookieName.length + 1;
    var end = allCookies.indexOf(";", start);
    if (end == -1)
    {
      end = allCookies.length;
    }
    return allCookies.substring(start, end);
  }
}

/*****************************************************************************/
/* cookiesEnabled                                                            */
/*                                                                           */
/* Do we think that permanent & session cookies are enabled?  Note that IE   */
/* 5.5 allows you to enable/disable session & permanent cookies independently*/
/* of one another and navigator.cookieEnabled in this case only tests for    */
/* permanent cookies, hence the seemingly unnecessary additional step below. */
/*                                                                           */
/* Returns                                                                   */
/*                                                                           */
/* True or false.                                                            */
/*****************************************************************************/

function cookiesEnabled()
{
  /***************************************************************************/
  /* Test for cookies enabled (or permanent cookies in IE 5.5).              */
  /***************************************************************************/
  if (navigator.cookieEnabled)
  {
    /*************************************************************************/
    /* Temporary session cookie.                                             */
    /*************************************************************************/
    var cookieName = 'webmailTestCookie';
    document.cookie = cookieName + '=1';

    /*************************************************************************/
    /* Test for session cookies enabled.                                     */
    /*************************************************************************/
    if (document.cookie.indexOf(cookieName) != -1)
    {
      document.cookie = cookieName + '=';
      return true;
    }
  }

  return false;
}

