/**************************************************************************\
SHARE 9
Copyright (c) Enigma Interactive 2005

Filename:		content_client.js
Description:	Provides the overall edit area interface controller.

History
ver	date		who			comment
-----------------------------------------------------------------------------
1	15/12/05	AJL			Created
\**************************************************************************/


var CONTROLLERS = { };
var CONTENT = {};

CONTENT.Controller = function() {
	this.inherit(OO.Listener);
	this.ajaxHandler = 'generic';
}
CONTENT.Controller.prototype = {
	initSelf: function() {
		this.ajax = AJAX.create(this, this.ajaxHandle);
		this.nextLoadId = 1;
	},
	
	listenToMessage: function(message, params) {
		switch (message) {
			default	:	return;
		}
	},
	
	showLoginPrompt: function() {
		CONTROLLERS.content.requestContent('alert', 'login', true);
	}
}

CONTENT.ContentController = function() {
	this.inherit(CONTENT.Controller);
	this.inherit(OO.Timer);
}

CONTENT.ContentController.prototype = {
	initSelf: function() {
		this.dialogs = { };
		this.store = { };
		this.initFns = { };
		this.unloads = { };
		this.objects = { };
		this.loadOrder = [ ];
		this.scriptCount = 0;
		this.scripts = { };
		this.loadIdList = { };
		this.loadQueue = [];
		this.header = document.getElementsByTagName('head')[0];
		this.requestInitialLoad();
		this.scriptLoadQueue = [ ];
		CC.messenger.registerListener(this, 'content');
	},
	
	requestInitialLoad: function() {
		$CR('content', 'initialLoad', 0, 'Loading the initial page structure');
	},
	
	setCurrentLocation: function(location) { this.currentLocation = location; $CM('session', 'maintainSession'); },
	getCurrentLocation: function() { return this.currentLocation; },
	
	go: function(location, params) {
		$CM('history', 'add', { mess: 'history,url', param: location });
		params = params || { };
		$CR('content', 'load', { location: location, params: params, sbLoadId: this.nextLoadId++, sbCurrentLocation: this.currentLocation }, 0, 'Loading page content' );
	},
	
	loadFloat: function(location, params, tmpURL) {
		params = params || { };
		
		if (tmpURL) {
			params.userLocation=this.currentLocation;
			$URL(tmpURL, { ccOnLoadComplete: { type: 'content', message: 'loadFloat', location: location, params: params } });
			return;
		}
		$CR('content', 'loadFloat', { location: location, params: params, sbLoadId: this.nextLoadId++ }, 0, 'Loading window content' );
	},
	
	unloadFloat: function(location) {
		$CR('content', 'unloadFloat', { location: location } );
	},
	
	loadAlert: function(id) { 
		this.requestLoad('alert', id);
	},
	
	loadContent: function(item) {
		var holder = DOM.get(item.holder);
		var tmpWrite = document.write;
		if (!holder) return;
		var s = CONTENT.currentScriptH = DOM.structure({ });
		var d = DOM.structure({  });
		if (item.clearholder) holder.innerHTML = '';
		holder.appendChild(d);
		d.appendChild(s);
		document.write = CONTENT.documentWrite;
		d.innerHTML = item.content;
		
		if (holder) {
			while (d.childNodes.length) { 
				if (item.id) this.store[item.id].push(d.childNodes[0]);
				holder.appendChild(d.childNodes[0]);
			}
		} else {
		}
		
		holder.removeChild(d);
		document.write = tmpWrite;
		return null;
	},
	
	updateCSS: function(path, content, itemId, atEnd)
	
	{
		var i,e,n,sheets = this.header.getElementsByTagName('STYLE');
		var n = DOM.structure({ t: 'style', _fileName: path });

		for (i=0;(e=sheets[i]);i++) { if (e.fileName&&(e.fileName.indexOf(path)!=-1)) break; }
		if (!e) { 
			e=DOM.structure({ t: 'style', _fileName: path });
			this.header.appendChild(e);
			DHTML.setLinkCSS(e, content);
		} else {
			n.fileName = e.fileName;
			n.realName = e.realName;
			n.shortName = e.shortName;
			if (atEnd) {
				this.header.appendChild(n);
			} else {
				this.header.insertBefore(n, e);
				this.header.insertBefore(e, n);
			}
			DHTML.setLinkCSS(n, content);
			this.header.removeChild(e);
			
			if (itemId && (this.store[itemId].indexOf(e)!=-1)) {
				this.store[itemId].deleteItem(e);
				this.store[itemId].push(n);
			}
		}
		return e;
	},
	
	loadCSS: function(item, itemId) {
		if (!item.content) return this.loadCSSOld(item);
		var realName = item.file.replace(/\/rev_[0-9]+_[0-9]+/, '');
		var shortName = realName.replace(/\?.*/, '');
		var ol,sheet = this.updateCSS(item.file, item.content, itemId, item.atend);

		sheet.shortName = shortName;
		sheet.realName = realName;
		if (ol=item.onload) $DM(100,ol.type,ol.message,ol.params);
		
		return sheet;
	},
	
	loadCSSOld: function(item) {
		var realName = item.file.replace(/\/rev_[0-9]+_[0-9]+/, '');
		var shortName = realName.replace(/\?.*/, '');
		var sheet = DOM.structure( { t: 'link', e: { rel: 'stylesheet', media: 'all', type: 'text/css', shortName: shortName, realName: realName, href: item.file } } );
		
		if (item.replacecss) this.replaceCSS(item.id, shortName, item.appendcss);
		this.removeCSSClashes(realName, item.appendcss);
		this.header.appendChild(sheet);
		
		if (item.onload) {
			this.ajax.preload(item.file, item.onload.type, item.onload.message, item.onload.params);
		}
		
		return sheet;
	},
	
	replaceCSS: function(id, name, append) {
		var links = this.store[id],items = [];
		
		for (var i=0,link;(link = links[i]);i++) if (name == link.shortName) items.push(link);
		this.removeCSSItems(items, append);
	},
	
	removeCSSClashes: function(file, append) {
		var store,items = [], links = this.header.getElementsByTagName('LINK');
		
		for (var i=0,link;(link = links[i]);i++) if (file == link.realName) items.push(link);
		this.removeCSSItems(items, append);
	},
	
	removeCSSMatching: function(match) {
		var store,items = [], links = this.header.getElementsByTagName('LINK');
		
		for (var i=0,link;(link = links[i]);i++) if (link.href.indexOf(match) != -1) items.push(link);
		this.removeCSSItems(items);
	},
	
	removeCSSItems: function(items, append) {
		var store;
		if (append) items.pop();

		for (var i=0,link;(link=items[i]);i++) {
			DHTML.removeSelf(link);
			
			store = this.store[link.storeID];
			if (store) store.deleteItem(link);
		}	
	},
	
	installJS: function(href, type, message, params) {
		var script = DOM.structure( { t: 'script', e: { charset: 'UTF-8', type: 'text/javascript', src: href } });
		
		this.header.appendChild(script);
		this.ajax.preload(href, type, message, params);
		
		return script;
	},
	
	removeJS: function(ele) {
		DHTML.removeSelf(ele);
	},
	
	getJSScript: function(ooTag) {
		if (!window[ooTag]) return null;
		var i=0,s,scripts = this.header.getElementsByTagName('SCRIPT');
		
		while (s=scripts[i++]) {
			if (s.ooTag==ooTag) return s;
		}
		return null;
	},
	
	loadJS: function(item) {
		var ooTag=item.file.replace(/.*\/([^\.]+)\.js/, '$1').toUpperCase();
		var script = this.getJSScript(ooTag);
		if (!script) {
			script = DOM.structure( { t: 'script', e: { itemId: item.id, ooTag: ooTag, charset: 'UTF-8', type: 'text/javascript', src: item.file } });
			this.scriptLoadQueue.push(script);
			this.header.appendChild(script);
		} else {
			this.scriptLoadQueue.push(script);
			this.setTimeout('jsInit', 10, this.jsInit );
		}

		return script;
	},
	
	preloadDialog: function(item) {
		this.dialogs[item.params.dialoglabel] = item;
	},
	
	loadDialog: function(label, controller) {
		if (this.dialogs[label]) {
			CC.dialogs.load(this.dialogs[label], controller);
			delete this.dialogs[label];
		}
	},
	
	queueLoad: function(item) {
		this.loadItem(item);
		//this.loadQueue.push(item);
		//this.lqTimeout = this.lqTimeout||this.setTimeout('loadQueue', 1, this.loadNext);
	},
	
	loadNext: function() {
		var item = this.loadQueue.shift();	
		if (!item) return (this.lqTimeout=0);

		this.loadItem(item);
		this.lqTimeout = this.setTimeout('loadQueue', 1, this.loadNext);
	},
	
	loadItem: function(item) {
		var ele;
		
		try { eval('item.params = {'+item.params+'}'); } catch(e) { item.params = {} };

		if (item.id) {
			
			if (this.loadOrder.indexOf(item.id) == -1) this.loadOrder.push(item.id);
			
			this.initFns[item.id] = this.initFns[item.id] || [ ];
			this.store[item.id] = this.store[item.id] || [ ];
			this.unloads[item.id] = this.unloads[item.id] || [ ];
			this.objects[item.id] = this.objects[item.id] || [ ];
		}
		
		switch (item.type) {
			case 'content'	:	ele = this.loadContent(item); break;
			case 'dialog'	:	ele = this.preloadDialog(item); break;
			case 'css'		:	ele = this.loadCSS(item, item.id); break;
			case 'js'		:	ele = this.loadJS(item); break;
		}
		
		if (item.id && ele) {
			this.store[item.id].push(ele);
			ele.storeID = item.id;
		}
	},
	
	updateItem: function(holder, content) {
		var ele = DOM.get(holder);
		
		if (ele) ele.innerHTML = content;
	},
	
	unloadItem: function(id) {
		var store = this.store[id];
		var ele, fn, scriptName;
		var i = this.loadOrder.indexOf(id);
		if (i > -1) this.loadOrder.splice(i, 1);
		
		if (store) {
			while (ele = store.pop()) {
				try { ele.disabled = true;  } catch(e) { };
				try { if (ele.parentNode) DHTML.removeSelf(ele); } catch(e) { };
			}
		}
		if (this.unloads[id]) while (fn = this.unloads[id].pop()) fn();
		
		if (this.objects[id]) while (this.objects[id].length) { ele = this.objects[id].pop(); if (ele) OO.dispose(ele); }
		if (this.scripts[id]) { while (scriptName = this.scripts[id].pop()) window[scriptName] = null;  }
		var links = this.header.getElementsByTagName('LINK');
		this.loadIdList[id] = null;
		
		for (i=0;(ele=links[i]);i++) if (ele.itemID == id) DHTML.removeSelf(ele);
	},
	
	unloadHolder: function(id) {
		var holder = DOM.get(id);
		
		if (holder) DHTML.clearElement(holder);
	},
	
	unloadRef: function(ref) { 
		var id,list = this.loadIdList[ref];
		if (list) while (id=list.pop()) this.unloadItem(id);	
	},
	
	unloadAll: function() {
		var id;
		while (id = this.loadOrder.pop()) this.unloadItem(id);
	},
	
	setLoadIDs: function(ids) { this.currentLoadIds = ids; },
	
	serveComplete: function(confirm) {
		if (!confirm) return this.setTimeout('serveComplete', 200, this.serveComplete, true);
		var styleList = this.header.getElementsByTagName('STYLE');
	},
	
	listenToMessage: function(message, data) {
		switch (message) { 
			case 'updateCSS'		:	this.updateCSS(data.filename, data.content); break;
			case 'contentLoad'		:	this.queueLoad(data.detail); break;
			case 'setLoadIDs'		:	this.setLoadIDs(data.ids); break;
			case 'contentUpdate'	:	this.updateItem(data.holder, data.content); break;
			case 'contentUnload'	:	this.unloadItem(data.contentid); break;
			case 'holderUnload'		:	this.unloadHolder(data.holderid); break;
			case 'unloadAll'		:	this.unloadAll(); break;
			case 'currentLocation'	:	
			case 'setLocation'		:	this.setCurrentLocation(data.location); break;
			case 'dialogMessage'	:	break;
			case 'clientParams'		:	this.setClientParams(data.clientparams); break;
			case 'loadFloat'		:	this.loadFloat(data.location, data.params); break;
			case 'consoleLog'		:	this.consoleLog(data.params); break;
			case 'serveComplete'	:	this.serveComplete(); break;
			case 'gotoURL'			:	this.gotoURL(data.url); break;
		}
	},
	
	gotoURL: function(url) { document.location.href=url; },
	
	jsInit: function() {
		var script;
		while (script = this.scriptLoadQueue[0]) {
			if (!script.isLoaded) break;
			this.scriptLoadQueue.splice(0, 1);

			if (!script.scriptObject) continue;
			if (!script.scriptObject.initSelf) continue;
			//try {
				script.scriptObject.initSelf();
			//} catch(e) { ERROR.handle(e); }
		}
		
		this.scriptCount = 0;
	},
	
	registerScript: function(fileName) {
		fileName = fileName.toLowerCase();
		for (var script,i=0;(script=this.scriptLoadQueue[i]);i++) {
			if (script.src.indexOf('/'+fileName+'.js') == -1) continue;
			script.isLoaded = true;
			script.scriptObject = window[fileName.toUpperCase()];
			this.setTimeout('jsInit', 10, this.jsInit );
			this.scripts[script.itemId] = this.scripts[script.itemId] || [];
			this.scripts[script.itemId].push(fileName.toUpperCase());

			this.loadIdList[script.itemId] = this.currentLoadIds;
			
			return script.itemId;
		} 
		alert('Invalid Script: '+fileName);
		
		return -1;
	},
	
	setClientParams: function(clientParams) {
		var key;
		this.clientParams = this.clientParams || { };
		for (key in clientParams) {
			this.clientParams[key] = clientParams[key];
		}
	},
	
	getClientParams: function(type) {
		if (!this.clientParams) return null;
		return this.clientParams[type.toLowerCase()];
	},
	
	registerObject: function(scriptRef, o) {
		 this.objects[scriptRef].push(o); 
	},
	
	consoleLog: function(params) { console.log.apply(console, params); },
	
	disposeSelf: function() {
		this.unloadAll();
	}
}

CONTENT.documentWrite = function(content) { if (CONTENT.currentScriptH) CONTENT.currentScriptH.innerHTML+=content; }
CONTENT.windowUnloadFN = function() { CC.content.unloadAll(); }
	
