Function.prototype.getObject = function () {
	var aArguments = [], oObject;
	for (var i = 0; i < arguments.length; i++) {
		aArguments[i] = 'arguments[' + i + ']';
	}
	eval('oObject = new this(' + aArguments.join(',') + ');');
	oObject.__construct.apply(oObject, arguments);
	return oObject;
}

function addEventHandler(oTarget, sEventType, fnHandler) {
	if (oTarget.addEventListener) {
		oTarget.addEventListener(sEventType, fnHandler, false);
	} else if (oTarget.attachEvent) {
		oTarget.attachEvent('on' + sEventType, fnHandler);
	} else {
		oTarget['on' + sEventType] = fnHandler;
	}
}

function getPosition(e) {
	e = e || window.event;
	var de = document.documentElement;
	var b = document.body;
	
	var cursor = {x:0, localX:0, y:0, localY:0};
	if (e.pageX || e.pageY) {
		cursor.x = e.pageX;
		cursor.y = e.pageY;
	} else {
		cursor.x = e.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
		cursor.y = e.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
	}
	
	cursor.localX = cursor.x - (de.scrollLeft || b.scrollLeft);
	cursor.localY = cursor.y - (de.scrollTop || b.scrollTop);
	
	return cursor;
}

function getBody() {
	var oBody = document.documentElement;
	if (oBody.tagName.toLowerCase() == 'html') {
		oBody = oBody.getElementsByTagName('body')[0];
	}
	return oBody;
}

function mergeObject() {
	var oMerged = new Object();
	for (var i = 0; i < arguments.length; i++) {
		for (var j in arguments[i]) {
			if (typeof oMerged[j] == 'object' && typeof arguments[i][j] == 'object') {
				oMerged[j] = mergeObject(oMerged[j], arguments[i][j]);
			} else {
				oMerged[j] = arguments[i][j];
			}
		}
	}
	return oMerged;
}

function Caller(fnFunction, oObject) {
	this.__fnFunction = fnFunction;
	this.__oObject = oObject;
	
	if (typeof Caller.__initialized == "undefined") {
		Caller.prototype.call = function () {
			return this.apply(arguments);
		}
		Caller.prototype.apply = function (aArguments) {
			if(typeof this.__oObject != "object") {
				return this.__fnFunction.apply(this.__fnFunction, aArguments);
			} else {
				return this.__fnFunction.apply(this.__oObject, aArguments);
			}
		}
		Caller.__initialized = true;
	}
}

function DocumentBuilder() {
	this.__oDocument = document.createDocumentFragment();
	
	if (typeof DocumentBuilder.__initialized == 'undefined') {
		DocumentBuilder.prototype.addElement = function (sElement, sContent, oAttributes) {
			var oElement = document.createElement(sElement);
			this.__setAttributes(oElement, oAttributes);
			sContent ? oElement.innerHTML = sContent : 0;
			this.__oDocument.appendChild(oElement);
			return oElement;
		}
		DocumentBuilder.prototype.getDocument = function () {
			return this.__oDocument;
		}
		DocumentBuilder.prototype.__setAttributes = function (oElement, oAttributes) {
			if (oAttributes instanceof Object) {
				for (var sAttrib in oAttributes) {
					oElement[sAttrib] = oAttributes[sAttrib];
				}
			}
		}
		DocumentBuilder.__initialized = true;
	}
}

function WindowAnimator(oWindowTitle, oWindowContent, bHideWindow) {
	this.__oWindow = new Object();
	this.__oButton = new Object();
	
	
	this.__oWindow.title = oWindowTitle;
	this.__oWindow.content = oWindowContent;
	this.__oWindow.isOpen = true;
	
	this.__oButton.open = null;
	this.__oButton.close = null;
	this.__oButton.isPrepared = false;
	
	if (typeof WindowAnimator.__initialized == 'undefined') {
		WindowAnimator.prototype.__construct = function (bHideWindow) {
			if (typeof bHideWindow == 'undefined' || bHideWindow == true) {
				this.__oWindow.content.style.display = 'none';
				this.__oWindow.isOpen = false;
			}
		}
		
		WindowAnimator.prototype.setButtons = function (oOpenButton, oCloseButton) {
			this.__prepare(oOpenButton, oCloseButton);
			this.__append();
		}
		
		WindowAnimator.prototype.open = function () {
			if (this.__oWindow.isOpen == false) {
				this.__oWindow.isOpen = true;
				this.__oWindow.content.style.display = 'block';
				this.__proceed();
			}
		}
		
		WindowAnimator.prototype.close = function () {
			if (this.__oWindow.isOpen == true) {
				this.__oWindow.isOpen = false;
				this.__oWindow.content.style.display = 'none';
				this.__proceed();
			}
		}
		
		WindowAnimator.prototype.__proceed = function () {
			if (this.__oButton.isPrepared == true) {
				this.__append();
			}
		}
		
		WindowAnimator.prototype.__append = function () {
			if (this.__oWindow.isOpen == true) {
				this.__replace('close', 'open');
			} else {
				this.__replace('open', 'close');
			}
		}
		
		WindowAnimator.prototype.__replace = function (sNewButton, sOldButton) {
			var oOldButton = this.__oButton[sOldButton];
			
			if (oOldButton.parentNode) {
				oOldButton.parentNode.removeChild(oOldButton);
			}
			
			this.__oWindow.title.appendChild(this.__oButton[sNewButton]);
		}
		
		WindowAnimator.prototype.__prepare = function (oOpenButton, oCloseButton) {
			this.__oButton.open = oOpenButton.cloneNode(true);
			this.__oButton.close = oCloseButton.cloneNode(true);
			addEventHandler(this.__oButton.open, 'click', this.__getEvent(this.open));
			addEventHandler(this.__oButton.close, 'click', this.__getEvent(this.close));
			this.__oButton.isPrepared = true;
		}
		
		WindowAnimator.prototype.__getEvent = function (fnMethod) {
			var oWindowAnimator = this;
			return function () {
				fnMethod.call(oWindowAnimator);
			}
		}
		
		WindowAnimator.__initialized = true;
	}
	
	this.__construct(bHideWindow);
}

function WindowCollection() {
	this.__aWindows = new Array();
	this.__oButton = new Object();
	this.__oGetter = null;
	this.__bUnhideByLink = true;
	
	this.__oButton.open = null;
	this.__oButton.close = null;
	
	if (typeof WindowCollection.__initialized == 'undefined') {
		WindowCollection.prototype.__construct = function () {
			
		}
		
		WindowCollection.prototype.allowUnhideByLink = function (bUnhideByLink) {
			this.__bUnhideByLink = bUnhideByLink;
		}
		
		WindowCollection.prototype.addWindow = function (sWindowId) {
			this.__aWindows.push(document.getElementById(sWindowId));
		}
		
		WindowCollection.prototype.setElementGetter = function (oCaller) {
			if (oCaller instanceof Caller) {
				this.__oGetter = oCaller;
			}
		}
		
		WindowCollection.prototype.setButtons = function (oOpenButton, oCloseButton) {
			this.__oButton.open = oOpenButton;
			this.__oButton.close = oCloseButton;
		}
		
		WindowCollection.prototype.apply = function () {
			var oWindow, aWindowElement, oWindowTitle, oWindowContent;
			var sWindowId = this.__getLocationId();
			
			for (var i = 0; i < this.__aWindows.length; i++) {
				aWindowElement = this.__oGetter.call(this.__aWindows[i]);
				oWindow = new WindowAnimator(aWindowElement[0], aWindowElement[1],
					(this.__aWindows[i].id != sWindowId || !this.__bUnhideByLink));
				oWindow.setButtons(this.__oButton.open, this.__oButton.close);
			}
		}
		
		WindowCollection.prototype.__scroll = function (sWindowId) {
			addEventHandler(window, 'load', function () {
				window.location.href = window.location.href;
			})
		}
		
		WindowCollection.prototype.__getLocationId = function () {
			var sLocation = window.location.href;
			var iIndex = sLocation.lastIndexOf('#') + 1;
			var sWindowId = '';
			
			if (iIndex > 0) {
				sWindowId = sLocation.substr(iIndex);
				this.__scroll(sWindowId);
			}
			return sWindowId;
		}
		
		WindowCollection.__initialized = true;
	}
	
	this.__construct();
}

function Window(sWindowId) {
	this.__oBody = new Object();
	this.__oSize = new Object();
	
	this.__sBackgroundClass = 'window_background';
	this.__oBackground = new Object();
	
	this.__sWindowId = sWindowId;
	this.__sWindowClass = 'window_content';
	this.__oWindow = new Object();
	this.__oCursor = new Object();
	
	this.__aObservers = new Array();
	this.__iBodyPadding = 20;
	this.__iSizeScroll = 20;
	
	if (typeof Window.__initialized == 'undefined') {
		Window.WINDOW_CLOSE = 1;
		Window.WINDOW_OPEN = 2;
		Window.WINDOW_RESIZE = 4;
		
		Window.prototype.__construct = function (sWindowId) {
			this.__sWindowId = sWindowId;
			this.__prepareClass();
			this.__prepareWindow();
			this.__prepareEvents();
		}
		Window.prototype.open = function () {
			this.__append();
			this.__positionWindow();
			this.notifyObservers(Window.WINDOW_OPEN);
		}
		Window.prototype.close = function () {
			this.notifyObservers(Window.WINDOW_CLOSE);
			this.__remove();
		}
		Window.prototype.getWindow = function () {
			return this.__oWindow;
		}
		Window.prototype.addObserver = function (oCaller) {
			if(oCaller instanceof Caller) {
				this.__aObservers.push(oCaller);
			}
		}
		Window.prototype.notifyObservers = function (iAction) {
			for(var i = 0, n = this.__aObservers.length; i < n; i++) {
				this.__aObservers[i].call(this, iAction);
			}
		}
		Window.prototype.__prepareClass = function (){
			this.__oBody = document.documentElement;
			if (document.documentElement.tagName.toLowerCase() == 'html') {
				this.__oBody = this.__oBody.getElementsByTagName('body')[0];
			}
		}
		Window.prototype.__append = function () {
			this.__oBody.appendChild(this.__oBackground);
			this.__oBody.appendChild(this.__oWindow);
		}
		Window.prototype.__remove = function () {
			this.__oBody.removeChild(this.__oBackground);
			this.__oBody.removeChild(this.__oWindow);
		}
		Window.prototype.__prepareWindow = function () {
			this.__createBackground();
			this.__createWindow();
		}
		Window.prototype.__prepareEvents = function () {
			var __oWindow = this;
			addEventHandler(window, 'resize', function () {
				__oWindow.__positionWindow();
				__oWindow.notifyObservers(Window.WINDOW_RESIZE);
			});
			addEventHandler(this.__oBody, 'mousemove', function (oEvent) {
				__oWindow.__oCursor = getPosition(oEvent);
				__oWindow.__positionWindow();
			});
		}
		Window.prototype.__positionWindow = function () {
			this.__prepareSizes();
			
			var iTop, iLeft;
			var iHeightOffset = this.__oSize.bodyHeight - this.__oSize.windowHeight - this.__iBodyPadding * 2;
			var iWidthOffset = this.__oSize.bodyWidth - this.__oSize.windowWidth - this.__iBodyPadding * 2;

			if (iHeightOffset < 0) {
				iTop = Math.round((this.__oCursor.localY * 100 / this.__oSize.bodyHeight) / 100 * iHeightOffset) + this.__iBodyPadding;
			} else {
				iTop = Math.round((iHeightOffset) / 2) + this.__iBodyPadding;
			}
			
			if (iWidthOffset < 0) {
				iLeft = Math.round(a = (this.__oCursor.localX * 100 / this.__oSize.bodyWidth) / 100 * iWidthOffset) + this.__iBodyPadding;
			} else {
				iLeft = Math.round(iWidthOffset / 2) + this.__iBodyPadding;
			}
			this.__oWindow.style.top = iTop + 'px';
			this.__oWindow.style.left = iLeft + 'px';
		}
		Window.prototype.__prepareSizes = function () {
			this.__oSize.bodyWidth = window.innerWidth || document.documentElement.offsetWidth;
			this.__oSize.bodyHeight = window.innerHeight || document.documentElement.offsetHeight;
			this.__oSize.windowWidth = this.__oWindow.offsetWidth;
			this.__oSize.windowHeight = this.__oWindow.offsetHeight;
		}
		Window.prototype.__createBackground = function () {
			this.__oBackground = document.createElement('div');
			this.__oBackground.className = this.__sBackgroundClass;
		}
		Window.prototype.__createWindow = function () {
			this.__oWindow = document.createElement('div');
			this.__oWindow.id = this.__sWindowId;
			this.__oWindow.className = this.__sWindowClass;
		}
		
		Window.__initialized = true;
	}
}

ContentWindow.prototype = new Window;
function ContentWindow(sWindowId, oDocument) {
	Window.call(this, sWindowId)
	this.__oDocument = oDocument;
	this.__oImage = new Object();
	this.__oTable = new Object();
	
	if (typeof ContentWindow.__initialized == 'undefined') {
		ContentWindow.prototype.__construct = function (sWindowId, oDocument) {
			this.__oDocument = oDocument;
			Window.prototype.__construct.call(this, sWindowId);
		}
		ContentWindow.prototype.open = function (sSrcImage, oTable) {
			this.__oImage.src = sSrcImage;
			Window.prototype.open.call(this);
			if (bIsIE == true) {
				this.__oTable.outerHTML = oTable.outerHTML;
				this.__prepareIE();
			} else {
				this.__oTable.parentNode.replaceChild(oTable, this.__oTable);
				this.__oTable = oTable;
			}
		}
		ContentWindow.prototype.close = function () {
			Window.prototype.close.call(this);
			this.__oImage.style.visibility = 'hidden';
		}
		ContentWindow.prototype.setReferences = function (oImage, oTable) {
			this.__oImage = oImage;
			this.__oTable = oTable;
			this.__prepareImage();
		}
		ContentWindow.prototype.__prepareIE = function () {
			if (bIsIE == true) {
				var aTable = this.__oWindow.getElementsByTagName('table');
				this.__oTable = aTable.item(0);
			}
		}
		ContentWindow.prototype.__prepareImage = function () {
			var oImage = this.__oImage;
			addEventHandler(this.__oImage, 'load', function () {
				oImage.style.visibility = 'visible';
			});
		}
		ContentWindow.prototype.__append = function () {
			Window.prototype.__append.call(this);
			this.__oWindow.appendChild(this.__oDocument);
		}
		ContentWindow.__initialized = true;
	}
}

ImageWindow.prototype = new Window;
function ImageWindow(sWindowId) {
	Window.call(this, sWindowId);
	this.__sWindowClass = 'window_image';
	this.__oImage = new Object();
	
	if (typeof ImageWindow.__initialized == 'undefined') {
		ImageWindow.IMAGE_LOADED = 8;
		ImageWindow.IMAGE_ERROR = 16;
		ImageWindow.IMAGE_ABORT = 32;
		
		ImageWindow.prototype.__construct = function (sWindowId) {
			Window.prototype.__construct.call(this, sWindowId);
		}
		ImageWindow.prototype.open = function (sSrcImage) {
			Window.prototype.open.call(this);
			this.__oImage.src = sSrcImage;
		}
		ImageWindow.prototype.close = function () {
			this.__oImage.style.visibility = 'hidden';
			Window.prototype.close.call(this);
		}
		ImageWindow.prototype.getImage = function () {
			return this.__oImage;
		}
		ImageWindow.prototype.__show = function () {
			this.__resizeWindow();
			this.notifyObservers(ImageWindow.IMAGE_LOADED);
			this.__oImage.style.visibility = 'visible';
		}
		ImageWindow.prototype.__append = function () {
			Window.prototype.__append.call(this);
			this.__oWindow.appendChild(this.__oImage);
		}
		ImageWindow.prototype.__prepareWindow = function () {
			Window.prototype.__prepareWindow.call(this);
			this.__createImage();
		}
		ImageWindow.prototype.__prepareEvents = function () {
			Window.prototype.__prepareEvents.call(this);
			var __oWindow = this;
			addEventHandler(this.__oImage, 'load', function () {
				__oWindow.__show();
			});
			addEventHandler(this.__oImage, 'click', function () {
				__oWindow.close();
			});
			addEventHandler(this.__oImage, 'error', function () {
				__oWindow.notifyObservers(ImageWindow.IMAGE_ERROR);
			});
			addEventHandler(this.__oImage, 'abort', function () {
				__oWindow.notifyObservers(ImageWindow.IMAGE_ABORT);
			});
		}
		ImageWindow.prototype.__resizeWindow = function () {
			this.__oWindow.style.width = this.__oImage.offsetWidth + 'px';
			this.__oWindow.style.height = this.__oImage.offsetHeight + 'px';
			this.__positionWindow();
		}
		ImageWindow.prototype.__createImage = function () {
			this.__oImage = document.createElement('img');
			this.__oImage.style.visibility = 'hidden';
		}
		ImageWindow.__initialized = true;
	}
}
