/************************************************************
upload_form.js - Function to implement JSON requested AJAX upload.
Copyright (C) 2006  Jeremy Nicoll

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Please see lgpl.txt for a copy of the license - this notice and the file
lgpl.txt must accompany this code.

Please go to www.SeeMySites.net/forum for questions and support.
***************************************************************
Highly modified by Craig Laparo (gruppler -at- gmail -dot- com)
***************************************************************/

//This function takes two paramaters: form (the ID of the form), and sid, which
//differentiates the different uploads from each other.
var ul_vars = {
    interval : 2000,    //The time in milleseconds between each status request.
    speeds : [],        //Keeps track of the speeds of each upload.
    timeouts : [],
    timeout : 10,
    retries : [],
    retry : 3,
    barWidth: 120
};

function uploadForm(form, sid){
    var theForm = $(form);
    // The variable request is an object that will contain details of the request.
    var request = {};
    var fileName = '';

    // This little bit loops through all the elements in the form, locates the
    // file input field, and extracts the file name of the file being uploaded.
    for(var i = 0; i < theForm.elements.length; i++){
        ele = theForm.elements[i];
        if(ele.type == 'file'){
            var fileName = ele.value;
            if(fileName.indexOf('/') > -1){
                fileName = fileName.substring(fileName.lastIndexOf('/') + 1, fileName.length);
            }else{
                fileName = fileName.substring(fileName.lastIndexOf('\\') + 1, fileName.length);
            }

            //Since there can only be one file per form for this script, we'll exit the loop here.
            ele.style.position = 'absolute';
            ele.style.left = '-9999em';
            ele.style.top = '-9999em';
            var fileNameSpan = $(ele.id + "_fileName");
            fileNameSpan.innerHTML = '';
            var fileImg = document.createElement('IMG');
                fileImg.src = icon(fileName);
            fileNameSpan.appendChild(fileImg);
            fileNameSpan.appendChild(document.createTextNode(fileName));
            fileNameSpan.style.display = '';
            break;
        }
    }
    if(fileName.replace('/\s/', '').toString() === ''){
        return;
    }

    theForm.submit();
    var ele;

    //These three parts of 'request' are required in order for the filestatus server-side script to work.
    request.sid = sid;
    request.fileName = fileName;
    request.iframe = theForm.target;
    request.overwrite = $('upload_overwrite').checked * 1;
    request.path = $('upload_path').value;

    theForm.repeater = new repeatGetAction('filestatus.php', request, ul_vars.interval);
    theForm.repeater.request = request;
    theForm.repeater.formId = theForm.id;
    theForm.repeater.successFunc = function(getBack){
        if(getBack.progress >= 100 || getBack.progress == 'done'){
            $(getBack.sid + '_progress').style.width = ul_vars.barWidth + 'px';
            $(getBack.sid + '_progressText').innerHTML = byteUnit(getBack.max_size, 1);
            $(getBack.sid + '_fileSize').innerHTML = '<img src="' + imgDir + '/ok.png">';
            $(getBack.sid + '_cancel').style.display = 'none';
            $(getBack.sid + '_restart').style.display = '';
            getBack.progress = 100;
            setStatus("Uploaded \"" + getBack.fileName + '"');
            loadDir();
            this.stop();
            return;
        }

        if(!$(getBack.sid + '_progress') || this.stopped){
            this.stop();
            return;
        }

        if(!ul_vars.speeds[getBack.sid]){
            ul_vars.speeds[getBack.sid] = [];
        }else if(ul_vars.speeds[getBack.sid].length == 3){
            ul_vars.speeds[getBack.sid].shift();
        }

        if(!ul_vars.timeouts[getBack.sid]){
            ul_vars.timeouts[getBack.sid] = 0;
        }

        if(!ul_vars.retries[getBack.sid]){
            ul_vars.retries[getBack.sid] = 0;
        }

        ul_vars.speeds[getBack.sid].push([getBack.current_size, getBack.time]);
        ul_vars.speeds[getBack.sid].sort(function(a, b) {return a[1] - b[1];});  //Sorts numerically instead of by string.

        var bytes_sec = 0;
        var bytes_append = 'B/s';
        if(ul_vars.speeds[getBack.sid].length == 3){
            var difSize = ul_vars.speeds[getBack.sid][2][0] - ul_vars.speeds[getBack.sid][0][0];
            var difTime = (ul_vars.speeds[getBack.sid][2][1] - ul_vars.speeds[getBack.sid][0][1]) / 1000;
            bytes_sec = difSize / difTime;
            if(bytes_sec > 1024){
                bytes_sec = bytes_sec / 1024;
                bytes_append = 'Ki' + bytes_append;
            }
            if(bytes_sec > 1024){
                bytes_sec = bytes_sec / 1024;
                bytes_append = 'Mi' + bytes_append;
            }

            if(!bytes_sec){
                ul_vars.timeouts[getBack.sid]++;
                if(ul_vars.timeouts[getBack.sid] >= ul_vars.timeout){
                    var tries = ul_vars.retry - ul_vars.retries[getBack.sid];
                    ul_vars.retries[getBack.sid]++;
                    if(tries > 0){
                        ul_vars.timeouts[getBack.sid] = 0;
                        message = "Retrying \"" + getBack.fileName + "\" " + tries + " more time";
                        message += (tries != 1) ? "s" : '';
                        message += ".";
                        setStatus(message, true);
                        ul_vars.speeds[getBack.sid] = new Array();
                        theForm.submit();
                    }else{
                        if($(getBack.sid + '_fileSize').innerHTML == '<img src="' + imgDir + '/x.png">'){
                            return;
                        }
                        theForm.repeater.cancel();
                        setStatus("Failed to upload \"" + getBack.fileName + '"', true);
                        return;
                    }
                }
            }else{
                ul_vars.timeouts[getBack.sid] = 0;
            }
        }
        if(!$(getBack.sid + '_progress')){
            return false;
        }

        $(getBack.sid + '_progress').style.width = Math.round(getBack.progress * ul_vars.barWidth / 100) + 'px';
        $(getBack.sid + '_progressText').innerHTML = byteUnit(getBack.current_size, 1) + ' / ' + byteUnit(getBack.max_size, 1);
        $(getBack.sid + '_fileSize').innerHTML = bytes_sec.toFixed(1) + ' ' + bytes_append;
    };
    theForm.repeater.failFunc = function(getBack){
        if($(getBack.sid + '_restart').style.display == ''){
            return false;
        }
        this.stop();
        $(getBack.sid + '_fileSize').innerHTML = '<img src="' + imgDir + '/x.png">';
        $(getBack.sid + '_cancel').style.display = 'none';
        $(getBack.sid + '_restart').style.display = '';
        $(getBack.iframe).src = 'blank.html';
        setStatus(getBack.error_msg, true);
    };
    theForm.repeater.restart = function(){
        $(this.request.sid + '_fileSize').innerHTML = '';
        $(this.request.sid + '_progress').style.width = '0px';
        $(this.request.sid + '_progressText').innerHTML = '';
        $(this.request.sid + '_restart').style.display = 'none';
        $(this.request.sid + '_cancel').style.display = '';
        ul_vars.timeouts[this.request.sid] = 0;
        ul_vars.retries[this.request.sid] = 0;
        uploadForm(this.formId, this.request.sid);
    }
    theForm.repeater.cancel = function(){
        $(this.request.sid + '_fileSize').innerHTML = '<img src="' + imgDir + '/x.png">';
        $(this.request.sid + '_cancel').style.display = 'none';
        $(this.request.sid + '_restart').style.display = '';
        $(this.request.iframe).src = 'blank.html';
        this.stop();
    }

    // This MUST be called before the action will start.  When the repeater has served its
    // purpose (or you get sick of it), you can call repeater.stop() to stop it.
    theForm.repeater.start();
}

function clearStoppedUploads(){
    var container = $('uploadContainer');
    if(!container){
       return false;
   }
    var items = container.getElementsByTagName('FORM');
    if(!items){
       return false;
   }
    for(var i = items.length - 1; i >= 0; i--){
        if(items[i].repeater && items[i].repeater.stopped){
            container.removeChild(items[i]);
        }
    }
    centerElement($('overlayFG').getElementsByTagName('DIV')[0]);
}

function addFileInput(session, id){
    var container = $('uploadContainer');
    if(!container || !session || !id || $('form' + id)){
        return false;
    }

    var form = document.createElement('FORM');
        form.method = 'POST';
        form.enctype = 'multipart/form-data';
        form.id = 'form' + id;
        form.name = form.id;
        form.action = '/cgi-bin/upload.cgi?sID=' + session + '' + form.id;
        form.target = 'upload_iframe' + (id % $('overlayFG').getElementsByTagName('IFRAME').length);
        form.style.margin = '.35em 0';
        form.style.clear = 'both';
    var cancel = document.createElement('A');
        cancel.href = 'blank.html';
        cancel.target = form.target;
        cancel.title = 'Cancel';
        cancel.formId = form.id;
        cancel.onclick = cancelButton;
        cancel.id = session + form.id + '_cancel';
        cancel.className = 'fileButton';
    var cancelImg = document.createElement('IMG');
        cancelImg.src = imgDir + '/cancel.png';
        cancelImg.id = cancel.id + 'Img';
    var restart = document.createElement('A');
        restart.href = 'javascript:void(0)';
        restart.title = 'Restart';
        restart.formId = form.id;
        restart.onclick = restartButton;
        restart.id = session + form.id + '_restart';
        restart.className = 'fileButton';
        restart.style.display = 'none';
    var restartImg = document.createElement('IMG');
        restartImg.src = imgDir + '/next.png';
        restartImg.id = restart.id + 'Img';
    var progBox = document.createElement('DIV');
        progBox.className = 'progressBox';
    var progBar = document.createElement('DIV');
        progBar.className = 'progressBar';
        progBar.id = session + form.id + '_progress';
        progBar.innerHTML = '&nbsp;';
    var progBarText = document.createElement('DIV');
        progBarText.className = 'progressBarText';
        progBarText.id = session + form.id + '_progressText';
        progBarText.innerHTML = '&nbsp;';
    var fileSize = document.createElement('DIV');
        fileSize.className = 'fileSize';
        fileSize.id = session + form.id + '_fileSize';
    var input = document.createElement('INPUT');
        input.type = 'file';
        input.className = 'file';
        input.name = 'file' + id;
        input.id = session + input.name;
        input.formId = id;
        input.session = session;
        input.onchange = fileInputOnChange;
    var fileName = document.createElement('SPAN');
        fileName.style.display = 'none';
        fileName.className = 'fileNameText';
        fileName.id = input.id + '_fileName';

    cancel.appendChild(cancelImg);
    restart.appendChild(restartImg);
    progBox.appendChild(progBarText);
    progBox.appendChild(progBar);
    form.appendChild(cancel);
    form.appendChild(restart);
    form.appendChild(progBox);
    form.appendChild(fileSize);
    form.appendChild(input);
    form.appendChild(fileName);
    container.appendChild(form);
    centerElement($('overlayFG').getElementsByTagName('DIV')[0]);
}

function cancelButton(){
    if($(this.formId).repeater){
        $(this.formId).repeater.cancel();
    }else{
        return false;
    }
}

function restartButton(){
    if($(this.formId).repeater){
        $(this.formId).repeater.restart();
    }else{
        return false;
    }
}

function fileInputOnChange(){
    uploadForm('form' + this.formId, (this.session + 'form' + this.formId));
    addFileInput(this.session, this.formId + 1);
}
