var browserIsSafari  = (navigator.userAgent.indexOf('Safari') != -1);
var browserIsIE  = (navigator.userAgent.indexOf('MSIE') != -1);
var AF_Portlets = [];

var AF_Portlets_interval = null;

function loadPortlets() {
	loadNextPortlet();
}

function loadNextPortlet() {
	for(var p=0; p<AF_Portlets.length; p++) {
		if(AF_Portlets[p].status == "init_lazy_complete") {
			AF_Portlets[p].loadPortlet({onComplete: loadNextPortlet});
			break;
		}
	}
}


Portlet = Class.create();
Portlet.prototype = {
	initialize: function(id, options) {
		this.status     = "initializing";
		this.id         = id;
		
		this.setOptions(options);		
		/* FSDocAtts have a referer url parameter passed as an escaped and encoded string within the url - 
			we decode the whole url here to avoid any problems with the encoded value later on. 
		*/
		if (this.options.isFSDocAtt) {
			this.options.url = decodeURIComponent(this.options.url);
		}
		
		if(this.options.parameters != "") this.options.parameters = this.options.parameters + '&';
		
		this.defaultParameters  = "AF_renderParam_portlet=portlet_"+this.id+"&"
					+ "AF_renderParam_embed=true";				     
		
		this.targetDiv = $(this.id);
		
		this.portletMenuHTML = this.getPortletMenu();
		
		this.xurl = this.options.url;
		this.xparameters = this.options.parameters;
		this.refererUrl = null;
		
		AF_Portlets[AF_Portlets.length] = this;
		
		this.portletComplete = Prototype.emptyFunction;
		
		if(!this.options.lazy) this.loadPortlet();		
		else {
			this.status = "init_lazy_complete";
			}		
	},
	
	setOptions: function(options) {
	
		this.options = {
			// default values of options
			title: 			'Autoforms Portlet',
			url: 			'about:blank',
			
			docroot:		'',
			lazy:			false,
			selection:		true,
			framework:		'default',
			parameters:		'',
			style:			'',
			suppressParameters:	false,
			isFSDocAtt:		'',
			FSaction:		'',
			titleField:		'',
			pointer: 		'',
			loadingHTML: "<table border='0' width='100%' height='100%' class='text' valign='center'><tr valign='center'><td align='center'><img src='"+options.docroot+"/common/images/ajax/loading.gif'/><br/><br/>Loading...</td></tr></table>"
		};
		
		Object.extend(this.options, options || {})
		
	},	
	
	setInnerHTML: function(newHTML) {
		this.targetDiv.innerHTML = this.portletMenuHTML + newHTML;
		
		this.initializeMenu();
	},
	
	loadPortlet: function(options) {
	
				var parameters = (this.options.suppressParameters)? "" : (this.options.parameters) ? this.options.parameters + "&"+this.defaultParameters : this.defaultParameters;
		parameters += "&AF_url_referer="+this.options.url;	
		// no url to load
		if(this.options.url == "about:blank") {
			this.status     = "init_complete";
			
			this.targetDiv.innerHTML = this.portletMenuHTML + this.targetDiv.innerHTML;
			
			this.initializeMenu();
			
			return;
		}	
		this.status     = "loading";
		this.portletComplete = ((options)? (options.onComplete || Prototype.emptyFunction): Prototype.emptyFunction);
		new Ajax.Request(
			this.options.url, Object.extend({
				parameters:   parameters,
				method:	      'get',
				onLoading:    this.targetDiv.innerHTML = this.options.loadingHTML,
				onComplete:   this.onComplete.bind(this),
				onFailure:    this.onFailure.bind(this),
				asynchronous: true
			}));
	},

	onComplete: function(transport) {
		var content = transport.responseText;
		replacement = "$1href=\"javascript:portlet_"+this.id+".openUrl('$9','',false);\"";
		content = content.replace(/((<a)(?!.*target=(\'|\")([^"\r\n]*?)(\'|\"))(.*))(href=(\'|\")((?!javascript\:)[^"\r\n]*?)(\'|\"))(?!.*target=(\'|\")([^"\r\n]*?)(\'|\"))/g, replacement);
		content.evalStyles();
		if(browserIsSafari){
			this.targetDiv.innerHTML = this.portletMenuHTML+content;
			var JSScript = getAllScripts(this.targetDiv);
			this.targetDiv.innerHTML = this.portletMenuHTML+content.stripScripts().stripStyleCss();
			addJSScriptToHead(JSScript);
		}else{
			this.targetDiv.innerHTML = this.portletMenuHTML+content.stripScripts().stripStyleCss();
		}
		content.importScripts();
		this.initializeMenu();
		this.status     = "init_complete";
		this.portletComplete();
		this.xurl = this.options.url;
		try{
			this.cKey = document.forms[0].AF_chainKey.value;
			eval(this.id+"_portletCallBack(this)");
		}catch(e){}
	},

	onFailure: function(transport) {
		this.targetDiv.innerHTML = "Error communicating with the server:\n" + transport.responseText.stripTags();
	},
	
	getPortletMenu: function() {
		var html = "";
		
		if(this.options.framework != "none" && this.options.docroot == "") {
			alert("portlet: you need to set docroot path to be able to draw the portlet framework")
			return html;
		}
		
		switch (this.options.framework) {
			case "none": html = ""; break;
			case "default":
			default: html = "<div id='"+this.id+"_handle' style='background-color: #cccccc;height: 20px;text-align: right;cursor:move;'><img onclick='portlet_"+this.id+".reload()' src='"+this.options.docroot+"/common/refresh.gif' style='cursor: pointer;' id='"+this.id+"_handle'/></div>"; break;
		}
		
		return html;
	},
	
	initializeMenu: function() {
		if($(this.id+'_handle')) {
			var oldone = Draggables.getById($(this.id+'_handle'));
			if(oldone) {
				oldone.destroy();
			}
			new Draggable(this.id, {handle:this.id+'_handle',revert:false,ghosting:false});	
		}
	},	
	
	reload: function() {
		this.loadPortlet(this.options.url);
	},
	
	
	refresh: function() {
		this.openUrl(this.xurl, this.xparameters, true);		
	},
	
	openUrl: function(url, parameters, reloading) {
		
		parameters = parameters != null ? parameters : "";
		reloading = reloading != null ? reloading : false;
		
		if(!reloading) {
			parameters = (this.options.suppressParameters)? "" : parameters + this.defaultParameters;
			parameters += "&AF_url_referer="+encodeURIComponent(this.xurl);
			this.refererUrl = this.xurl;
			
		}
		
		else {		
			parameters = this.xparameters + this.defaultParameters;		
			parameters += "&AF_url_referer="+encodeURIComponent(this.refererUrl);
		}
		
		//if parameter maximisePortlet is passed, maximize portlet
		if (url.indexOf("maximizePortlet=true") != -1) this.maximize();
		
		this.targetDiv.innerHTML = this.options.loadingHTML;			
		this.xurl = url;

		var request = new Ajax.Request(
			url, Object.extend({
				parameters:   parameters,
				method:	      'get',
				asynchronous: true,
				onComplete:   this.onRefreshComplete.bind(this)
			}));
		
	},
	
	
	onRefreshComplete: function(transport) {		
		var content = transport.responseText;
		if (content == "") {
			this.reload();
			return;
		}
		
		replacement = "$1href=\"javascript:portlet_"+this.id+".openUrl('$9','',false);\"";
		content = content.replace(/((<a)(?!.*target=(\'|\")([^"\r\n]*?)(\'|\"))(.*))(href=(\'|\")((?!javascript\:)[^"\r\n]*?)(\'|\"))(?!.*target=(\'|\")([^"\r\n]*?)(\'|\"))/g, replacement);
		content.evalStyles();
		if(browserIsSafari){
			this.targetDiv.innerHTML = this.portletMenuHTML+content;
			var JSScript = getAllScripts(this.targetDiv);
			this.targetDiv.innerHTML = this.portletMenuHTML+content.stripScripts().stripStyleCss();
			addJSScriptToHead(JSScript);
		}else{
			this.targetDiv.innerHTML = this.portletMenuHTML+content.stripScripts().stripStyleCss();
		}
		
		content.importScripts();
		this.initializeMenu();
		this.targetDiv.style.cursor = "default";
		this.status = "complete";
	
		if (this.options.isFSDocAtt) {
			if (this.options.FSaction == "add") {
				var res = [];
				res[0] = this.cKey;
				if (this.titleField && this.titleField != "") {				
					res[1] = this.titleField; // should be the title...
				} else {
					res[1] = this.cKey;
				}
				if (document.getElementById("AF_isExecutedSuccessfully") && document.getElementById("AF_isExecutedSuccessfully").value == "true") {
					eval("window.opener." + this.options.pointer + ".addResult(res)");
					portletsCloseWindow();			
				}
			}
			if (this.options.FSaction == "edit") {
				//cKey is the chainkey
				var tit;
				if (this.titleField && this.titleField != "") {
					tit = this.titleField; // should be the title...
				} else {
					tit = this.cKey;
				}
				// This is either an edit or a delete
				// check the delete first:
				if (document.getElementById("AF_isDeleteAction") && document.getElementById("AF_isDeleteAction").value == "true") {
					eval("window.opener." + this.options.pointer + ".deleteByCKey(this.cKey)");
					portletsCloseWindow();
				} else {
					// Editing.. reflect changes to the title
					if (document.getElementById("AF_isExecutedSuccessfully") && document.getElementById("AF_isExecutedSuccessfully").value == "true") {
						eval("window.opener." + this.options.pointer + ".editResult(this.cKey, tit)");
						portletsCloseWindow();
					}
				}
			}
		}
		
	},
	
	submitForm: function (form,action) {
	   parameters = Form.serialize(form);
	   parameters = parameters != "" ? parameters + "&"+this.defaultParameters : this.defaultParameters;
	   parameters += "&AF_url_referer="+encodeURIComponent(this.xurl);
	   this.refererUrl = this.xurl;
	   this.xurl = action + "?" + parameters.substring(0,parameters.indexOf("AF_url_referer"));	   
	   this.setTitleField();
	   var request = new Ajax.Request(
			action, Object.extend({
				parameters:   parameters,
				method:	      form.method,
				asynchronous: true,
				onComplete:   this.onRefreshComplete.bind(this)
			}));
			
	   
	   return false;

	},
	
	setTitleField: function() {		
		if(this.options.titleField) {
	    	var titleFieldElt = document.getElementById(this.options.titleField);
	   			if(titleFieldElt != null) {
				   this.titleField = document.getElementById(this.options.titleField).value;
				 }
		}
	},
	
	hide: function() {		
		this.targetDiv.style.display = "none";
	},
	
	show: function() {
		if (browserIsIE) this.targetDiv.style.setAttribute("cssText",this.options.style);
		else this.targetDiv.setAttribute("style",this.options.style);
	},
	
	maximize: function() {
		for(i=0; i < AF_Portlets.length; i++) {
			if (AF_Portlets[i] != this) {
				AF_Portlets[i].hide();
			}
		}

		if (browserIsIE) this.targetDiv.style.setAttribute("cssText","overflow-y:visible;overflow-x:hidden;width:100%;height:100%;float:left;display:block;");
		else this.targetDiv.setAttribute("style","overflow-x:hidden;overflow-y:visible;width:100%;height:100%;float:left;");
	},
	
	restore: function() {
		for(i=0; i < AF_Portlets.length; i++) {
			//if (AF_Portlets[i] != this) {
				AF_Portlets[i].show();
			//}
		}
		//this.targetDiv.style = this.options.style;
	}
}

function getAllScripts(node) {

	// if node is null or browser is not safari then abort
	if (!node || !browserIsSafari) return;

	// due to certain strange behavior in the portlet mechanism
	// I am forced to collect all scripts and put them aside for later manipulation
	// because portlet must run the following this.targetDiv.innerHTML = this.portletMenuHTML+content.stripScripts().stripStyleCss();
	// before i can place the js scrpts in the header
	var tempScriptContainer  = document.getElementById("portletScriptContainer");
	if(tempScriptContainer){
		tempScriptContainer.innerHTML = '';
	}else{
		tempScriptContainer=document.createElement('div');
		tempScriptContainer.setAttribute("id","portletScriptContainer");
	}

	// IE wants it uppercase
	var scriptTag = node.getElementsByTagName('SCRIPT');
	
	// ok right now i place all the js files into the tempScriptContainer
	for(var i = scriptTag.length - 1; i >= 0; i--) {
		if(scriptTag[i].getAttribute("src")!=null){
			var fileRef=document.createElement('script');
			fileRef.setAttribute("type","text/javascript");
			fileRef.setAttribute("src", scriptTag[i].getAttribute("src"));
			fileRef.setAttribute("id", node.id);
			tempScriptContainer.appendChild(fileRef);
		}
	}

	// now i search for scripts with a body and place those scripts in the tempScriptContainer.
	var scriptTag = node.getElementsByTagName('SCRIPT');
	var scriptTagBody;

	for(var i=0;i<scriptTag.length; i++) {
		scriptTagBody = scriptTag[i].innerHTML;
		scriptTag[i].innerHTML = "";

		var newScriptTag = document.createElement("script");
		newScriptTag.type = "text/javascript";
		newScriptTag.setAttribute("id", node.id);
		newScriptTag.innerHTML = scriptTagBody;
		tempScriptContainer.appendChild(newScriptTag);
	}
	return tempScriptContainer;
}

function addJSScriptToHead(tempContainerObj) {
	// if node is null or browser is not safari then abort
	if (!tempContainerObj || !browserIsSafari) return;

	// IE wants it uppercase
	var scriptTag = tempContainerObj.getElementsByTagName('SCRIPT');
	var scriptTagID;
	var scriptTagBody;
	if(scriptTag != null){
	
		scriptTagID = scriptTag[0].id;
		
		// remove script that were previously loaded by this portlet
		var bodyScript = document.getElementsByTagName("head")[0];
		var exsistingScript = bodyScript.getElementsByTagName('SCRIPT');
		for(var i = exsistingScript.length - 1; i >= 0; i--) {
			if(exsistingScript[i].id == scriptTagID){
				exsistingScript[i].parentNode.removeChild(exsistingScript[i]);
			}
		}
		
		// now lets re insert the new version of the scripts
		// first we add the scripts with src js files
		// but we must make sure that those files have not been imported already by the main page safari crashes if that happems
		for(var i = scriptTag.length - 1; i >= 0; i--) {
			var found = false;
			if(scriptTag[i].getAttribute("src")!=null){
				var headerScripts = document.getElementsByTagName("head")[0].getElementsByTagName('SCRIPT');
				for(var x = headerScripts.length - 1; x >= 0; x--) {
					if(headerScripts[x].getAttribute("src") == scriptTag[i].getAttribute("src")){
						found = true;
					}
				} 
				if(!found){
					var fileRef=document.createElement('script');
					fileRef.setAttribute("type","text/javascript");
					fileRef.setAttribute("src", scriptTag[i].getAttribute("src"));
					fileRef.setAttribute("id", scriptTagID);
					document.getElementsByTagName("head").item(0).appendChild(fileRef);
				}
			}
		}
		
		// now lets add script tags with a body
		for(var i=0;i<scriptTag.length; i++) {
			scriptTagBody = scriptTag[i].innerHTML;
			var newScriptTag  = document.createElement("script");
			newScriptTag.type = "text/javascript";
			newScriptTag.id = scriptTagID;
			newScriptTag.innerHTML = scriptTagBody;
			document.getElementsByTagName("head")[0].appendChild(newScriptTag);
		}
	}
}


function portletsCloseWindow() {
	if(browserIsIE) {
		window.close();
	} else {
		setTimeout('window.close()',1000);
	}
}