function UploadsManager() {
	var $me = this;

	$(document).bind('FormManager.Form.Ready', function ($e, $prefix) {
		var $form_id = FormManager.form_param($prefix, 'form_id');

		$me.Init($form_id);
	});
}

UploadsManager = new UploadsManager();

/* ==== Private Attributes ==== */
UploadsManager._uploadersCreated = 0;
UploadsManager._uploadersReady = 0;

UploadsManager._debugMode = false;
UploadsManager._Uploaders = {};

/* ==== Private methods ==== */
UploadsManager.iterate = function($method, $timeout) {
	var $me = this;
	var args = Array.prototype.slice.call(arguments); // convert to array

	if ($timeout !== undefined) {
		// 2nd parameter is given
		if ((Object.prototype.toString.call($timeout) === '[object String]') && $timeout.match(/^timeout:([\d]+)$/)) {
			// it's string in format "timeout:<number>"
			$timeout = parseInt(RegExp.$1);
		}
		else {
			// this is not the timeout, but 1st parameter of iteratable method
			$timeout = undefined;
		}
	}

	if ($timeout !== undefined) {
		// make delayed iteration (helps with direct innerHTML assignments in IE)
		args.splice(args.length - 1, 1); // remove timeout

		setTimeout(function() { $me.iterate.apply($me, args); }, $timeout);
		return ;
	}

	args.splice(0, 1); // remove method name

	$.each(this._Uploaders, function (index, uploader) {
		uploader[$method].apply(uploader, args);
	});
};

UploadsManager._hasQueue = function() {
	var has_queue = false;

	$.each(this._Uploaders, function (index, uploader) {
		var tmp = uploader.hasQueue();

		has_queue = has_queue || tmp;
	});


	return has_queue;
};

/* ==== Public methods ==== */
UploadsManager.Init = function ($form_id) {
	var $me = this,
		$submit_handler = function ($e) {
			if ($me._hasQueue()) {
				submitted = false;
				$e.stopImmediatePropagation();
				alert('File upload is in progress. Please cancel the upload or wait until it\'s completed.');

				return false;
			}

			return true;
		};

	if ( $form_id === undefined ) {
		$form_id = $form_name;
	}

	$('#' + $form_id).unbind('submit', $submit_handler).submit($submit_handler);
};

UploadsManager.AddUploader = function(id, params) {
	this.Init();

	this._Uploaders[id] = new Uploader(id, params);
	this._uploadersCreated++;
};

UploadsManager.RemoveUploader = function(id) {
	this._Uploaders[id].remove();
	delete this._Uploaders[id];
	this._uploadersCreated--;
};

/* ==== Flash event handlers ==== */
UploadsManager.onReady = function () {
	this._uploadersReady++;

	if (this._uploadersReady == this._uploadersCreated) {
		// all uploaders are ready
		Application.processHooks('m:OnUploadersReady');
	}
};