sheetEngine = {

	///
	/// PRIVATE PROPERTIES
	///
	iconArray		: [],
	iconTray		: null,
	actualSheet		: null,
	hoverTitle		: null,
	zIndex			: 2,
	modalOpen		: false,
	numSheetOpen	: 0,

	///
	/// PUBLIC METHODS
	///

	// Initializes class properties
	init : function()
	{
		// Set values on class properties
		this.iconTray = document.getElementById("IconTray");
		this.hoverTitle =  window.parent.document.getElementById("processHoverTitle");

		this.iconArray["customer"] = 'icons/customer.gif';
		this.iconArray["notice"] = 'icons/notice.gif';
		this.iconArray["confirm"] = 'icons/confirm.gif';
		this.iconArray["phone"] = 'icons/phone.gif';
		this.iconArray["cellphone"] = 'icons/cellphone.gif';
		this.iconArray["letter"] = 'icons/letter.gif';
		this.iconArray["email"] = 'icons/email.gif';
		this.iconArray["fax"] = 'icons/fax.gif';
		this.iconArray["print"] = 'icons/print.gif';
		this.iconArray["employee"] = 'icons/employee.gif';
		this.iconArray["car"] = 'icons/cars.gif';
		this.iconArray["trashcan"] = 'icons/trashcan.gif';
		this.iconArray["slaugtherhouse"] = 'icons/slaugtherhouse.gif';
		this.iconArray["agreements"] = 'icons/agreements.gif';
		this.iconArray["truck"] = 'icons/truck.gif';
		this.iconArray["businessman"] = 'icons/businessman.gif';
		this.iconArray["book"] = 'icons/book.gif';
		this.iconArray["source"] = 'icons/source.gif';
		this.iconArray["jobs"] = 'icons/jobs.gif';
		this.iconArray["inspection"] = 'icons/star.gif';
		this.iconArray["log"] = 'icons/log.gif';
		this.iconArray["hotline"] = 'icons/hotline.gif';
		this.iconArray["weight"] = 'icons/weight.gif';
		this.iconArray["search"] = 'icons/search.gif';
		this.iconArray["convert"] = 'icons/convert.gif';
		this.iconArray["print"] = 'icons/print.gif';
		this.iconArray["copy"] = 'system/copy2.gif';
		this.iconArray["payments"] = 'icons/file.gif';
		this.iconArray["remarks"] = 'icons/book.gif';
		this.iconArray["customerRelations"] = 'icons/customer_relations.gif';
		this.iconArray["sell"] = 'sell.gif';
		this.iconArray["buy"] = 'buy.gif';
		this.iconArray["cartageReport"] = 'cartage_report.gif';

		return;
	},
	//
	// Creates a sheet from the given properties set in obj argument.
	//
	create : function( obj )
	{
		if( ! this.modalOpen )
		{
			if( (this.numSheetOpen < 24) || (obj.sheetType == "confirm" || obj.sheetType == "notice") )
			{
				// First create the generic sheet.
				oGenericSheet = this.createGenericSheet( obj );
				oGenericSheet.sheetEngine = this;

				oGenericSheet.sheetType = obj.sheetType;
				oGenericSheet.sheetOpener = obj.sheetOpener;
				oGenericSheet.events = obj.events;

				sheetEngine.actualSheet = oGenericSheet;
				// Then take action, depending on the sheet type
				switch( obj.sheetType )
				{
					case "external" :

						this.numSheetOpen++;

						// Create iframe
						var oIframe = document.createElement("iframe");
						oIframe.src = obj.href;
						oIframe.id = "iframe_" + sheetEngine.actualSheet.id;
						oIframe.height = obj.height;
						oIframe.width = obj.width;
						oIframe.frameborder = 0;
						oIframe.scrolling = "auto";
						oIframe.marginwidth = 0;
						oIframe.marginheight = 0;

						// Append it to the generic sheet
						oGenericSheet.appendChild( oIframe );

						// Make the z-index handling
						oGenericSheet.onmousedown = function()
						{
							// Make sure that the window aint opening if a modal window is opened
							if( ! this.sheetEngine.modalOpen )
							{
								var zIndex = (this.sheetEngine.zIndex++);
								this.style.zIndex = zIndex;
							}

							// Set the actual sheet property
							sheetEngine.actualSheet = this;

							return;
						}

					break;
					case "internal" :
						this.numSheetOpen++;

						// Create container
						var oContainer = document.createElement("div");
						oContainer.className = "internalSheet";

						oContent = document.createElement("div");
						oContent.className = "opaqueFocus";
						oContent.style.backgroundColor = "#FFFFFF";
						oContent.style.width = "100%";
						oContent.style.height = "100%";
						oContent.style.padding = "10px";
						oContent.innerHTML = obj.text;
						oContainer.appendChild( oContent );

						oGenericSheet.appendChild( oContainer );

						// Make the z-index handling
						oGenericSheet.onmousedown = function()
						{
							// Make sure that the window aint opening if a modal window is opened
							if( ! this.sheetEngine.modalOpen )
							{
								var zIndex = (this.sheetEngine.zIndex++);
								this.style.zIndex = zIndex;
							}

							// Set the actual sheet property
							sheetEngine.actualSheet = this;

							return;
						}
					break;
					case "confirm" : case "notice" :

						// Remember that there is a modal window open now
						this.modalOpen = true;

						// Set the event object as a property on the sheetEngine
						this.events = obj.events;

						// Set special modal style
						oGenericSheet.style.backgroundColor = "#CCCCCC";

						// Create the text container
						oText = document.createElement("div");
						oText.innerHTML = obj.text;
						oText.style.paddingTop = "15px";
						oText.style.height = "65px";
						oGenericSheet.appendChild( oText );

						if( obj.sheetType == "confirm" )
						{ 
							obj.iconType = "confirm";

							// Create btn container
							oBtnContainer = document.createElement("div");
							oBtnContainer.style.textAlign = "right";
							oBtnContainer.style.marginRight = "8px";

							// Create yes and no buttons
							for( var x = 0; x <= 1; x++ )
							{
								oBtn = document.createElement("input");
								oBtn.type = "button";
								oBtn.className = "btnMedium";
								oBtn.value = ( x == 0 ) ? "Ja" : "Nej";

								// Set click event
								oBtn.onclick = function()
								{
									sheetEngine.modalOpen = false;
									document.body.removeChild( this.parentElement.parentElement );
									if( this.value == "Ja" )
									{
										if( sheetEngine.events != null )
										{
											sheetEngine.events.yes();
										}
									}
									else
									{
										if( sheetEngine.events != null )
										{
											sheetEngine.events.no();
										}
									}
									//sheetEngine.events = null;

									return;
								}

								oBtnContainer.appendChild( oBtn );
							}

							oGenericSheet.appendChild( oBtnContainer );
						}
						else if( obj.sheetType == "notice" )
						{ 
							obj.iconType = "notice";

							// Create notice btn event
							oBtn = document.createElement("input");
							oBtn.type = "button";
							oBtn.className = "btnMedium";
							oBtn.value = "Ok";

							// Set click event
							oBtn.onclick = function()
							{
								sheetEngine.modalOpen = false;
								document.body.removeChild( this.parentElement );

								// Fire events attached to the notice sheet
								if( obj.events != null)
								{
									if( obj.events.onOk != null )
									{
										obj.events.onOk();
									}
								}

								return;
							}

							oGenericSheet.appendChild( oBtn );
						}

					break;
				}

				// Append the sheet to the document.
				document.body.appendChild( oGenericSheet );

				// Create an trayicon, matching the created sheet.
				this.setIcon( obj.iconType, obj.sheetName, oGenericContainer.id );

				// Apply events to sheet buttons (only applies if sheet is inline).
				appendButtonClickEvent();
			}
			else
			{ 
				// Create notice sheet.
				var obj = new Object();

				// Set default properties
				obj.sheetType = "notice";
				obj.sheetName = "Tester";
				obj.height = 100;
				obj.width = 300;
				obj.text = "Systemet tillader ikke flere åbne vinduer";

				this.create( obj );
			}
		}

		return;
	},

	///
	/// PRIVATE METHODS
	///

	// Creates a generic sheet for use in several containers
	createGenericSheet : function( obj )
	{
		// Create generic container
		oGenericContainer = document.createElement("div");
		oGenericContainer.className = "genericSheet";
		oGenericContainer.style.width = obj.width + 4 + "px";
		oGenericContainer.style.height = obj.height + 20 + "px";
		oGenericContainer.style.zIndex = this.zIndex++;
		oGenericContainer.style.left = ( (1275 - obj.width) / 2 ) + "px";
		oGenericContainer.style.top = ( (800 - obj.height) / 2 ) + "px";
		oGenericContainer.id = this.createUniqueId();

		// Create header for the genric container
		oHeader = document.createElement("div");
		oHeader.className = "genericSheetHeader";
		oHeader.innerHTML = obj.sheetName;

		// Set header move event
		oHeader.onmousedown = function()
		{
			var sheetType = this.parentElement.sheetType;
			if( ( ! sheetEngine.modalOpen ) || ( sheetType == "confirm" || sheetType == "notice" ) )
			{
				document.moveElement = this.parentElement;
				document.doMove = true;
				document.movingBorderFrame = document.getElementById("sheetBorder_" + this.parentElement.id );

				document.movingBorderFrame.style.display = "block";
				document.movingBorderFrame.style.top = this.parentElement.style.top;
				document.movingBorderFrame.style.left = this.parentElement.style.left;
				document.movingBorderFrame.style.zIndex = this.parentElement.style.zIndex + 100;

				// Create a layer, that stretches across the entire app.
				var oFiller = document.createElement("div");
				oFiller.className = "opaqueTransperant moveHelpFiller";
				oFiller.style.zIndex = this.parentElement.style.zIndex + 200;
				oFiller.id = "moveHelpFiller";
				document.body.appendChild( oFiller );
			}

			document.onmouseup = function()
			{
				if( document.moveElement != null )
				{
					var sheetType = document.moveElement.sheetType;
					if( ( ! sheetEngine.modalOpen ) || ( sheetType == "confirm" || sheetType == "notice" ) )
					{
						document.doMove = false;

						var iNewTop = document.movingBorderFrame.style.top;
						var iNewLeft = document.movingBorderFrame.style.left;

						document.moveElement.style.top = iNewTop;
						document.moveElement.style.left = iNewLeft;

						document.movingBorderFrame.style.zIndex = 0;
						document.movingBorderFrame.style.display = "none";

						// Remove filler
						var oMoveHelpFiller = document.getElementById("moveHelpFiller");
						if( oMoveHelpFiller != null )
						{
							document.body.removeChild( oMoveHelpFiller );
						}
					}
				}

				return;
			}
			document.onmousemove = function()
			{
				if( this.doMove )
				{
					var oMousePos = getEventPosition( event );
					var iMiddleX = (this.moveElement.style.pixelWidth / 2);
					var iMiddleY = (this.moveElement.style.pixelHeight / 2);

					var oContainerPos = new Object();
					oContainerPos.x = oMousePos.x;
					oContainerPos.y = oMousePos.y;

					// Redefine x pos
					if( ( oMousePos.x - iMiddleX ) < 0  )
					{
						oContainerPos.x = iMiddleX;
					}
					if( ( oMousePos.x + iMiddleX ) > 1271 )
					{
						oContainerPos.x = 1271 - iMiddleX;
					}

					// Redefine y pos
					if( ( oMousePos.y ) < 14 )
					{
						oContainerPos.y = 14;
					}
					if( ( oMousePos.y + 13 + this.moveElement.style.pixelHeight ) > 873 )
					{
						oContainerPos.y = 873 - this.moveElement.style.pixelHeight - 13;
					}

					this.movingBorderFrame.style.top = ( oContainerPos.y - 13 ) + "px";
					this.movingBorderFrame.style.left = ( oContainerPos.x - iMiddleX ) + "px";
				}

				return;
			}

			return;
		}

		// This is the only place, where a modal check is not made with the property of this class. The property is simply not set yet.
		if( obj.sheetType != "confirm" && obj.sheetType != "notice" )
		{
			// Create close button
			oCloseBtn = document.createElement("img");
			oCloseBtn.src = "static/images/system/x.gif";
			oCloseBtn.style.position = "absolute";
			oCloseBtn.style.top = "3px";
			oCloseBtn.style.left = (obj.width - 20) + "px";
			oCloseBtn.onmousedown = function()
			{
				this.parentNode.parentNode.style.display='none';
				
				var self = this;
				setTimeout(function(){
					sheetEngine.closeSheet(self);
				}, 10); 
				return;
			}

			// Create minimize button
			oMinimizeBtn = document.createElement("img");
			oMinimizeBtn.src = "static/images/system/_.gif";
			oMinimizeBtn.style.position = "absolute";
			oMinimizeBtn.style.left = (obj.width - 37) + "px";
			oMinimizeBtn.style.top = "3px";
			oMinimizeBtn.sheetEngine = this;

			oMinimizeBtn.onmousedown = function()
			{
				if( ! sheetEngine.modalOpen )
				{
					oSheetBorder = document.getElementById("sheetBorder_" + this.parentElement.parentElement.id );
					oSheetBorder.style.display = "none";

					this.parentElement.parentElement.style.display = "none";
				}
				return;
			}

			// Append the buttons
			oHeader.appendChild( oMinimizeBtn );
			oHeader.appendChild( oCloseBtn );
		}

		// Append the header
		oGenericContainer.appendChild( oHeader );

		// Create the MovingBorderFrame
		document.body.appendChild( this.createMovingBorderFrame( oGenericContainer ) );

		return oGenericContainer;
	},
	//
	// Sets the icon on the container and in the tray
	//
	setIcon : function( iconType, iconName, iconId )
	{
		// Create the icon
		var oIcon = document.createElement("img");
		oIcon.src = "static/images/" + this.iconArray[iconType];
		oIcon.width = 16;
		oIcon.height = 16;
		oIcon.style.marginLeft = "2px";
		oIcon.style.marginRight = "2px";
		oIcon.name = iconName;
		oIcon.id = "icon_" + iconId;
		oIcon.type = "user.sheet";

		// Set the hover methods
		if( ! this.modalOpen )
		{
			oIcon.onmousemove = function()
			{
				sheetEngine.iconMouseMove( this );
			}
			oIcon.onmouseover = function()
			{
				sheetEngine.iconMouseOver( this );
			}
			oIcon.onmouseout = function()
			{
				sheetEngine.iconMouseOut();
			}
			oIcon.onclick = function()
			{
				sheetEngine.iconClick( this );
			}

			// Prepend to the tray
			this.iconTray.insertAdjacentElement("afterBegin", oIcon );
		}

		// Finally, prepend the icon to the container
		var oConIcon = document.createElement("img");
		oConIcon.src = "static/images/" + this.iconArray[iconType];
		oConIcon.width = 16;
		oConIcon.height = 16;
		oConIcon.style.position = "absolute";
		oConIcon.style.left = "1px";
		oConIcon.style.top = "2px";
		oConIcon.ondblclick = function()
		{
			sheetEngine.closeSheet( this );
			return;
		}

		oSheetContainer = document.getElementById( iconId.replace( "icon_", "" ) );
		oSheetHeader = oSheetContainer.getElementsByTagName("div")[0];
		oSheetHeader.appendChild( oConIcon );

		return;
	},
	//
	// Icon events (used also by the system icons)
	//
	iconMouseOver : function( oIcon )
	{
		this.hoverTitle.style.display = "block";
		this.hoverTitle.style.zIndex = this.zIndex + 2;
		this.hoverTitle.innerHTML = oIcon.name;

		return;
	},
	iconMouseMove : function( oIcon )
	{
		var oMousePos = getEventPosition( event );
		this.hoverTitle.style.left = (oMousePos.x - 25) + "px";

		return;
	},
	iconMouseOut : function()
	{
		this.hoverTitle.style.display = "none";

		return;
	},
	iconClick : function( oIcon )
	{
		if( ! this.modalOpen )
		{
			switch( oIcon.type )
			{
				case "user.sheet" :

					iContainerId = oIcon.id.replace( "icon_", "" );
					document.getElementById( iContainerId ).style.display = "block";
					document.getElementById( iContainerId ).style.zIndex = (this.zIndex++);

					break;
				case "system.trashcan" :

					oIcon.style.display = "none";

					// Create events for the trashcan
					trashcanEvt = new Object();
					trashcanEvt.onclose = function()
					{
						document.getElementById("trayTrashcan").style.display = "block";
					}

					var obj = new Object();
					obj.width = 800;
					obj.height = 480;
					obj.sheetType = "external";
					obj.sheetName = "Papirkurv";
					obj.iconType = "trashcan";
					obj.href = "trashcan.php";
					obj.events = trashcanEvt;
					this.create( obj );

					break;
				case "system.history" :

					var obj = new Object();
					obj.width = 800;
					obj.height = 480;
					obj.sheetType = "external";
					obj.sheetName = "Handlings log";
					obj.iconType = "log";
					obj.href = "actionlog.php";
					this.create( obj );

					break;
			}
		}

		return;
	},
	//
	// Create's and return the box, which can be seen when a container is moved or minimized
	//
	createMovingBorderFrame : function( oInfoObj )
	{
		oBorderFrame = document.createElement("div");
		oBorderFrame.className = "genericMoveBorder";
		oBorderFrame.style.width = oInfoObj.style.width;
		oBorderFrame.style.height = oInfoObj.style.height;
		oBorderFrame.style.top = oInfoObj.style.top;
		oBorderFrame.style.left = oInfoObj.style.left;
		oBorderFrame.id = "sheetBorder_" + oInfoObj.id;

		return oBorderFrame;
	},
	//
	// Closes a sheet
	//
	closeSheet : function( oCloser, forceClose )
	{
		var validClose = false;

		if( ( ! sheetEngine.modalOpen ) || forceClose )
		{
			sheetEngine.numSheetOpen--;

			if( oCloser == null )
			{
				// The container is being closed by a user control
				oCloser = sheetEngine.actualSheet;

				// Prepare variables for use
				var iId = oCloser.getAttribute("id");
			}
			else
			{
				// Check if the sheet is being closed by the close button or manual (with the complete sheet object)
				if(oCloser.getAttribute("sheetType") == null )
				{
					// Prepare variables for use
					var iId = oCloser.parentElement.parentElement.getAttribute("id");
					oCloser = oCloser.parentElement.parentElement;
				}
				else
				{
					var iId = oCloser.id;
				}
			}
			validClose = true;
		}

		// Fire sheet close event
		if( oCloser.events != null )
		{
			if( oCloser.events.onclose != null )
			{
				//
				// The event is evaled. This is duo to the issue with running releashed code (e.g. when trying to run code, parsed from a page that is no longer avaliable).
				//
				try
				{
					eval( oCloser.events.onclose.toString().split("{")[1].split("}")[0] );
				}
				catch( e )
				{
					// Create notice sheet.
					var obj = new Object();

					// Set default properties
					obj.sheetType = "notice";
					obj.sheetName = "Warning";
					obj.height = 100;
					obj.width = 300;
					obj.text = "FEJL. Frikørt kode kunne ikke eval'es. Exception smidt i sheetEngine.js\n\nDebug output: " + e.description;

					this.create( obj );
				}
			}
			validClose = true;
		}

		if( validClose )
		{
			// Clear the container and all childNodes
			document.body.removeChild( oCloser );
			document.body.removeChild( document.getElementById("sheetBorder_" + iId ) );

			// Remove the icon attached to the container
			document.getElementById("icon_" + iId ).removeNode(true);
		}
		return;
	},
	//
	// Returns a random number
	//
	createUniqueId : function()
	{
	    // Generate random number [temporary id generation, TODO: Fix this]
	    var rndNum = parseInt( Math.random( 0, 100 ) * 1000000, 10 );

	    return rndNum;
	}
}
