/** @fileoverview
 * Common logic for cms components.
 * @author Russ Tennant <russ@i2rd.com> 
 * @requires prototype.js version >=1.5
 */
if(typeof cmslib == 'undefined') {
cmslib = true;
if(typeof cms == 'undefined'){cms = {};}

cms.ZIndex = {};
cms.ZIndex.LOW = 10;
cms.ZIndex.MEDIUM = 200;
cms.ZIndex.HIGH = 500;
/** Tries to reload the page without triggering conditional-gets and adding to the history.
 * @param {bool} force flag to determine if the page should be forced to be reloaded regardless
 * of the browser history.
 */
cms.reloadPage = function(force) {
	var w = window;
	if(window.top){w = window.top;}
	if(force) {
		w.location.reload();
	} else {
		var path = unescape(w.location.pathname);
		if(path.indexOf("#") == (path.length - 1)) { path = path.substring(0, path.length - 1); }
		w.location.replace( path ); // Prevents entry from being added to browser history.
		w.setTimeout("cms.reloadPage(true)", 15000);
	}
};
cms_autoid_serial = 0;
cms.getId = function(element) {
	if(!element.id) {
		var pref = "ag_";
		if(element.nodeName){pref = element.nodeName.toLowerCase() + "_" + pref;}
		element.id = pref + (cms_autoid_serial++);
	}
	return element.id;
};
cms.removePageElementPath = function(path) {
	if(!path){return path;}
	var split = path.split("/");
	if(split.length !== 0) {
		var last = split[split.length - 1];
		if(last.match(/[a-zA-Z0-9]+,bx\d+[a-zA-Z0-9,]*/)) {
			split.length = split.length - 1;
			path = split.join("/");
		}
	}
	if(path.indexOf("/") !== 0){path = "/" + path;}
	return path;
};
cms.getBaseURL = function() {
	return window.location.protocol + "//" + window.location.host;
};
cms.getSanitizedURL = function() {
	return cms.getBaseURL() + cms.removePageElementPath(window.location.pathname);
};
cms.windowObservers = [];
cms.contentObservers = [];
cms.windowEvent = null;
cms.contentEvent = null;
cms.onWindowLoadCalled = false;
cms.onContentLoadCalled = false;
cms.fireWindowLoadEvent = function(observer) {
	try { observer.call(null, cms.windowEvent); } catch(e) {
		log4js.logger.error("Unable to call observer in cms.fireWindowLoadEvent", e);
	}
};
cms.fireContentLoadEvent = function(observer) {
	try { observer.call(null, cms.contentEvent); } catch(e) {
		log4js.logger.error("Unable to call observer in cms.fireContentLoadEvent", e);
	}
};
// http://dean.edwards.name/weblog/2005/09/busted/
/** Execute the specified function on DOM load or after.
 * @param observer the observer to register.
 */
cms.executeOnContentLoadOrAfter = function(observer) {
	if(!observer){return;}
	if(cms.onContentLoadCalled){cms.fireContentLoadEvent(observer);}
	else{cms.contentObservers.push(observer);}
};
cms._onContentLoad =  function(evt) {
	if(cms.onContentLoadCalled){return;}
	cms.contentEvent = evt || window.event;
	cms.onContentLoadCalled = true;
	var o;
	//log4js.logger.info("Firing " + cms.contentObservers.length + " listeners. windowLoad? " + cms.onWindowLoadCalled);
	while( (o = cms.contentObservers.pop()) ) {cms.fireContentLoadEvent(o);}
};
/**
 * Execute the specified function on window load or after.
 */
cms.executeOnWindowLoadOrAfter = function(observer) {
	if(!observer){return;}
	if(cms.onWindowLoadCalled) { cms.fireWindowLoadEvent(observer); }
	else { cms.windowObservers.push(observer); }
};
Event.observe(window, 'load', function(evt) {
	cms.windowEvent = evt || window.event;
	// onContentLoad has not been called. Call it now.
	if(!cms.onContentLoadCalled) {
		//log4js.logger.info("Firing onContentLoad late.");
		cms._onContentLoad(cms.windowEvent);
	}
	cms.onWindowLoadCalled = true;
	var o;
	while( (o = cms.windowObservers.pop()) ) {
		cms.fireWindowLoadEvent(o);
	}
});

cms.__xhtml = null;
cms.isXhtml = function() {
	if(!(document && i2rd.getBody())){
		throw new Error("You must call this method, cms.isXhtml(), after the document has been loaded.");
	}
	if(!cms.__xhtml) {
		var body = i2rd.getBody();
		var de = document.documentElement;
		var nsuri = (de ? de.namespaceURI : body.namespaceURI);
		var dt = document.doctype;
		cms.__xhtml =  (nsuri && nsuri.match(/xhtml/))
			|| (dt && dt.publicId && dt.publicId.toLowerCase().match(/xhtml/))
			|| (dt && dt.systemId && dt.systemId.toLowerCase().match(/xhtml/));
	}
	return cms.__xhtml;
};
cms.__strict = null;
cms.isStrict = function() {
	if(!(document && i2rd.getBody())){
		throw new Error("You must call this method, cms.isStrict(), after the document has been loaded.");
	}
	if(!cms.__strict) {
		var dt = document.doctype;
		var p = (dt ? dt.publicId : false);
		var s = (dt ? dt.systemId : false);
		cms.__strict = (p && p.toLowerCase().match(/strict/))
			|| (s && s.toLowerCase().match(/strict/));
	}
	return cms.__strict;
};
cms.isIE = function() { // compat.
	return Prototype.Browser.IE;
};
/* Ref.
if(typeof Node == 'undefined') {
	var Node = new Object();
	Node.ELEMENT_NODE                   = 1;
  	Node.ATTRIBUTE_NODE                 = 2;
	Node.TEXT_NODE                      = 3;
	Node.CDATA_SECTION_NODE             = 4;
	Node.ENTITY_REFERENCE_NODE          = 5;
  	Node.ENTITY_NODE                    = 6;
  	Node.PROCESSING_INSTRUCTION_NODE    = 7;
  	Node.COMMENT_NODE                   = 8;
  	Node.DOCUMENT_NODE                  = 9;
  	Node.DOCUMENT_TYPE_NODE             = 10;
  	Node.DOCUMENT_FRAGMENT_NODE         = 11;
  	Node.NOTATION_NODE                  = 12;
}
*/
cms.getParent = function(el, pTagName) {
	if (el === null){return null;}
    while (el.parentNode && (!el.tagName ||
        (el.tagName.toUpperCase() != pTagName.toUpperCase()))){
      el = el.parentNode;
    }
	return el;
};
/** 
 * Set the inner HTML/XHTML. 
 * @return true on success; false otherwise.
 */
cms.setInnerHTML = function(el, xml) {
	if(!el) {
		log4js.logger.error("Got null element in setInnerHTML.", new Error());
		return false;
	}
	el = $(el);
	try {
		var html = "";
   		if(typeof(xml) == "string") {
   			html = xml;
		}else{
			var i,ib;
			if(xml.xml) {
				for ( i=0,ib=xml.childNodes.length; i < ib; i++ )
					{html += xml.childNodes[i].xml;}
			}else{
				var xmlSerializer = new XMLSerializer();
				for (i=0,ib=xml.childNodes.length ; i < ib; i++ ) {
					var tmp = xmlSerializer.serializeToString(xml.childNodes[i]);
					tmp = tmp.replace( /<textarea([^>]*)\/>/gi, '<textarea$1></textarea>' ) ;
					html += tmp;
				}
			}
        }
		Element.update(el, html);
		return true;
	} catch(e) { log4js.logger.error("Failed to update element: " + cms.getId(el), e); }
  	return false;
};
cms.copyTxtToClipboard = function(txt) {
		if(!txt) {
			var selObj = window.getSelection(); 
			if(selObj){txt = selObj.txt;}
		}
		if(window.clipboardData) {
			window.clipboardData.setData('Text', txt);
		} else if(typeof Components != 'undefined') {
			//http://developer.mozilla.org/en/docs/index.php?title=Using_the_Clipboard
			try {
				netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
				var ch = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
				ch.copyString(txt);
			}catch(e) {
				var se = (e + "").indexOf("denied") > -1;
				if(se) { // Prompt user to give permission.
					cms.promptPermission("copy to the clipboard");
				}
				log4js.logger.info("Unable to copy to clipboard. " + e, e);
			}
		} else {
			/*var tr=document.selection.createRange();
			if(tr.text == txt)
				tr.execCommand("Copy");*/
		}
};
cms.promptPermission = function(perm) {
	var asked = i2rd.getCookie("asked-uxpc");
	if(!asked) {
		if(!confirm("To enable '" + perm + "', you need to grant permission." 
		+ " Please set 'signed.applets.codebase_principal_support' to true in about:config and grant permission when prompted."
		+ " Press Cancel if you no longer wish to see this message.")) {
			var time = new Date();
			time.setMonth(time.getMonth() + 1);
			i2rd.setCookie("asked-" + perm.replace(/ /g,"-"), "1", time, "/");
		}
	}
};
/**
* Get elements by tag name. Checks tag name in upper and lower case 
* for HTML and XHTML compat.
* @param tagName the tag name in lower case.
* @param start the start element. If not specified, use the document element.
* @return a node list or empty array.
*/
cms.getElementsByTagName = i2rd.getElementsByTagName;

cms.sendMouseClick = function(el) {
	el = $(el);
	var impl = document.implementation;
	if(impl && impl.hasFeature("MouseEvents","2.0") ) {
		var de = document.createEvent("MouseEvents");
		de.initMouseEvent("click", false, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		el.dispatchEvent(de);
	}
	else if(cms.isIE()){el.click();}
	else{log4js.logger.warn("Generated mouse events not supported for browser");}
};

// OnContentLoad listener setup.
try {
	var ua = navigator.userAgent;
	if (document.addEventListener  && 
		(ua.match(/Firefox/) || ua.match(/SeaMonkey/)) ) {
		document.addEventListener("DOMContentLoaded", cms._onContentLoad, null);
	} else if(document.attachEvent &&  !window.opera) {
        document.write("<script id=__cmsOnContentLoad defer " + "src='//:'><\/script>");
        document.getElementById("__cmsOnContentLoad").onreadystatechange = function() {
            if (this.readyState == "complete") {
                this.onreadystatechange = null;
                cms._onContentLoad();
            }
        };
    } else {
		cms._timer = setInterval(function() {
            var drs = document.readyState;
			if ((drs && /complete|loaded/.test(drs))
			    || cms.onWindowLoadCalled) {
				clearInterval(cms._timer);
				delete cms._timer;
				cms._onContentLoad();
			}
		}, 10);
	}
} catch(e) {
	log4js.logger.error("Unable to setup oncontentload check.", e);
}

if(typeof console != 'undefined' && console.firebug) {
    var cnt =parseInt(i2rd.getCookie("firebug-notice") || 0) + 1;
    if(cnt < 4) {
        var time = new Date();
		time.setHours(time.getHours() + (7 * 24));
		i2rd.setCookie("firebug-notice", cnt, time, "/");
        console.group("Firebug Notice");
        console.info("You have firebug enabled. Disable firebug to improve the performance of this site. \n"
                         + "Other options to improve firebug's performance impact: \n"
                         + "1. Disable network monitoring in the Net tab.\n"
                         + "2. Disable \"Show XmlHttpRequests\" in the Console tab.\n"
                         + "3. Set the 'javascript.options.strict' config to false in about:config.\n" 
                         );
        console.groupEnd();
    }
}

} // End conditional eval.
