/*
 * Copyright (c) 2005-2015 RevX Systems, Corp.,  All Rights Reserved.
 *
 * All Rights Reserved.  Unpublished rights reserved under
 * the copyright laws of the United States.
 *
 * The software contained on this media is proprietary to
 * and embodies the confidential technology of RevX Systems
 * Possession, use, duplication or dissemination of
 * the software and media is authorized only pursuant to
 * a valid written license from RevX Systems.
 *
 * RESTRICTED RIGHTS LEGEND  Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set
 * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013,
 * or in FAR 52.227-19, as applicable.
 *
 */

  var gUrlRedirect = "";   // At any given time, this will contain the URL
                           // of a page we wish to redirect to after a server
                           // server interaction.  Once the modal dismissal
                           // is clicked, this will var will instruct the
                           // close function where to redir to - if at all.

/************************************************************************/
/*      Function:       fnRedir(url)                                    */
/*                                                                      */
/*      Summary:        Routine to perform a client side redirect.      */
/*                                                                      */
/************************************************************************/
function fnRedir(url)
{
    window.location = url;
}

/************************************************************************/
/*      Function:       fnShowModalPopup(Title,Message)                 */
/*                                                                      */
/*      Summary:        Routine to show a modal popup window.           */
/*                                                                      */
/************************************************************************/
function fnShowModalPopup(Title,Message)
{
    new Messi(Message, {title: Title,
                        buttons: [
                                   {id: 0, label: 'OK', val: 'Y'}
                                 ],
                        modal: true,
                        center: true,
                        width: 350});
}

/************************************************************************/
/*      Function:       fnShowModalWindow(Title,Message)                */
/*                                                                      */
/*      Summary:        Routine to show a modal popup window            */
/*                      more appropriate for content.                   */
/*                                                                      */
/************************************************************************/
function fnShowModalWindow(Title,Message)
{
    //var top  = ( screen.height / 2) - (480 / 2) + 'px';
    var top  = '100px';
    var left = ( $(window).width() / 2) - (600 / 2) + 'px';

    new Messi(Message, {title: Title, modal: true, center: false,
                        width: 600, height: 480,
                        position: { top: top, left: left } });
}

/************************************************************************/
/*      Function:       fnShowModalPopupYesNoCancel(Title,Message)      */
/*                                                                      */
/*      Summary:        Routine to show a modal popup window which      */
/*                      has a Yes, No, or Cancel option on it.          */
/*                                                                      */
/************************************************************************/
function fnShowModalPopupYesNoCancel(Title,Message)
{
    var dialog = new Messi(
        Message,
        {
            title: Title,
            width: 350,
            modal: true,
            center: true,
            buttons: [
                {id: 0, label: 'Yes',    val: 'Y'},
                {id: 1, label: 'No',     val: 'N',  class: 'btn-danger'},
                {id: 2, label: 'Cancel', val: 'C'}
            ]
        }
    );

    return dialog.value;
}



/************************************************************************/
/*      Function:       fnShowModalPopupRedir(Title,Message,Redir)      */
/*                                                                      */
/*      Summary:        Routine to show a modal popup window and then   */
/*                      redirect to a new URL.                          */
/*                                                                      */
/************************************************************************/
function fnShowModalPopupRedir(Title,Message,Redir)
{
    new Messi(Message, { title: Title,
                         buttons: [
                           {id: 0, label: 'OK', val: 'Y'}
                         ],
                         modal: true,
                         center: true,
                         width: 350,
                         callback: function(val) {window.location = Redir; }
    });
}

/************************************************************************/
/*      Function:       fnShowSavedBanner()                             */
/*                                                                      */
/*      Summary:        Routine to show a brief message on the screen   */
/*                      indicating the save operation was successful.   */
/*                                                                      */
/************************************************************************/
function fnShowSavedBanner()
{
    new Messi('Your Changes Have Been Saved!', {autoclose: 1500, center: true });
}

/************************************************************************/
/*      Function:       fnShowAutoBanner(Message)                       */
/*                                                                      */
/*      Summary:        Routine to show a brief message on the screen   */
/*                      indicating some user feedback.                  */
/*                                                                      */
/************************************************************************/
function fnShowAutoBanner(Message)
{
    new Messi(Message, {autoclose: 1500, center: true });
}

/************************************************************************/
/*      Function:       fnShowModalActivated()                          */
/*                                                                      */
/*      Summary:        Routine to show the modal activated UI          */
/*                                                                      */
/************************************************************************/
function fnShowModalActivated()
{
    $('#modalActivated').show();
}

/************************************************************************/
/*      Function:       fnCloseModalActivated()                         */
/*                                                                      */
/*      Summary:        Routine to allow a user to click the modal      */
/*                      activated window and hide the DIV.              */
/*                                                                      */
/************************************************************************/
function fnCloseModalActivated()
{
    $('#modalActivated').hide();
}

/************************************************************************/
/*      Function:       fnShowModalSuccess()                            */
/*                                                                      */
/*      Summary:        Routine to show the modal success UI            */
/*                                                                      */
/************************************************************************/
function fnShowModalSuccess()
{
    $('#modalSuccess').show();
}

/************************************************************************/
/*      Function:       fnCloseModalSuccess()                           */
/*                                                                      */
/*      Summary:        Routine to allow a user to click the modal      */
/*                      success window and hide the DIV.                */
/*                                                                      */
/************************************************************************/
function fnCloseModalSuccess()
{
    $('#modalSuccess').hide();
    // If next page has been declared, then go to it.
    if ( gUrlRedirect.length > 1 ) window.location = gUrlRedirect;
}

/************************************************************************/
/*      Function:       fnShowModalFail()                               */
/*                                                                      */
/*      Summary:        Routine to show the modal fail UI               */
/*                                                                      */
/************************************************************************/
function fnShowModalFail()
{
    $('#modalFail').show();
}

/************************************************************************/
/*      Function:       fnToggleExpand()                                */
/*                                                                      */
/*      Summary:        Invoke the slideToggle on a paragraph tag       */
/*                                                                      */
/************************************************************************/
function fnToggleExpand(strDomParent, strDomSelector)
{
  /* Set the UI element to indicate based on a visable or collapsed state. */
  var isVisible = $( strDomSelector ).is( ":visible" );
  var strHtml   = $(strDomParent).html();

  if ( isVisible )
  {
    $(strDomParent).html( strHtml.replace('\u25BC','\u25BA'))
  }
  else
  {
    $(strDomParent).html( strHtml.replace('\u25BA','\u25BC'))
  }

  $(strDomSelector).toggle(100);
}

/************************************************************************/
/*      Function:       fnCloseModalFail()                              */
/*                                                                      */
/*      Summary:        Routine to allow a user to click the modal      */
/*                      fail window and hide the DIV.                   */
/*                                                                      */
/************************************************************************/
function fnCloseModalFail()
{
    $('#modalFail').hide();
}

/************************************************************************/
/*      Function:       fnShowModal()                                   */
/*                                                                      */
/*      Summary:        Routine to present the modal busy window.       */
/*                                                                      */
/************************************************************************/
function fnShowModal()
{
    $('#modal').show();
}

/************************************************************************/
/*      Function:       fnCloseModal()                                  */
/*                                                                      */
/*      Summary:        Routine to close the modal UI                   */
/*                                                                      */
/************************************************************************/
function fnCloseModal()
{
    $('#modal').hide();
}

/************************************************************************/
/*      Function:       fnFirstCharUpper                                */
/*                                                                      */
/*      Summary:        Convert a string so its first character is an   */
/*                      upper case character.                           */
/*                                                                      */
/************************************************************************/
function fnFirstCharUpper(str)
{
    return str.slice(0,1).toUpperCase() + str.slice(1).toLowerCase();
}

/************************************************************************/
/*      Function:       fnPause                                         */
/*                                                                      */
/*      Summary:        Generic routine to sleep for a pre-determined   */
/*                      number of milliseconds.                         */
/*                                                                      */
/************************************************************************/
function fnPause(milliseconds)
{
    var now = new Date();
    var exitTime = now.getTime() + milliseconds;

    while(true)
    {
        now = new Date();
        if (now.getTime() > exitTime) return;
    }
}

/************************************************************************/
/*      Function:       fnDoPostXML                                     */
/*                                                                      */
/*      Summary:        Function to process a POST to a designated      */
/*                      handler and return the XML response object.     */
/*                                                                      */
/************************************************************************/
function fnDoPostXML_SYNCH(data,uri)
{
    var xmlhttp = false;

    if (window.ActiveXObject)       xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    else if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest();

    xmlhttp.open('POST', uri, false);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.send(data);

    xmlDom     = xmlhttp.responseXML;

    //xmlString  = fnXMLToString(xmlDom);
    //alert("common.js: " + xmlString);

    return xmlDom;
}

/************************************************************************/
/*      Function:       fnDoPostXML_ASYNCH                              */
/*                                                                      */
/*      Summary:        Function to process an asynchronous POST to a   */
/*                      designated handler.                             */
/*                                                                      */
/************************************************************************/
function fnDoPostXML_ASYNCH(data,uri)
{
    var xmlhttp = false;

    if (window.ActiveXObject)       xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    else if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest();

    /* Grab the data */
    var strPost = data;

    /* Define the code which will process when the POST is complete. */
    xmlhttp.onreadystatechange = function()
    {
        if (xmlhttp.readyState==4)
        {
            xmlDom     = xmlhttp.responseXML;
            xmlString  = fnXMLToString(xmlDom);

            return xmlString;
        }
    }

    xmlhttp.open('POST', uri, true);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.send(strPost);
}


/************************************************************************/
/*      Function:       fnXMLToString                                   */
/*                                                                      */
/*      Summary:        Function to convert a DOM to a string           */
/*                                                                      */
/************************************************************************/
function fnXMLToString(objDom)
{
    var strXml;
    try {  // Mozilla browsers
        serializer = new XMLSerializer();
        strXml     = serializer.serializeToString(objDom);
    }
    catch (e) {
        // Internet Explorer has a different approach
        strXml = objDom.xml;
    }

    return strXml;
}

/************************************************************************/
/*      Function:       fnStringToXML                                   */
/*                                                                      */
/*      Summary:        Function to convert a string into a DOM         */
/*                                                                      */
/************************************************************************/
function fnStringToXML(strXML)
{
    var parser = new DOMParser();
    var xmlDom = parser.parseFromString(strXML, "text/xml")
    return xmlDom;
}

/************************************************************************/
/*      Function:       isInteger                                       */
/*                                                                      */
/*      Summary:        General purpose routine to verify a value is    */
/*                      numeric.                                        */
/*                                                                      */
/************************************************************************/
function isInteger(s)
{
    var i;
    for (i = 0; i < s.length; i++)
    {
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    return true;
}

/************************************************************************/
/*      Function:       isAlphaOnly                                     */
/*                                                                      */
/*      Summary:        General purpose routine to verify if a string   */
/*                      contains only alphabetic characters A-Z.        */
/*                                                                      */
/************************************************************************/
function isAlphaOnly(s)
{
    var i;
    for (i = 0; i < s.length; i++)
    {
        var c = s.charAt(i);
        if (((c < "A") || (c > "Z"))) return false;
    }
    return true;
}

/************************************************************************/
/*      Function:       isAlphaNumeric                                  */
/*                                                                      */
/*      Summary:        General purpose routine to verify if a string   */
/*                      contains alphabetic and numeric characters.     */
/*                                                                      */
/************************************************************************/
function isAlphaNumeric(s)
{
    var i;
    for (i = 0; i < s.length; i++)
    {
        var c = s.charAt(i);
        if (((c < "A") || (c > "9"))) return false;
    }
    return true;
}

/************************************************************************/
/*      Function:       fnRegister()                                    */
/*                                                                      */
/*      Summary:        Routine to perform new user registration.       */
/*                                                                      */
/************************************************************************/
function fnRegister()
{
    $.post( 'handlers/register/Register.RegisterUser.php',
        {   kit_id: document.getElementById('kit_id') ? document.getElementById('kit_id').value : '',
            kit_qty: document.getElementById('kit_qty') ? $( "#kit_qty" ).spinner( "value" ) : '',
            subscription_id: document.getElementById('subscription_id').value,
            username: document.getElementById('username').value,
            password: document.getElementById('password').value,
            cardholder: document.getElementById('cardholder').value,
            cardnumber: document.getElementById('cardnumber').value.replace(/[^\d]/g, ''),
            ccaddress: document.getElementById('ccaddress').value,
            cccity: document.getElementById('cccity').value,
            cccountry: document.getElementById('cccountry') ? document.getElementById('cccountry').value : '',
            ccstate: document.getElementById('ccstate').value,
            cczip: document.getElementById('cczip').value,
            ccexpyear: document.getElementById('ccexpyear').value,
            ccexpmonth: document.getElementById('ccexpmonth').value,
            company: document.getElementById('company') ? document.getElementById('company').value : '',
            shipto: document.getElementById('shipto').value,
            shipaddress: document.getElementById('shipaddress').value,
            shipcity: document.getElementById('shipcity').value,
            shipcountry: document.getElementById('shipcountry') ? document.getElementById('shipcountry').value : '',
            shipstate: document.getElementById('shipstate').value,
            shipzip: document.getElementById('shipzip').value,
            phone1: document.getElementById('phone1') ? document.getElementById('phone1').value : '',
            phone2: document.getElementById('phone2') ? document.getElementById('phone2').value : '',
            phone3: document.getElementById('phone3') ? document.getElementById('phone3').value : '',
            phone4: document.getElementById('phone4') ? document.getElementById('phone4').value : '',
            shipping_id: document.getElementById('shipping_id') ? document.getElementById('shipping_id').value : '',
            meid: document.getElementById('meid') ? document.getElementById('meid').value : '',
            payment_type: document.getElementById('payment_type') ? document.getElementById('payment_type').value : 'cc',
            bank_routing: document.getElementById('bank_routing') ? document.getElementById('bank_routing').value : '',
            bank_account: document.getElementById('bank_account') ? document.getElementById('bank_account').value : '',
            bank_account_type: document.getElementById('bank_account_type') ? document.getElementById('bank_account_type').value : '',
            token: document.getElementById('token').value },
        function(data)
        {
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;
            var respWarning = data.getElementsByTagName('warning')[0].firstChild.nodeValue;

            if ( respCode == '0' )
            {
                //$("#registerForm").load("plugs/Register.Success.xhtml");
                // Reset the form so that if someone uses the "BACK" button, the form will be reset.
                $("input[type=text], textarea").val("");
                $("select").prop("selectedIndex","0");
                $('#terms').attr('checked', false);

                gUrlRedirect = data.getElementsByTagName('loginurl')[0].firstChild.nodeValue
                if ( respWarning != 'none' )
                {
                  fnShowModalPopupRedir("WARNING",respWarning,gUrlRedirect);
                }
                else
                {
                  fnShowModalPopupRedir("SUCCESSFUL",respMessage,gUrlRedirect);
                }

            }
            else
            {
                //alert("OhSnap URL: " + data.getElementsByTagName('ohsnapurl')[0].firstChild.nodeValue);
                //window.location = data.getElementsByTagName('ohsnapurl')[0].firstChild.nodeValue;
                fnShowModalPopup('ALERT', respMessage );
                gUrlRedirect = "";
                //fnShowModalFail();
            }
        });
}

/************************************************************************/
/*      Function:       fnLogin                                         */
/*                                                                      */
/*      Summary:        This routine will pull together the completed   */
/*                      form data and submit it to the server handler   */
/*                      to complete the login.                          */
/*                                                                      */
/************************************************************************/
function fnLogin()
{
    if ( fnValidateUsername(    document.getElementById('username') )  == false ) return;
    if ( fnValidatePassword(    document.getElementById('password') )  == false ) return;

    $.post( 'handlers/login/Login.Authenticate.php',
        {   username: document.getElementById('username').value,
            token:    document.getElementById('token').value,
            password: document.getElementById('password').value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    var respUrl     = data.getElementsByTagName('redir')[0].firstChild.nodeValue;
                    fnRedir(respUrl);
                    break;

                default:
                    fnShowModalPopup('Login Failed',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnAddNewServiceRow                              */
/*                                                                      */
/*      Summary:        Routine to add a new service line using only    */
/*                      the system configured default values.           */
/*                                                                      */
/*      Package         is the Package ID in which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/*      Service         is the Service ID on which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/************************************************************************/
function fnAddNewServiceRow( Package, Service )
{
    $.post( 'handlers/devices/Devices.ActivateNewDevice.php',
        {   token:      document.getElementById('token').value,
            package_id:  Package,
            service_id:  Service,
            type:        'entitlement',
            meid:        '',
            iccid:       '',
            imei:        '' },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    //fnRedir(data.getElementsByTagName('redir')[0].firstChild.nodeValue);
                    var newRow = '<tr><td colspan="100%"><p class="small" style="color: red;">New Entitlement has been added.  Please refresh your browser to configure it.</p></td></tr>';
                    $('#'+Package+'_'+Service+' tr:last').after(newRow);
                    break;

                default:
                    fnShowModalPopup('Entitlement Failed',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnActivateNewMEID                               */
/*                                                                      */
/*      Summary:        Routine to allow for new MEID devices to be     */
/*                      added to an account.                            */
/*                                                                      */
/*      fldMEID         is the name of the Document object which        */
/*                      contains the MEID id to activate.               */
/*                                                                      */
/*      Package         is the Package ID in which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/*      Service         is the Service ID on which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/************************************************************************/
function fnActivateNewMEID(fldMEID, Package, Service )
{
  var objMEID   = document.getElementById(fldMEID);
  var objDOMKey = '#package-delete-' + Package;

  if ( objMEID.className == 'Invalid' )
  {
    fnShowModalPopup('HINT','A valid MEID is required to activate.  The MEID can be located somewhere on your equipment.');
    return;
  }

  // Remove the delete package icon (if present)
  $(objDOMKey).remove();

  // dispatch the post.
  $.post( 'handlers/devices/Devices.ActivateNewDevice.php',
      {   token:      document.getElementById('token').value,
          package_id:  Package,
          service_id:  Service,
          type:        'meid',
          meid:        objMEID.value,
          iccid:       '',
          imei:        '' },
      function(data)
      {
          fnCloseModal();
          //alert( fnXMLToString(data) ); // Debug

          var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
          var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

          switch(respCode)
          {
              case '0':
                  //fnRedir(data.getElementsByTagName('redir')[0].firstChild.nodeValue);
                  var newRow = '<tr><td colspan="100%"><p class="small" style="color: red;">'+objMEID.value+' is now pending activation.  Please refresh your browser to check on it.</p></td></tr>';
                  $('#'+Package+'_'+Service+' tr:last').after(newRow);
                  objMEID.value = ''; objMEID.className = 'Invalid';
                  break;

              default:
                  fnShowModalPopup('Activation Failed',respMessage);
                  break;
          }
      });
}

/************************************************************************/
/*      Function:       fnActivateNewIMEI                               */
/*                                                                      */
/*      Summary:        Routine to allow for a new IMEI to be           */
/*                      added to an account. This is used primarily for */
/*                      non-integrated services that wish to add a new  */
/*                      service row which only contains an IMEI.  This  */
/*                      is most common with WiFi devices in a SaaS      */
/*                      line management model.                          */
/*                                                                      */
/*      fldIMEI         is the name of the Document object which        */
/*                      contains the IMEI id to activate.               */
/*                                                                      */
/*      Package         is the Package ID in which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/*      Service         is the Service ID on which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/************************************************************************/
function fnActivateNewIMEI(fldIMEI, Package, Service )
{
    var objIMEI   = document.getElementById(fldIMEI);
    var objDOMKey = '#package-delete-' + Package;

    if ( objIMEI.className == 'Invalid' )
    {
        fnShowModalPopup('HINT','A valid IMEI is required to activate.  The IMEI is located somewhere on your equipment.');
        return;
    }

    // Remove the delete package icon (if present)
    $(objDOMKey).remove();

    // dispatch the post.
    $.post( 'handlers/devices/Devices.ActivateNewDevice.php',
        {   token:      document.getElementById('token').value,
            package_id:  Package,
            service_id:  Service,
            type:        'imei',
            imei:        objIMEI.value,
            iccid:       ''},
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    //fnRedir(data.getElementsByTagName('redir')[0].firstChild.nodeValue);
                    var newRow = '<tr><td colspan="100%"><p class="small" style="color: red;">'+objIMEI.value+' is now pending activation.  Please refresh your browser to check on it.</p></td></tr>';
                    $('#'+Package+'_'+Service+' tr:last').after(newRow);
                    objIMEI.value = ''; objIMEI.className = 'Invalid';
                    break;

                default:
                    fnShowModalPopup('Activation Failed',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnDeactivateDevice                              */
/*                                                                      */
/*      Summary:        Routine to allow for the deactivation of a line */
/*                                                                      */
/*      KeyPrefix       is an index into the AccountInfo structure      */
/*                      so the server side knows which                  */
/*                      Package/Service/Line is being deactivated.      */
/*                                                                      */
/*      DeviceId        Is the actual device ID which is being deleted  */
/*                                                                      */
/************************************************************************/
function fnDeactivateDevice(KeyPrefix, DeviceId )
{
  var strTop  = parseInt((screen.height/2)*.40) + 'px';
  var strLeft = parseInt((screen.width/2)*.65) + 'px';

  var dialog = new Messi(
      "You have chosen to remove and deactivate a device on your account. If you wish to re-activate this equipment in the future, you may have to perform Over The Air (OTA) Activation to properly restore service.  Please consult with your product manufacturer before continuing.<br><br>If you wish to re-activate this device in the future, you may be <span style=\"color: red;\"><b>CHARGED</b></span> a <span style=\"color: red;\"><b>FEE</b></span> to do so (consult your welcome letter for details).<br><br>" + DeviceId + " will be <span style=\"color: red;\"><b>DEACTIVATED</b></span> and <span style=\"color: red;\"><b>REMOVED</b></span>.<br><br><br>Are you sure you wish to continue?<br><br>",
      {
          title: "DEACTIVATION ALERT",
          width: 450,
          modal: true,
          center: false,
          position: { top: strTop, left: strLeft },
          buttons: [
              {id: 0, label: 'YES',    val: 'Y'},
              {id: 1, label: 'NO',     val: 'N',  class: 'btn-danger'}
          ],
          callback: function(val) {  switch(val) {
                                       case 'N': break;
                                       case 'Y':
                                           setTimeout( function(){fnDeactivateDeviceConfirmed(KeyPrefix,DeviceId)}, 1000);
                                           break;

                                       default: break;
                                     }
                                  }
      }
    );
}

/************************************************************************/
/*      Function:       fnDeletePackage                                 */
/*                                                                      */
/*      Summary:        Routine to allow for the removal of a qualified */
/*                      package.                                        */
/*                                                                      */
/*      KeyPrefix       contains the Package# prefix that corresponds   */
/*                      to the package which should be removed.         */
/*                                                                      */
/************************************************************************/
function fnDeletePackage( KeyPrefix )
{
    var strTop  = parseInt((screen.height/2)*.40) + 'px';
    var strLeft = parseInt((screen.width/2)*.65) + 'px';

    var dialog = new Messi(
        "You have chosen to remove an Active subscription on your account.  Billing history will remain, but you will no longer be able to manage it.<br><br><br>Are you sure you want to remove it?<br><br>",
        {
            title: "REMOVE SUBSCRIPTION",
            width: 450,
            modal: true,
            center: false,
            position: { top: strTop, left: strLeft },
            buttons: [
                {id: 0, label: 'YES',    val: 'Y'},
                {id: 1, label: 'NO',     val: 'N',  class: 'btn-danger'}
            ],
            callback: function(val) {  switch(val) {
                case 'N': break;
                case 'Y':
                    setTimeout( function(){fnDeletePackageConfirmed(KeyPrefix)}, 1000);
                    break;

                default: break;
            }
            }
        }
    );
}

/************************************************************************/
/*      Function:       fnPayNowVerify                                  */
/*                                                                      */
/*      Summary:        Confirm with the end-user they want to pay      */
/*                      their outstanding account balance.              */
/*                                                                      */
/************************************************************************/
function fnPayNowVerify()
{
    var strTop  = parseInt((screen.height/2)*.40) + 'px';
    var strLeft = parseInt((screen.width/2)*.65) + 'px';

    var dialog = new Messi(
        'You have chosen to make a one-time payment for the unpaid balance on your account.<br><br>Verify or update your <span style="color: red; font-weight: bold">current payment method</span> before processing this payment. If you wish to use an alternate method of payment, please choose <span style="color: red; font-weight: bold;">"NO"</span> and update your payment method before proceeding.<br><br><span style="font-weight: bold;">NOTE:</span> If your account is currently suspended for non-payment, the suspension will be lifted automatically when your payment is successfully processed.<br><br><br>Do you want to make this one-time payment now?<br><br>',
        {
            title: "ONE-TIME PAYMENT",
            width: 450,
            modal: true,
            center: false,
            position: { top: strTop, left: strLeft },
            buttons: [
                {id: 0, label: 'YES',    val: 'Y'},
                {id: 1, label: 'NO',     val: 'N',  class: 'btn-danger'}
            ],
            callback: function(val) {  switch(val) {
                case 'N': break;
                case 'Y':
                    setTimeout( function(){fnPayNowConfirmed()}, 1000);
                    break;

                default: break;
              }
            }
        }
    );
}

/************************************************************************/
/*      Function:       fnPayNowConfirmed                               */
/*                                                                      */
/*      Summary:        Routine to actually perform a Pay Now           */
/*                                                                      */
/************************************************************************/
function fnPayNowConfirmed()
{
    $.post( 'handlers/myaccount/MyAccount.PayNow.php',
        {   token:      document.getElementById('token').value },
        function(data)
        {
          //fnCloseModal();
          //alert( fnXMLToString(data) ); // Debug

          var respCode     = data.getElementsByTagName('error')[0].firstChild.nodeValue;
          var respMessage  = data.getElementsByTagName('description')[0].firstChild.nodeValue;
          var respUrlRedir = data.getElementsByTagName('redir')[0].firstChild.nodeValue;

          switch(respCode)
          {
                case '0':
                    fnCloseModal();
                    fnShowModalPopupRedir("SUCCESS",respMessage,respUrlRedir);
                    break;

                default:
                    fnCloseModal();
                    fnShowModalPopupRedir("ERROR",respMessage,respUrlRedir);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnDeactivateDeviceConfirmed                     */
/*                                                                      */
/*      Summary:        Routine to actually perform the deactivation    */
/*                                                                      */
/*      KeyPrefix       is an index into the AccountInfo structure      */
/*                      so the server side knows which                  */
/*                      Package/Service/Line is being deactivated.      */
/*                                                                      */
/*      DeviceId        Is the actual device ID which is being deleted  */
/*                                                                      */
/************************************************************************/
function fnDeactivateDeviceConfirmed(KeyPrefix, DeviceId )
{
  //fnShowAutoBanner("Device Deactivation Successful for " + KeyPrefix + " " + DeviceId);
  //return;

  $.post( 'handlers/devices/Devices.DeactivateDevice.php',
      {   token:      document.getElementById('token').value,
          KeyPrefix:  KeyPrefix,
          DeviceId:   DeviceId },

          function(data)
          {
            //fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;
            var respUrlRedir = data.getElementsByTagName('redir')[0].firstChild.nodeValue;

            switch(respCode)
            {
              case '0':
                $('#' + KeyPrefix).remove();
                fnCloseModal();
                //fnShowAutoBanner("Device Deactivation Success");
                fnShowModalPopupRedir("SUCCESS",respMessage,respUrlRedir);
                break;

              default:
                fnCloseModal();
                //fnShowModalPopup('Device Deactivation Failed',respMessage);
                fnShowModalPopupRedir("ERROR",respMessage,respUrlRedir);
                break;
            }
      });
}

/************************************************************************/
/*      Function:       fnDeletePackageConfirmed                        */
/*                                                                      */
/*      Summary:        Routine to actually perform the removal         */
/*                      of a qualified package from a subscribers       */
/*                      account.                                        */
/*                                                                      */
/*      KeyPrefix       This is the prefix string which points to the   */
/*                      Package# key which should be removed.           */
/*                                                                      */
/************************************************************************/
function fnDeletePackageConfirmed( KeyPrefix )
{
    $.post( 'handlers/myaccount/MyAccount.DeletePackage.php',
        {   token:      document.getElementById('token').value,
            KeyPrefix:  KeyPrefix },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode     = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage  = data.getElementsByTagName('description')[0].firstChild.nodeValue;
            var respUrlRedir = data.getElementsByTagName('redir')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowModalPopupRedir("SUCCESS",respMessage,respUrlRedir);
                    break;

                default:
                    fnShowModalPopup("ERROR",respMessage);
                    break;
            }

        });
}

/************************************************************************/
/*      Function:       fnAddNewPackage                                 */
/*                                                                      */
/*      Summary:        Routine to allow for a new Package to be added  */
/*                      to a subscribers account.                       */
/*                                                                      */
/*      fldPackage      Is a reference to the new subscription drop down*/
/*                      field on the page.                              */
/*                                                                      */
/************************************************************************/
function fnAddNewPackage(fldPackage)
{
  if ( fldPackage.className == 'Invalid' )
  {
    fnShowModalPopup('HINT','You must select an available subscription to add.');
    return;
  }

  $.post( 'handlers/myaccount/MyAccount.AddPackage.php',
      {   token:      document.getElementById('token').value,
          package_id:  fldPackage.value },
      function(data)
      {
          fnCloseModal();
          //alert( fnXMLToString(data) ); // Debug

          var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
          var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

          switch(respCode)
          {
            case '0':
              fnShowModalPopupRedir('SUCCESS',respMessage,data.getElementsByTagName('redir')[0].firstChild.nodeValue);
              //fnShowModalPopup('SUCCESS',respMessage);
              //fnShowAutoBanner(respMessage);
              //fnPause(3000);
              //fnRedir(data.getElementsByTagName('redir')[0].firstChild.nodeValue);
              break;

            default:
              fnShowModalPopup('ERROR',respMessage);
              break;
          }
      });
}

/************************************************************************/
/*      Function:       fnActivateNewSim                                */
/*                                                                      */
/*      Summary:        Routine to allow for new SIM to be added        */
/*                      to an account.                                  */
/*                                                                      */
/*      fldICCID        is the name of the Document object which        */
/*                      contains the device ICCID to activate.          */
/*                                                                      */
/*      fldIMEI         is the name of the Document object which        */
/*                      contains the IMEI to activate.                  */
/*                                                                      */
/*      Package         is the Package ID in which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/*      Service         is the Service ID on which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/************************************************************************/
function fnActivateNewSim(fldICCID, fldIMEI, Package, Service )
{
    var objICCID   = document.getElementById(fldICCID);
    var objIMEI    = document.getElementById(fldIMEI);

    var objDOMKey    = '#package-delete-' + Package;
    var objDOMTxtKey = '#package-txt-delete-' + Package;


    // If an ICCID object reference was provided, then validate it.
    if ( fldICCID != null && objICCID.className == 'Invalid' )
    {
        fnShowModalPopup('HINT','A valid ICCID and IMEI are required to activate.  You can find them located somewhere on your equipment.');
        return;
    }

    // If an IMEI object reference was provided, then validate it.
    if ( fldIMEI != null && objIMEI.className == 'Invalid' )
    {
        fnShowModalPopup('HINT','A valid ICCID and IMEI are required to activate.  You can find them located somewhere on your equipment.');
        return;
    }

    // Remove the delete package icon (if present)
    $(objDOMKey).remove();
    $(objDOMTxtKey).remove();

    $.post( 'handlers/devices/Devices.ActivateNewDevice.php',
        {   token:      document.getElementById('token').value,
            package_id:  Package,
            service_id:  Service,
            type:        'iccid',
            meid:        '',
            iccid:       objICCID.value,
            imei:        objIMEI.value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    //fnRedir(data.getElementsByTagName('redir')[0].firstChild.nodeValue);
                    var newRow = '<tr><td colspan="100%"><p class="small" style="color: red;">'+objICCID.value+' is now pending activation.  Please refresh your browser to check on it.</p></td></tr>';
                    $('#'+Package+'_'+Service+' tr:last').after(newRow);
                    objICCID.value = ''; objICCID.className = 'Invalid';
                    objIMEI.value = '';  objIMEI.className =  'Invalid';
                    break;

                default:
                    fnShowModalPopup('Activation Failed',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnActivateNewMeidWithImei                       */
/*                                                                      */
/*      Summary:        Routine to allow for a new MEID to be added     */
/*                      along with an IMEI.                             */
/*                                                                      */
/*      fldMEID         is the name of the Document object which        */
/*                      contains the device MEID to activate.           */
/*                                                                      */
/*      fldIMEI         is the name of the Document object which        */
/*                      contains the IMEI to activate.                  */
/*                                                                      */
/*      Package         is the Package ID in which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/*      Service         is the Service ID on which to activate  the new */
/*                      device.                                         */
/*                                                                      */
/************************************************************************/
function fnActivateNewMeidWithImei(fldMEID, fldIMEI, Package, Service )
{
    var objMEID    = document.getElementById(fldMEID);
    var objIMEI    = document.getElementById(fldIMEI);

    // If an MEID object reference was provided, then validate it.
    if ( fldMEID != null && objMEID.className == 'Invalid' )
    {
        fnShowModalPopup('HINT','A valid MEID and IMEI are required to activate.  You can find them located somewhere on your equipment.');
        return;
    }

    // If an IMEI object reference was provided, then validate it.
    if ( fldIMEI != null && objIMEI.className == 'Invalid' )
    {
        fnShowModalPopup('HINT','A valid MEID and IMEI are required to activate.  You can find them located somewhere on your equipment.');
        return;
    }

    $.post( 'handlers/devices/Devices.ActivateNewDevice.php',
        {   token:      document.getElementById('token').value,
            package_id:  Package,
            service_id:  Service,
            type:        'meid',
            meid:        objMEID.value,
            iccid:       '',
            imei:        objIMEI.value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    //fnRedir(data.getElementsByTagName('redir')[0].firstChild.nodeValue);
                    var newRow = '<tr><td colspan="100%"><p class="small" style="color: red;">'+objMEID.value+' is now pending activation.  Please refresh your browser to check on it.</p></td></tr>';
                    $('#'+Package+'_'+Service+' tr:last').after(newRow);
                    objMEID.value = ''; objMEID.className = 'Invalid';
                    objIMEI.value = ''; objIMEI.className = 'Invalid';
                    break;

                default:
                    fnShowModalPopup('Activation Failed',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnChangeDeviceState                             */
/*                                                                      */
/*      Summary:        Routine to allow for equipment device state     */
/*                      changes.                                        */
/*                                                                      */
/*      AccountInfoKey  Will contain the Package1_Service_Item1         */
/*                      identifier so the backend handler knows which   */
/*                      line to update.                                 */
/*                                                                      */
/*      Status          The status to change the device to.             */
/*                                                                      */
/************************************************************************/
function fnChangeDeviceState(AccountInfoKey, Status)
{

    $.post( 'handlers/devices/Devices.ChangeDeviceState.php',
        {   token:      document.getElementById('token').value,
            status:     Status,
            line_key:   AccountInfoKey },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowAutoBanner('Order Submitted - it may take up to 24 hour(s) to complete');
                    break;

                default:
                    fnShowModalPopup('Status Change Request Failed',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnSaveAccountInfo                               */
/*                                                                      */
/*      Summary:        Routine to save modified Account Information    */
/*                      originating from the MyAccount UserX.           */
/*                                                                      */
/************************************************************************/
function fnSaveAccountInfo()
{
    if (document.getElementById('first_name').className.indexOf('Valid') < 0 ||
        document.getElementById('middle_name').className.indexOf('Valid') < 0 ||
        document.getElementById('last_name').className.indexOf('Valid') < 0 ||
        document.getElementById('address1').className.indexOf('Valid') < 0 ||
        document.getElementById('address2').className.indexOf('Valid') < 0 ||
        document.getElementById('city').className.indexOf('Valid') < 0 ||
        document.getElementById('state').className.indexOf('Valid') < 0 ||
        document.getElementById('country').className.indexOf('Valid') < 0 ||
        document.getElementById('emailaddress').className.indexOf('Valid') < 0 ||
        document.getElementById('zip').className.indexOf('Valid') < 0  )
    {
      fnShowModalPopup('ACTION NEEDED',"Correct any incomplete fields");
      return;
    }

    $.post( 'handlers/myaccount/MyAccount.SaveAccountInfo.php',
        {   token:       document.getElementById('token').value,
            company:     document.getElementById('company') ? document.getElementById('company').value : '',
            first_name:  document.getElementById('first_name').value,
            middle_name: document.getElementById('middle_name').value,
            last_name:   document.getElementById('last_name').value,
            address1:    document.getElementById('address1').value,
            address2:    document.getElementById('address2').value,
            city:        document.getElementById('city').value,
            state_id:    document.getElementById('state').value,
            country_id:  document.getElementById('country').value,
            emailaddress:document.getElementById('emailaddress').value,
            zip:         document.getElementById('zip').value,
            phone1:      document.getElementById('phone1') ? document.getElementById('phone1').value : '',
            phone2:      document.getElementById('phone2') ? document.getElementById('phone2').value : '',
            phone3:      document.getElementById('phone3') ? document.getElementById('phone3').value : '',
            phone4:      document.getElementById('phone4') ? document.getElementById('phone4').value : '' },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowAutoBanner(respMessage);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnSaveBillingInfo                               */
/*                                                                      */
/*      Summary:        Routine to save modified Billing and Payment    */
/*                      information on the account.                     */
/*                                                                      */
/************************************************************************/
function fnSaveBillingInfo()
{
    if (document.getElementById('ccname').className.indexOf('Valid') < 0 ||
        document.getElementById('cardnumber').className.indexOf('Valid') < 0 ||
        document.getElementById('ccexpyear').className.indexOf('Valid') < 0 ||
        document.getElementById('ccexpmonth').className.indexOf('Valid') < 0 ||
        document.getElementById('ccaddress').className.indexOf('Valid') < 0 ||
        document.getElementById('cccity').className.indexOf('Valid') < 0 ||
        document.getElementById('cczip').className.indexOf('Valid') < 0 ||
        document.getElementById('cccountry').className.indexOf('Valid') < 0 ||
        document.getElementById('ccstate').className.indexOf('Valid') < 0  )
    {
        fnShowModalPopup('ACTION NEEDED',"Correct any incomplete fields");
        return;
    }

    $.post( 'handlers/myaccount/MyAccount.SaveBillingInfo.php',
        {   token:       document.getElementById('token').value,
            ccname:      document.getElementById('ccname').value,
            cardnumber:  document.getElementById('cardnumber').value.replace(/-/g,''),
            ccexpyear:   document.getElementById('ccexpyear').value,
            ccexpmonth:  document.getElementById('ccexpmonth').value,
            ccaddress:   document.getElementById('ccaddress').value,
            cccity:      document.getElementById('cccity').value,
            cczip:       document.getElementById('cczip').value,
            ccstate:     document.getElementById('ccstate').value,
            cccountry:   document.getElementById('cccountry').value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowAutoBanner(respMessage);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnSaveBankingInfo                               */
/*                                                                      */
/*      Summary:        Routine to save modified Billing and Payment    */
/*                      information on the account.                     */
/*                                                                      */
/************************************************************************/
function fnSaveBankingInfo()
{
    if (document.getElementById('bank_routing').className.indexOf('Valid') < 0 ||
        document.getElementById('bank_account').className.indexOf('Valid') < 0 ||
        document.getElementById('bank_account_type').className.indexOf('Valid') < 0 )
    {
        fnShowModalPopup('ACTION NEEDED',"Correct any incomplete fields");
        return;
    }

    $.post( 'handlers/myaccount/MyAccount.SaveBankingInfo.php',
        {   token:             document.getElementById('token').value,
            bank_routing:      document.getElementById('bank_routing').value,
            bank_account:      document.getElementById('bank_account').value,
            bank_account_type: document.getElementById('bank_account_type').value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowAutoBanner(respMessage);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnChangePassword                                */
/*                                                                      */
/*      Summary:        Routine to modify a users password.             */
/*                                                                      */
/************************************************************************/
function fnChangePassword()
{
    if (document.getElementById('cur_password').className.indexOf('Valid') < 0 ||
        document.getElementById('password').className.indexOf('Valid') < 0 ||
        document.getElementById('vpassword').className.indexOf('Valid') < 0 )
    {
        fnShowModalPopup('CHANGE PASSWORD',"You must provide your current and verified new password");
        return;
    }

    $.post( 'handlers/myaccount/MyAccount.ChangePassword.php',
        {   token:        document.getElementById('token').value,
            cur_password: document.getElementById('cur_password').value,
            password:     document.getElementById('password').value,
            vpassword:    document.getElementById('vpassword').value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowAutoBanner(respMessage);
                    $('#cur_password').val('');
                    $('#password').val('');
                    $('#vpassword').val('');
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnChangeNickname                                */
/*                                                                      */
/*      Summary:        Routine to modify a line's nickname.            */
/*                                                                      */
/************************************************************************/
function fnChangeNickname(LineKey, objNickname)
{
    objNickname.value = objNickname.value.toUpperCase();

    $.post( 'handlers/devices/Devices.ChangeNickname.php',
        {   token:        document.getElementById('token').value,
            line_key:     LineKey,
            nickname:     objNickname.value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowAutoBanner(respMessage);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnChangeServiceLevelField                       */
/*                                                                      */
/*      Summary:        Routine to modify a line's custom field.        */
/*                                                                      */
/************************************************************************/
function fnChangeServiceLevelField(LineKey, FieldName, objField, FieldDesc )
{
    //objField.value = objField.value.toUpperCase();

    $.post( 'handlers/devices/Devices.ChangeServiceLevelField.php',
        {   token:        document.getElementById('token').value,
            line_key:     LineKey,
            field_name:   FieldName,
            field_desc:   FieldDesc,
            field_value:  objField.value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowAutoBanner(respMessage);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnSendPasswordRequest                           */
/*                                                                      */
/*      Summary:        Routine to initiate a password reset request    */
/*                      process                                         */
/*                                                                      */
/************************************************************************/
function fnSendPasswordRequest()
{
    if (document.getElementById('email').className.indexOf('Valid') < 0 )
    {
        fnShowModalPopup('PASSWORD RESET',"You must provide your current email address");
        return;
    }

    $( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
        console.log(thrownError);
    });

    $.post( 'handlers/myaccount/MyAccount.ResetRequest.php',
        {   email:        document.getElementById('email').value },
        function(data)
        {
            fnCloseModal();

            console.log( fnXMLToString(data) );

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    //fnShowAutoBanner(respMessage);
                    fnShowModalPopup('CONFIRMED',respMessage);
                    $('#email').val('');
                    $('#btn_send').prop("disabled",true);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnSendPasswordReset                             */
/*                                                                      */
/*      Summary:        Routine to process a password reset             */
/*                                                                      */
/************************************************************************/
function fnSendPasswordReset()
{
    if (document.getElementById('password').className.indexOf('Valid') < 0 ||
        document.getElementById('vpassword').className.indexOf('Valid') < 0 )
    {
        fnShowModalPopup('ACTION REQUIRED',"You must provide a valid password and they must match");
        return;
    }

    $.post( 'handlers/myaccount/MyAccount.ResetPassword.php',
        {   password:       document.getElementById('password').value },
        function(data)
        {
            fnCloseModal();
            //alert( fnXMLToString(data) ); // Debug

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    //fnShowAutoBanner(respMessage);
                    fnShowModalPopupRedir('CONFIRMED',respMessage,'/login.php');
                    $('#password').val(''); $('#vpassword').val('');
                    $('#btn_send').prop("disabled",true);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }
        });
}

/************************************************************************/
/*      Function:       fnShowDeviceDetails                             */
/*                                                                      */
/*      Summary:        Routine to fetch and present in modal fashion,  */
/*                      the indicated devices' details.                 */
/*                                                                      */
/************************************************************************/
function fnShowDeviceDetails(LineKey, Kind, DeviceId )
{
  var htmlResponse = "";

  $.post( 'handlers/devices/Devices.VerizonGetDetails.php',
      {   token:          document.getElementById('token').value,
          line:           LineKey,
          kind:           Kind,
          device_id:      DeviceId },
      function(data)
      {
        fnShowModalWindow(DeviceId + " Information", data);
      }
  );
}

/************************************************************************/
/*      Function:       fnUploadCsvUsage                                */
/*                                                                      */
/*      Summary:        Routine to HTTP upload a VZW usage CSV file.    */
/*                                                                      */
/************************************************************************/
function fnUploadCsvUsage( objFile )
{
    //var formData = new FormData();
    //formData.append('file', $('#UsageFileToUpload')[0].files[0]);

    $.ajax({
        url : '../handlers/usage/Usage.CsvFileUpload.php',
        type : 'POST',
        data: new FormData($('form')[0]),
        cache: false,
        contentType: false,
        processData: false,
        success : function(data) {
            //console.log(data);
            $("#UsageFileToUpload").val("");


            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowModalPopup('SUCCESS',respMessage);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }

           //alert( fnXMLToString(data));
        }
    });

}

/************************************************************************/
/*      Function:       fnUploadVerizonLineStatus                       */
/*                                                                      */
/*      Summary:        Routine to HTTP upload a VZW Line Status file.  */
/*                                                                      */
/************************************************************************/
function fnUploadVerizonLineStatus( objFile )
{
  $.ajax({
        url : '../handlers/verizon/Verizon.UploadLineStatus.php',
        type : 'POST',
        data: new FormData($('form')[1]),
        cache: false,
        contentType: false,
        processData: false,
        success : function(data) {
            $("#LineFileToUpload").val("");

            var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
            var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

            switch(respCode)
            {
                case '0':
                    fnShowModalPopup('SUCCESS',respMessage);
                    break;

                default:
                    fnShowModalPopup('ALERT',respMessage);
                    break;
            }

            //alert( fnXMLToString(data));
        }
    });

}

/************************************************************************/
/*      Function:       fnCarrierDumpDeviceSubmit                       */
/*                                                                      */
/*      Summary:        Reload carrier dump device with option values.  */
/*                                                                      */
/************************************************************************/
function fnCarrierDumpDeviceSubmit()
{
    window.location.replace("/utility/Carrier.DumpDevice.php?carrier=" + $("#carrier").val() + "&kind=" + $("#kind").val() + "&id=" + $("#identifier").val());
}

/************************************************************************/
/*      Function:       fnClaimPrepaidCard                              */
/*                                                                      */
/*      Summary:        Routine to redeem a prepaid card number         */
/*                                                                      */
/*                                                                      */
/************************************************************************/
function fnClaimPrepaidCard()
{
    if (	$("#prepaidCardNumber").hasClass("Valid") )
    {
      $.post( 'handlers/myaccount/MyAccount.PrepaidCard.Claim.php',
          {   token:        document.getElementById('token').value,
              cardnumber:   document.getElementById('prepaidCardNumber').value },
          function(data)
          {
              var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
              var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;
              var redirUrl    = data.getElementsByTagName('redir')[0].firstChild.nodeValue;

              switch(respCode)
              {
                  case '0':
                      fnShowModalPopupRedir('SUCCESS',respMessage,redirUrl);
                      break;

                  default:
                      fnShowModalPopup('ALERT',respMessage);
                      break;
              }
          });
    }

}

/************************************************************************/
/*      Function:       fnLoadBill                                      */
/*                                                                      */
/*      Summary:        Routine to load a bill for the account          */
/*                                                                      */
/*                                                                      */
/************************************************************************/
function fnLoadBill()
{
    if ( $( "#bill_dropdown option:selected" ).val() != 'empty' )
    {
      $.post( 'handlers/gui/MyAccount.BillingHistory.php',
            {   token:          $( "#token" ).val(),
                invoice_number: $( "#bill_dropdown option:selected" ).val() },
            function(data)
            {
                var respCode = data.getElementsByTagName('error')[0].firstChild.nodeValue;

                switch(respCode)
                {
                    case '0':
                        var invoiceNumber     = data.getElementsByTagName('invoiceNumber')[0].firstChild.nodeValue;
                        var redirUrl          = data.getElementsByTagName('redir')[0].firstChild.nodeValue;
                        var date_created      = data.getElementsByTagName('date_created')[0].firstChild.nodeValue;
                        var transactionsTable = data.getElementsByTagName('transactionsTable')[0].firstChild.nodeValue;
                        var download1         = data.getElementsByTagName('download1')[0].firstChild.nodeValue;
                        var download2         = data.getElementsByTagName('download2')[0].firstChild.nodeValue;

                        var invoiceHead = "<div style=\"float: left;\">" +
                                          "<span style=\"font-size: 14px; font-weight: bold; padding-left: 0px; padding-bottom: 0; text-align: center; vertical-align: top; color: red\">INVOICE SUMMARY</span><br>" +
                                            date_created + " - Invoice #" + invoiceNumber + "<br>" +
                                          "</div>" +
                                          "<div style=\"float: left; margin-left: 25px;\">" +
                                            "<a target=\"_blank\" href=\"" + download1 + "\"><img title=\"Download PDF Invoice\" src=\"/images/pdf-icon.png\" width=\"26\" height=\"36\"</a>  " +
                                            "<a target=\"_blank\" href=\"" + download2 + "\"><img title=\"Download XLS Invoice\" src=\"/images/xls-icon.png\" width=\"26\" height=\"36\" /></a>" +
                                          "</div>";


                        $( "#invoiceHead" ).html(invoiceHead);
                        $( "#billingHistoryTransactionsTable" ).html(transactionsTable);
                        break;

                    case '3':

                        var invoiceHead = "<div style=\"float: left;\">" +
                            "<span style=\"font-size: 14px; font-weight: bold; padding-left: 0px; padding-bottom: 0; text-align: center; vertical-align: top; color: red\">INVOICE SUMMARY</span> " +
                            "  <span>&nbsp; - No detail on record for this Invoice!</span>" +
                            "</div>";

                        $( "#invoiceHead" ).html(invoiceHead);
                        $( "#billingHistoryTransactionsTable" ).html("<span></span>");
                        break;

                    default:
                        var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;
                        fnShowModalPopup('ALERT',respMessage);
                        break;
                }
            });
    }

}

/************************************************************************/
/*      Function:       formatDigitGroups                               */
/*                                                                      */
/*      Summary:        Return a number grouped by a digits separator.  */
/*                                                                      */
/************************************************************************/

function formatDigitGroups ( nbrString )
{
  return nbrString.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

/************************************************************************/
/*      Function:       fnCreateChart                                   */
/*                                                                      */
/*      Summary:        Create a new Chart based on provided data.      */
/*                                                                      */
/************************************************************************/
function fnCreateChart(elmParent, elmChild, chData )
{

    var iMinChartHeight   = 70;   /* Minimum <div> height to host a chart */
    var iBarSize          = 50;   /* Size in px per bar on the chart. */

    /* Define the Chart Options */
    var chOptions =      {
        responsive:           true,
        maintainAspectRatio:  false,
        events:               ['click'],
        legend:               { display: true},
        tooltips:             {
            callbacks: {
                label: function(tooltipItem) {
                    return tooltipItem.yLabel;
                }
            }
        },
        scales:               {
            yAxes: [{
                ticks: {
                    display: false,
                    beginAtZero: true
                }
            }],
            xAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        },
        animation:            {
            duration: 500,
            easing: "easeOutQuart",
            onComplete: function () {
                var ctx          = this.chart.ctx;
                ctx.font         = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
                ctx.font.color   = chData.datasets[0].rxFontColor;
                ctx.textAlign    = 'left';
                ctx.textBaseline = 'bottom';

                this.data.datasets.forEach(function (dataset)
                {
                    for (var i = 0; i < dataset.data.length; i++)
                    {

                        /*
                         * We need a reference to the model for the bar, so we know how to paint
                         * on it.
                         */

                        var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;

                        /*
                         * Set the font color which is drawn on top of the bar.
                         */

                        ctx.fillStyle = dataset.rxFontColor;

                        /*
                         * Calculate where on the bar we'll paint the volume of usage and label.
                         */

                        left = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._xScale.left;
                        y_pos = model.y + 7;

                        /*
                         * Add a comma to the quantity and draw the text on the bar.
                         */

                        bar_label = dataset.data[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " " + dataset.rxUnit + " - " + model.label;
                        ctx.fillText( bar_label, left + 15, y_pos);
                    }
                });
            }
        }
    };

    /*
     * Calculate the height of the <div> to host this chart
     * based on the number of bars present in the chart.
     *
     * Formula = Minimum Height + (# of Bars * 50px per Bar)
     */

    var iDivHeight = iMinChartHeight + (chData.datasets[0].data.length * iBarSize);

    /*
     * Create the new <div> and <canvas> for the chart dynamically
     * within the provided <div> parent container.
     */

    fnCreateChartContainer(elmParent, elmChild, iDivHeight );

    /*
     * Fetch a reference of the new chart element so we can begin
     * applying some basic styling to it.
     *
     * Much of the styling is provided in custom token data elements
     * as part of the dataset[] object for the chart.  The custom
     * properties are prefixed with an "rx" so they don't collide
     * with current or future ChartJS development.
     */

    var elmChart = document.getElementById(elmChild).getContext('2d');
    var elmCtx   = document.getElementById(elmChild);

    /*
     * Set the background color for the chart based on what is present
     * in the custom property for the dataset on the chart.
     */

    elmCtx.style.backgroundColor = chData.datasets[0].rxBgColor;

    /*
     * Instantiate a gradient object on the node for applying to
     * the surface of the bar chart.
     *
     * If a given customer doesn't want a gradient, then it should
     * be configured with all 3 steps set to the same rgb codes with
     * 1 for opacity.
     */

    var gradient = elmChart.createLinearGradient(500,0,100,0);
    gradient.addColorStop(0,  chData.datasets[0].rxGradient1); // custom dataset property
    gradient.addColorStop(.4, chData.datasets[0].rxGradient2); // custom dataset property
    gradient.addColorStop(1,  chData.datasets[0].rxGradient3); // custom dataset property

    chData.datasets[0].borderColor      = gradient; // apply it to the bar
    chData.datasets[0].backgroundColor  = gradient; // apply it to the bar's background

    /*
     * Add some additional default styling to the dataset for each
     * bar that will be drawn on the chart.
     */

    chData.datasets[0].borderWidth      = 1;
    chData.datasets[0].pointRadius      = 0;
    chData.datasets[0].fill             = true;

    /*
     * Apply standard drop shadow.  If the customer doesn't want a drop shadow,
     * you should only need to set the opactity on the rgba to 0 so it will not
     * be seen.
     */

    chData.datasets[0].shadowOffsetX    = 3;
    chData.datasets[0].shadowOffsetY    = 3;
    chData.datasets[0].shadowBlur       = 10;
    chData.datasets[0].shadowColor      = chData.datasets[0].rxShadowColor;

    /*
     * Instantiate the chart in the new container.
     */

    var chart    = new Chart(elmChart, {    type:    'horizontalBar',
                                            data:    chData,
                                            options: chOptions});

}

/************************************************************************/
/*      Function:       fnCreateChartContainer                          */
/*                                                                      */
/*      Summary:        Create a new DIV with proper sizing to host     */
/*                      the Chart drawn on the UI.                      */
/*                                                                      */
/************************************************************************/
function fnCreateChartContainer( elmParent, elmChild, iDivHeight )
{
    divString = '<div id="' + elmChild + 'Host" style="height: ' + iDivHeight + 'px; margin-bottom: 50px;"></div>';
    $('#' + elmParent).append(divString);

    canvasString = '<canvas id="' + elmChild + '"></canvas>';
    $('#' + elmChild + 'Host').append(canvasString);
}

/************************************************************************/
/*      Function:       fnEnterpriseDMSuspendDevice                     */
/*                                                                      */
/*      Summary:        Suspend a device using the enterprise device    */
/*                      manager                                         */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMSuspendDevice( iccid, success )
{
  $.post( '/handlers/devices/Enterprise.SuspendDevice.php',
    {
      token: document.getElementById('token').value,
      iccid: iccid },

    function(data)
    {
      fnCloseModal();

      var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
      var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

      switch(respCode)
      {
        case '0':
          fnShowAutoBanner('Suspension submitted. Please allow up to 24 hours for completion');
          success(true);
          break;

        default:
          fnShowModalPopup('Suspension Failed',respMessage);
          success(false);
          break;
      }
    });
}

/************************************************************************/
/*      Function:       fnEnterpriseDMRestoreDevice                     */
/*                                                                      */
/*      Summary:        Restore a device using the enterprise device    */
/*                      manager                                         */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMRestoreDevice( iccid, success )
{
  $.post( '/handlers/devices/Enterprise.RestoreDevice.php',
    {
      token: document.getElementById('token').value,
      iccid: iccid },

    function(data)
    {
      fnCloseModal();

      var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
      var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

      switch(respCode)
      {
        case '0':
          fnShowAutoBanner('Restore submitted. Please allow up to 24 hours for completion');
          success(true);
          break;

        default:
          fnShowModalPopup('Restore Failed',respMessage);
          success(false);
          break;
      }
    });
}

/************************************************************************/
/*      Function:       fnEnterpriseDMDeleteDevice                      */
/*                                                                      */
/*      Summary:        Delete a device using the enterprise device     */
/*                      manager                                         */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMDeleteDevice( iccid, success )
{
  $.post( '/handlers/devices/Enterprise.DeleteDevice.php',
    {
      token: document.getElementById('token').value,
      iccid: iccid },

    function(data)
    {
      fnCloseModal();
      //alert( fnXMLToString(data) ); // Debug

      var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
      var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

      switch(respCode)
      {
        case '0':
          fnShowAutoBanner('Line has been removed.');
          success(true);
          break;

        default:
          fnShowModalPopup('Line Removal Failed',respMessage);
          success(false);
          break;
      }
    });
}

/************************************************************************/
/*      Function:       fnEnterpriseDMModifyDevice                      */
/*                                                                      */
/*      Summary:        Modify a device using the enterprise device     */
/*                      manager                                         */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMModifyDevice( iccid, fieldToken, serviceId, value, success )
{
  $.post( '/handlers/devices/Enterprise.ModifyDevice.php',
    {
      token: document.getElementById('token').value,
      iccid: iccid,
      fieldToken: fieldToken,
      serviceId: serviceId,
      value: value
    },
    function(data)
    {
      fnCloseModal();


      var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
      var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

      switch(respCode)
      {
        case '000':
          fnShowAutoBanner('Nickname has been changed.');
          success(true);
          break;

        default:
          fnShowModalPopup('Nickname cannot be changed',respMessage);
          success(false);
          break;
      }
    });
}

/************************************************************************/
/*      Function:       fnEnterpriseDMFilterByPackage                   */
/*                                                                      */
/*      Summary:        Filters the grid view by the package value      */
/*                      in the associated dropdown                      */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMFilterByPackage(grid, package)
{
  // Clear any pakcage filtering first
  grid.events.fire("filterChange", ['', 'package', 'inputFilter']);

  if (package !== '*')
    grid.events.fire("filterChange", [package, 'package', 'inputFilter']);

  fnEnterpriseDMUpdateActiveLineCount(package);

}

/************************************************************************/
/*      Function:       fnEnterpriseDMUpdateActiveLineCount             */
/*                                                                      */
/*      Summary:        Updates the text displaying total active        */
/*                      per package                                     */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMUpdateActiveLineCount(package)
{
  if (package === "*")
  {
    var totalActive = 0;
    for (var pkg in activeLinesPerPackage)
      totalActive += activeLinesPerPackage[pkg];

    $('#edmPackageLineCount').html('Active Lines on Subscription: <b>'+ totalActive +'</b>');
  }
  else
  {
    $('#edmPackageLineCount').html('Active Lines on Subscription: <b>'+activeLinesPerPackage[package]+'</b>');
  }

}

/************************************************************************/
/*      Function:       fnEnterpriseDMToggleActivateModal               */
/*                                                                      */
/*      Summary:        Toggles the activation modal for the enterprise */
/*                      device manager.                                 */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMToggleActivateModal()
{
  $('#edmActivateWrapper').toggle();
  if (!$('#edmActivateWrapper').is(":visible"))
  {
    $('#edmPackageDropdown').val("*");
    fnEnterpriseDMFilterByPackage(grid,"*");
    grid.data.removeAll();
    grid.data.load("/handlers/devices/Enterprise.LoadDeviceManagerCache.php?v=" + Date.now()).then(function(data){  grid.paint() });
    fnEnterpriseDMUpdateActiveLineCount('*');
  }
}

/************************************************************************/
/*      Function:       fnEnterpriseDMUpdateServices                    */
/*                                                                      */
/*      Summary:        Updates the service options given a selected    */
/*                      package in the activate modal                   */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMUpdateServices(accountSubs, package)
{
  var html = '';
  for (var service in accountSubs[btoa(package)])
    html += '<option value="'+ service +'">'+ atob(accountSubs[btoa(package)][service]) +'</option>';

  $('#edmActivateServiceDropdown').html(html);
  $('#edmActivateSelectedPackageText').html(package);
}

/************************************************************************/
/*      Function:       fnEnterpriseDMActivateDevice                    */
/*                                                                      */
/*      Summary:        Activate a device using the enterprise device   */
/*                      manager                                         */
/*                                                                      */
/************************************************************************/
function fnEnterpriseDMActivateDevice()
{

  var imei = $("#edmActivateImei").val();
  var iccid = $("#edmActivateIccid").val();
  var packageId = $("#edmActivatePackageDropdown option:selected").val();
  var serviceId = $("#edmActivateServiceDropdown option:selected").val();

  if ( !imei || !iccid || !packageId || !serviceId )
  {
    fnShowAutoBanner('<span style="color:red; text-align: center">Missing required input. Please verify device details and subscription</span>');
    return;
  }


  if ($("#edmActivateImei").hasClass('edmInvalid') || $("#edmActivateIccid").hasClass('edmInvalid') || $("#edmActivatePackageDropdown").hasClass('edmInvalid') || $("#edmActivateServiceDropdown").hasClass('edmInvalid'))
  {
    fnShowAutoBanner('<span style="color:red; text-align: center">Required input is invalid. Fix red input fields.</span>');
    return;
  }

  $.post( '/handlers/devices/Enterprise.ActivateDevice.php',
    {
      token: document.getElementById('token').value,
      iccid: iccid,
      imei: imei,
      packageId: packageId,
      serviceId: serviceId
    },
    function(data)
    {
      fnCloseModal();

      var respCode    = data.getElementsByTagName('error')[0].firstChild.nodeValue;
      var respMessage = data.getElementsByTagName('description')[0].firstChild.nodeValue;

      switch(respCode)
      {
        case '0':
          fnShowAutoBanner(iccid + ' has been activated. Please allow up to 24 hours.');
          $("#edmActivateImei").val('');
          $("#edmActivateIccid").val('');
          break;

        default:
          fnShowModalPopup('FAILED TO ACTIVATE','<span style="color:red">' + respMessage + '</span>');
          break;
      }
    });
}