if (typeof Exception === "undefined")
{
	Exception = String;
}

var Uploader = function(queueContainer)
{
	var cookie = null;
	var folderIDInput = null;
	var viewhashes = [];
	var servers = [];
	var files = [];
	var swfu = null;
	var originalTitle = document.title;
	
	var queuedCount = 0;
	var queuedSize = 0;
	var completeSize = 0;
	
	/* **********************
	   Public methods.
	   ********************** */
	
	this.addFile = function()
	{
		swfu.selectFiles();
	}
	
	this.startQueue = function()
	{
		if (swfu.getStats().files_queued > 0) 
		{	
			//Upload files
			var doUpload = function()
			{
				swfu.addPostParam('folderViewhash', folderIDInput ? folderIDInput.value : '');
				swfu.addPostParam('cookie', cookie);
				
				startNextFile();
				
				window.onbeforeunload = function(){
					return i18n.text.uploader.unload.toString();
				};
			}
			
			//Make sure user has a folder
			if (folderIDInput && folderIDInput.options.length == 0)
			{
				if (FileFactory && FileFactory.createFolder)
				{
					return FileFactory.createFolder(i18n.text.uploader.createFolder, doUpload);
				}
				else
				{
					return alert(i18n.text.uploader.selectFolder);
				}
			}
			
			doUpload();
		}
		else
		{
			alert(i18n.text.uploader.error.noFiles);
		}
	}
	
	this.cancelQueue = function()
	{
		window.onbeforeunload = null;

		swfu.stopUpload();
		var stats = swfu.getStats();
		while (stats.files_queued > 0) {
			swfu.cancelUpload();
			stats = swfu.getStats();
		}
		
		for (var i = 0; i < files.length; i++)
		{
			files[i].setCancelling();
		}
		
		if (swfu.getStats().successful_uploads > 0)
		{
			completeQueue();
		}
		
		queuedSize = 0;
		completeSize = 0;
		showProgress();
	}
	
	this.setServers = function(values)
	{
		servers = values;
	}
	
	this.setCookie = function(value) {
		cookie = value;
	}
	
	this.setfolderIDInput = function(value)
	{
		folderIDInput = value;	
	}
		
	/* **********************
	   Private functions.
	   ********************** */
	
	var showInterfaceOptionsDo = function()
	{
		$('#uploadCancel').show();
		$('#fileQueue').show();
		$('#uploadOptions').fadeIn('slow');
	}
	
	var showInterfaceOptions = function()
	{
		$('#fileQueue').show();
		window.setTimeout(function(){
			showInterfaceOptionsDo();
		}, 250);
	}
	
	var startNextFile = function()
	{
		var server = getServer()
		if(server) 
		{
			currentServer = server;
			swfu.setUploadURL(server.url);
			swfu.startUpload();
		}
		else 
		{
			alert(i18n.text.uploader.error.generic);
		}
   
	}
		
	var getServer = function() 
	{
		var totalWeight = 0;
		for(var i = 0; i < servers.length; i++) 
		{
			totalWeight += servers[i].weight;
		}
		
		if(totalWeight == 0)
		{
			return false;
		}
		
		var targetWeight = Math.floor(Math.random() * totalWeight + 1);
		var counter = 0;
		swfu.debug("Total weight is " + totalWeight);
		
		for(var i = 0; i < servers.length; i++) 
		{
			counter += servers[i].weight;
			if(counter >= targetWeight)
			{
				return servers[i];
			}
		}
		
		swfu.debug("Get server fallback");
		return servers[Math.floor(Math.random() * servers.length)];
	}
	
	var isViewhash = function(input) 
	{
		return typeof(input) == 'string' && input.match(/^[a-z0-9]{3,16}$/i)!==null;
	}
	
	var isViewhash = function(input)
	{
		return typeof(input) == 'string' && input.match(/^[a-z0-9]{3,16}$/i) !== null;
	}
	
	var completeQueue = function()
	{
		window.onbeforeunload = null;
		
		var url = '/file/complete.if.php/';
		var count = 0;
		while (viewhashes.length > 0)
		{
			var viewhash = viewhashes.shift();
			if (isViewhash(viewhash))
			{
				url += viewhash + '/';
				count++;
			}
		}
		if (count > 0)
		{
			parent.document.getElementById('tab-computer-frame').src = url;
		}
	}	
	
	var showProgress = function(currentFileSize)
	{
		currentFileSize = isNaN(currentFileSize) ? 0 : currentFileSize;
		var progress = (completeSize + currentFileSize) / queuedSize;
		var percent = Math.min(100, Math.round(progress * 100));
		
		if (queuedSize == 0 || (completeSize + currentFileSize) == 0)
		{
			document.title = originalTitle;
		}
		else
		{
			document.title = i18n.text.uploader.progress.format(percent + '%') + ' - ' + originalTitle;
		}
	}

	/* **********************
	   Event Handlers
	   ********************** */
	
	var getFileProgress = function(file)
	{
		for (var i = 0; i < files.length; i++)
		{
			if (files[i].fileProgressID == file.id)
			{
				return files[i];
			}
		}
	}
	
	var fileQueued = function(file) {
		try {
			showInterfaceOptions();
			swfu.debug("FileQueued: " + file.name);
			var progress = new FileProgress(file, queueContainer);
			files.push(progress);
			progress.setStatus(i18n.text.uploader.ready);
			progress.toggleCancel(true, this);	
			
			queuedSize += file.size;
			queuedCount += 1;
		} catch (ex) {
			swfu.debug(ex);
		}
	}
	
	var fileQueueError = function(file, errorCode, message) {
		try {
			swfu.debug("FileQueueError: " + file + ", " + errorCode);
			if (errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
				alert(
						i18n.text.uploader.error.fileLimit + "\n" +
						(message > 1 ? i18n.text.uploader.fileLimit.format(message) : '')
					 );
				return;
			}
			showInterfaceOptions();			
			var progress = new FileProgress(file, queueContainer);
			files.push(progress);
			progress.setError();
			progress.toggleCancel(true, swfu);
	
			switch (errorCode) {
			case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
				progress.setStatus(i18n.text.uploader.error.filesize);
				swfu.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
				progress.setStatus(i18n.text.uploader.error.empty);
				swfu.debug("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
				progress.setStatus(i18n.text.uploader.error.fileType);
				swfu.debug("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			default:
				if (file !== null) {
					progress.setStatus(i18n.text.uploader.error.unhandled);
				}
				swfu.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			}
		} catch (ex) {
	        swfu.debug(ex);
	    }
	}
	
	var uploadStart = function(file) {
		try {
			swfu.debug("UploadStart: " + file);
			/* I don't want to do any file validation or anything,  I'll just update the UI and
			return true to indicate that the upload should start.
			It's important to update the UI here because in Linux no uploadProgress events are called. The best
			we can do is say we are uploading.
			 */
			
			var progress = getFileProgress(file);
			progress.setStatus(i18n.text.uploader.uploading);
			progress.setUploading();
			showProgress();
		}
		catch (ex) {}
		
		return true;
	}
	
	var uploadProgress = function(file, bytesLoaded, bytesTotal) {
		try {
			swfu.debug("UploadProgress: " + file);
			var progress = getFileProgress(file);
			progress.setProgress(bytesLoaded, bytesTotal);
			showProgress(bytesLoaded);
		} catch (ex) {
			swfu.debug(ex);
		}
	}
	
	var uploadSuccess = function(file, serverData) {
		try {
			swfu.debug("UploadSuccess: " + file);
			viewhashes.push(serverData);
			completeSize += file.size;
			var progress = getFileProgress(file);
			progress.setComplete();
			if (isViewhash(serverData))
			{
				var fileName = new String(file.name);
				var downloadURL = "http://" + document.location.host + "/file/" + serverData + "/n/"+fileName.replace(/[^a-z0-9\-\.]+/ig, "_");
				progress.setStatus(downloadURL);
				progress.setURL(downloadURL);
				
			}
			else
			{
				progress.setStatus(i18n.text.uploader.complete);
			}
			showProgress();
		} catch (ex) {
			swfu.debug(ex);
		}
	}
	
	var uploadError = function(file, errorCode, message) {
		try {
			swfu.debug("UploadError: " + file + ", " + errorCode);
			var progress = getFileProgress(file);
			progress.setError();
			completeSize += file.size;
			
			switch (errorCode) {
			case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
				progress.setStatus(i18n.text.uploader.error.http.format(message));
				swfu.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
				progress.setStatus(i18n.text.uploader.failed);
				swfu.debug("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.IO_ERROR:
				progress.setStatus(i18n.text.uploader.error.io);
				swfu.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
				progress.setStatus(i18n.text.uploader.error.security);
				swfu.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
				progress.setStatus(i18n.text.uploader.error.limit);
				swfu.debug("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
				progress.setStatus(i18n.text.uploader.error.validation);
				swfu.debug("Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
				// If there aren't any files left (they were all cancelled) disable the cancel button
				progress.setStatus(i18n.text.uploader.cancelled);
				progress.setCancelled();				
				break;
			case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
				progress.setStatus(i18n.text.uploader.stopped);
				break;
			default:
				progress.setStatus(i18n.text.uploader.unhandled + ": " + errorCode);
				swfu.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			}
			showProgress();
		} catch (ex) {
	        swfu.debug(ex);
	    }
	}
	
	var uploadComplete = function(file) {
		swfu.debug("UploadComplete: " + file);
		var uploaded = swfu.getStats().successful_uploads;
		
		
		if (swfu.getStats().files_queued == 0) 
		{
			completeQueue();
		}
		else
		{
			showProgress();
			startNextFile();
		}
	}
	
	/* **********************
	   Initiailization
	   ********************** */
	
	var settings = 
	{
		flash_url : "/img/upload/uploader.swf",
		upload_url: "/upload.php",	// Relative to the SWF file
		file_size_limit : "300 MB",
		file_types : "*.*",
		file_types_description : "All Files",
		file_upload_limit : 25,
		file_queue_limit : 25,
		debug: document.location.search.indexOf('debug') > 0,

		flash_color: 'transparent',
		flash_width: '400',
		flash_height: '30',
		flash_container_id: 'flashContainer',
		flash_label: i18n.text.uploader.browse,
		
		// The event handler functions are defined in handlers.js
		file_queued_handler : fileQueued,
		file_queue_error_handler : fileQueueError,
		upload_start_handler : uploadStart,
		upload_progress_handler : uploadProgress,
		upload_error_handler : uploadError,
		upload_success_handler : uploadSuccess,
		upload_complete_handler : uploadComplete,
		queue_complete_handler : null	// Queue plugin event
	}
	
	swfu = new SWFUpload(settings);	
	
	//Set listeners
	var uploader = this;
	
	(function(){
		uploader.setfolderIDInput(document.getElementById('folderTree'));
		
		//Buttons
		$('#uploadCancel').click(function() 
		{
			uploader.cancelQueue();
		});
		
		$('#uploadStart').click(function() 
		{ 
			uploader.startQueue();
		});
		 		
		//Toggle mode
		$('#switchHTTP').click(function()
		{
			$('#uploader').addClass('basic').removeClass('advanced');
			showInterfaceOptionsDo();
			$('#uploadContainer').hide();
			return false;
		});
		
		$('#switchFlash').click(function()
		{
			$('#uploader').addClass('advanced').removeClass('basic');
			$('#uploadContainer').show();
			return false;
		});
		
		$('#uploader').submit(function()
		{
			$('#uploadOne').attr('disabled', true);
		});
		
		$('#fileOne').change(function()
		{
			$('#uploadOne').attr('disabled', false);
		});
		
		if ($('input[name="enabled"]').val() == 1)
		{
			$('#uploadOne').attr('disabled', false);
			$('#uploadCancel').attr('disabled', false);
			$('#uploadStart').attr('disabled', false);
		}
		
	}).apply(this);
}

Uploader.init = function()
{
	var fallback = function() {
		$('.uploaderError').show();
		$('#flashWarning').show();
		$('#uploader').addClass('error').addClass('basic');
	}
	
	if (window.FlashDetect && (!FlashDetect.installed || FlashDetect.major < 9))
	{
		return fallback();
	}
	
	try
	{
		var uploader = new Uploader(		
			queueContainer = document.getElementById('uploadContainer')
		);		
		return uploader;
	}
	catch (ex)
	{
		fallback();
		throw ex;
	}
};

$(document).ready(function(){
	$("#uploadMore").hover(function(){
		$(this).css({cursor:'pointer'});
	},
	function(){
		$(this).css({cursor:'auto'});
	}).bind("click", function(e){
		e.preventDefault();
		
		parent.document.getElementById('tab-computer-frame').src = "/upload/upload.if.php";
	});
	
	$("#email").hover(function(){
		$(this).css({cursor:'pointer'});
	},
	function(){
		$(this).css({cursor:'auto'});
	}).bind("click", function(e){
		e.preventDefault();
		
		window.parent.$.facebox($("#modalContainer").html())
	});
});