/**
 *
 * This script implements the main-class 
 * of the Widget Application.
 *
 * @author 	Alex Buchgeher <alexander.buchgeher(at)gmail(dot)com>
 * @created september 2006
 *
 */

var MSIE = (navigator.appName == "Microsoft Internet Explorer");
var DEBUG = false;

function a(mixed) {
	if((location.search).search(/debug=1/) != -1 && DEBUG) {
		alert(mixed);
	}
}
function debug(mixed) {
	if((location.search).search(/debug=1/) == -1 || !DEBUG) { return; }
	var debugWrapper = $("debug");
	if(debugWrapper == undefined) {
		debugWrapper = document.createElement("div");
		debugWrapper.id = "debug";
		debugWrapper.onclick = function() {
			debugWrapper.innerHTML = "";
		}
		var p = document.getElementsByTagName("body")[0];
		p.appendChild(debugWrapper);
	}
	var debug = document.createElement("div");
	debug.className = "debug";
	debug.innerHTML = mixed;
	debugWrapper.appendChild(debug);
}
function rand() {
	return Math.random() * 999999;
}

var wdgt = new Object();
wdgt.IMAGEPATH = "typo3conf/ext/liferadiowidgets/res/images/";
wdgt.SCRIPTPATH = "typo3conf/ext/liferadiowidgets/res/widgets/";
wdgt.POPUP_CSSPATH = "typo3conf/ext/liferadiowidgets/res/widgets-popup.css";
wdgt.AJAX = "index.php?eID=tx_liferadiowidgets_pi1";
wdgt.TRIGGERTIME = 1000 * 20;

Livestream = Class.create();
Livestream.prototype = {
	initialize: function() {
		this.win = null;
		this.width = 512;
		this.height = 670;
	},
	showimg: function() {
		var path = '/radio';
		window.open(path, "liferadiolivestream", "width="+this.width+",height="+this.height+",resizable=1");
	},  
	show: function() {
		var path = '/radio';
		window.open(path, "liferadiolivestream", "width="+this.width+",height="+this.height+",resizable=1");
	},
	showwebcam: function() {
		var path = '/typo3conf/ext/liferadiowidgets/res/livestream.html';
		window.open(path, "liferadiolivestream", "width=334,height=320,resizable=1");
	}
}
wdgt.LIVESTREAM = null;

var Widgets = new Object();
Widgets.Setup = new Object();
Widgets.Setup.OnAir = {
	id: "OnAir",
	title: "Jetzt auf Sendung",
	icon: "onair_icon.jpg",
	iconinuse: "onair_icon_inuse.jpg",
	headerimage: "onair_headerimage.jpg",
	descr: "Jetzt auf Sendung",
	multiple: false,
	fixed: false, 
	closeable: true,
	script: "class.onair.js?v=3",
	interval: (1000 * 60 * 15),
	dataObj: {}
};
Widgets.Setup.Songfinder = {
	id: "Songfinder",
	title: "Die beste Musik",
	icon: "songfinder_icon.jpg",
	iconinuse: "songfinder_icon_inuse.jpg",
	headerimage: "songfinder_headerimage.jpg",
	descr: "Die beste Musik",
	multiple: false,
	fixed: false, 
	closeable: true,
	script: "class.songfinder.js?v=5",
	interval: (1000 * 60 * 1), 
	dataObj: {}
};
Widgets.Setup.Weather = {
	id: "Weather",
	title: "Wetter",
	icon: "weather_icon.jpg",
	iconinuse: "weather_icon_inuse.jpg",
	headerimage: "weather_headerimage.jpg",
	descr: "Wetter description",
	multiple: false,
	fixed: false, 
	closeable: true,
	cities: [
		"Braunau am Inn",
		"Eferding",
		"Freistadt",
		"Gmunden",
		"Grieskirchen",
		"Kirchdorf an der Krems",
		"Linz",
		"Perg",
		"Ried im Innkreis",
		"Rohrbach",
		"Schärding",
		"Steyr",
		"Urfahr",
		"Vöcklabruck",
		"Wels"
	],
	script: "class.weather.js?v=4",
	dataObj: {city: "Linz", forecast: 0}
};
Widgets.Setup.TrafficReport = {
	id: "TrafficReport",
	title: "Stauschau",
	icon: "traffic_icon.jpg",
	iconinuse: "traffic_icon_inuse.jpg",
	headerimage: "traffic_headerimage.jpg",
	descr: "Stauschau descr",
	multiple: false,
	fixed: false, 
	closeable: true,
	script: "class.trafficreport.js?v=2",
	interval: (1000 * 60 * 15), 
	dataObj: {}
};
Widgets.Setup.Webcam = {
	id: "Webcam",
	title: "Webcam",
	icon: "webcam_icon.jpg",
	iconinuse: "webcam_icon_inuse.jpg",
	headerimage: "webcam_headerimage.jpg",
	descr: "Webcam descr",
	multiple: false,
	fixed: false, 
	closeable: true,
	script: "class.webcam.js?v=5",
	interval: (1000 * 60 * 1), 
	dataObj: {}
};
Widgets.Setup.Soundsgood = {
	id: "Soundsgood",
	title: "Kling gelb. Kling gut.",
	icon: "soundsgood_icon.jpg",
	iconinuse: "soundsgood_icon_inuse.jpg",
	headerimage: "soundsgood_headerimage.jpg",
	descr: "Klingt gelb. Klingt gut. descr",
	multiple: false,
	fixed: false, 
	closeable: true,
	script: "class.soundsgood.js?v=2",
	dataObj: {}
};
wdgt.DEFAULT = new Array(
	{id: Math.floor(rand()), open: true, type: "OnAir", dataObj: {}},
	{id: Math.floor(rand()), open: true, type: "Songfinder", dataObj: {}},
	{id: Math.floor(rand()), open: true, type: "Weather", dataObj: {city: "Linz", forecast:0}}
);

Widget = Class.create();
Widget.prototype = {			
	initialize: function(widgetName, appObj) {
		this.type = widgetName;
		this.localData = new Object();
 		this.id = null;
		this.obj = null;
		this.body = null;
		this.cObj = null;
		this.applicationObj = appObj;
		this.initialized = false;
		this.title = Widgets.Setup[widgetName]["title"];
		this.headerimage = Widgets.Setup[widgetName]["headerimage"];
		this.closeable = Widgets.Setup[widgetName]["closeable"];
		this.icon = Widgets.Setup[widgetName]["icon"];
		this.iconinuse = Widgets.Setup[widgetName]["iconinuse"];
		this.descr = Widgets.Setup[widgetName]["descr"];
		this.multiple = Widgets.Setup[widgetName]["multiple"];
		this.fixed = Widgets.Setup[widgetName]["fixed"];
		this.script = Widgets.Setup[widgetName]["script"];
		this.interval = Widgets.Setup[widgetName]["interval"];
		this.dataObj = Widgets.Setup[widgetName]["dataObj"];
		this.loadingbarEnabled = false;
		this.open = true;
		this.hold = false;
		Event.observe(window, 'unload', this.unload.bind(this), false);
	},
	setId: function(id) {
		if(this.id == null) {
			if(id == null) {id = Math.floor(rand()); }
			this.id = id;
		}
		if(this.obj != null) { this.obj.id = "widget_" + this.id; }
	},
	getIcon: function() {	
		var widgetIcon = document.createElement("div");
		var span = document.createElement("span");
		var txt = document.createTextNode(this.title);
		widgetIcon.style.background = "url(" + wdgt.IMAGEPATH + this.icon + ") center no-repeat";
		widgetIcon.className = "widget";
		span.appendChild(txt);
		widgetIcon.appendChild(span);
		this.obj = widgetIcon;
		this.obj.onclick = this.insert.bindAsEventListener(this);
		this.obj.onmousedown = this.setTimer.bind(this);
		return widgetIcon;
	},
	insert: function(e) {
		var time = new Date().getTime();
		if((time - this.time) > 280) {return; }
		this.applicationObj.insert(this);
		this.removeEventListener();
		
	},
	removeEventListener: function() {
		this.obj.onclick = null;
	},
	getDataObj: function() {
		var obj = new Object();
		obj.id = this.id;
		obj.open = this.open;
		obj.type = this.type;
		obj.dataObj = this.dataObj;
		return obj;
	},
	getIconWrapper: function() {
		var iconWrapper = document.createElement("div");
		iconWrapper.className = "widgetwrapper";
		iconWrapper.id = this.title;
		var iconurl = wdgt.IMAGEPATH + this.iconinuse;
		this.preloadImage(iconurl);
		iconWrapper.background = "url(" + iconurl + ") center no-repeat";
		return iconWrapper();
	},
	preloadImage: function(url) {
		this.applicationObj.preloadImages(url);	
	},
	buildWidget: function() {
		this.applicationObj.embedScriptFile(this.script);
		if(this.obj == null) {
			this.obj = document.createElement("div");
			this.obj.className = "widget";
		}
		this.obj.removeAttribute("style");
		this.obj.innerHTML = "";
		var header = document.createElement("div");
		var span = document.createElement("span");
		var txt = document.createTextNode(this.title);
		var closeButton = document.createElement("div");
		var toggleButton = document.createElement("div");
		header.className = "widget-header";
		var headerimageUrl = wdgt.IMAGEPATH + this.headerimage;
		this.preloadImage(headerimageUrl);
		header.style.background = "#ffe200 url(" + headerimageUrl + ") no-repeat left center";
		closeButton.className = "widget-close";
		toggleButton.className = "widget-slideup";
		span.appendChild(txt);
		//header.appendChild(span);
		if(this.closeable || this.fixed) {
			header.appendChild(closeButton);
		}
		header.appendChild(toggleButton);
		Event.observe(closeButton, "click", this.close.bind(this)); 
		Event.observe(toggleButton, "click", this.toggleSmooth.bind(this));
		var body = document.createElement("div");
		body.className = "widget-body";
		var widget = this.obj;
		widget.appendChild(header);
		widget.appendChild(body);
		this.setId(null);
		this.body = body;
		this.body.innerHTML = "";
		this.toggleButton = toggleButton;
		if(DEBUG) { header.title = "WidgetID: " + this.id }
		this.loadingbar(false);
		this.waitForClass();
		this.removeEventListener();
		this.toggleWithoutSaving();
		this.applicationObj.blockChangeOrderSaving = false;
		return this.obj;
	},	
	waitForClass: function() {
		if(Widgets[this.type]) {
			this.cObj = new Widgets[this.type](this);
		} else {
			setTimeout(this.waitForClass.bind(this), 1);
		}
	},
	saveUserData: function() {
		if(this.applicationObj.t3SessMgmEnabled) {
			var postBody = "mode=saveuserdata&id=" + this.id;
			postBody+= "&data=" + JSON.stringify(this.dataObj);
			var options = {
				asynchronous: true,
				postBody: postBody,
				method: "post"
			};
			new Ajax.Request(wdgt.AJAX, options);
		} else {
			var settings = JSON.parse(this.applicationObj.sessMgm.getKey("usersettings"));
			for(var i in settings) {
				if(settings[i]["id"] == this.id) {
					settings[i]["dataObj"] = this.dataObj;
				}
			}			
			this.applicationObj.sessMgm.setKey("usersettings", JSON.stringify(settings));
		}
	},
	initDragAndDrop: function() {
		if(!this.initialized||true) {
			var options = {
				tag: "div",
				overlap: "vertical",
				dropOnEmpty: false,
				only: "widget",
				handle: "widget-header",
				//containment: [this.applicationObj.dropzoneID],
				constraint: false,
				revert: true,
				ghosting: false,
				onUpdate: this.build.bind(this),
				onChange: this.changeBeforeBuild.bind(this)
			};
			Sortable.create(this.type, options);
		}
	},
	changeBeforeBuild: function() {
		this.applicationObj.blockChangeOrderSaving = true;
		this.obj.firstChild.style.height = "17px";
		this.obj.firstChild.style.width = "1px";
		this.obj.firstChild.style.display = "block";
		this.obj.firstChild.innerHTML = "";
		var headerimageUrl = wdgt.IMAGEPATH + this.headerimage;
		this.preloadImage(headerimageUrl);
		this.obj.style.background = "#ffe200 url(" + headerimageUrl + ") left center no-repeat";
	},
	build: function() {
		this.buildWidget();
		this.applicationObj.saveInsert(this);	
	},
	sendRequest: function(url, parameters, func, noblock) {
		if(this.isBlocked() && noblock == undefined) { return; }
		if(url == "") { url = wdgt.AJAX; }
		if(parameters != "") {
			parameters += "&";
		}
		parameters += "cHash="+rand();
		var options = {
			asynchronous: true,
			method: "get",
			requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'must-revalidate'],
			parameters: parameters,
			onComplete: func,
			on404: this.error404.bind(this),
			on403: this.error403.bind(this),
			onFailure: this.errorDefault.bind(this)
		};
		new Ajax.Request(url, options);
	},
	errorDefault: function(e) {
		//this.error(e.responseText);
		this.error("Der Server antwortet nicht. Prüfen Sie gegebenenfalls Ihre Internetverbindung.");
	},
	error403: function(e) {
		this.error(e.responseText);
		//this.error("Sie haben nicht die benötigten Rechte um die Ressource zu laden.");
	},
	error404: function(e) {
		//this.error(e.responseText);
		this.error("Die Ressource ist momentan nicht verfügbar");
	},
	error: function(string) {
		this.loadingbar(false);
		this.body.innerHTML = string;
	},
	setTimer: function() {
		this.time = new Date().getTime();
	},
	isBlocked: function(index) {
		if(index == undefined) {
			index = 0;
		}
		var blocked = true;
		if(!this.open) { 
			this.loadingbar(false);
			blocked = true;
		} else {
			if(this.trigger == null) {	
				this.trigger = new Array();
				this.trigger[index] = new Date().getTime();
				blocked = false;
			} else {	
				var dt = new Date().getTime() - this.trigger[index];
				if(dt > wdgt.TRIGGERTIME) {
					this.trigger[index] = new Date().getTime();
					blocked = false;
				} else {
					blocked = true;
				}
			}
		}
		return blocked;
	},
	toggleSmooth: function() {
		this.toggle(wdgt.TOGGLESMOOTHTIME);
	},
	toggleWithoutSaving: function() {
		if(!this.open) {
			try {
				this.body.toggle();
			} catch(e) {
				this.open = true;
				this.toggle(0.1, false);
			}
			this.toggleButton.className = "widget-slidedown";
		}
	},
	toggle: function(time, save) {
		if(time <= 0) {
			try {
				this.body.toggle();
			} catch(e) {
				this.toggle(0.1);
				return;
			}
		} else {
			var options = { duration: time };
			if(this.open) {
				new Effect.BlindUp(this.body, options);
			} else {
				new Effect.BlindDown(this.body, options);
			}
		}
		this.open = !this.open;
		if(this.open) {
			this.toggleButton.className = "widget-slideup";	
			try {
				this.cObj.refresh();
			} catch(e) {}
		} else {
			this.toggleButton.className = "widget-slidedown";
		}
		if(save == false && save != undefined) { return; }
		var obj = {
			id: this.id,
			open: this.open
		};
		if(this.applicationObj.t3SessMgmEnabled) {
			var postBody = "mode=openclose";
			postBody+= "&data=" + JSON.stringify(obj);
			var options = {
				asynchronous: true,
				postBody: postBody,
				method: "post"
			};
			new Ajax.Request(wdgt.AJAX, options);
		} else {
			var settings = JSON.parse(this.applicationObj.sessMgm.getKey("usersettings"));
			for(var i in settings) {
				if(settings[i].id == obj.id) {
					settings[i].open = obj.open;
				}
			}
			this.applicationObj.sessMgm.setKey("usersettings", JSON.stringify(settings));
		}
	},
	slideUp: function(time) {
		if(this.open) { this.toggle(time); }
	},
	slideDown: function(time) {
		if(!this.open) { this.toggle(time); }
	},
	loadingbar: function(show) {
		if(show && !this.loadingbarEnabled) {
			var loadingbarNode = document.createElement("div");
			loadingbarNode.id = "widget-loadingbar" + this.id;
			loadingbarNode.appendChild(document.createTextNode("LOADING..."));
			this.body.appendChild(loadingbarNode);
			this.loadingbarEnabled = true;
		} else if(!show && this.loadingbarEnabled) {
			var loadingbarNode = $("widget-loadingbar"+this.id);
			loadingbarNode.style.display = "none";
			Element.remove(loadingbarNode);
			this.loadingbarEnabled = false;
		}
	},
	close: function() {
		var confirmation = true;
		if(wdgt.CONFIRMCLOSEEVENT) {
			confirmation = confirm("Sind Sie sicher dass sie das Widget schliessen möchten?");
		}
		if(confirmation) {
			try {
				var id = this.cObj.intervalID;
				if(id > 0) { clearInterval(id); }
			} catch(e) {
			} finally {
				if(!MSIE) {
					new Effect.Fade(this.obj, { afterFinish: this.remove.bind(this) });
				} else {
					this.remove();
					return;
				}
			}
		}
	},
	remove: function() {
		this.obj.style.display = "none";
		this.obj.onclick = null;
		this.cObj.pObj.dataObj = null;
		this.cObj.pObj = null;
		delete this.cObj;
		delete this.localData;
		Element.remove(this.obj);
		this.applicationObj.remove(this);
		this.applicationObj = null;
		this.cleanUp();
	},
	cleanUp: function() {
		delete this.localData;
		this.localData = null;
		this.applicationObj = null;
		this.body = null;
		if(this.cObj != null) {
			this.cObj.pObj = null;
			try {
				this.cObj.cleanUp();
			} catch(e) {
			} finally {
				delete this.cObj;
				this.cObj = null;
			}
		} 
		this.type = null;
		this.localData = null;
		this.id = null;
		this.obj = null;
		this.body = null;
		this.cObj = null;
		this.applicationObj = null;
		this.initialized = null;
		this.title = null;
		this.headerimage = null;
		this.closeable = null;
		this.icon = null;
		this.iconinuse = null;
		this.descr = null;
		this.multiple = null;
		this.fixed = null;
		this.script = null;
		this.interval = null;
		this.dataObj = null;
		this.loadingbarEnabled = null;
		this.open = null;
		this.hold = null;
		delete this.trigger;
		this.trigger = null;
	},
	unload: function() {
		try {
			this.obj.onclick = null;
			this.cleanUp();
		} catch(e) {a("Widget-Class Memory Management Problem: " + this.type); }
	}
};

SessionMgm = Class.create();
SessionMgm.prototype = {
	initialize: function() {
		var d = new Date();
		d.setYear(d.getFullYear()+1);
		this.expires = d.toGMTString()
		this.path = '/';
		this.domain = null;
		this.secure = null;
		delete d;
		d = null;
	},
	setKey: function(key, val) {
		var r;
		var dc = key + '=' + escape(val);
		dc+= (this.domain) ? '; domain=' + this.domain : '';
		dc+= (this.expires) ? '; expires=' + this.expires : '';
		dc+= (this.path)	? '; path=' + this.path : '';
		dc+= (this.secure) ? '; secure=' + this.secure : '';
		dc+= (this.domain) ? '; domain=' + this.domain : '';
		document.cookie = dc;
		return;		
	},
	getKey: function(key) {
		var dc = document.cookie;
		var prefix = key + "=";
		var begin = dc.indexOf("; " + prefix);
		if (begin == -1) {
			begin = dc.indexOf(prefix);
			if (begin != 0) { return null; }
		} 
		else begin += 2;
		var end = document.cookie.indexOf(";", begin);
		if (end == -1) { end = dc.length; }
		return unescape(dc.substring(begin + prefix.length, end));	
	},
	delKey: function(key) {
		if (this.getKey(key)) {
			document.cookie = this.key + "=" +
			((this.path) ? "; path=" + this.path : "") +
			((this.domain) ? "; domain=" + this.domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
		}
	}
}

WidgetApplication = Class.create();
WidgetApplication.prototype = {
	initialize: function(widgetbarID, dropzoneID, typo3SiteRelPath, t3SessMgmEnabled, widgetToggleSpeed, widgetConfirmCloseEvent) {
		wdgt.TYPO3_SITE_REL_PATH = typo3SiteRelPath == "" ? '/' : typo3SiteRelPath;
		wdgt.TOGGLESMOOTHTIME = widgetToggleSpeed == "" ? -1.0 : widgetToggleSpeed;
		wdgt.CONFIRMCLOSEEVENT = widgetConfirmCloseEvent == "" ? false : widgetConfirmCloseEvent;		
		this.widgetbarNode = $(widgetbarID);
		this.dropzoneNode = $(dropzoneID);
		this.dropzoneID = dropzoneID;
		this.t3SessMgmEnabled = t3SessMgmEnabled;
		if(!this.t3SessMgmEnabled) {
			this.sessMgm = new SessionMgm();
		}
		this.blockChangeOrderSaving = false;
		this.widgetbarAr = new Array();
		this.dropzoneAr = new Array();
		this.initIconSpaces();
		this.preloadImages(wdgt.IMAGEPATH + "widget_slidedown.gif");
		this.preloadImages(wdgt.IMAGEPATH + "widget_slideup.gif");
		this.preloadImages(wdgt.IMAGEPATH + "widget_close.gif");
		this.sendRequest();
		Event.observe(window, 'unload', this.unload.bind(this), false);
	},
	sendRequest: function() {
		var parameters = new String()
		if(this.t3SessMgmEnabled) {
			parameters = "mode=init&cHash=" + rand();
		} else {
			parameters = "mode=init2&cHash=" + rand();
		}
		var options = {
			asynchronous: true,
			method: "get",
			parameters: parameters,
			requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'must-revalidate'],
			onComplete: this.procReq.bind(this)
		};
		new Ajax.Request(wdgt.AJAX, options);
	},
	procReq: function(xhr) {
		var jsonObj = JSON.parse(xhr.responseText);
		if(!this.t3SessMgmEnabled) {
			var settings = JSON.parse(this.sessMgm.getKey("usersettings"));
			var timestamp = this.sessMgm.getKey("timestamp");
			if(!settings) {
				settings = wdgt.DEFAULT;
			}
			if(settings == null) { settings = new Array(); }
			if(jsonObj.tstamp > timestamp && jsonObj.widget != 0) { 
				var flag = false;
				for(var i in settings) {
					if(settings[i].type == jsonObj.widget) {
						flag = true;
					}
				}
				if(!flag) { 
					var newSettings = new Array();
					var type = jsonObj.widget;
					var ontopwidget = {
						id: parseInt(rand()),
						open: true,
						type: type,
						dataObj: Widgets.Setup[type]["dataObj"]
					};
					newSettings.push(ontopwidget);
					for(var i in settings) {
						newSettings.push(settings[i]);
					}
					settings = newSettings;
				}
			}
			jsonObj = settings;
			delete settings;
			settings = null;
			this.sessMgm.setKey("timestamp", new Date().getTime());
			this.sessMgm.setKey("usersettings", JSON.stringify(jsonObj));			
		}
		this.loadApp(jsonObj);
	},
	loadApp: function(jsonObj) {
		for(var wtype in Widgets.Setup) {
			if(typeof(wtype) == "function" || wtype == "extend") { continue; }
			if(!this.added2Dropzone(wtype, jsonObj)) {
				this.add2WidgetBar(wtype);
			}
		}
		for(var key in jsonObj) {
			var wdgt = jsonObj[key];
			if((typeof(wdgt) == "function") || (jsonObj[key] == null)) { continue; }
			try {
				var p = new Widget(wdgt.type, this);
				p.id = wdgt.id;
				p.setId(null);
				p.open = wdgt.open;
				p.dataObj = wdgt.dataObj;
				var wd = p.buildWidget();
				this.dropzoneNode.appendChild(wd);
				p.initDragAndDrop();
				this.dropzoneAr.push(p);
				delete p;
				p = null;
			}catch(e) { debug("error init widget: " + wdgt.type); }
		}
		this.initDropzone();
		this.widgetbarAr = null;
		this.dropzoneAr = null;
	},
	added2Dropzone: function(wtype, jsonObj) {
		for(var key in jsonObj) {
			var wdgt = jsonObj[key];
			if((typeof(wdgt) == "function") || (jsonObj[key] == null)) { continue; }
			if(jsonObj[key]["type"]==wtype) { return true; }
		}		
		return false;
	},
	add2WidgetBar: function(type) {
		var p = $(type);
		var w = new Widget(type, this);
		p.appendChild(w.getIcon());
		w.initDragAndDrop();
	},
	preloadImages: function(a) {
		if(document.images) {
			var dummy = new Image();
			dummy.src = a;
		}
	},
	getOrder: function() {
		var p = this.dropzoneNode;
		p = p.firstChild;
		var order = "";
		while(p!= null) {
			order+= p.id + ",";
			p = p.nextSibling;
		}
		return order;
	},
	insert: function(widgetObj) {
		var firstChild = this.dropzoneNode.childNodes[0];
		if(firstChild == null) {
			this.dropzoneNode.appendChild(widgetObj.buildWidget());			
		} else {
			this.dropzoneNode.insertBefore(widgetObj.buildWidget(), firstChild);
		}
		this.saveInsert(widgetObj, false);
	},
	remove: function(widgetObj) {
		widgetObj.cObj = null;
		widgetObj.applicationObj = null;
		Sortable.destroy(widgetObj.type);
		if(this.t3SessMgmEnabled) {
			var obj = {id: widgetObj.id };
			var postBody = "mode=close";
			postBody+= "&data=" + JSON.stringify(obj);
			var options = {
				asynchronous: true,
				postBody: postBody,
				method: "post"
			};
			new Ajax.Request(wdgt.AJAX, options);
		} else {
			var settings = JSON.parse(this.sessMgm.getKey("usersettings"));
			var newsettings = new Array();
			for(var i in settings) {
				if(settings[i]["id"] != widgetObj.id) {
					newsettings.push(settings[i]);
				}
			}
			this.sessMgm.setKey("usersettings", JSON.stringify(newsettings));
		}
		var type = widgetObj.type;
		widgetObj = null;
		this.add2WidgetBar(type);
	},
	initDropzone: function() {
		var cont = new Array();
		var cnt = 0;
		for(var key in Widgets.Setup) {
			if(typeof(Widgets.Setup[key]) == "function") continue;
			cont[cnt++] = (Widgets.Setup[key]["id"]);
		}
		var cont = new Array(this.dropzoneID).concat(cont);
		var options = {
			tag: "div",
			overlap: "vertical",
			dropOnEmpty: true,
			only: "widget",
			handle: "widget-header",
			containment: cont,
			constraint: false,
			revert: true,
			ghosting: false,
			onUpdate: this.saveOrder.bind(this)
		};
		Sortable.create(this.dropzoneID, options);
	},
	initIconSpaces: function() {
		var p = this.widgetbarNode;
		for(var widgetName in Widgets.Setup) {
			if(typeof(Widgets.Setup[widgetName]) == "function") { continue; };
			if(Widgets.Setup[widgetName]["closeable"] == false) { continue;	};
			var iconwrapper = document.createElement("div");
			iconwrapper.className = "widgetwrapper";
			iconwrapper.id = widgetName;
			var iconimageUrl = wdgt.IMAGEPATH + Widgets.Setup[widgetName]["iconinuse"];
			this.preloadImages(iconimageUrl);
			iconwrapper.style.background = "url(" + iconimageUrl + ") center no-repeat";
			p.appendChild(iconwrapper);
		}
	},
	embedScriptFiles: function() {
		for(var i in Widgets.Setup) {
			if(typeof(Widgets.Setup[i]) == "function") { continue; };
			this.embedScriptFile(Widgets.Setup[i]['script']);
		}
	},
	embedScriptFile: function(scriptfile) {
		if(this.embeddedScriptFiles == null) {
			this.embeddedScriptFiles = new Array();
		}
		if(this.embeddedScriptFiles.indexOf(scriptfile) != -1) { return; } 
		var script = document.createElement("script");
		script.src = wdgt.SCRIPTPATH + scriptfile;
		script.type = "text/javascript";
		script.charset = "utf-8";
		var head = document.getElementsByTagName("head")[0];
		head.appendChild(script);
		this.embeddedScriptFiles.push(scriptfile);
	},
	saveInsert: function(widgetObj) {
		if(this.t3SessMgmEnabled) {
			var postBody = "mode=insert";
			postBody+= "&data=" + JSON.stringify(widgetObj.getDataObj());
			postBody+= "&order=" + this.getOrder();
			var options = {
				asynchronous: true,
				postBody: postBody,
				method: "post"
			};
			new Ajax.Request(wdgt.AJAX, options);
		} else {
			var settings = JSON.parse(this.sessMgm.getKey("usersettings"));
			settings.push(widgetObj.getDataObj());
			settings = this.orderUserSettings(settings, this.getOrder());
			this.sessMgm.setKey("usersettings", JSON.stringify(settings));
		}
		this.initDropzone();
	},
	saveOrder: function() {
		if(this.blockChangeOrderSaving) { return; }
		if(this.t3SessMgmEnabled) {
			var postBody = "mode=changeorder";
			postBody+= "&order=" + this.getOrder();
			var options = {
				asynchronous: true,
				postBody: postBody,
				method: "post"
			};
			new Ajax.Request(wdgt.AJAX, options);
		} else {
			var settings = JSON.parse(this.sessMgm.getKey("usersettings"));
			settings = this.orderUserSettings(settings, this.getOrder());
			this.sessMgm.setKey("usersettings", JSON.stringify(settings));			
		}
	},
	orderUserSettings: function(settings, order) {
		var sorted = new Array();
		order = order.split(',');
		for(var i in order) {
			for(var k in settings) {
				if(typeof(settings[k]) == "function") { continue; }
				if( order[i] == "widget_" + settings[k]["id"]) {
					sorted.push(settings[k]);
				}
			}
		}
		return sorted;
	},
	unload: function() {
		try {
			delete this.widgetbarAr;
			delete this.dropzoneAr;
			delete this.widgetbarNode;
			delete this.dropzoneNode;
			delete this.dropzoneID;
			delete this.blockChangeOrderSaving;
			delete this.sessMgm;
			this.sessMgm = null;
		} catch(e) { a("WidgetApplication-Class Memory Management Problem"); }
	}
};