// Loader for modules in required sequence
// ATTENTION: set lmJsPath and lmJsVersion (if needed) first!
// (c) MI-6, 2006, Author: Andery I. Tserkus (zerkella@i.ua)

// Constants
LM_S_READY = 'READY';
LM_S_LOADED = 'LOADED';
LM_S_LOADING = 'LOADING';

// Inits path
if (typeof(lmJsPath) == 'undefined')
	lmJsPath = '';

var lmModules = {
	UTIL: {path: 'util.js'},
	DROPDOWN: {path: 'dropdown.js'},
	DATAPROVIDER: {path: 'data_provider.js'},
	RSSREADER: {path: 'rssreader.js'},
	PICLITE: {path: 'pic_lite.js'},
	PICEDIT: {path: 'pic_edit.js'},
	LVS: {path: 'label_viz_sync.js'},
	LVSR: {path: 'label_viz_sync_radio.js'},
	SWFCREATOR: {path: 'mmSWFUpload.js'},
	SUGGESTION: {path: 'suggestion.js'},
	SWFUPLOAD: {path: 'i/swfupload220b2_i.js'},
	ORG_CORE: {path: 'i/org_core.js'},
	ORG_HELPERS: {path: 'i/org_helpers.js'},
	ORG_CALENDAR: {path: 'i/org_calendar.js'},
	ORG_YEAR: {path: 'i/org_year.js'},
	ORG_MONTH: {path: 'i/org_month.js'},
	ORG_WEEK: {path: 'i/org_week.js'},
	ORG_DAY: {path: 'i/org_day.js'},
	ORG_DASHBOARD: {path: 'i/org_dashboard.js'},
	ORG_DASHHELPERS: {path: 'i/org_dash_helpers.js'},
	ORG_INDITEMS: {path: 'i/org_inditems.js'},
	RAT_POPUP: {path: 'i/rating_popup.js'},
	PEOPLE_ONLINE: {path: 'i/people_online.js'},
	POPUPDIV: {path: 'i/popupdiv.js'},
	POPUPDIVU: {path: 'i/popupdiv_u.js'},
	HTML5DD: {path: 'i/drag_files.js'}
}

// Variables
var lmQueue = new Array(); // Queue of requests on load
var lmTimerHndl = false; // Handle of timer
var lmNotifyController = null; // Object to notify on load start and on load finish
var lmLoading = false; // Whether some objects loading
var lmNotified = false; // Whether some indicator notified of current status of this object

// Checks whether module is ready
function lmIsModuleStatus(moduleName, status) {
	var flagName = moduleName + '_' + status;
	var isOn = false;
	if (typeof(window[flagName]) != 'undefined')
		isOn = window[flagName];
	return isOn;
}

// Sets module status
function lmSetModuleStatus(moduleName, status) {
	var flagName = moduleName + '_' + status;
	window[flagName] = true;
}

// Calls designated func after all modules get needed status
// Callee is either func or data object method {object: object, funcName: funcName}
function lmCallAfterModulesStatus(status, modules, callee, param) {
	var len = lmQueue.length;
	if (typeof(param) == 'undefined')
		param = null;
		
	// Set data
	var data = new Object();
	data.status = status;
	data.modules = modules;
	data.callee = callee;
	data.param = param;
	lmQueue[len] = data;

	// Add all needed modules to load
	var len = modules.length;
	for (var i = 0; i < len; i++) {
		var moduleName = modules[i];
		if (typeof(lmModules[moduleName]) == 'undefined')
			continue;
			
		// Check whether to load it or it's already loading/loaded
		if (lmIsModuleStatus(moduleName, LM_S_LOADING) || lmIsModuleStatus(moduleName, LM_S_LOADED) || lmIsModuleStatus(moduleName, LM_S_READY))
			continue;
			
		lmSetModuleStatus(moduleName, LM_S_LOADING);

		var h = document.getElementsByTagName("HEAD")[0];
		if (h) {
			var js = document.createElement("SCRIPT");
			var addVer = '';
			if (typeof(lmJsVersion) != 'undefined')
				var addVer = '?ver=' + lmJsVersion;
			js.src =  lmJsPath + lmModules[moduleName].path + addVer;
			h.appendChild(js);
		}
	}
	
	// Check their status
	if (!lmTimerHndl)
		lmTimerHndl = setInterval(lmCheckModulesStatus, 150);
	lmCheckModulesStatus();
}

// Calls designated func after all modules are ready
function lmCallAfterModulesReady(modules, callee, param) {
	lmCallAfterModulesStatus(LM_S_READY, modules, callee, param);
}

// Calls func (object method) when module is loaded
function lmCallAfterModulesLoaded(modules, callee, param) {
	lmCallAfterModulesStatus(LM_S_LOADED, modules, callee, param);
}

// Checks for each task - whether all modules got needed status and calls appropriate callee
function lmCheckModulesStatus() {
	var i = 0;
	while (i < lmQueue.length) {
		var len = lmQueue[i].modules.length;
		var allReady = true;
		for (var j = 0; j < len; j++) {
			if (!lmIsModuleStatus(lmQueue[i].modules[j], lmQueue[i].status)) {
				allReady = false;
				break;
			}
		}
		if (allReady) {
			callee = lmQueue[i].callee;
			param = lmQueue[i].param;
			lmQueue.splice(i, 1);
			if (typeof(callee) == 'object') {
				callee.object[callee.funcName](param);
				callee.object = null;
			} else {
				callee(param);
			}
		} else {
			i++;
		}
	}
	if (lmQueue.length == 0) {
		clearInterval(lmTimerHndl);
		lmTimerHndl = false;
	}
	
	// Notify object if needed
	if (lmQueue.length) {
		if (!lmLoading) {
			lmLoading = true;
			lmNotified = false;
		}
	} else {
		if (lmLoading) {
			lmLoading = false;
			lmNotified = false;
		}
	}
	if (lmNotifyController && !lmNotified) {
		lmNotifyController.onLoadNotify(lmQueue, lmLoading ? 'start' : 'finish');
		lmNotified = true;
	}
}