/*   5/04/2009 - ALIWEB's JavaScript for the NIIN/NSN Pages

//      NIIN Variables and Functions
// loadNIINPage() - Handle special functions after the page loads
// IsNIINInPage() - Return the NIIN object for the passed NIIN/NSN
// checkNSN() - Check to see if the passed value is a valid NSN
// noteBadNSN() - Popup an alert for a bad NSN
// fillInOnClick() - Add a onClick() to each TD anchor
// getRpt() - Hide the table and get their NIIN report
// finalValids() - Try to find the NIIN in the page
// clearSeleColor() - Clear a selection's color
// setSeleColor() - Set a selection's color to red
// setupForEdits() - Load the behavior we want for our fields
// setupFieldErrors() - Preload any field errors
// focusToFirst() - Set the focus to the first field
// validateForm() - Validate all fields
// setupFormFields() - Setup all fields for a form
// addErrorSpan() - Add a span element containing an error message
// hasWarning() - Return true if the passed field has a warning
// validateField(oFld) - Validate a field
// stdValidations() - Handle all standard validations for a part
// getEntry() - Return the entry for a field
// getButtonGroup() - Return the button group for radio button name
// getRadioValue() - Return the value of a radio button group
// updtFieldStatus() - Update the error status of a field
// chkReqd() - Check that something was entered into the field
// chkNumber() - Check that only valid numbers were entered
// chkUSPhone() - Check that a valid phone number was entered
// chkAllPhone() - Check that a valid US or foreign phone number was entered
// chkEmail() - Check that a valid email address was entered
// chkNSN() - Check that a valid NSN or NIIN was entered
// loadLabelFocus() - If a label is clicked, set the focus to its field
// fldLite() - Hilight the activated field
// fldUnlite() - Unhilight the activated field

*/
/************************************************************************/


//      NIIN Functions

// Variables for searching, navigating within this page
var oSeleID = '';       // Previously selected NIIN object

// loadNIINPage() - Handle special functions after the page loads
function loadNIINPage()    {

    // If we have a passed NIIN, point to it
    bFoundNIIN = false;
    var oObj = document.getElementById("cGoToNIIN");
    if (oObj)   {
        var niinLink = oObj.value;
        var objNIIN = IsNIINInPage(niinLink)
        if (objNIIN)  {
            setSeleColor(objNIIN);
            objNIIN.scrollIntoView(true);
            bFoundNIIN = true;
            if (!checkNSN(niinLink)) {
                noteBadNSN(niinLink);
            }
        } else {
            var oObj = document.getElementById("cSrchNSN");
            oObj.select();
        }
    }
    if (!bFoundNIIN)    {
        focusToFirst();
    }

    // Fill in the onClick()'s
    fillInOnClick();

    // Done
}

// IsNIINInPage() - Return the NIIN object for the passed NIIN/NSN
function IsNIINInPage(lookFor)  {

    // If this is an NSN, lop off the FSC
    var cNIIN = lookFor;
    if (lookFor.length > 9)  {
        cNIIN = cNIIN.Right(9);
    }

    // The NIIN is in our page if we have an object prefaced with an underscore
    var oNIIN = document.getElementById("_" + cNIIN);
    return oNIIN
}

// checkNSN() - Check to see if the passed value is a valid NSN
function checkNSN(theNSN)   {

    // Ignore this if it's a NIIN
    bRetVal = true;
    if (theNSN.length > 9) {

        // See if the NSN is on this page
        var oNSN = document.getElementsByName(theNSN)[0];
        if (!oNSN)   {
            bRetVal = false;
        }
    }
    return bRetVal;
}

// noteBadNSN() - Popup an alert for a bad NSN
function noteBadNSN(cNIIN)   {

    // This must be an alert because they might be positioned anywhere on this
    //  very long page.
    var cFSC = cNIIN.Left(4);
    var cMsg = "Please note: The FSC has changed from your entry of " +
      cFSC + ".";
    alert(cMsg);
}

// fillInOnClick() - Add a onClick() to each span with theNIIN class
function fillInOnClick()  {
    var oTable, oRows, i, oTR, oCells, j, oTD, oChildren, k, oChild

    // Find the table
    oTable = document.getElementById("NIINTable");
    if (!(oTable == null))  {

        // Do each row in the table
        oRows = oTable.rows;
        for (i = 0; i < oRows.length; i++)  {

            // oRows is an array with each TR object
            oTR = oRows[i];

            // Do each cell in the row
            oCells = oTR.cells;
            for (j = 0; j < oCells.length; j++)  {

                // oCells is an array with each TD object
                oTD = oCells[j];

                // Look for the anchor with an ID
                if (!(oTD == null))  {
                    oChildren = oTD.childNodes;
                    for (k = 0; k < oChildren.length; k++)  {
                        oChild = oChildren[k];
                        if (oChild.tagName == "SPAN" &&
                          hasClass(oChild, "theNIIN") )  {
                            if ( !Empty(oChild.id) )  {

                                // Set the onClick()
                                oChild.onclick = function()  {
                                    getRpt( this );
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
     }

    // Done
}

// getRpt() - Hide the table and get their NIIN report
function getRpt(oSpan)  {

    // Get our NIIN
    var cNIIN = oSpan.innerHTML;

    // Go to the top of the page
    var oContent = document.getElementById("Content");
    oContent.scrollIntoView(true);

    // Find the 3 objects we care about:
    var oTopMsg = document.getElementById("TopMsg");

    // The other 2 we'll have to get using classes
    var oEntries = null;
    var oTable = null;
    var oPage = document.getElementById("Page");
    for (var i = 0; i < oPage.childNodes.length; i++)  {
        var oObj = oPage.childNodes[i];

        // The Entry object has a gradient class
        if (hasClass(oObj, 'gradient')) {
            oEntries = oObj;
        }

        // The table object has a tblNIIN class
        if (hasClass(oObj, 'tblNIIN')) {
            oTable = oObj;
        }
    }

    // Add the note to Top Note
    oTopMsg.innerHTML = 'Your page is being retrieved. One moment please.';

    // Clear the classes and data for the entry box; we'll use that for the
    //  NSN Info
    removeClass(oEntries, "gradient center clear width75");
    oEntries.innerHTML = '';
    oEntries.id = 'NSNInfo';

    // Blow away the table to make the page smaller
    addClass(oTable, "hidden");

    // Change our location to the report
    var url = "/" + cNIIN + ".nsn";
    window.location.href = url;

    // Done
}

// finalValids() - Try to find the NIIN in the page
function finalValids() {

    // If it's empty, we can't look it up
    var chkVar = document.getElementById("cSrchNSN");
    var cNIIN = chkVar.value.StrTran("-", "").AllTrim();
    if (!cNIIN) {
        alert("Nothing was entered to look for, please try again.");
        return false;
    }

    // Must have 9 or 13 digits
//  if (!(cNIIN.length == 9 || cNIIN.length == 13))  {
//      alert("Find value must be 9 or 13 digits, try again.");
//      return false;
//  }

    // Restore the old selection's settings (if there is one)
    clearSeleColor();

    // Look for the NIIN in our page
    var objNIIN = IsNIINInPage(cNIIN)
    if (objNIIN)  {
        setSeleColor(objNIIN);
        objNIIN.scrollIntoView(true);
        if (!checkNSN(cNIIN)) {
            noteBadNSN(cNIIN);
        }
        validErrCount = 1;
        return false;
    }  else  {
        var srchEntry = document.getElementById("cSrchEntry");
        srchEntry.value = cNIIN;
    }

    // Done
    return true;
}

// clearSeleColor() - Clear a selection's color
function clearSeleColor()   {
    if (oSeleID)    {
        oSeleID.style.fontWeight = '';
        oSeleID.style.fontSize = '';
        oSeleID.style.color = '';
        oSeleID = null;
    }
}

// setSeleColor() - Set a selection's color to red
function setSeleColor(oTheNIIN)   {
    if (oTheNIIN)    {
        oTheNIIN.style.fontWeight = 'bold';
        oTheNIIN.style.fontSize = '1.2em';
        oTheNIIN.style.color = 'red';
        oSeleID = oTheNIIN;
    }
}

//      Global Variables
var validErrCount = 0;       // Number of errors during page validation

// Array of all forms formatted as:
//      .Fld1 - Form ID
//      .Fld2 - Form Object
//      .Fld3 - Entry Fields Array (containing only field objects)
var raPageForms = new Array();

// Incoming field errors array; loaded as:
//      .Fld1 = field's ID
//      .Fld2 = error message
// Assigments must be done within the web page
var incomingErrors = new Array();

//      Form Functions

// setupForEdits() - Load the behavior we want for our fields
function setupForEdits()   {

    // Handle each form; one at a time
    var numForms = document.forms.length;
    for (var nRow=0; nRow < numForms; nRow++)    {
        var form = document.forms[nRow];

        // Handle all of this form's fields
        var raFlds = setupFormFields(form);

        // Add the form's submit handler
        form.onsubmit = function()    {
            return (validateForm(this.getAttribute("id")));
        }

        // Add the form and fields array to our global array
        var formID = form.getAttribute("id");
        raPageForms[nRow] = new LoadChoice(formID, form, raFlds);
    }

    // Now, load any initial error messages into their fields
    setupFieldErrors();
}

// setupFieldErrors() - Preload any field errors
function setupFieldErrors() {

    // Here we need to see if we have any errors recorded in our incoming
    //  array; if so, we're to pre-load the error message into the field.
    var errCount = incomingErrors.length;
    for (var i = 0; i < errCount; i++)    {
        if (incomingErrors[i].Fld1)    {
            var fieldID = incomingErrors[i].Fld1;
            var message = incomingErrors[i].Fld2;
            var fldObj = document.getElementById(fieldID);
            updtFieldStatus(fldObj, message);
            fldUnlite(fldObj);
        }
    }
}

// focusToFirst() - Set the focus to the first field
function focusToFirst()   {
    var form = document.forms[0];
    for (var nRow=0; nRow < form.elements.length; nRow++)    {
        var elem = form.elements[nRow];
        if (elem.tagName == "INPUT" || elem.tagName == "SELECT" ||
          elem.tagName == "TEXTAREA") {
            elem.focus();
            break;
        }
    }
}

// validateForm() - Validate all fields
function validateForm(formID) {
    validErrCount = 0;                      // Reset

    // Get our form's field array
    var raFields = false;
    var numForms = raPageForms.length;
    for (var i = 0; i < numForms; i++)   {
        var thisID = raPageForms[i].Fld1;
        if (thisID == formID)   {
            raFields = raPageForms[i].Fld3;
            break;
        }
    }

    // Now, validate each of the form's fields
    if (raFields)   {
        var numFlds = raFields.length;
        for (i = 0; i < numFlds; i++)   {
            var theFld = raFields[i];

            // Make it look like it's been changed, then validate it
            if (!hasClass(theFld, 'itChanged')) {
                addClass(theFld, 'itChanged');
            }
            validateField(theFld);
        }
        var retStatus = (validErrCount == 0)
        if (!retStatus) {
            focusToFirst()
        }
    }

    // If there's a finalValids() function, call that
    if (this.finalValids)    {
        this.finalValids(formID);
    }
    return (validErrCount == 0);
}


//      Field Functions

// setupFormFields() - Setup all fields for a form
function setupFormFields(theForm)   {

    // We'll need to return an array of fields for the form
    var raFields = new Array()

    // Now, handle all fields for the form
    var fields = theForm.elements;
    for (var i=0; i < fields.length; i++)  {
        var thisFld = fields[i];

        // Handle only user entry fields...
        if (!(thisFld.tagName == "INPUT" || thisFld.tagName == "SELECT" ||
          thisFld.tagName == "TEXTAREA")) {
            continue;
        }

        // ...and ignore buttons.  Also, radio buttons can't be in error, nor
        //  can they be invalid so ignore them.  (If we have to do something
        //  with them it will require a custom function and custom load
        //  listener.
        if (thisFld.tagName != "TEXTAREA") {
            var fldType = thisFld.getAttribute("type")
            if (fldType)    {
                fldType = fldType.toLowerCase();
            }
            if (fldType == 'button' || fldType == 'reset' ||
              fldType == 'submit' || fldType == 'hidden')
                continue;
        }

        // Add this field to our array and create its error span object
        fldCount = raFields.length;
        raFields[fldCount] = thisFld;
        addErrorSpan(thisFld);

        // Setup this field's display and focus/blur handlers. Also, radio
        //  buttons can't be in error, nor can they be invalid so ignore them.
        //  (If we have to do something with them it will require a custom
        //  function and custom load listener.
        if (fldType != 'radio')   {
            fldUnlite(thisFld);
            thisFld.onfocus = function()    {
                fldLite(this);
            }
            thisFld.onblur = function() {
                validateField(this);
                fldUnlite(this);
            }
        }
    }
    return raFields;
}

// addErrorSpan() - Add a span element containing an error message
function addErrorSpan(errFld)   {

    // Create a <span> element with blank text; set its class and id
    var objSpan = document.createElement("span");
    var objText = document.createTextNode("");
    objSpan.appendChild(objText);
    objSpan.className = "red bold";
    objSpan.id = "err" + errFld.getAttribute("name");

    // Add the span element after the field
    insertAfter(objSpan, errFld);
}

// hasWarning() - Return true if the passed field has a warning
function hasWarning(fld) {

    // Two conditions are require for the field to show a warning:
    //  1. It must have a chkReqd class
    //  2. Its value must be empty
    if (hasClass(fld, 'chkReqd'))   {
        value = fld.value;
        if (Empty(value))   {
            return true;
        }
    }
    return false;
}


//      Field Validations

// validateField(oFld) - Validate a field
function validateField(oFld)    {
    var entry = getEntry(oFld);

    // If this has some classes, go handle the standard validations
    var errMessage = "";
    if (oFld.className) {
        errMessage = stdValidations(oFld, entry);
    }

    // If there's a check_<fldname> method, go run it
    if (errMessage.length == 0) {
        checkFunc = "check_" + oFld.getAttribute("name")
        if (this[checkFunc])    {
            errMessage = this[checkFunc](entry);
        }
    }

    // Update the field's status
    updtFieldStatus(oFld, errMessage);
    return true;        // We'll always let them out of a field
}

// stdValidations() - Handle all standard validations for a part
function stdValidations(oFld, entry)    {
    warnMsg = "";
    if (hasClass(oFld, "chkReqd")) {
        warnMsg = chkReqd(oFld, entry);
    }
    if (warnMsg.length == 0 && hasClass(oFld, "chkNumber")) {
        warnMsg = chkNumber(oFld, entry);
    }
    if (warnMsg.length == 0 && hasClass(oFld, "chkUSPhone"))  {
        warnMsg = chkUSPhone(oFld, entry);
    }
    if (warnMsg.length == 0 && hasClass(oFld, "chkAllPhone"))  {
        warnMsg = chkAllPhone(oFld, entry);
    }
    if (warnMsg.length == 0 && hasClass(oFld, "chkEmail"))  {
        warnMsg = chkEmail(oFld, entry);
    }
    if (warnMsg.length == 0 && hasClass(oFld, "chkNSN"))  {
        warnMsg = chkNSN(oFld, entry);
    }
    return warnMsg;
}

// getEntry() - Return the entry for a field
function getEntry(fld) {
    var fldType = fld.tagName.toLowerCase();
    if (fldType == "input") {
        fldType = fld.getAttribute("type")
    }
    switch (fldType)    {
    case "text":
        trimVal = fld.value.AllTrim();
        fld.value = trimVal;
        return trimVal
    case "password":
        trimVal = fld.value.AllTrim();
        fld.value = trimVal;
        return trimVal
    case "checkbox":
        return fld.checked;           // true or false
    case "radio":
        return getRadioValue(fld);    // value of selected button
    case "select":
        return fld.value;
    case "textarea":
        trimVal = fld.value.AllTrim();
        fld.value = trimVal;
        return trimVal
    }
    return "";
}

// getButtonGroup() - Return the button group for radio button name
function getButtonGroup(buttonName) {
    var btnGroup = false;
    for (var i = 0; i < raPageForms.length; i++)   {
        var thisForm = raPageForms[i].Fld2;
        if (thisForm[buttonName])   {
            var btnGroup = thisForm[buttonName];
            break;
        }
    }
    return btnGroup;
}

// getRadioValue() - Return the value of a radio button group
function getRadioValue(btn) {
    var btnName = btn.getAttribute("name");
    var btnGroup = getButtonGroup(btnName);
    for (var i=0; i < btnGroup.length; i++) {
        if (btnGroup[i].checked == true)    {
            return btnGroup[i].value;
        }
    }
    return "";
}

// updtFieldStatus() - Update the error status of a field
function updtFieldStatus(theFld, errMsg)    {
    var spanName = "err" + theFld.getAttribute("name");
    var objSpan = document.getElementById(spanName);
    spanText = objSpan.firstChild;
    if (errMsg.length == 0) {
        if (hasClass(theFld, "fldOops")) {
            removeClass(theFld, "fldOops");
        }
        spanText.nodeValue = errMsg;
    } else  {
        validErrCount += 1;
        if (!hasClass(theFld, "fldOops")) {
            addClass(theFld, "fldOops");
        }
        spanText.nodeValue = " " + errMsg;
    }
    fldUnlite(theFld);
}

// chkReqd() - Check that something was entered into the field
function chkReqd(fld, fldEntry)    {
    var msg = ""

    // We'll only show the error message if the field was changed
    if (Empty(fldEntry)) {
        if (hasClass(fld, 'itChanged')) {
            msg = "An entry is needed."
        }
    } else {

        // Here we have an entry
        if (!hasClass(fld, 'itChanged')) {
            addClass(fld, 'itChanged');
        }
    }
    return msg;
}

// chkNumber() - Check that only valid numbers were entered
function chkNumber(fld, fldEntry)    {
    var msg = "";
    if (fldEntry.length > 0)    {

        // Strip out commas
        var stripped = fldEntry.replace(/,/g, '');
        var pattern = /^-?\d+(\.\d+)?$/;
        if (!pattern.test(stripped))  {
            msg = "The entry can only be a number."
        }
    }
    return msg;
}

// chkUSPhone() - Check that a valid phone number was entered
function chkUSPhone(fld, fldEntry)    {
    var msg = "";
    if (fldEntry.length > 0)    {

        // Use a reg expr to strip out spaces, dashes, periods and parentheses
        var stripped = fldEntry.replace(/[\(\)\.\-\ ]/g, '');

        // Make sure what's left is numeric
        var pattern = /^\d+$/;
        if (!pattern.test(stripped))  {
            msg = "Phone has invalid characters.";
        } else if ((stripped.length != 10)) {
            msg = "Phone number is wrong length.";
        }
    }
    return msg;
}

// chkAllPhone() - Check that a valid US or foreign phone number was entered
function chkAllPhone(fld, fldEntry)    {
    var msg = "";
    if (fldEntry.length > 0)    {

        // Use a reg expr to strip out spaces, dashes, periods and parentheses
        //  and plus sign
        var stripped = fldEntry.replace(/[\(\)\.\-\ \+]/g, '');

        // Make sure what's left is numeric
        var pattern = /^\d+$/;
        if (!pattern.test(stripped))  {
            msg = "Phone has invalid characters.";
        }
    }
    return msg;
}

// chkEmail() - Check that a valid email address was entered
function chkEmail(fld, fldEntry)    {
    var msg = "";
    if (fldEntry.length > 0)    {
        var pattern = /^[\w\.\-]+@([\w\-]+\.)+[a-zA-Z]+$/;
        if (!pattern.test(fldEntry))  {
            msg = "The Email entry is invalid."
        }
    }
    return msg;
}

// chkNSN() - Check that a valid NSN or NIIN was entered
function chkNSN(fld, fldEntry)    {
    var msg = "";

    // Toss any dashes
    testEntry = fldEntry.StrTran("-", "").AllTrim();

    // NSNs must now be 13 chars long, NIINs are 9 chars
    if (!(fldEntry.length == 9 || fldEntry.length == 13))    {
        msg = "That NSN/NIIN entry is invalid."
    }
    return msg;
}

//      Label Functions

// loadLabelFocus() - If a label is clicked, set the focus to its field
function loadLabelFocus()   {
    if (!document.getElementsByTagName) return false;
    var oLabels = document.getElementsByTagName("label");
    for (var i=0; i < oLabels.length; i++)  {
        var thisLabel = oLabels[i];
        var forAttr = thisLabel.getAttribute("for");
        if (forAttr) {
            thisLabel.onclick = function () {
                var id = this.getAttribute("for");
                if (!document.getElementById(id))
                    return false;
                var element = document.getElementById(id);
                element.focus();
            }
        }
    }
}

//      Style Functions

// fldLite() - Hilight the activated field
function fldLite(obj)    {

    // Needed to overcome styling deficiencies in IE
    obj.style.background = '#E4F7FA';
    obj.style.border = '2px solid #001C70';
}

// fldUnlite() - Unhilight the activated field
function fldUnlite(obj)    {

    // Needed to overcome styling deficiencies in IE
    if (hasClass(obj, 'fldOops'))   {
        obj.style.background = '#FF3E3E';
    } else if (hasWarning(obj))    {
        obj.style.background = '#FFDDDD';
    } else {
        obj.style.background = '#EEEEEE';
    }
    obj.style.border = '2px solid #999999';
}


//      Load Listeners (these run after the page loads)
addLoadListener(loadLabelFocus);
addLoadListener(setupForEdits);

addLoadListener(loadNIINPage);          // (runs after page loads)

