function Logger() {
	var logElement = undefined;
	
	this.log = function(message) {
		if (!message) {
			return;
		}
		if (!logElement) {
			logElement = document.getElementById("move-metadata-log");
		}
		if (logElement) {
//			while (logElement.hasChildNodes()) {
//			    logElement.removeChild(logElement.lastChild);
//			}
			var node = document.createTextNode(message);
			logElement.appendChild(node);
		}
	};
}

var logger = new Logger();

function getWindowHeight() {
		var y = window.innerHeight;
		if (y) {
			return y;
		}
		if (!document.documentElement.clientHeight) {
			return document.body.clientHeight;
		}
		y = document.documentElement.clientHeight;
		if (y > 0) {
			return y; 
		}
	
		return document.body.clientHeight; 
};
	
function getWindowWidth() {
		var y = window.innerWidth;
		if (y) {
			return y;
		}
		if (!document.documentElement.clientWidth) {
			return document.body.clientWidth;
		}
		y = document.documentElement.clientWidth;
		if (y > 0) {
			return y; 
		}
	
		return document.body.clientWidth; 
};


function WindowDimensions(width, height) {
	var usedWidth = 0 + (typeof(width) == 'number' && width > 0) ? width : getWindowWidth();
	var usedHeight = 0 + (typeof(height) == 'number' && height > 0) ? height : getWindowHeight();
	this.getWidth = function() {
		return usedWidth;
	};
	this.getHeight = function() {
		return usedHeight;
	};
	this.toString = function() {
		return "(WxH)=(" + usedWidth + "x" + usedHeight + ")";
	};
};

function WindowSizeTracker() {
	if (window.windowSizeTrackerInstance) {
		return window.windowSizeTrackerInstance;
	}

	var hasStarted = undefined;
	var previousWindowSize = undefined;
	var newWindowSize = undefined;
	var listenerFunction = undefined;
	var delay = 100;
	
	this.start = function() {
		if (this.hasStarted) {
			return;
		}
		this.hasStarted = true;
		
		var timerFunction = function() {
			var prevSize = previousWindowSize;
			var newSize = newWindowSize;
			if (newSize == undefined) {
				newSize = new WindowDimensions();
			}
			if (prevSize==undefined || prevSize.getWidth() != newSize.getWidth() || prevSize.getHeight() != newSize.getHeight()) {
				previousWindowSize = newSize;
				
				var start = new Date().getTime();

				if (listenerFunction) {
					listenerFunction(newSize, prevSize);
				}
				
				var end = new Date().getTime();
				
				if (end - start > 0.25 * delay) {
					delay = 2 * (end - start + 0.25);
				}				
			}
			
			window.setTimeout(timerFunction, delay);
		};
		
		timerFunction();
	};
	
	this.invalidateSize = function() {
		newWindowSize = new WindowDimensions();
	};
	
	this.setListener = function(newListenerFunction) {
		if (newListenerFunction) {
			listenerFunction = newListenerFunction;
		}
	};
	
	window.windowSizeTrackerInstance = this;
};



function initWindowSizeTracker() {
	var tracker = new WindowSizeTracker();
	
	tracker.start();
};

function invalidateWindowSize() {
	new WindowSizeTracker().invalidateSize();
};

function setWindowSizeChangeListener(listenerFunction) {
	new WindowSizeTracker().setListener(listenerFunction);
}




function PageLayout() {
	if (window.pageLayoutInstance) {
		return window.pageLayoutInstance;
	}
	
	var mainFrame = undefined;
	var menuFrame = undefined;
	var contentFrame = undefined;
	var calendarFrame = undefined;
	var measurementParagraph = undefined;
	var emInPixels = 10;
	var menuBeforeContent = undefined;
	
	this.onPageLayoutChange = function(dimensions, oldDimensions) {
		if (mainFrame == undefined) {
			mainFrame = document.getElementById("middle-frame");
		}
		if (menuFrame == undefined) {
			menuFrame = document.getElementById("middle-left-frame");
		}
		if (contentFrame == undefined) {
			contentFrame = document.getElementById("content-frame");
		}
		if (calendarFrame == undefined) {
			calendarFrame = document.getElementById("calendar-frame");
		}
		if (measurementParagraph == undefined) {
			measurementParagraph = document.getElementById("measurement");
		}

		var getMenuBeforeContent = function() {
			if (menuFrame.offsetTop == undefined || contentFrame.offsetTop == undefined) {
				var emInPixels = measurementParagraph.offsetHeight;
				var minWidthForMenuLeft = (12 + 35 + 2) * emInPixels;
				
				return dimensions.getWidth() > minWidthForMenuLeft;
			} 
			else {
				var menuTop = menuFrame.offsetTop;
				var contentTop = contentFrame.offsetTop;
				
				var result = contentTop <= menuTop;
				
//				logger.log("MenuTop=" + menuTop + "; contentTop=" + contentTop + "; menuBefore=" + result + "\n");
				
				return result;
			}
		};
		
		var placeFrames = function(menuBeforeContent) {
			mainFrame.removeChild(menuFrame);
			mainFrame.removeChild(contentFrame);
			mainFrame.removeChild(calendarFrame);
			
			if (menuBeforeContent) {
				mainFrame.appendChild(menuFrame);
				mainFrame.appendChild(contentFrame);
				mainFrame.appendChild(calendarFrame);
			}
			else  {
				mainFrame.appendChild(contentFrame);
				mainFrame.appendChild(menuFrame);
				mainFrame.appendChild(calendarFrame);
			}
		};
		
		var iterationsLeft = 1;
		
		var verifyLayout = function() {
			var menuBeforeContentNow = getMenuBeforeContent();
			
			if (menuBeforeContent == undefined || menuBeforeContentNow != menuBeforeContent) {
				menuBeforeContent = menuBeforeContentNow;
				placeFrames(menuBeforeContentNow);
			}
			
			if (iterationsLeft > 0 && menuBeforeContentNow) {
			  iterationsLeft = iterationsLeft - 1;
			  window.setTimeout(verifyLayout, 10);
			}
			return menuBeforeContentNow;
		};
		
		window.setTimeout(verifyLayout, 10);
	};
	
	
	window.pageLayoutInstance = this;
};


function onLayoutChange(dimensions, oldDimensions) {
	new PageLayout().onPageLayoutChange(dimensions, oldDimensions);
}

function initLayoutOnWindResize() {
	var tracker = new WindowSizeTracker();
	
	tracker.setListener(onLayoutChange);
	tracker.start();
}
