/** 
 * This file is part of w@w.
 *
 * W@W web application framework.
 * Copyright (C) 2007 Catholic University of Louvain (Belgium)
 * <blambeau@info.ucl.ac.be>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301 USA
 */

/**
  * Performs request to composer and modify page elements
  */
var WawRequest = new Class.create();
WawRequest.prototype = {

	/** Currently reloading? */
	processing : false,
	
	oldcog : '',
	
	/** Last hash of the location. */
	lastHash : '',
	
	/** Creates a new instance */
	initialize: function() {
	},
	
	/** Removes any leading hash that might be on a location. 
	  * To be fair: taken from dhtmlHistory (licence problem??). */
	removeHash: function(hashValue) {
	   if (hashValue == null || hashValue == undefined)
	      return null;
	   else if (hashValue == "")
	      return null;
	   else if (hashValue.length == 1 && hashValue.charAt(0) == "#")
	      return null;
	   else if (hashValue.length > 1 && hashValue.charAt(0) == "#")
	      return hashValue.substring(1);
	   else
	      return hashValue;     
	},          

	/** Fired when history changes. */
	handleHistory: function() {
		hash = window.location.hash;
		if (hash != ws.lastHash && !ws.processing) {
			ws.processing = true;
			ws.handleLoading();
		}
		timer = setTimeout(ws.handleHistory, 200);
	},

	/** Handles the loading of the page. */
	handleLoading: function() {
		// load
		url = 'ajax.php';

		// create params, add client-session when found
		params = 'waw_req_action=waw.main:reloadView&qname=waw.main:Body';
		hash = this.removeHash(window.location.hash);
		if (hash != null && hash.substring(0,16) == 'waw_cs_encoding=') {
			cs = '';
			params += '&' + hash;
		}

		// make body request
		this.doAction(url,params,'waw.main:Ajax','false');

	},
	
	/** Reloads a view, based on its qualified name. */
	reloadView: function(qname) {
		// load
		url = 'ajax.php';

		// create params
		params = 'waw_req_action=waw.main:reloadView&qname=' + qname;
		
		// reload the view through that action
		this.doAction(url,params,'waw.main:Ajax','true');
	},
	
	/** Send an action to the server. */
	doAction: function(url, params, mainSlot, async) {
		if (async == null) {
			async = 'true';
		}
		
		im = document.getElementById('wawcog');
		if (im != null) {
			oldcog = im.src;
			im.src = 'modules/waw/main/images/cog_running.gif';
		}
		
		// handle url
		url = url + '?waw_main_output=' + mainSlot;
		
		// handle params
		params += '&' + cs;
		
		// make request
		var myAjax = new Ajax.Request(url, { method: 'get', 
						                     parameters: params, 
						                     onComplete: this.viewsReload,
						                     asynchronous: async});
	},
	
	doFormSubmit: function(formname, url, params, mainSlot, async) {

		if (async == null) {
			async = 'true';
		}
		
		im = document.getElementById('wawcog');
		if (im != null) {
			oldcog = im.src;
			im.src = oldcog;
		}

		// handle url
		url = url + '?waw_main_output=' + mainSlot;
		
		// Get params 
		var form = document.getElementById(formname);
		url = url + "&" + Form.serialize(form);
		// concat cs to params
		params += '&' + cs;

		// make request
		var myAjax = new Ajax.Request(url, { method: 'get', 
						                     parameters: params, 
						                     onComplete: this.viewsReload,
						                     asynchronous: async});
	},
	
	/** Reloads the views. */
	viewsReload: function(xr) {
		// enter critical section (to avoid history tracking)
		ws.processing = true;

		// get xml response
		xml = xr.responseXML;
		xmlDoc = xml.documentElement;
		
		// javascripts updates 
		updates = xmlDoc.getElementsByTagName("script-update");
		for (i=0; i<updates.length; i++) {
			/** Don't ever try to rename this variable to its
			    more convenient name 'item' because it will
			    crash IE !! */
			myitem = updates.item(i);
			script_src = myitem.attributes.getNamedItem('src').nodeValue;
			if (!ws.hasScript(script_src)) {
				var html_doc = document.getElementsByTagName('head').item(0);
			    var js = document.createElement('script');
			    js.setAttribute('language', 'javascript');
			    js.setAttribute('type', 'text/javascript');
			    js.setAttribute('src', script_src);
			    html_doc.appendChild(js);
			}
		}
		
		// css updates 
		updates = xmlDoc.getElementsByTagName("css-update");
		for (i=0; i<updates.length; i++) {
			/** Don't ever try to rename this variable to its
			    more convenient name 'item' because it will
			    crash IE !! */
			myitem = updates.item(i);
			css_href = myitem.attributes.getNamedItem('href').nodeValue;
			
			if (!ws.hasStylesheet(css_href)) {
				// for IE
				if (document.createStyleSheet) {
					document.createStyleSheet(css_href);
				} 
				
				// for FF
				else {
					newSS = document.createElement('link');
					newSS.rel = 'stylesheet';
					newSS.type = 'text/css';
					newSS.href = css_href;
					document.getElementsByTagName("head")[0].appendChild(newSS);
				}
			}
		}
		
		// view updates
		updates = xmlDoc.getElementsByTagName("view-update");
		for (i=0; i<updates.length; i++) {
			myitem = updates.item(i);
			div = myitem.attributes.getNamedItem('div').nodeValue;
			container = document.getElementById(div);
			if (container != null) {
				container.style.visibilty = false;
				container.innerHTML = myitem.childNodes[0].data;
				var scripts = container.getElementsByTagName("script");
				if (scripts) {
					for (j=0; j<scripts.length; j++) {
						eval(scripts[j].innerHTML);
					}
				}
				container.style.visibilty = true;
			}
		}

		// new client session
		cs = xmlDoc.getElementsByTagName("client-session").item(0).childNodes[0].data;
		window.location.hash = cs;
		
		// Save the history in the hidden frame...
		if (isInternetExplorer()) {
			document.getElementById('wawFrameHistory').src = "history.htm?"+cs+"#"+cs;
		}
		
		// cog not running now
		im = document.getElementById('wawcog');
		if (im != null) {
			im.src = oldcog;
		}
		
		// affect hash and leave critical section
		ws.lastHash = window.location.hash;
		ws.processing = false;		
		
		enableTooltips();
	},
	
	hasStylesheet: function(href) {
		links = document.getElementsByTagName("head")[0].getElementsByTagName('link');
		for (j=0; j<links.length; j++) {
			myitem = links.item(j);
			ihref = myitem.attributes.getNamedItem('href').nodeValue;
			if (ihref == href) {
				return true;
			}
		}
		return false;
	},
	
	hasScript: function(src) {
		scripts = document.getElementsByTagName("head")[0].getElementsByTagName('script');
		for (j=0; j<scripts.length; j++) {
			myitem = scripts.item(j);
			isrc = myitem.attributes.getNamedItem('src').nodeValue;
			if (isrc == src) {
				return true;
			}
		}
		return false;
	},
	
	failure: function(xr) {
		alert("unknown failure");
	},
	
	showPopup: function(who, view) {
		where = view.replace(':','__');
		where = where.replace('.','_');
		popups = document.getElementById('waw_main__popups');
		if (popups == null) {
			return;
		}
	
		container = document.getElementById(where);
		if (container == null) {
			container = document.createElement("div");
			container.id = where;
			popups.appendChild(container);
			
			// update position
			pos = this.findPos(who);
			container.style.position = 'absolute';
			container.style.left = pos[0] + 'px';
			container.style.top = (pos[1]+20) + 'px';

			this.reloadView(view);
		} else {
			popups.removeChild(container);
		}
	},
	
	findPos: function(obj) {
		var curleft = curtop = 0;
		if (obj.offsetParent) {
			curleft = obj.offsetLeft
			curtop = obj.offsetTop
			while (obj = obj.offsetParent) {
				curleft += obj.offsetLeft
				curtop += obj.offsetTop
			}
		}
		return [curleft,curtop];
	}	
	
};


