/*********
* Javascript for file upload demo
* Copyright (C) Tomas Larsson 2006
* http://tomas.epineer.se/

* Licence:
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under this License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*/
function PeriodicalAjax(url, parameters, frequency, decay, onSuccess, onFailure, upload_progress_fails_limit, upload_no_progress_limit, upload_progress_timeout) {
    function createRequestObject() {
        var xhr;
        try {
            xhr = new XMLHttpRequest();
        }
        catch (e) {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xhr;
    }

    function send() {
        if(!stopped) {
            try{
                xhr.open('post', url, true);
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.onreadystatechange = function() { self.onComplete(); };
                xhr.send(parameters);

                timeout_timer = setTimeout( function(){ xhr.abort();}, upload_progress_timeout);
            } catch(e){}
        }
    }

    this.stop = function() {
        stopped = true;
        clearTimeout(this.timer);
    }

    this.start = function() {
        upload_progress_fails_count = 0;
        upload_no_progress_count = 0;
        stopped = false;
        this.onTimerEvent();
    }

    this.onComplete = function() {
        if(this.stopped) return false;
        if ( xhr.readyState == 4) {

            clearTimeout(timeout_timer);

            if(xhr.status == 200) {
                upload_progress_fails_count = 0;
                if(xhr.responseText == lastResponse) {
                    decay = decay * originalDecay;
                } else {
                    decay = 1;
                }
                lastResponse = xhr.responseText;
                if(onSuccess instanceof Function) {
                    onSuccess(xhr);
                }
                this.timer = setTimeout(function() { self.onTimerEvent(); }, decay * frequency * 1000);
            } else {
                upload_progress_fails_count++;
                if (xhr.status == 500 || upload_progress_fails_count >= upload_progress_fails_limit){
                    if(onFailure instanceof Function) {
                        onFailure(xhr);
                    }
                } else {
                    this.timer = setTimeout(function() { self.onTimerEvent(); }, decay * frequency * 1000);
                }
            }
        }
    }

    this.getResponse = function() {
        if(xhr.responseText) {
            return xhr.responseText;
        }
    }

    this.onTimerEvent = function() {
        send();
    }

    var timeout_timer;
    var fails_progress_count;
    var self = this;
    var stopped = false;
    var originalDecay = decay || 1.2;
    decay = originalDecay;
    var xhr = createRequestObject();
    var lastResponse = "";
    this.start();
}

function ProgressTracker(sid, options) {

    this.onSuccess = function(xhr) {
        try {
            if(parseInt(xhr.responseText) >= 100) {
                periodicalAjax.stop();
                if(options.onComplete instanceof Function) {
                	if (options.scope) {
                		options.onComplete.call(options.scope);
                	} else {
                    	options.onComplete();
                	}
            	}
            } else if(xhr.responseText && xhr.responseText == lastResponse) {
                upload_no_progress_count++;
                if (upload_no_progress_count >= upload_no_progress_limit){
                    this.onFailure(xhr);
                }
            } else if(xhr.responseText && xhr.responseText != lastResponse) {
                if(options.onProgressChange instanceof Function) {
                    options.onProgressChange(xhr.responseText);
                }
                if(options.progressBar && options.progressBar.style) {
                    options.progressBar.style.width = parseInt(xhr.responseText) + "%";
                }
                lastResponse = xhr.responseText;
                upload_no_progress_count = 0;
            }

        } catch(e) {
            log_error('ProgressTracker: ' + e, '', '');
            options.onFailure(xhr.responseText);
        }
    }

    this.onFailure = function(xhr) {

        if(options.onFailure instanceof Function) {
            if (options.scope) {
                options.onFailure.call(options.scope, xhr.responseText, xhr.status);
            } else {
                options.onFailure(xhr.responseText, xhr.status);
            }
        } else {
            alert(xhr.responseText);
        }
        periodicalAjax.stop();
    }

    var upload_progress_fails_count = 0;
    var upload_no_progress_count = 0;
    var self = this;
    var lastResponse = -1;
    options = options || {};
    var url = '/upload/progress';
    var frequency = options.frequency || 0.5;
    var decay = options.decay || 2;
    var upload_progress_fails_limit = options.upload_progress_fails_limit || 5;
    var upload_no_progress_limit = options.upload_no_progress_limit || 5;
    var upload_progress_timeout = options.upload_progress_timeout || 10000;
    var periodicalAjax = new PeriodicalAjax(url, 'sid=' + sid, frequency, decay, function(request){self.onSuccess(request);},function(request){self.onFailure(request);}, upload_progress_fails_limit, upload_no_progress_limit, upload_progress_timeout);

    return periodicalAjax;
}
