// DataEntryConfirm.js - keep a copy of all the form data and test
// if it has changed - confirm both discards and saves

// this is the data from the forms on the screen
var RunConfirm = true;
var allReadyChanged = false;
var formData;

// get the data encapsulated in the cookie
function getCookieVal (offset) {
    var endstr = document.cookie.indexOf (";", offset);
    if (endstr == -1)
        endstr = document.cookie.length;
    return unescape(document.cookie.substring(offset, endstr));
}

// get a cookie value from the name
function GetCookie (name) {

    // look for the name provided plus the equal of the name value pair
    var arg = name + "=";
    // the length of the name plus the equal sign
    var alen = arg.length;
    // the total length of the cookie
    var clen = document.cookie.length;

    //alert("GetCookie: name=" + name + " cookie="  + document.cookie);

    // use brute force traversing the cooking field by field
    var i = 0;
    while (i < clen) {
        var j = i + alen;
        var piece = document.cookie.substring(i, j);
        //alert("GetCookie: name=" + name + " arg=" + arg + " current piece=" + piece + " index=" + i);
        if (piece == arg) {
            //alert("GetCookie: name=" + name + " value: " + getCookieVal(j));
            return getCookieVal (j);
        }
        i = document.cookie.indexOf(";", i) + 1;
        if (i == 0) 
            break;
        if (document.cookie.substring(i, i+1) == " ")
            i++;
    }
    //alert("Cookie: name=" + name + " not found");
    return null;
}

// set a cookie name value pair
function SetCookie (name, value) {
    //alert("BEFORE SetCookie: " + document.cookie);
    //alert("SetCookie name: " + name + " value: " + value);

    var argv = SetCookie.arguments;
    var argc = SetCookie.arguments.length;
    var expires = (2 < argc) ? argv[2] : null;
    var path = (3 < argc) ? argv[3] : null;
    var domain = (4 < argc) ? argv[4] : null;
    var secure = (5 < argc) ? argv[5] : false;
    document.cookie = name + "=" + escape (value) +
                      ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
                      ((path == null) ? "" : ("; path=" + path)) +
                      ((domain == null) ? "" : ("; domain=" + domain)) +
                      ((secure == true) ? "; secure" : "");

    //alert("AFTER SetCookie: name: " + name + " cookie: " + document.cookie);
}

// expire the cookie now
function DeleteCookie(name) {
    var expires = new Date();
    expires.setTime(expires.getTime() - 1 ); 
    document.cookie = name + "=" + escape("") + ";expires=" + expires.toGMTString();
    //alert("AFTER DeleteCookie: name: " + name + " cookie: " + document.cookie);
}

//  an array of popped menu items
var poppedMenus = new Array();

// mark a menu as open by saving the popped entry
function OpenMenu(menuName) {
    if (menuName == null) {
        return;
    }
    for (i = 0; i < poppedMenus.length; i++) {
        if (poppedMenus[i] == null) {
            //alert("OpenMenu: " + menuName + "-use old spot " + i);
            poppedMenus[i] = menuName;
            return;
        }
    }
    //alert("OpenMenu: " + menuName + "-use new spot " + poppedMenus.length);
    poppedMenus[poppedMenus.length] = menuName;
}

// close a menu by deleting the popped entry
function CloseMenu(menuName) {
    if (menuName == null) {
        return;
    }
    for (i = 0; i < poppedMenus.length; i++) {
        if (poppedMenus[i] == menuName) {
            //alert("CloseMenu: remove " + menuName + " from position " + i);
            poppedMenus[i] = null;
        }
    }
}

function ToggleMenu(menuName) {
    //alert("ToggleMenu: " + menuName);
    for (i = 0; i < poppedMenus.length; i++) {
        if (poppedMenus[i] == menuName) {
            //alert("ToggleMenu: remove " + menuName + " from position " + i);
            poppedMenus[i] = null;
            return;
        }
    }
    OpenMenu(menuName);
}

// turn the popped menu screens into cookies which expire in three
// seconds
function CookifyMenu() {
    for (i = 0; i < poppedMenus.length; i++) {
        if (poppedMenus[i] == null) {
            continue;
        }

        //alert("Cookifing: " + poppedMenus[i]);

        var cookKey = 'menu-' + poppedMenus[i];

        var expires = new Date();
        expires.setTime(expires.getTime() + 3000 ); 

        document.cookie = cookKey + "=block;expires=" + expires.toGMTString();
        //alert("AFTER CookifyMenu: name: " + cookKey + " cookie: " + document.cookie);
    }
}

// this form doesn't need a test
function registerNoTest() {
    RunConfirm = false;
}

// register all of the data on the form
function registerData(clear) {
    // clear the change registration if needed
    if (clear == null)
        clear = false;
    else
        clear = true;
    if (clear)
        registerClear();

    // don't bother to register changes if there have already been
    // changes
    var priorChange = GetCookie("AnyChange");
    if (priorChange != null) {
        if (priorChange == "true") {
            allReadyChanged = true;
            return;
        }
    }

    // now we need to save the form data
    var numVars = 0;
    var i, j, k;

    // calculate number of elements to save
    for (i = 0; i < document.forms.length; i++)
         numVars += document.forms[i].elements.length;

    // allocate space fo the elements
    formData = new Array ([numVars]);

    // copy the elements
    k = 0;
    for (i = 0; i < document.forms.length; i++)
        for (j = 0; j < document.forms[i].elements.length; j++)
            formData[k++] = document.forms[i].elements[j].value;
}

// clear the registration
function registerClear() {
    SetCookie("AnyChange","false");
    var allReadyChanged = false;
    var formData = null;
}

// loop through each of the elements in each of the forms.
// if any element has changed return true.
function changedData() {
    
    // if there had been prior changes, they are still in effect
    if (allReadyChanged != null)
        if (allReadyChanged == true)
            return true;

    // if there is nothing saved, we can't really say there is any
    // change
    if (formData == null)
        return false;

    // look to see if any of the fields on the form have changed
    var i, j, k;
    k = 0;
    for (i = 0; i < document.forms.length; i++)
        for (j = 0; j < document.forms[i].elements.length; j++) {
            if (!document.forms[i].elements[j].name) {
                k++;
                continue;
            }
            if (document.forms[i].elements[j].name.indexOf("editDetail") == 0) {
                k++;
                continue;
            }
            if (document.forms[i].elements[j].name.indexOf("deleteDetail") == 0) {
                k++;
                continue;
            }
            if (formData[k++] != document.forms[i].elements[j].value)
                return true;
        }
    return false;
}

// save the confirm information
function confirmWait() {
    if (changedData())
        SetCookie("AnyChange","true");
    return true;
}

// force a saved change
function confirmForceChange() {
    SetCookie("AnyChange","true");
    return true;
}

// confirm that you would like to save the changes
function confirmSave(msg) {
    if (msg == null)
        msg = "Are you sure you want to save the changes to the data?";
    if (changedData()) {
        if (RunConfirm) {
            if (confirm(msg)) {
                registerClear();
                return true;
            }
            return false;
        }
    }
    return true;
}

// confirm that you would like to delete the record
function confirmDelete(msg) {
    if (msg == null)
        msg = "Are you sure you want to delete the record?";

    if (confirm(msg)) {
        registerClear();
        return true;
    }
    return false;
}

// confirm that you would like to delete the record
function confirmDetailDelete(msg) {
    if (msg == null)
        msg = "Are you sure you want to delete the item?";

    if (confirm(msg)) {
        confirmForceChange();
        return true;
    }
    return false;
}

// confirm that you would like to move to something else discarding the
// changes to the current form.
function confirmDiscard(msg) {
    if (msg == null)
        msg = "Are you sure you want to abandon the changes to the data?";
    if (changedData()) {
        if (RunConfirm) {
            if (confirm(msg)) {
                registerClear();
                return true;
            }
            return false;
        }
    }
    return true;
}


// start up the confirmation system
function tradexStart() {
    for (i = 0 ; i < tradexStart.arguments.length ; i++) {
        if (tradexStart.arguments[i] == 'restart') {
            registerClear();
        }
        if (tradexStart.arguments[i] == 'notest') {
            registerNoTest();
        }
        if (tradexStart.arguments[i] == 'noback') {
            window.history.forward();
        }
    }
    registerData();

    restoreScreenPosition();
    return true;
}

// from a button, spring the enclosing hyperlink
function clickAnchor(fieldID) {
    var obj = document.getElementById(fieldID).href;location.href=(obj);
}

// save the screen position
function saveScreenPosition(fieldObj, fieldIndex) {
    if (fieldObj == null) {
        return;
    }
    var fieldName = fieldObj.name;
    if (fieldName == null) {
        return;
    }
    SetCookie("RestoreScreenPosition",fieldName);
    if (fieldIndex == null) {
        return;
    }
    SetCookie("RestoreScreenIndex",fieldIndex);
}

// catch the tabbed to field and save the position
// if a submit is in progress
function catchAndSaveTabPosition(fieldObj, fieldIndex) {
    if (!fieldObj)
        return;
    if (submitInProgress == true)
        saveScreenPosition(fieldObj, fieldIndex);
}


////////////////////////////////////////////////////////////
// restore the screen position
function restoreScreenPosition() {
    // make sure there is a position to restore
    var fieldName = GetCookie("RestoreScreenPosition");
    if (fieldName == null) {
        return;
    }
    if (fieldName.length == 0) {
        return;
    }

    // the item might be in a table of like items
    var fieldIndex = GetCookie("RestoreScreenIndex");
    if (fieldIndex == null) {
        fieldIndex = 1;
    }

    // toss the cookies as unnecessary
    SetCookie("RestoreScreenPosition","");
    SetCookie("RestoreScreenIndex","");

    // struts eval just likes the fields name
    var truncPos = fieldName.lastIndexOf("].");
    if (truncPos > 0) {
        truncPos += 2;
        fieldName = fieldName.substring(truncPos, fieldName.length);
    }

    // position the screen
    var fieldObj = Struts_eval(fieldName, fieldIndex);
    if (fieldObj == null) {
        return;
    }

    // adjust the focus
    fieldObj.focus();
}


////////////////////////////////////////////////////////////
// get the width of the client screen in pixels
function getClientWidth() {
    if (document)
        if (document.body)
            if (document.body.clientWidth)
                return document.body.clientWidth;
    if (window)
        if (window.body)
            if (window.body.innerWidth)
                return window.body.innerWidth;

    return "640";
}

// get the height of the client screen in pixels
function getClientHeight() {
    if (document)
        if (document.body)
            if (document.body.clientHeight)
                return document.body.clientHeight;

    if (window)
        if (window.body)
            if (window.body.innerHeight)
                return window.body.innerHeight;

    return "640";
}


////////////////////////////////////////////////////////////
// submit a form
var submitInProgress = false;
function isSubmitInProgress() {
    return submitInProgress;
}
function isSubmitOK() {
    return !submitInProgress;
}


function submitForm(formName) {
    if (isSubmitInProgress())
        return false;

    submitInProgress = true;

    if (!formName)
        formName = 0;

    document.forms[formName].submit();
    return true;
}

function submitFormForRecalculate(formName, noConfirm) {
    if (isSubmitInProgress()) {
        return false;
    }
    submitInProgress = true;

    if (!formName)
        formName = 0;

	if (noConfirm == null || noConfirm == false)
        confirmWait();
    
    document.forms[formName].recalcfields.value=true;
    document.forms[formName].submit();
    return true;
}

function submitRecalculateMethod(methodName, formName, noConfirm) {
    if (isSubmitInProgress()) {
        return false;
    }
    if (!methodName) {
        return false;
    }
    submitInProgress = true;

	if (!formName)
		formName = 0;

	if (noConfirm == null || noConfirm == false)
		confirmWait();

    document.forms[formName].runMethod.value=methodName;
    document.forms[formName].recalcfields.value=true;
    document.forms[formName].submit();
    return true;
}


function submitLookupAgainRunMethod(methodName, formName, noConfirm) {
    if (isSubmitInProgress()) {
        return false;
    }
    if (!methodName) {
        return false;
    }
    submitInProgress = true;

	if (!formName)
		formName = 0;

	if (noConfirm == null || noConfirm == false)
		confirmWait();

    document.forms[formName].runMethod.value=methodName;
    document.forms[formName].lookupagain.value=true;
    document.forms[formName].submit();
    return true;
}


////////////////////////////////////////////////////////////
var autoSave = false;
function doAutoSave(autoSaveConfigured) {
    if (isSubmitInProgress()) {
        return;
    }
    if (!autoSaveConfigured) {
        return;
    }
    if (autoSaveConfigured != 'true') {
        return;
    }
    if (autoSave) {
        document.forms[0].save.value='true';
        submitForm('0');
    }
    autoSave = true;
    setTimeout('doAutoSave("true")', 600000);
}

function isActiveElement(elementID) {
    if (!document.activeElement) {
        return false;
    }
    if (!elementID) {
        return false;
    }
    var currentElement = document.activeElement;
    if (currentElement.id) {
        return currentElement.id == elementID;
    }
    return false;
}


////////////////////////////////////////////////////////////
// set a select object to a value
function setSelectToValue(selectField, value) {
    if (!selectField)
        return;
    if (!value)
        return;
    if (!selectField.length)
        return;

    for (i = 0; i < selectField.length; i++) {
        if (selectField[i].value == value) {
            selectField.selectedIndex = i;
            return;
        }
    }
}

////////////////////////////////////////////////////////////
// routine to coordinate a submit or a lookup
var delayedSubmitException = null;
var delayedSubmitAllowedExceptions = null;
var delayedSubmitSourceField = null;
var delayedSubmitPending = false;
var delayedSubmitMethod = null;
var delayedSubmitFormName = null;

// this is a window that we can write to, to debug this damned code
//var delayedSubmitDebugWindow = window.open("", "DelayedSubmitTester", "width=400,height=600");
//delayedSubmitDebugWindow.document.close();
//delayedSubmitDebugWindow.document.open();

function delayedSubmitCleanup() {

    if (delayedSubmitAllowedExceptions != null) {
        for (i = 0; i < delayedSubmitAllowedExceptions; i++) {
            if (document.forms[0].elements[delayedSubmitAllowedExceptions[i]])
                document.forms[0].elements[delayedSubmitAllowedExceptions[i]].onmousedown = null;
        }
    }
    delayedSubmitAllowedExceptions = null;

    delayedSubmitException = null;
    delayedSubmitPending = false;
    delayedSubmitSourceField = null;

    document.onmouseup = null;
    return true;
}

// start the delayed submit
function delayedSubmitOnfocus() {

    // not enough parameters, exit
    if (delayedSubmitOnfocus.arguments.length <= 1)
        return delayedSubmitCleanup();

    // invalid source field
    var sourceField = delayedSubmitOnfocus.arguments[0];
    if (!sourceField)
        return delayedSubmitCleanup();

    // create the list of fields which are exceptions
    var exceptions = new Array(delayedSubmitOnfocus.arguments.length-1);
    for (i = 1; i < delayedSubmitOnfocus.arguments.length; i++)
        exceptions[i-1] = delayedSubmitOnfocus.arguments[i];

    delayedSubmitException = null;
    delayedSubmitPending = false;
    delayedSubmitSourceField = sourceField;
    delayedSubmitAllowedExceptions = exceptions;

    // set the onmouse down events on the exception items
    for (var i = 0; i < exceptions.length; i++)
        if (document.forms[0].elements[exceptions[i]])
            document.forms[0].elements[exceptions[i]].onmousedown=delayedSubmitOnmousedown;
    return true;
}
    
// clean up the delayed submit if no pending exception
function delayedSubmitOnBlur() {
    if (delayedSubmitException == null) 
        return delayedSubmitCleanup();
    return true;
}

// mark that the mouse down event has happend
function delayedSubmitOnmousedown() {
    if (delayedSubmitSourceField == null) 
        delayedSubmitCleanup();
    else if (event && event.srcElement && event.srcElement.name) {
        delayedSubmitException = event.srcElement.name;
        document.onmouseup = delayedSubmitOnmouseup;
    }
    else 
        delayedSubmitCleanup();
    return true;
}

// on change, either submit if no exception pending or mark submit
// pending
function delayedSubmitOnchange() {
    if (delayedSubmitException == null) {
        submitFormForRecalculate();
        return delayedSubmitCleanup();
    }
    delayedSubmitPending = true;
    return true;
}

function delayedSubmitRecalculateMethod(methodName, formName) {
    if (delayedSubmitException == null) {
        submitRecalculateMethod(methodName, formName, true);
        return delayedSubmitCleanup();
    }
    delayedSubmitMethod = methodName;
	delayedSubmitFormName = formName;
    delayedSubmitPending = true;
    return true;
}

// on mouse up
function delayedSubmitOnmouseup() {

    // no source field, just clean up
    if (delayedSubmitSourceField == null || delayedSubmitPending == false) 
        return delayedSubmitCleanup();

    // if clicked in the source field, just exit
    var eventName = null;
    if (event == null) ;
    else if (event.srcElement == null) ;
    else if (event.srcElement.name == null) ;
    else 
        eventName = event.srcElement.name;

    // force the submission if not in the exception event
    if (eventName != delayedSubmitException) {
        if (delayedSubmitMethod == null) {
            submitFormForRecalculate();
		} else {
            submitRecalculateMethod(delayedSubmitMethod, delayedSubmitFormName, true);
		}
    }

    // cleanup since we are done
    return delayedSubmitCleanup();
}


////////////////////////////////////////////////////////////
// sum of a string of fields on a form, additional arguments are
// field names to accumulate.  first param could be a field object
// or a field name
function sumFieldListToField(totalField) {

    // no total field, nothing to do
    if (!totalField)
        return;

    // total field should be an input type
    if (!totalField.type || !totalField.value) {

        // could be a field name, try and find it
        totalField = Struts_eval(totalField);
        if (!totalField)
            return;
        if (!totalField.value)
            return;
    }

    // if there is nothing to sum we are done
    if (sumFieldListToField.arguments.length <= 1) {
        totalField.value = "0";
        return;
    }

    // duplicate the arguments but remove the total field
    var args = new Array(sumFieldListToField.arguments.length-1);
    for (i = 0; i < sumFieldListToField.arguments.length-1; i++) 
        args[i] = sumFieldListToField.arguments[i+1];

    var total = sumFieldList(args);
    totalField.value = total;

    // check for the work field and update the formatted value
    var alternateField = Struts_eval(totalField.name + sumFieldListSkipEndsWith);
    if (alternateField) {
        alternateField.value = reformatNumber(totalField.value);
    }
}


////////////////////////////////////////////////////////////
// accumulate a bunch of fields, this should be a list
// of the names to total
var sumFieldListSkipEndsWith = "Wrk";

function sumFieldList() {

    // if there is nothing to sum we are done
    if (!sumFieldList.arguments)
        return 0;
    if (sumFieldList.arguments.length <= 0) 
        return 0;

    // the total
    var total = 0;

    // search each of the forms
    for (i = 0; i < document.forms.length; i++) {
        var f = document.forms[i];

        // then search each of the elements in the form
        for (j = 0; j < f.elements.length; j++) {
            var e = f.elements[j];

            // no name, don't bother
            if (e.name == null)
                continue;

            // make sure there is some value
            if (!e.value)
                continue;
            if (sumFieldListSkipEndsWith) {
                if (e.name.indexOf(sumFieldListSkipEndsWith) == e.name.length - sumFieldListSkipEndsWith.length)
                    continue;
            }

            // for each of the list of fields 
            for (k = 0; k < sumFieldList.arguments.length; k++) {
                var s = sumFieldList.arguments[k];

                // see if the name matches the current element
                if (e.name.indexOf(s) < 0)
                    continue;

                // make sure there is a value to accumulate
                var elementValue = parseFloat(e.value);
                if (isNaN(elementValue))
                    continue;

                // now we need to accumulate the totals
                total += elementValue;
            }
        }
    }

    return total;
}


////////////////////////////////////////////////////////////
// equivalent of java trim method
function trim(s) {
    if (!s)
        return s;
    while (s.length > 0) {
        var c = s.substring(0,1);
        if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
            s = s.substring(1, s.length);
            continue;
        }
        break;
    }
    while (s.length > 0) {
        var c = s.substring(s.length-1, s.length);
        if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
            s = s.substring(0, s.length-1);
            continue;
        }
        break;
    }
    return s;
}


////////////////////////////////////////////////////////////
// function to total a group of fields with various units
// of measure and return a string with a comma delmited
// sting of value/unit pairs
function accumulateByUnitOfMeasure() {

    // if there is nothing to sum we are done
    if (!accumulateByUnitOfMeasure.arguments)
        return 0;
    if (accumulateByUnitOfMeasure.arguments.length <= 0) 
        return 0;

    // the totals
    var totals = new Array(0);
    var unitsOfMeasure = new Array(0);

    // search each of the forms
    for (i = 0; i < document.forms.length; i++) {
        var f = document.forms[i];

        // then search each of the elements in the form
        for (j = 0; j < f.elements.length; j++) {
            var e = f.elements[j];

            // no name, don't bother
            if (e.name == null)
                continue;

            // make sure there is some value
            if (!e.value)
                continue;
            if (sumFieldListSkipEndsWith) {
                if (e.name.indexOf(sumFieldListSkipEndsWith) == e.name.length - sumFieldListSkipEndsWith.length)
                    continue;
            }

            // for each of the list of fields 
            for (k = 0; k < accumulateByUnitOfMeasure.arguments.length; k++) {
                var s = accumulateByUnitOfMeasure.arguments[k];

                // see if the name matches the current element
                if (e.name.indexOf(s) < 0)
                    continue;

                // make sure there is a value to accumulate
                var elementValue = parseFloat(e.value);
                if (isNaN(elementValue))
                    continue;

                // get the unit of measure
                var unit = trim(e.value);
                for (i = 0; i < unit.length; i++) {
                    if (!isDigit(unit.charAt(i))) {
                        unit = trim(unit.substring(i, unit.length));
                        break;
                    }
                }

                // find the unit of measure index
                var index = -1;
                for (i = 0; i < unitsOfMeasure.length; i++) {
                    if (unitsOfMeasure[i] == unit) {
                        index = i;
                        break;
                    }
                }

                // the unit was not previously in the index, add it
                if (index < 0) {
                    index = totals.length;
                    totals[totals.length] = 0;
                    unitsOfMeasure[unitsOfMeasure.length] = unit;
                }

                // now we need to accumulate the totals
                totals[index] += elementValue;
            }
        }
    }

    // build the result string
    var result = '';
    for (i = 0; i < totals.length; i++) {
        if (i > 0)
            result += ", ";
        result += totals[i];
        result += ' ';
        result += unitsOfMeasure[i];
    }
    return result;
}
