﻿(function(scope) {

var data_callback, form, last_streamed_upload_attempt_was_valid = false, max_file_size = 1024 * 1024 * 20, validation_has_occurred = false;

var size_to_text = function(bytes) {
	var i = 0;

    while(1023 < bytes){
        bytes /= 1024;
        ++i;
    };
    
	return i 
		? bytes.toFixed(2) + ["", " Kb", " Mb", " Gb", " Tb"][i]
		: bytes + " bytes";
};

var sendFile = function(toString, maxSize) {
    var isFunction = function(Function) {
		return toString.call(Function) === "[object Function]"; 
	};

	var split = "onabort.onerror.onloadstart.onprogress".split("."),
        length = split.length;

    return function(handler) {
		if (handler.file && maxSize && maxSize < handler.file.fileSize) {
            if (isFunction(handler.onerror))
                handler.onerror();

            return;
        };

        var xhr = new XMLHttpRequest(); 
		var upload = xhr.upload;

        for (var i = 0; i < length; i++)
            upload[split[i]] = function(event) {
                return function(rpe) {
                    if (isFunction(handler[event]))
                        handler[event].call(handler, rpe, xhr);
                };
            }(split[i]);

        upload.onload = function(rpe) {
            if (handler.onreadystatechange === false) {
                if (isFunction(handler.onload))
                    handler.onload(rpe, xhr);
            } else {
                setTimeout(function() {
                    if (xhr.readyState === 4) {
                        if (isFunction(handler.onload))
                            handler.onload(rpe, xhr);
                    } else
                        setTimeout(arguments.callee, 15);
                }, 15);
            }
        };

        xhr.open("post", handler.url || "?upload=true", true);
        xhr.setRequestHeader("If-Modified-Since", "Mon, 26 Jul 1997 05:00:00 GMT");
        xhr.setRequestHeader("Cache-Control", "no-cache");
        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
		xhr.setRequestHeader("Content-Type", "multipart/form-data");

		if (handler.file) {
			var _filename = typeof handler.file.fileName != 'undefined' ? handler.file.fileName : handler.file.name;
			var _filesize = typeof handler.file.fileSize != 'undefined' ? handler.file.fileSize : handler.file.size;

			xhr.setRequestHeader("X-File-Name", _filename);
			xhr.setRequestHeader("X-File-Size", _filesize);
			xhr.setRequestHeader("X-File-Type", handler.file.type);
		}

        xhr.send(handler.file || '');

        return handler;
    };
}(Object.prototype.toString, max_file_size);

var send_multiple_files = function(handler) {
    var length = handler.files.length,
		i = 0,
        onload = handler.onload;

    handler.current = 0;
    handler.total = 0;
    handler.sent = 0;

    while (handler.current < length)
        handler.total += handler.files[handler.current++].fileSize;

    handler.current = 0;

    if (length) {
        handler.file = handler.files[handler.current];
        sendFile(handler).onload = function(rpe, xhr) {
            if (++handler.current < length) {
                handler.sent += handler.files[handler.current - 1].fileSize;
                handler.file = handler.files[handler.current];
                sendFile(handler).onload = arguments.callee;
            } else if(onload) {
                handler.onload = onload;
                handler.onload(rpe, xhr);
            }
        };
    };

    return  handler;
}

var create_upload_status_panel = function() {
	var panel = new YAHOO.widget.Panel('uploadStatus', { 
		close       : false,
		draggable   : false,
		effect      : { effect : YAHOO.widget.ContainerEffect.FADE, duration : 0.5 },
		fixedcenter : true,
		visible     : false,
		width       : '200px'
	});

	panel.setHeader('Please wait...');
	panel.setBody('<img src="/include/image/icons/throbber.gif" alt="Uploading" style="float:left; margin-right:10px;" /><span id="percentageUploaded" style="float:left; color:#000;">0% uploaded</span>');
	panel.render(document.body);

	return panel;
};
		
var get_upload_status_panel = function() {
	var panel = $('uploadStatus');

	if (panel == null)
		panel = create_upload_status_panel();
	
	return panel;
};

var show_upload_info_for_old_browsers = function() {
	var panel = new YAHOO.widget.Panel('uploadStatus', { 
		close       : false,
		draggable   : false,
		effect      : { effect : YAHOO.widget.ContainerEffect.FADE, duration : 0.5 },
		fixedcenter : true,
		visible     : false,
		width       : '200px'
	});

	panel.setHeader('Please wait...');
	panel.setBody('<img src="/include/image/icons/throbber.gif" alt="Uploading" style="float:left; margin-right:10px;" /> Uploading');
	panel.render(document.body);
	panel.show();
};

var on_submit = function(submit_event) {
	if (!validation_has_occurred || !last_streamed_upload_attempt_was_valid) return;

	var is_firefox = BrowserDetect.browser === 'Firefox' && BrowserDetect.version >= 3.6;
	var is_chrome = BrowserDetect.browser === 'Chrome' && BrowserDetect.version >= 5;
	
	if (!is_firefox && !is_chrome) { 
		show_upload_info_for_old_browsers();
		return;
	}
	
	Event.stop(submit_event);

	var data = data_callback();
	var onload = data.onload;

	data.onload = function(ev, xhr) {
		get_upload_status_panel().hide();
		onload(ev, xhr);
	};

	data.onloadstart = function(ev, xhr) {
		var panel = get_upload_status_panel();
		$('percentageUploaded').innerHTML = '0% uploaded';

		if (!panel.visible) panel.show();
	};

	data.onprogress = function(ev, xhr) {
		var percentage = Math.round((ev.loaded * 100) / ev.total) + '% uploaded';
		get_upload_status_panel();
		$('percentageUploaded').innerHTML = percentage;			
	};

	// data = {
	//		file: file_object,
	//		url: url,
	//		onerror: function() {},
	//		onload: function() {},
	//		onloadstart: function() {},
	//		onprogress: function() {},
	// }

	sendFile(data); 
};

scope.StreamedUpload = {
	after_validation: function(ev) {
		validation_has_occurred = true;
		on_submit(ev);
	},

	attach_to_form: function(form) {
//		Event.observe(form,'submit', on_submit.bind(scope), false);	
	},

	create_upload_status_panel: create_upload_status_panel,

	get_upload_status_panel: get_upload_status_panel,

	max_file_size: max_file_size,

	register_callback: function(callback) {
		data_callback = callback;
	},

	set_last_attempt_was_valid: function(valid) {
		last_streamed_upload_attempt_was_valid = valid;
	},

	size_to_text: size_to_text
};

})(this);
