function geeXWebPlatform () {
	var self			= this;
	self.serial			= null;
	self.guest			= 0;
	self.object			= null;
	self.editorLink			= null;
	self.xmlHttp			= null;
	self.header			= null;
	self.headerTitle		= null;
	self.headerCornerLeft		= null;
	self.headerCornerRight		= null;
	self.mainMenu			= null;
	self.mainMenuEntries		= new Array();
	self.mainMenuEntryCount		= 0;
	self.borderLeft			= null;
	self.borderRight		= null;
	self.alertBox			= null;
	self.alertBoxShadow		= null;
	self.parent			= null;
	self.contextCanvas		= null;
	self.contextProtected		= 0;
	self.throbber			= null;
	self.hintBar			= null;
	self.hintTimer			= null;
	self.init = function (parent) {
		self.createEditor();
		self.buildMenu();
		try { parent.appendChild(self.object); } catch (err) { parent = null; }
		document.getElementById('htmlNavigation').style.display = 'none';
		self.parent		= parent;
	}
	self.initGuest = function (parent) {
		self.createEditor();
		self.buildGuestMenu();
		try { parent.appendChild(self.object); } catch (err) { parent = null; }
		document.getElementById('htmlNavigation').style.display = 'none';
		self.parent		= parent;
		self.guest		= 1;
	}
	self.createEditor = function () {

		self.object				= document.createElement('div');
		self.object.className			= 'geeXWebPlatformContainer';

		// Throbber
		self.throbber				= document.createElement('img');
		self.throbber.className			= 'throbber';
		self.throbber.src			= 'images/geeXwebplatform.throbber.gif';
		self.throbber.title			= 'Loading ...';
		self.object.appendChild(self.throbber);

		// Editor Header Components
		self.header				= document.createElement('div');
		self.header.className			= 'geeXWebPlatformHeader';
		self.headerTitle			= document.createElement('span');
		self.headerTitle.className		= 'headerTitle';
		self.headerCornerLeft			= document.createElement('img');
		self.headerCornerLeft.src		= 'images/geeXwebplatform.header.background.gradiant.corner.left.png';
		self.headerCornerLeft.className		= 'headerCornerLeft';
		self.headerCornerRight			= document.createElement('img');
		self.headerCornerRight.src		= 'images/geeXwebplatform.header.background.gradiant.corner.right.png';
		self.headerCornerRight.className	= 'headerCornerRight';
		self.headerLogo				= document.createElement('img');
		self.headerLogo.src			= 'images/ezbarcodez.logo.png';
		self.headerLogo.className		= 'headerLogo';
		self.header.onmousedown			= function (e) { self.disableSelect(e); }
		self.header.onmouseup			= function () { self.enableSelect(); }

		// Build Editor Header
		self.header.appendChild(self.headerCornerLeft);
		self.header.appendChild(self.headerCornerRight);
		self.header.appendChild(self.headerLogo);
		self.header.appendChild(self.headerTitle);
		self.object.appendChild(self.header);

		// Editor Main Menu Components
		self.mainMenu			= document.createElement('div');
		self.mainMenu.className		= 'mainMenu';
		self.mainMenu.onmousedown	= function (e) { self.disableSelect(e); }
		self.mainMenu.onmouseup		= function () { self.enableSelect(); }

		// Editor Main Menu Rounded Edges
		self.mainMenuLeft		= document.createElement('div');
		self.mainMenuLeft.className	= 'mainMenuCornerLeft';
		self.mainMenuRight		= document.createElement('div');
		self.mainMenuRight.className	= 'mainMenuCornerRight';

		// Context canvas
		self.contextCanvas		= document.createElement('div');
		self.contextCanvas.className	= 'contextCanvas';
		self.object.appendChild(self.contextCanvas);

		// Hint bar
		self.hintBar			= document.createElement('div');
		self.hintBar.className		= 'hintBar';
		document.body.appendChild(self.hintBar);

		// Editor borders
		self.borderLeft			= document.createElement('div');
		self.borderLeft.className	= 'geeXWebPlatformBorderLeft';
		self.object.appendChild(self.borderLeft);
		self.borderRight		= document.createElement('div');
		self.borderRight.className	= 'geeXWebPlatformBorderRight';
		self.object.appendChild(self.borderRight);

		// Alert Box
		self.alertBoxShadow		= document.createElement('div');
		self.alertBoxShadow.className	= 'alertBoxShadow';
		self.alertBox			= document.createElement('div');
		self.alertBox.className		= 'alertBox';
		self.alertBox.onmousedown	= function (e) { if (window.event) var e = window.event; self.disableSelect(e);
								try { self.alertBox.style.opacity = 0.2;			} catch (err) {}
								try { self.alertBox.style.filter = "alpha(opacity=20)";		} catch (err) {}
								try { self.alertBoxShadow.style.opacity = 0.10;			} catch (err) {}
							}
		self.alertBox.onmouseup		= function () {
								self.enableSelect();
								try { self.alertBox.style.opacity = 0.90;			} catch (err) {}
								try { self.alertBox.style.filter = "alpha(opacity=100)";	} catch (err) {}
								try { self.alertBoxShadow.style.opacity = 0.4;			} catch (err) {}
							}
		self.alertBox.onmouseout	= self.alertBox.onmouseup;
		self.object.appendChild(self.alertBoxShadow);
		self.object.appendChild(self.alertBox);

		// SubContext Box
		self.subContextBox			= document.createElement('div');
		self.subContextBox.className		= 'subContextBox';
		self.subContextBoxShadow		= document.createElement('div');
		self.subContextBoxShadow.className	= 'alertBoxShadow';
		self.object.appendChild(self.subContextBoxShadow);
		self.object.appendChild(self.subContextBox);
	}
	self.clearContextCanvas = function () {
		while (self.contextCanvas.childNodes[0]) {
			try { self.contextCanvas.removeChild(self.contextCanvas.childNodes[0]); }
			catch (err) { alert(err) }
		}
		self.contextProtected = 0;
	}
	self.buildContextCanvas = function (html) {
		self.contextCanvas.innerHTML = html;
	}
	self.buildMenu = function () {
		self.addMenuEntry ('New Label',			function () { self.fetch('newlabel');		} );
		self.addMenuEntry ('My Library',		function () { self.fetch('mylibrary');		} );
		self.addMenuEntry ('Catalog',			function () { self.fetch('catalog');		} );
		self.addMenuEntry ('Settings',			function () { self.fetch('settings','',1);	} );
		self.addMenuEntry ('Help',			function () { self.fetch('help','');		} );
		self.addMenuEntry ('Feedback',			function () { self.fetch('feedback','',1);	} );
		self.flushMenuEntries ();
		self.object.appendChild(self.mainMenu);
		self.object.appendChild(self.mainMenuLeft);
		self.object.appendChild(self.mainMenuRight);
	}
	self.buildGuestMenu = function () {
		self.addMenuEntry ('New Label',			function () { self.fetch('newlabel');		} );
		self.addMenuEntry ('Catalog',			function () { self.fetch('catalog');		} );
		self.addMenuEntry ('Privacy Policy',		function () { self.fetch('privacypolicy','',1);	} );
		self.addMenuEntry ('Help',			function () { self.fetch('help','');		} );
		self.addMenuEntry ('Feedback',			function () { self.fetch('feedback','',1);	} );
		self.addMenuEntry ('<img src="images/geexmedia.transparent.logo.png" style="width: 64px; height: 29px;"></img>',
								function () { self.fetch('about','',1);	} );
		self.flushMenuEntries ();
		self.object.appendChild(self.mainMenu);
		self.object.appendChild(self.mainMenuLeft);
		self.object.appendChild(self.mainMenuRight);
	}
	self.addMenuEntry = function (title,action,idx) {
		if (title != '' && title != null) {
			var t							= self.mainMenuEntryCount++;
			self.mainMenuEntries[t]					= document.createElement('div');
			self.mainMenuEntries[t].className			= 'mainMenuEntry';
			if (idx == null || idx >= t) {
				self.mainMenuEntries[t].innerHTML		= title;
				self.mainMenuEntries[t].onclick			= action;
			} else {
				for (var i=t;i>=idx && i > 0;i--) {
					self.mainMenuEntries[i].innerHTML	= self.mainMenuEntries[i-1].innerHTML;
					self.mainMenuEntries[i].onclick		= self.mainMenuEntries[i-1].onclick;
				}
				self.mainMenuEntries[idx].innerHTML		= title;
				self.mainMenuEntries[idx].onclick		= action;
			}
		}
	}
	self.flushMenuEntries = function () {
		while (self.mainMenu.childNodes[0]) {
			try { self.mainMenu.removeChild(self.mainMenu.childNodes[0]); }
			catch (err) {}
		}
		for (var i=0; i<self.mainMenuEntryCount; i++) {
			try { self.mainMenu.appendChild(self.mainMenuEntries[i]); }
			catch (err) {}
		}
	}
	self.clearAlertBox = function () {
		while (self.alertBox.childNodes[0]) {
			try { self.alertBox.removeChild(self.alertBox.childNodes[0]); }
			catch (err) { alert(err) }
		}
	}
	self.clearSubContextBox = function () {
		while (self.subContextBox.childNodes[0]) {
			try { self.subContextBox.removeChild(self.subContextBox.childNodes[0]); }
			catch (err) { alert(err) }
		}
	}
	self.disableSelect = function (e) {
		try { e.preventDefault(); }
		catch (err) {
			self.oldSelectStart	= document.onselectstart;
			self.oldDragStart	= document.ondragstart;
			document.onselectstart	= new Function ("return false");
			document.ondragstart	= new Function ("return false");
		}
	}
	self.enableSelect = function (e) {
		try {
			document.onselectstart	= new Function (self.oldSelectStart);
			document.ondragstart	= new Function (self.oldDragStart);
		} catch (err) {}
	}
	self.confirm = function (q,confirmed,unconfirmed) {
		self.clearAlertBox();
		var msg				= document.createElement('p');
		msg.innerHTML			= q;
		var buttonPar			= document.createElement('p');
		buttonPar.style.textAlign	= 'center';
		var buttonTrue			= document.createElement('input');
		buttonTrue.type			= 'submit';
		buttonTrue.value		= 'Yes';
		buttonTrue.onclick		= 
			function () {
				self.alertBoxShadow.style.display	= 'none';
				self.alertBox.style.display		= 'none';
				try { confirmed(); }
				catch (err) {
					try { eval(confirmed); }
					catch (err) { self.alert(err); }
				}
			}
		buttonTrue.style.marginRight	= '4px';
		var buttonFalse			= document.createElement('input');
		buttonFalse.type		= 'submit';
		buttonFalse.value		= 'No';
		buttonFalse.onclick		=
			function () {
				self.alertBoxShadow.style.display	= 'none';
				self.alertBox.style.display		= 'none';
				try { eval(unconfirmed); }
				catch (err) { self.alert(err) }
			}
		self.alertBox.appendChild(msg);
		buttonPar.appendChild(buttonTrue);
		buttonPar.appendChild(buttonFalse);
		self.alertBox.appendChild(buttonPar);
		self.alertBoxShadow.style.display = 'inline';
		self.alertBox.style.display = 'inline';
	}
	self.alert = function (html,andthen) {
		self.clearAlertBox();
		self.alertBox.innerHTML		= html;
		var buttonPar			= document.createElement('p');
		buttonPar.style.textAlign	= 'center';
		var button			= document.createElement('input');
		button.type			= 'submit';
		button.value			= 'OK';
		button.onclick			=
			function () {
				self.alertBoxShadow.style.display	= 'none';
				self.alertBox.style.display		= 'none';
				try { andthen(); }
				catch (err) {
					try { eval(andthen); }
					catch (err) { self.alert(err); }
				}
			}
		buttonPar.appendChild(button);
		self.alertBox.appendChild(buttonPar);
		self.alertBoxShadow.style.display	= 'inline';
		self.alertBox.style.display		= 'inline';
	}
	self.hideAlert = function () {
		self.alertBoxShadow.style.display	= 'none';
		self.alertBox.style.display		= 'none';
	}
	self.subContext = function (html) {
		self.clearSubContextBox();
		self.subContextBox.innerHTML		= html;
		self.subContextBoxShadow.style.display	= 'inline';
		self.subContextBox.style.display	= 'inline';
	}
	self.hideSubContext = function () {
		self.subContextBoxShadow.style.display	= 'none';
		self.subContextBox.style.display	= 'none';
	}
	self.getXmlHttp = function () {
		try { if (window.XMLHttpRequest)	return new XMLHttpRequest(); 			} catch (err) {}
		try { if (window.ActiveXObject)		return new ActiveXObject("Microsoft.XMLHttp");	} catch (err) {}
		try { if (window.ActiveXObject)		return new ActiveXObject("Msxml2.XMLHttp");	} catch (err) {}
		return null;
	}
	self.fetch = function (context,flags,noprompt) {
		var continueFetch = function () {
			var urlStr	= 'remote/';
			var params	= 'context='+context+'&'+flags;
			if (context != 'hintbar') {
				self.alertBoxShadow.style.display = 'none';
				self.alertBox.style.display = 'none';
				self.subContextBoxShadow.style.display = 'none';
				self.subContextBox.style.display = 'none';
			}
			self.throbber.style.display = 'inline';
			self.xmlHttp.open('POST',urlStr,true);
			self.xmlHttp.onreadystatechange =
				function () {
					if (self.xmlHttp.readyState == 4 && self.xmlHttp.status == 200) {
						self.throbber.style.display = 'none';
						self.hideAlert();
						eval(self.xmlHttp.responseText);
						try {
							self.xmlHttp.close();
						} catch (err) {
							self.xmlHttp = null;
						}
					}
				}
			self.xmlHttp.setRequestHeader("Content-type",	"application/x-www-form-urlencoded");
			// IE6 Hack:  Without this workaround, the AJAX is VERY slow in IE6
			var IE6 = false /*@cc_on || @_jscript_version < 5.7 @*/;
			if (IE6==false) {
				self.xmlHttp.setRequestHeader("Content-length",	params.length);
				self.xmlHttp.setRequestHeader("Connection",	"close");
			} else {
				self.alert('Page loading ...');
			}
			self.xmlHttp.send(params);
		}
		self.xmlHttp = self.getXmlHttp();
		if (self.xmlHttp) {
			if (	self.contextProtected == 1 && noprompt != 1 && self.guest == 0) {
				self.confirm (	"Are you sure you want to continue?"+
						"<br /><br />Any unsaved work will be lost.",
						continueFetch
					);
			} else continueFetch();
		} else self.alert('Your browser does not support AJAX');
	}
	self.checkSession = function () {
		document.location.reload();
	}
	self.getNextHint = function () {
		self.fetch('hintbar','',1);
	}
}

function helpWidget (editor) {
	var self		= this;
	self.editor		= editor;
	self.canvas		= editor.subContextBox;
	self.canvasShadow	= editor.subContextBoxShadow;
	self.clear = function () {
		self.editor.clearSubContextBox();
	}
	self.show = function () {
		self.canvas.style.display = 'inline';
		self.canvasShadow.style.display = 'inline';
	}
	self.hide = function () {
		self.canvas.style.display = 'none';
		self.canvasShadow.style.display = 'none';
	}
}

function redirectAfterLogin () {
	function doIt () { document.location.replace('./'); }
	setTimeout(doIt,100);
}
