////////////////////////////////////////////////////////////////////////
//
// Filename:    upload.js
// Purpose:     Upload files to the server
// Method:      FORM elements, setInterval()
//
// Author:      J.van.der.Steen@diff.nl
// Date:        2010-02-10
//
// Note:        The upload facility requires specific FORM elements.
// See also:    xslt.js and document.js
//
// Documentation setDocument():
//
// Set/change an upload document
//
// The strategy:
// 1. We start uploading the document data (by triggering
//    the file upload form) and keep track of the upload
//    by periodically checking the iframe content.
// 2. Once it contains the number of bytes transferred
//    (the response of control/upload.phtml) the upload was
//    successful and the filename can be adjusted and the
//    document element is actually turned dirty.
// 3. During upload the user is not allowed to unload the dossier.
//    This is accomplished by giving the document element its own
//    saveNeeded() method which returns true while uploading and
//    when the document element itself has turned dirty.
//
// Implementation details:
//    1. trigger upload form 
//    2. install setInterval('uploadExec(' + this.guid + ')', 100)
//       to check the iframe content
//    3. set this.monitor to interval handler
//    4. create callback of setInterval():
//       a. check content of iframe:
//          1. empty                   no response yet
//             a. check if maximum time has passed (10 sec?)
//                if so, <clean up>
//          2. <SCRIPT>...</SCRIPT>    error occured
//             a. <clean up>
//          3. number                  transfer finished
//             a. adjust document element properties (including dirty)
//             b. <clean up>
//       <clean up>
//          1. clearInterval(this.monitor)
//          2. set this.monitor to -1
//
////////////////////////////////////////////////////////////////////////


/*
 * Emit error for supplied document.
 */
function uploadError(type, guid, filename, error)
{
    debug         ("Error in Upload(" + type + "," + guid + "," + filename + "): '" + error + "'");
    showModalAlert("Upload of '" + filename + "' failed.<p style='text-align:center;'>Please try again.");
}

/**
 * Abort all active upload's
 */
function uploadAbort(type)
{
    //
    // Stop all upload monitors of supplied type
    //
    var list = FiuBase.prototype.getLookupTableByType(type);
    for (var i = 0; i < list.length; i++) {
        var obj = FiuBase.prototype.getLookupTable(type, list[i]);
        if (obj !== null) {
            obj.uploadAbort();
        }
    }
}

/*
 * Check for installed upload handler and remove it when it exists.
 */
function uploadClean(type, guid, filename)
{
    var uploadfile = FiuBase.prototype.getLookupTable(type, guid);

    if (uploadfile === null) {
        var error = "A technical error encountered: the '" + type + "' element is gone!\n"
                  + "Please restart your browser."
                  ;
        uploadError(type, guid, filename, error);
        return;
    }

    uploadfile.uploadAbort();
}

/*
 * Set the filename in the interface
 */
function uploadSetFilename(type, guid, filename)
{
    var uploadfile = FiuBase.prototype.getLookupTable(type, guid);
    if (uploadfile !== null) {
        uploadfile.updateHeaderText(filename);
    }
}

/*
 * Emit feedback for supplied upload document.
 */
function uploadReport(type, guid, filename, log, error)
{
    var msg;

    if (log === true) {
        msg = "Upload(" + type + "," + guid + "," + filename + "): '" + error + "'";
        debug(msg);
    }

    uploadSetFilename(type, guid, error);
}

/*
 * Handler of document upload data.
 */
function uploadExec(type, guid, filename)
{
    var error = '';

    try {
        // debug("Upload('" + filename + "')");

        //
        // Lookup the document we're handling
        //
        var uploadfile = FiuBase.prototype.getLookupTable(type, guid);

        if (uploadfile === null) {
            //
            // The upload document disappeared...
            //
            error = "A technical error encountered: the '" + type + "' element is gone!\n"
                  + "Please restart your browser."
                  ;
            uploadError(type, guid, filename, error);
            return;
        }

        var iframe = getE('iframe-' + guid);
        if (iframe === null) {
            error = "A technical error encountered: the response frame is gone!\n"
                  + "Please restart your browser."
                  ;
            uploadError(type, guid, filename, error);

            //
            // Clear interval
            //
            uploadClean(type, guid, filename);
            return;
        }

        //
        // Check its content
        //
        var txt = iframe.contentWindow.document.body !== null
                ? iframe.contentWindow.document.body.innerHTML.strip()
                : ''
                ;

        if (txt === '') {
            //
            // No response yet.
            //
            if (uploadfile.monitorAge++ < (config.uploadElapse / config.uploadInterval)) {
                error = 'uploading... (' + uploadfile.monitorAge + ')';
                uploadReport(type, guid, filename, false, error);
                return;
            } else {
                error = "The upload takes too long (over " + config.uploadElapse / 1000 + " sec)!"
                      + "<p style='text-align:center;'>Please contact FIU.NET office."
                      ;
                uploadError(type, guid, filename, error);
            }
        } else {
            //
            // Response received, error or number of bytes.
            //
            if (isNaN(txt) === false) {
                error = 'completed, received ' + parseInt(txt, 10) + ' bytes';
                uploadReport(type, guid, filename, true, error);
                //
                // Adjust upload document filename and dirty bit
                //
                uploadfile.uploadSetFilename(filename);
            } else {
                //
                // We received error feedback from the server
                //
                error = "Upload failed:\n"
                      + "<p style='text-align:center;'>"
                      + txt
                      ;
                uploadError(type, guid, filename, error);
            }
        }

        //
        // Clean up
        //
        uploadClean(type, guid, filename);
    }
    catch(err) {
        error = '';
        for (prop in err) {
            error += " " + err[prop] + ";";
        }
        uploadError(type, guid, filename, error);
    }
}

