/*
 * zlstTiles.js
 *
 * Copyright (c) 2010-2011 by Zelestra, ZELESTRA.COM. All Rights Reserved.
 *
 * @author David C. Tessman
 * @version 1.10 2011-04-21
 */

var Tiles = {

	// Public Methods

	// Loads a tile of the specified name into the specified element
	// and then calls the appropriate on loaded function once it is loaded
	loadTile: function (elem,name,properties) {
		Tiles._loadTileCss(elem,name,properties);
	},
	
	// dynamically loads a script file and calls the optionally specified function
	// once loaded.
	loadScript: function(url,fnc) {
		var scripts = document.getElementsByTagName("script");
		for (var i=0; i < scripts.length; i++) {
			if(Tiles._normalizeUrl(scripts[i].src) == url) {
				if (fnc != null)
					fnc();
				return;
			}
		}
		var script = new Element("script",{type:"text/javascript",src:url});
		if (fnc != null) {
			if (Prototype.Browser.IE) {
				if (script.readyState == "loaded") {
					document.getElementsByTagName("head")[0].appendChild(script);
					fnc();
					return;
				}
				script.onreadystatechange = Tiles._onIEReadyStateChange.bind(script,fnc);
			} else
				script.onload = fnc;
		}
		document.getElementsByTagName("head")[0].appendChild(script);
	},
	
	// Private Methods

	// Evaluates inline script tags
	_evalHtml: function(elem) {
		elem.select("script").each(function(n) {
		var oldWrite = document.write;
		var newWrite = function(x) {
			this.insert({after:x});
		};
		document.write = newWrite.bind(n);
		eval(n.innerHTML);
		document.write = oldWrite;
		});
	},

	// dynamically attaches a CSS file to a page
	_loadTileCss: function(elem,name,properties) {
		if (properties && (properties.tileCssUrlTemplate != null))
			var url =  properties.tileCssUrlTemplate.replace(/\$\{name\}/g,name);
		else
			var url = "/themes/default/tiles/${name}Tile/${name}Tile.css".replace(/\$\{name\}/g,name);
		if (url.length == 0) {
			Tiles._loadTileHtml(elem,name,properties);
			return;
		}
		var links = document.getElementsByTagName("link");
		for (var i=0; i < links.length; i++) {
			if(Tiles._normalizeUrl(links[i].href) == url) {
				Tiles._loadTileHtml(elem,name,properties);
				return;
			}
		}
		var link = new Element("link",{rel:"stylesheet",type:"text/css",href:url});
		if (Prototype.Browser.IE)
			link.onload = Tiles._loadTileHtml.bind(this,elem,name,properties);
		document.getElementsByTagName("head")[0].appendChild(link);
		if (!Prototype.Browser.IE)
			window.setTimeout(Tiles._loadTileCssPoll.bind(this,elem,name,properties,url),50);
	},

	_loadTileCssPoll: function(elem,name,properties,url) {
		var count = 0;
		try {
			var sheets = document.styleSheets;
			for(var j=0, k=sheets.length; j<k; j++) {
				var sheet = sheets[j];
				if(sheet.ownerNode.href && sheet.ownerNode.href.indexOf(url) != -1) {
					count = sheet.cssRules.length;
					break;
				}
			}
		} catch(e) {
		}
		if (count == 0)
			window.setTimeout(Tiles._loadTileCssPoll.bind(this,elem,name,properties,url),50);
		else
			Tiles._loadTileHtml(elem,name,properties);
	},

	// dynamically load HTML of tile
	_loadTileHtml: function(elem,name,properties) {
		if (properties && (properties.tileHtmlUrlTemplate != null))
			var url =  properties.tileHtmlUrlTemplate.replace(/\$\{name\}/g,name);
		else
			var url = "/tiles/${name}Tile.html".replace(/\$\{name\}/g,name);
		if (url.length == 0) {
			Tiles._onTileLoaded(elem,name,properties);
			return;
		}
		document.loadAjaxTile(elem,url,{onSuccess:Tiles._onTileLoaded.bind(this,elem,name,properties),onUnload:Tiles._onTileUnloading.bind(this,elem,name,properties)});
	},

	// normalizes a URL to be root-relative
	_normalizeUrl: function(url) {
		if (url.substring(0,4) == "http") {
			if (url.substring(0,7) == "http://") {
				var idx = url.substring(7).indexOf("/");
				url = url.substring(idx + 7);
			} else if (url.substring(0,8) == "https://") {
				var idx = url.substring(8).indexOf("/");
				url = url.substring(idx + 8);
			}
		}
		if (url.substring(0,1) != "/")
			url = "/" + url;
		return url;
	},

	// handles IE ready state change
	_onIEReadyStateChange: function (fnc) {
		if (this.readyState == "loaded")
			fnc();
	},

	// handles on tile script loaded
	_onTileScriptLoaded: function (name,properties,basename) {
		var c = basename.substring(0,1).toUpperCase();;
		fnc =  eval(c + basename.substring(1) + ".initialize");
		if (typeof fnc == "function")
			fnc(properties);
		if (properties && (properties.onSuccess != null))
			properties.onSuccess(properties);
	},

	// handles on tile loaded
	_onTileLoaded: function (elem,name,properties) {
		if (properties && (properties.evalHtmlEnabled == true))
			Tiles._evalHtml(elem);
		if (properties && (properties.tileJsUrlTemplate != null))
			var url =  properties.tileJsUrlTemplate.replace(/\$\{name\}/g,name);
		else
			var url = "/javascript/tiles/${name}Tile.js".replace(/\$\{name\}/g,name);
		if (url.length == 0) {
			if (properties && (properties.onSuccess != null))
				properties.onSuccess(properties);
			return;
		}
		Tiles.loadScript(url,Tiles._onTileScriptLoaded.bind(this,name,properties,url.basename(".js")));
	},

	// handles on tile unloading
	_onTileUnloading: function (elem,name,properties) {
		var c = name.substring(0,1).toUpperCase();;
		fnc =  eval(c + name.substring(1) + "Tile.finalize");
		if (typeof fnc == "function")
			fnc(properties);
	}

};
