/*
	layoutctrl.js
	
	v2.03, 2007-06-05, Christian Augustin

*/
/*
	A major re-design to fix some mysterious problems with Firefox!
	
	Requires
	layoutctrl_styles/ (in same directory)
	
	Caveats
	.applyCssAdditions no longer exists, use browser CSS class names instead!
	
	History
	2007-06-05 cma: ESC toggles showAnnotations, shift+ESC cycles styles.
	2007-03-28 cma: Problem with loadStyle and MSIE 6 fixed (using doc.write).
	2007-03-11 cma: scriptPath from presets as fall-back (loader.js legacy mode).
	2007-03-11 cma: Declared 2.0.
	2007-02-09 cma: First functional version of 2.00 (beta state).
	2007-02-09 cma: Initial setup.

	Technical Advice:
	Don't manipulate document.documentElement.className directly prior to a
	document.write -- this will choke Firefox in some cases!
	
*/

var LayoutCtrl = {

	stylesPath: 'layoutctrl_styles/',
	scriptPath: '',

	widthClasses: [],

	heightClasses: [],

	stylesCSS: [
		{name: 'initial', disabled: false},
		{name: 'show_annotations', disabled: true},
		{name: 'show_mediasizes', disabled: true},
		{name: 'show_blocks', disabled: true}
	],

	styles: [
		{css: '', grid: false, media: false},
		{css: 'show_annotations show_mediasizes', grid: true, media: true},
		{css: 'show_blocks', grid: true, media: false}
	],

	showAnnotations: false,

	showAnnotationsCSS: 'show_annotations',
	
	presets: ['stylesPath', 'scriptPath', 'heightClasses', 'widthClasses', 'stylesCSS', 'styles', 'showAnnotations'],
	
	getPresets: function() {
		if (typeof presets == 'undefined' || !presets.LayoutCtrl) return;
		for (var i in LayoutCtrl.presets) {
			var n = LayoutCtrl.presets[i];
			if (typeof presets.LayoutCtrl[n] != 'undefined') {
				LayoutCtrl[n] = presets.LayoutCtrl[n];
			};
		};
	},

	getScriptPath: function() {
		/* Don't use document.scripts due to a Safari bug! */
		var s = document.getElementsByTagName('script');
		for (var i=0; i<s.length; i++) {
			var src = s[i].src;
			if (src && (src.lastIndexOf('layoutctrl') > src.lastIndexOf('/'))) {
				return src.substring(0, src.lastIndexOf('layoutctrl'));
			};
		};
		return '';
	},

	getBrowserClassNames: function() {
		var cn = '', ua = navigator.userAgent;
		var os = ua.match(/Macintosh|Windows|Linux/);
		os = (os) ? os[0].substring(0,3) : '';
		if (window.opera) {
			cn = 'isOpera';
		} else if (document.all) {
			cn = 'isMsie';
		} else if (ua.match('Gecko/')) {
			cn = 'isGecko';
		} else if (ua.match('AppleWebKit/')) {
			cn = 'isWebKit';
		} else if (document.childNodes && !document.all && !navigator.taintEnabled) {
			cn = 'isKhtml';
		};
		cn += os ? (cn ? ' ' + cn + os + ' ' : '') + 'is' + os : '';
		/* MSIE compatibility mode: isMsieBackCompat | isMsieCSS1Compat */
		if (!window.opera && document.all && document.compatMode) {
			cn += ' isMsie' + document.compatMode;
		};
		return cn;
	},
	
	getWindowWidth: function() {
		var html = document.documentElement;
		var body = document.body;
		if (window.innerWidth) return window.innerWidth
		else if (html && html.offsetWidth) return html.offsetWidth
		else if (body && body.offsetWidth) return body.offsetWidth
		else return 0;
	},
	
	getWindowHeight:function() {
		var html = document.documentElement;
		var body = document.body;
		if (window.innerHeight) return window.innerHeight
		else if (html && html.offsetHeight) return html.offsetHeight
		else if (body && body.offsetHeight) return body.offsetHeight
		else return 0;
	},

	getWidthClassName: function() {
		var lc = LayoutCtrl, wcs = lc.widthClasses;
		var wc = '', ww = lc.getWindowWidth();
		if (!wcs || !wcs.length || !ww) return '';
		for (var i=0; i<wcs.length; i++) {
			var tmp = LayoutCtrl.widthClasses[i];
			if (ww > wcs[i].w) wc = wcs[i].wc;
		};
		return wc ? 'browserWidth' + wc : '';
	},

	getHeightClassName: function() {
		var lc = LayoutCtrl, hcs = lc.heightClasses;
		var hc = '', wh = lc.getWindowHeight();
		if (!hcs || !hcs.length || !wh) return '';
		for (var i=0; i<hcs.length; i++) {
			if (wh > hcs[i].h) hc = hcs[i].hc;
		};
		return hc ? 'browserHeight' + hc : '';
	},

	applyBrowserClasses: function() {
		if (!document.documentElement) return;
		var lc = LayoutCtrl, html = document.documentElement;
		var cn = lc.getBrowserClassNames();
		var wc = lc.getWidthClassName(), hc = lc.getHeightClassName();
		var hcn = html.className || '';
		if (cn) hcn += (hcn ? ' ' : '') + cn;
		if (wc) hcn += (hcn ? ' ' : '') + wc;
		if (hc) hcn += (hcn ? ' ' : '') + hc;
		html.className = hcn;
	},
	
	applySizeClasses: function() {
		if (!document.documentElement) return;
		var lc = LayoutCtrl, html = document.documentElement;
		var wc = lc.getWidthClassName(), hc = lc.getHeightClassName();
		var hcn = html.className;
		hcn = html.className || '';
		if (hcn.match('browserWidth')) {
			hcn = hcn.replace(/browserWidth\S+/, wc);
		} else if (wc) {
			hcn += ' ' + wc;
		};
		if (hcn.match('browserHeight')) {
			hcn = hcn.replace(/browserHeight\S+/, hc);
		} else if (hc) {
			hcn += ' ' + hc;
		};
		html.className = html.className.replace(/\s+/g, ' ');
		if (html.className != hcn) html.className = hcn;
	},
	
	showGrid: function() {
		var db = document.body, dbcn = db.className || '';
		if (!dbcn) {
			db.className = 'showGrid';
		} else if (!dbcn.match(/(^|\s)showGrid(\s|$)/)) {
			db.className += ' showGrid';
		};
	},
	
	hideGrid: function() {
		var db = document.body, dbcn = db.className || '';
		if (dbcn.match('showGrid')) db.className = dbcn.replace(/(\s?)showGrid\s?/, '$1');
	},
	
	toggleGrid: function() {
		var db = document.body, dbcn = db.className || '';
		if (dbcn.match('showGrid')) {
			db.className = dbcn.replace(/(\s?)showGrid\s?/, '$1');
		} else {
			db.className = (dbcn ? dbcn + ' ' : '') + 'showGrid';
		};
	},

	showMediaSizes: function() {
		if (document.all || !document.createElement) return;
		var imgs = document.getElementsByTagName('img');
		var objs = document.getElementsByTagName('object');
		var divs = document.getElementsByTagName('div');
		var elms = [];
		for (var i=0; i<imgs.length; i++) elms[elms.length] = imgs[i];
		for (var o=0; o<objs.length; o++) elms[elms.length] = objs[o];
		for (var d=0; d<divs.length; d++) elms[elms.length] = divs[d];
		for (var e=0; e<elms.length; e++) {
			var elm = elms[e];
			if (elm.tagName.match(/img/i)
				|| (elm.className
				&& elm.className.match(/(^|\s)imageDummy(\s|$)/))
			) {
				if (!elm.nextSibling
					|| !elm.nextSibling.className
					|| !elm.nextSibling.className.match(/showMediaSize/)
				) {
					var ms = elm.parentNode.insertBefore(
						document.createElement('div'), elm.nextSibling
					);
					ms.style.position = 'absolute';
					ms.style.top = elm.offsetTop + 'px';
					ms.style.left = elm.offsetLeft + 'px';
					ms.style.width = elm.offsetWidth + 'px';
					ms.style.height = elm.offsetHeight + 'px';
					ms.className = 'showMediaSize';
					ms.appendChild(document.createElement('div')).className =
						'showMediaSizeOverlay';
					ms.appendChild(document.createElement('div')).className =
						'showMediaSizeValues';
					ms.lastChild.appendChild(
						document.createTextNode(elm.offsetWidth + ' x ' + elm.offsetHeight)
					);
				};
			};
		};
	},

	loadStyle: function(name, disabled) {
		if (!document.getElementsByTagName || !name) return;
		var lc = LayoutCtrl;
		if (document.all && !window.opera && !window.XMLHttpRequest) {
			// MSIE 6 breaks under some circumstances using DOM ...
			if (lc.initComplete || !document.write) return;
			document.write('<link rel="' + ((disabled) ? 'alternate ' : '' )
				+ 'stylesheet" type="text/css" href="'
				+ lc.stylesPath + name + '.css" id="' + name
				+ '" title="' + name + '"'
				+ ((disabled) ? ' disabled="disabled"' : '') + ' />\n');
		} else {
			var l, h;
			if (!(l = document.createElement('link'))) return;
			l.type = 'text/css'; l.rel = 'stylesheet';
			if (disabled) {
				l.rel = 'alternate ' + l.rel;
				l.disabled = 'disabled';
			};
			l.title = l.id = name;
			l.href = LayoutCtrl.stylesPath + name + '.css';
			if (!(h = document.getElementsByTagName('head'))) return;
			h[0].appendChild(l);
		};
	},
	
	showStyle: function(name) {
		var ss = document.getElementById(name);
		if (!ss) return;
		ss.disabled = false;
	},
	
	hideStyle: function(name) {
		var ss = document.getElementById(name);
		if (!ss) return;
		ss.disabled = true;
	},

	toggleStyle: function(name) {
		var ss = document.getElementById(name);
		if (!ss) return;
		ss.disabled = (ss.disabled) ? false : true;
	},
	
	actualStyle: 0,
	
	executeStyles: function() {
		var lc = LayoutCtrl, s = lc.actualStyle, st = lc.styles[s];
		if (st.css) {
			var styles = st.css.split(' ');
			for (var c=0; c<styles.length; c++) lc.hideStyle(styles[c]);
		};
		s = (++s < lc.styles.length) ? s : 0;
		st = LayoutCtrl.styles[s];
		(st.grid) ? LayoutCtrl.showGrid() : lc.hideGrid();;
		if (st.media) lc.showMediaSizes();
		if (st.css) {
			styles = st.css.split(' ');
			for (c=0; c<styles.length; c++) lc.showStyle(styles[c]);
		};
		lc.actualStyle = s;
	},

	clicked: function(evt) {
		evt = (evt) ? evt : ((event) ? event : null);
		if (evt && evt.altKey && !evt.shiftKey) {
			LayoutCtrl.executeStyles();
			evt.cancelBubble = true;
			return false;
		};
		return true;
	},

	keydown: function(evt) {
		evt = (evt) ? evt : ((event) ? event : null);
		if (evt.type == "keydown" && evt.keyCode == 27) {
			if (evt.shiftKey) {
				LayoutCtrl.executeStyles();
			} else if (LayoutCtrl.showAnnotationsCSS) {
				LayoutCtrl.toggleStyle(LayoutCtrl.showAnnotationsCSS);
			};
			evt.cancelBubble = true;
			return false;
		};
		return true;
	},
	
	pageLoaded: function() {
		var lc = LayoutCtrl;
		if ((lc.widthClasses && lc.widthClasses.length) ||
				(lc.heightClasses && lc.heightClasses.length)) {
			lc.applySizeClasses();
			if (window.addEventListener) {
				window.addEventListener('resize', lc.applySizeClasses, false);
			} else {
				/* The following approaches make MSIE 6/7 hang on resizes ... */
				/*
				window.attachEvent('onresize', function() {
					lc.applySizeClasses(); return false;
				});
				*/
				//window.onresize = function() {lc.applySizeClasses(); return false;};
			};
		};

		if (document.documentElement && !document.all) {
			document.documentElement.onclick = lc.clicked;
			document.documentElement.onkeydown = lc.keydown;
		} else {
			document.body.onclick = lc.clicked;
			document.body.onkeydown = lc.keydown;
		};
	},
		
	init: function() {
		var lc = LayoutCtrl;
		lc.getPresets();
		lc.scriptPath = lc.getScriptPath()||lc.scriptPath;
		lc.stylesPath = lc.scriptPath + lc.stylesPath;
		lc.applyBrowserClasses();

		var ss = lc.stylesCSS;
		for (var s=0; s<ss.length; s++) lc.loadStyle(ss[s].name, ss[s].disabled);

		if (lc.showAnnotations) lc.showStyle(lc.showAnnotationsCSS);

		/* Try to enable MSIE 6 SP 1 background image caching */
		/* http://www.mister-pixel.com/, also found in MooTools ... */
		if (window.ActiveXObject && !window.XMLHttpRequest)
			try {document.execCommand("BackgroundImageCache", false, true);} catch (e){};

		if (window.addEventListener)
			window.addEventListener('load', lc.pageLoaded, false)
		else if (window.attachEvent)
			window.attachEvent('onload', lc.pageLoaded);

		lc.initComplete = true;
	}
		
};

if (!LayoutCtrl.initComplete) LayoutCtrl.init();
