/*
 *  This file is part of WebSiCo: online Web Site Composer, http://websico.net
 *  Copyright (c) 2005-2011 Olivier Seston, http://seston.net
 *	All rights reserved.
 *  --------------------------------------------------------------------------
 *	GLOBAL OPERATIONS IN ANY MODE
 *  ---------------------------------------
 */

//	Globals set by bodystart.php
//	----------------------------
var ws_mode;

//	Add event listener kind of compatibility for old browsers, not only IE
//  Probably buggy, should be revisited.....
//	----------------------------------------------------------------------
if (!window.addEventListener) {
    function addEventListener(event_name, handler, capture) {
    	var old_handler = this['on' + event_name] ? this['on' + event_name] : function(){};
    	this['on' + event_name] = function() {old_handler(); return handler();};
    }
}

//  If I'm in an info window, I become suicidal when my parent dies..
//  -----------------------------------------------------------------
if (self.name == 'ws_info_window')
    setInterval("if (!self.opener || self.opener.closed) self.close()", 500);

//	An ugly attempt to fix containers height:
//	We are in a flexible (horizontal and vertical) layout made of an undefined
//	of imbricated rows and columns in an undefined depth arrangement.
//	We'd like each container would get 100% height of it's container, with a
//	controlled repartion of space for it's contents.
//  The css flexible box model would be a solution (in theory), when it'll be
//  really specified and widely implemented, which is not the case for now (2012).
//  So we use a table model (implemented in html table for old browsers and in css
//	for modern ones) and even with that we encounter issues and limitations
//	(relative height computing of table rows by a certain browser, you can guess
//	which one, including version 8).
//	Issues coming from different behaviours of different browsers
//	and from margins, borders and paddings do not facilitate the job.
//  So it's more secure to hard fix here...
//  Some parts of code are only for browsers that don't like css display: table
//	---------------------------------------------------------------------------
var ws_containerList = new Array();				// Setup by Display() of each container
var ws_rTout = 0;
window.addEventListener("load", ws_computeLayout, false);
window.addEventListener("resize", function(){
							clearTimeout(ws_rTout);
							ws_rTout = setTimeout("ws_computeLayout(true)", 10); // Not too often
						}, false);

function ws_computeLayout(withReset) {
	// Loops start from the first container contained by page
	// Page is the last one in the list
	if (withReset) {
		// First we reset height of involved containers (useful when resizing window)
		for (var i = ws_containerList.length-2; i >= 0; i--) {
			var elt = ws_containerList[i];
			elt.style.height = '';
			// ***** All that stuff should be forgotten when IE7- is dead
			if (WS_HTML_TABLED){
			    for (wrapper = elt.firstChild; wrapper; wrapper = wrapper.nextSibling){
			        if (wrapper.className
							&& wrapper.className.indexOf('stretchWrapper') != -1){
			            wrapper.style.height = '';
					}
				}
			}
		}
		if (WS_HTML_TABLED) {
		    var tds = document.getElementById('firstContainer').getElementsByTagName('TD');
		    for (var j = 0; tds[j]; j++) {  // Don't remember why it's useful...
		        tds[j].height = '';
			}
		}
			// *****
	}
	//  Then we fix them
	var ws_alpha_part = new RegExp(/[^0-9.\-]+.*/);
	ws_fixTable(document.getElementById('firstContainer')); // ***** IE7-
	for (var i = ws_containerList.length-2; i >= 0; i--) {
		var elt = ws_containerList[i];

		// The system container case
		// If alone in its cell, it's heighted like its parent
		if (elt.ws_props & WS_SYSTEM_CONTAINER && elt.ws_props & WS_ALONE) {
			var newHeight = elt.ws_owner.offsetHeight;		// Don't use clientHeight because of IE7-
			var computedStyle;
			if (!(elt.ws_owner.ws_props & WS_SYSTEM_CONTAINER)) {
				computedStyle = elt.ws_owner.currentStyle || window.getComputedStyle(elt.ws_owner, null);
				newHeight -= computedStyle.borderTopWidth.replace(ws_alpha_part, '') * 1
							+ computedStyle.borderBottomWidth.replace(ws_alpha_part, '') * 1
							+ computedStyle.paddingTop.replace(ws_alpha_part, '') * 1
							+ computedStyle.paddingBottom.replace(ws_alpha_part, '') * 1;
			} else {
			    // Fix parent cell height, otherwise it might grow (in a vertical container)
				elt.ws_owner.style.height = elt.ws_owner.offsetHeight + 'px';
			}
			elt.style.height = newHeight + 'px';
		    // ***** All that stuff should be forgotten when IE7- is dead
		    if (WS_HTML_TABLED && elt.tagName == 'TABLE'){
				ws_fixTable(elt);
			}
			// *****
		}

		// The stretched user container case
		else if (!(elt.ws_props & WS_SYSTEM_CONTAINER) && elt.ws_props & WS_VALIGN) {
		    elt.offsetParent.style.verticalAlign = 'top';   // To squeeze top space
			var lastSibling = document.getElementById(elt.ws_owner.ws_lastContentId);
			var computedStyle = lastSibling.currentStyle || window.getComputedStyle(lastSibling, null);
			var lastSiblingBottom = findPosY(lastSibling) + lastSibling.offsetHeight
									+ computedStyle.marginBottom.replace(ws_alpha_part, '') * 1;
			computedStyle = elt.ws_owner.currentStyle || window.getComputedStyle(elt.ws_owner, null);
			var ownerInnerBottom = findPosY(elt.ws_owner) + elt.ws_owner.offsetHeight
								- computedStyle.paddingBottom.replace(ws_alpha_part, '') * 1
								- computedStyle.borderBottomWidth.replace(ws_alpha_part, '') * 1;
			if (lastSiblingBottom < ownerInnerBottom || ws_mode & WS_EDIT) {
			    // If there is available room we wrap the block contents
				// in a valignable html block, unless valign is top and mode is visitor
				if (!elt.ws_outerWrapper && (!(elt.ws_props & WS_VALIGN_T) || ws_mode & WS_EDIT)) {
					var insideClass = elt.ws_props & WS_VALIGN_T ? "top" :
					                    elt.ws_props & WS_VALIGN_M ? "middle" : "bottom";
					if (WS_HTML_TABLED) {    // Should disappear with IE7-
					    var outerWrapper = document.createElement('table');
					    var innerWrapper = document.createElement('td');
						outerWrapper.appendChild(document.createElement('tbody'));
						outerWrapper.firstChild.appendChild(document.createElement('tr'));
						outerWrapper.firstChild.firstChild.appendChild(innerWrapper);
					} else {
					    var outerWrapper = document.createElement('div');
					    var innerWrapper = document.createElement('div');
						outerWrapper.appendChild(innerWrapper);
					}
				    outerWrapper.className = "stretchWrapper";
				    innerWrapper.className = insideClass;
				    while (e = elt.firstChild) {
						innerWrapper.appendChild(e);
					}
					elt.appendChild(outerWrapper);
					elt.ws_innerWrapper = innerWrapper;
					elt.ws_outerWrapper = outerWrapper;
				}
				computedStyle = elt.currentStyle || window.getComputedStyle(elt, null);
				var newHeight = elt.offsetHeight		// Don't use clientHeight because of IE7-
								- computedStyle.borderTopWidth.replace(ws_alpha_part, '') * 1
								- computedStyle.borderBottomWidth.replace(ws_alpha_part, '') * 1
								- computedStyle.paddingTop.replace(ws_alpha_part, '') * 1
								- computedStyle.paddingBottom.replace(ws_alpha_part, '') * 1
								+ ownerInnerBottom - lastSiblingBottom;
				if (elt.ws_owner.ws_props & WS_SYSTEM_CONTAINER) {
					// Fix parent cell height, otherwise it might grow (in a vertical container)
					elt.ws_owner.style.height = elt.ws_owner.offsetHeight + 'px';
				}
				elt.style.height = newHeight + 'px';
			    // ***** All that stuff should be forgotten when IE7- is dead
			    if (WS_HTML_TABLED){
				    for (wrapper = elt.firstChild; wrapper; wrapper = wrapper.nextSibling){
				        if (wrapper.className
								&& wrapper.className.indexOf('stretchWrapper') != -1){
				            wrapper.style.height = elt.style.height;
						}
					}
				}
				// ****
			}
		}
	}
	// In case of edition mode
	if (window.ws_computeCellLimits)
		ws_computeCellLimits();
	if (window.ws_selectedElement)
	    ws_highlightElement();
}
function ws_fixTable(elt){
	// If tabled layout (IE7-) we have to fix
	// all tds before resizing their contents...
    var tds = elt.getElementsByTagName('TD');
    var heights = [];
    for (var j = 0; tds[j]; j++) {  // get heights before resizing any td
        heights[j] = tds[j].offsetHeight;
	}
    for (var j = 0; tds[j]; j++) {
        var parent = tds[j].parentNode;
		while (parent = parent.parentNode) {
		    if (parent.tagName == 'TABLE') {
		        if (parent == elt)
			        tds[j].style.height = heights[j] + 'px';
		        break;
			}
		}
	}
}

//	Special command keys (mode switch, gallery control, ...)
//  Use bestial method to be sure with all browsers.
//	--------------------------------------------------------
document.onkeydown =
	function(event) {
		var event = window.event || event;
        var target = event.target || event.srcElement;

		if (ws_gallery && ws_gallery.active >= 0) { // Gallery keydowns in general handler, beuark..
		    if (event.keyCode == 27) {									// ESC
		    	ws_gallery.hide();
			} else if (event.keyCode == 39 || event.keyCode == 32) {	// Right arrow or space bar
				ws_gallery.show(ws_gallery.active + 1);
			} else if (event.keyCode == 37) {							// Left arrow
				ws_gallery.show(ws_gallery.active - 1);
            }
        } else if (event.keyCode == 123 && event.altKey && event.shiftKey) {	// ALT + SHIFT + F12
        	ws_reloadRequest({mode: (ws_mode == WS_DEBUG ? 0 : WS_DEBUG)});
        } else if (event.keyCode == 123 && event.altKey && !ws_dont_explore) {	// ALT + F12
			ws_reloadRequest({mode: (ws_mode == WS_EXPLORE ? 0 : WS_EXPLORE)});
        } else if (event.keyCode == 123 && event.shiftKey) {					// SHIFT + F12
        	ws_reloadRequest({mode: (ws_mode == WS_PREVIEW ? 0 : WS_PREVIEW)});
        } else if (event.keyCode == 123) {                                      // F12
          	ws_reloadRequest({mode: (ws_mode == WS_EDIT ? 0 : WS_EDIT)});
	    } else if (window.ws_cancelAction && event.keyCode == 27) {				// ESC
            ws_cancelAction();
        } else if (window.ws_validateAction && (event.metaKey || event.ctrlKey) && event.keyCode == 83) { // CTRL + S
            ws_validateAction();
		} else if (window.ws_validateAction && event.keyCode == 13 && target.tagName == "INPUT") { // ENTER
            ws_validateAction();
        } else {
			return true;
		}
        return false;
	};
function ws_onclick_badge(event) {
	if (!event.ctrlKey) {
		if (event.altKey && event.shiftKey)
			ws_reloadRequest({mode: (ws_mode == WS_DEBUG ? 0 : WS_DEBUG)});
	    else if (event.altKey)
	        if (!ws_dont_explore)
	            ws_reloadRequest({mode: (ws_mode == WS_EXPLORE ? 0 : WS_EXPLORE)});
	        else
	            return false;
		else if (event.shiftKey)
			ws_reloadRequest({mode: (ws_mode == WS_PREVIEW ? 0 : WS_PREVIEW)});
		else
			ws_reloadRequest({mode: (ws_mode == WS_EDIT ? 0 : WS_EDIT)});
		event.cancelBubble = true;
		return false;
	}
}

/*  GALLERY MANAGEMENT
 *  ------------------*/
var ws_gallery;		// Global gallery object
// Now gallery object is built onmouseover of thumbnail image, this is to avoid waiting for
// all thumbnail images load in main page
window.addEventListener("load", function(){ws_gallery = new ws_Gallery()}, false);

function ws_Gallery(){
	this.active = -1;
	this.movie = 0;
	this.moviePeriod = 2500;							// In millisecond unit
	this.controlImg = document.createElement('img');	// To load it in cache
	this.controlImg.src = WS_CORE_PATH + 'ws_images/ws_gallery_control.gif';
	this.movieOnImg = document.createElement('img');	// To load it in cache
	this.movieOnImg.src = WS_CORE_PATH + 'ws_images/ws_movie_on.gif';
	this.goodBrowserResize = navigator.userAgent.indexOf('Safari') != -1 ||
                                navigator.userAgent.indexOf('Opera') != -1; // Simply the best

	// Build table of images and set onclick callbacks
	this.images = [];
	var links = document.getElementsByTagName('a');
	for (var i = 0, j = 0; i < links.length; i++) {	// Images encapsulated in a link of class "zoomable"
		if (links[i].firstChild && links[i].firstChild.tagName == 'IMG' && links[i].className.indexOf("zoomable") != -1) {
			var a = links[i];
			var img = a.firstChild;
			this.images[j] = {
				thumbNail: img,    
				path: a.href,
				width: img.width,
				height: img.height,
				img: document.createElement('img'),
				loaded_path: 0,
				requested_path: 0,
				progressImg: document.createElement('img')	// Each one has it's own progress bar (this is because of concurrence issues)
			};
			this.images[j].progressImg.className = "progressBar";
			this.images[j].progressImg.src = WS_CORE_PATH + 'ws_images/ws_progress.gif';
			this.images[j].img.ws_galleryIndex = j;
			var caption = links[i].parentNode.getElementsByTagName('div');
			for (var k = 0; caption[k]; k++){
			    if (caption[k].className == 'ws_img_caption') {
					this.images[j].caption = caption[k].innerHTML;
					break;
				}
			}
			a.ws_gIndex = j++;
			a.onclick = function(event){
							event = window.event || event;
							if (ws_mode & WS_EDIT) ws_cancelAction();
							ws_gallery.show(this.ws_gIndex);
							event.cancelBubble = true;
							return false};
			a.onmousedown = function(event){return false};
			img.onmouseover = function(){ws_gallery.loadImage(this.parentNode.ws_gIndex); return false};
		}
	}

	// Build DOM elements
	if (this.images.length) {

		// Gallery image
		this.gallery = document.createElement('div');
		this.gallery.onmouseover = function() {
			clearTimeout(this.ws_hideControl);
			ws_gallery.control.style.visibility = 'visible';
			this.ws_hideControl = setTimeout("ws_gallery.control.style.visibility='hidden';", 3000);
			};
		this.gallery.appendChild(document.createElement('div'));	// Just to build a first child, will be replaced by progressBar
		this.caption = this.gallery.appendChild(document.createElement('div'));
		this.caption.className = "caption";
		this.img = this.gallery.appendChild(document.createElement('img'));
		this.img.className = "image";
		this.img.onclick = function(){ws_gallery.hide()};

		// Control bar
		this.control = this.gallery.appendChild(document.createElement('div'));
		this.control.className = "control";
		this.counter = this.control.appendChild(document.createElement('div'));
		this.counter.className = "counter";
		this.controlMapImg = this.control.appendChild(document.createElement('img'));
		this.controlMapImg.src = this.controlImg.src;
		this.controlMapImg.useMap = "#controlMap";
		this.control.onmouseover = function(event) {
			event = window.event || event;
			clearTimeout(this.parentNode.ws_hideControl);
			event.cancelBubble = true;
			return false};
		var map = this.control.appendChild(document.createElement('map'));
		map.id = "controlMap";
		map.name = "controlMap";
		map.innerHTML = '\
			<area href="javascript:ws_gallery.show(ws_gallery.active + 1)" coords="0,5,30,25" />\
			<area href="javascript:ws_gallery.show(ws_gallery.active -1)" coords="0,28,30,48" />\
			<area href="javascript:ws_gallery.movieControl()" coords="0,60,30,80" />\
			<area href="javascript:ws_gallery.setMoviePeriod(ws_gallery.moviePeriod/2 - 1)" coords="0,80,30,92" />\
			<area href="javascript:ws_gallery.setMoviePeriod(ws_gallery.moviePeriod*2 + 1)" coords="0,92,30,105" />\
			<area href="javascript:ws_gallery.hide()" coords="0,130,30,160" />\
			';

		// Add event handlers
		// Keydown is in general keydown handler
		window.addEventListener("resize", function(){ws_gallery.resize()}, false);
		this.resize();	// To set initial size
	}
}

ws_Gallery.prototype.show = function(i) {
	i = (i < 0) ? this.images.length - 1 : (i >= this.images.length) ? 0 : i;

	// Progress bar
	this.gallery.replaceChild(this.images[i].progressImg, this.gallery.firstChild);
	this.gallery.firstChild.style.left = (ws_getInnerWidth() - this.gallery.firstChild.width) / 2 + 'px';
	this.active = i;

	// Caption and counter
	if (this.images[i].caption) {
		this.caption.innerHTML = this.images[i].caption;
		this.caption.style.display = '';
	} else {
		this.caption.style.display = 'none';
	}
	this.counter.innerHTML = (i+1) + '/' + this.images.length;

	// Image
	var ratio = Math.min(this.width / this.images[i].width, this.height / this.images[i].height);
	var width = this.images[i].width * ratio;
	var height = this.images[i].height * ratio;
	this.img.style.width = width + 'px';
	this.img.style.height = height + 'px';
	this.img.style.marginTop = (ws_getInnerHeight() - height) / 2 + 'px';
	this.img.src = this.images[i].loaded_path || this.images[i].thumbNail.src;
	this.loadImage(i);
	this.loadImage(i + 1);
	this.loadImage(i - 1);

	// Page obfuscation must happen after scroll savings
	document.body.appendChild(this.gallery);
	var page = document.getElementById('outerContainer');
	if ((pageToolBar = document.getElementById('ws_pageToolbar'))) {
		pageToolBar.style.display = 'none';
		page = page.parentNode;
	}
	if (!page.style.display.length) {
		this.savedScrollX = ws_getScrollX();
		this.savedScrollY = ws_getScrollY();
	}
	page.style.display = 'none';
	document.body.className = 'gallery';
	window.scroll(0, 0);
};

ws_Gallery.prototype.loadImage = function(i) {		// Load images
	i = (i < 0) ? this.images.length - 1 : (i >= this.images.length) ? 0 : i;
	var gImg = this.images[i];

	// For some browsers it's really better to size image with the help of a server php
	var imagePath = this.goodBrowserResize ? gImg.path
        : WS_CORE_PATH + "ws_buildimage.php?url=" + gImg.path + "&height=" + this.height + "&width=" + this.width;
	if (imagePath != gImg.requested_path) {	// Some acrobatics because .src is modified by browser
		gImg.requested_path = imagePath;
		gImg.img.ws_galleryIndex = i;
		gImg.progressImg.style.visibility = 'visible';
		gImg.img.onload = function() {
			var gImg = ws_gallery.images[this.ws_galleryIndex];
			gImg.loaded_path = gImg.requested_path;
			gImg.progressImg.style.visibility = 'hidden';
			if (ws_gallery.active == this.ws_galleryIndex) {
				ws_gallery.img.src = this.src;
				// To avoid FF & IE little resizing caused by border
            	ws_gallery.img.style.width = '';
            	ws_gallery.img.style.height = '';
            }
			};
		gImg.img.src = gImg.requested_path;
	}
};

ws_Gallery.prototype.resize = function() {			// Resize window
	this.width = ws_getInnerWidth() - 40;
	this.height = ws_getInnerHeight() - 40;
//	this.progressBar.style.left = (ws_getInnerWidth() - this.progressBar.width) / 2 + 'px';
	if ((i = this.active) >= 0)
		this.show(i);
};

ws_Gallery.prototype.hide = function hide() {		// Hide gallery
	if (this.active >= 0) {
	    var page = document.getElementById('outerContainer');
		if ((pageToolBar = document.getElementById('ws_pageToolbar'))) {
			pageToolBar.style.display = '';
			page = page.parentNode;
		}
		document.body.className = '';
		document.body.removeChild(this.gallery);
        // The display reset must be after removeChild (for IE8, probably a sequencing issue)
		page.style.display = '';
		document.body.focus();	// To clear blinking cursor with FF (!?)
		clearTimeout(this.gallery.ws_hideControl);
		this.movieControl(0);
		this.active = -1;
		// Very strange but the scroll must be at the end,
        // otherwise at best it's not done and at worst the gallery is not hidden (IE8)
		window.scroll(this.savedScrollX, this.savedScrollY);
	}
};

ws_Gallery.prototype.movieControl = function(action) {
	this.movie = arguments.length ? action : !this.movie;
	clearInterval(this.movieTimer);
	if (this.movie) {
		this.controlMapImg.src = this.movieOnImg.src;
		this.movieTimer = setInterval("ws_gallery.show(ws_gallery.active + 1);", this.moviePeriod);
	} else {
		this.controlMapImg.src = this.controlImg.src;
	}
};

ws_Gallery.prototype.setMoviePeriod = function(period) {
	if (this.movie) {
		this.moviePeriod = period;
		if (this.moviePeriod < 0) this.moviePeriod = 0;
		this.movieControl(1);
	}
};

//	MENU SHOW/HIDE
//	--------------
function ws_showMenu(menuId) {
	var menu = document.getElementById(menuId);
	var parentItem = menu.parentNode;
	if (menu && !menu.ws_active) {
		menu.ws_active = true;
		menu.style.display = 'block';			// When hidden display is set to 'none', to disapear from layout
		menu.style.fontSize = '100%';			// To keep font-size same as parent
		if (!menu.ws_displayed) {
			parentItem.appendChild(menu);	// This is to display over parent (works with IE, in place of z-index..)
			var parentX = parentItem.offsetLeft + findPosX(parentItem.offsetParent) - findPosX(menu.offsetParent);
			var parentY = parentItem.offsetTop +  findPosY(parentItem.offsetParent) - findPosY(menu.offsetParent);
			parentItem.getElementsByTagName('a')[0].className += ' hover';
			menu.style.margin = 0;				// To be close to parent
			// Try normal position
			if (parentItem.parentNode.className == "horizontal") {
				menu.style.top = '';
				menu.style.left = '';
				menu.style.minWidth = parentItem.offsetWidth + 'px';
				if (findPosX(menu) + menu.offsetWidth > ws_getInnerWidth() + ws_getScrollX())
					menu.style.left = parentX - (menu.offsetWidth - parentItem.offsetWidth) + 10 + 'px';
			} else {
				menu.style.top = parentY + 'px';
				menu.style.left = parentX + parentItem.offsetWidth - 10 + 'px';
				if (findPosX(menu) + menu.offsetWidth > ws_getInnerWidth() + ws_getScrollX())
					menu.style.left = parentX - menu.offsetWidth + 10 + 'px';
			}
			// Adjust position in case of overflow
			if ((overflow = findPosY(menu) + menu.offsetHeight - (ws_getInnerHeight() + ws_getScrollY())) > 0)
				menu.style.top = parentY - overflow + 'px';
			if (findPosY(menu) < ws_getScrollY())
				menu.style.top = ws_getScrollY() - findPosY(menu.offsetParent) + 'px';
			if (findPosX(menu) < ws_getScrollX())
				menu.style.left = ws_getScrollX() - findPosX(menu.offsetParent) + 'px';
		}
		menu.ws_displayed = true;
		ws_overPopup = 1;						// To hide some maintenance targets
	}
}
function ws_hideMenu(menuId) {
	var menu = document.getElementById(menuId);
	if (menu && menu.ws_active) {
		menu.ws_active = false;
		setTimeout("\
			var menu=document.getElementById('" + menuId + "');\
			if (!menu.ws_active){\
				menu.style.display = 'none';\
				ws_overPopup = 0;\
				var parentA = menu.parentNode.getElementsByTagName('a')[0];
				parentA.className = parentA.className.replace(' hover', '');\
				menu.ws_displayed = false;\
			}", 100);
	}
}

//	USER SELECTION
//	--------------
function ws_userSelect(objectId, check) {
	var cdata = '';
	if (document.cookie.search('wsc_selected=') != -1) {
		cdata = document.cookie.replace(/.*wsc_selected=([^;]*).*/, '$1');
	  	cdata = cdata.replace(objectId, '');
	  	cdata = cdata.replace(/^,*/, '');
	  	cdata = cdata.replace(/(,*)$/, '');
	  	cdata = cdata.replace(/,,*/g, ',');
	}
	if (check) {
	  	if (cdata.length) cdata += ',';
	  	cdata += objectId;
	}
	d = new Date(new Date().getTime() + 30*24*3600*1000).toGMTString();
	document.cookie = 'wsc_selected=' + cdata + '; expires=' + d;
}

//	FIND ABSOLUTE COORDINATES OF AN OBJECT
//	--------------------------------------
//	Thanks to Peter-Paul Koch, www.quirksmode.org
//	---------------------------------------------
function findPosX(obj) {
	var curleft = 0;
	if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
        } while (obj = obj.offsetParent);
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}
function findPosY(obj) {
	var curtop = 0;
	if (obj.offsetParent) {
        do {
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

//	FIND WINDOW VALUES
//	------------------
//	Thanks to Peter-Paul Koch, www.quirksmode.org
//	---------------------------------------------
function ws_getScrollX() {
	if (window.pageXOffset)
		return window.pageXOffset;
	else if (document.documentElement && document.documentElement.scrollLeft)
		return document.documentElement.scrollLeft;
	else
	  	return document.body.scrollLeft;
}
function ws_getScrollY() {
	if (window.pageYOffset)
		return window.pageYOffset;
	else if (document.documentElement && document.documentElement.scrollTop)
		return document.documentElement.scrollTop;
	else
	  	return document.body.scrollTop;
}
function ws_getInnerWidth() {
	if (window.innerWidth)
		return window.innerWidth;
	else if (document.documentElement && document.documentElement.clientWidth)
		return document.documentElement.clientWidth;
	else
		return document.body.clientWidth;
}
function ws_getInnerHeight() {
	if (window.innerHeight)
		return window.innerHeight;
	else if (document.documentElement && document.documentElement.clientHeight)
		return document.documentElement.clientHeight;
	else
		return document.body.clientHeight;
}
function ws_getDocumentWidth() {
  	if (window.scrollMaxX)				// FF
  		return ws_getInnerWidth() + window.scrollMaxX;
  	else
  		return document.body.scrollWidth;
}
function ws_getDocumentHeight() {
  	if (window.scrollMaxY)				// FF
  		return ws_getInnerHeight() + window.scrollMaxY;
  	else
  		return document.body.scrollHeight;
}

//	SET HTML ELEMENT OPACITY
//	------------------------
//	Not too many opacity manip with IE because of well known font anti-aliasing issue:
//	anti-aliasing fall back in 'standard' even if 'cleartype' is used on the user os,
//	with surprising bad visual effect in some cases.
//	So we must use it with (great) care...,
//	so great care that it's sometimes not called for IE :)
//	----------------------------------------------------------------------------------
function ws_setOpacity(element, opacity) {
	element.style.zoom = 1;		// Element must have layout to take filter in account (IE specific..)
	element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity*100 + ')';
	element.style.opacity = opacity;
}

//	MISC UTILS
//	----------

//	String manipulation
//	-------------------
function ws_bsn2nl(s) {
	return s.replace(/\\n/g, "\n");
}

//  Setup some element members
//  --------------------------
function ws_setupElement(id, properties, ownerId, lastContentId) {
    if (elt = document.getElementById(id)) {
        properties & WS_CONTAINER ? ws_containerList.push(elt) : ws_componentList.push(elt);
    	elt.ws_props = properties;
    	elt.ws_owner = document.getElementById(ownerId);
    	elt.ws_lastContentId = lastContentId || 0;
    }
}

//	Reload actual page with query variables
//	---------------------------------------
function ws_reloadRequest(variables) {
    var sep = "?";
	for (var i in variables) {
		str = new String(location.href);
		if (location.search) {
			var match = str.match(new RegExp('([?&])' + i + '=[^&#]*'));
		    if (match) {
	        	str = str.replace(match[0], match[1] + i + "=" + variables[i]);
	        	if (str.indexOf('?') == -1 && str.indexOf('&') != -1)
	        		str = str.replace(/(^[^&]+)&/, '$1?');
			} else {
		        str += "&" + i + "=" + variables[i];
			}
		} else if (location.hash) {
		        str = str.replace("#", "?" + i + "=" + variables[i] + "#");
		} else {
			str += sep + i + "=" + variables[i];
			sep = "&";
		}
	}
	location.href = str;
}

//	Mail address decode for mailto link
//	-----------------------------------
function Disp(str, obj) {
	var res = "";
	for(var i = 0; i < str.length; i++)
			res += String.fromCharCode(str.charCodeAt(i) + i%4 - 1);
	if (obj)
    	obj.href = 'mailto:' + res;
    return res;
}

//	Open miniWindow
//	---------------
var ws_miniWindow = 0;
function miniWindow(url, width, height) {
  	if (ws_miniWindow)
  		ws_miniWindow.close();	// To be recreated on top
  	if (!width) width = 100;
  	if (!height) height = 100;
	ws_miniWindow = open(url,'miniWindow','resizable, scrollbars, width=' + width + ', height=' + height);
}

//	Smoothly adjust window size to fit it's content
//	-----------------------------------------------
function adjustWindowSize(startWidth, startHeight, w) {
	if (!w) w = window;
	w.resizeTo(startWidth ? startWidth : 110, startHeight ? startHeight : 110);
	w.scrollTo(1000,1000);
	w.focus();
	var delta = 16;
    // Move the window during growth to avoid IE loop
	// when on screen bottom or right limit
	// Incidently, not so bad visual effect !
	var step = w.document.documentElement.scrollLeft / 5;
	while(w.document.documentElement.scrollLeft) {	// Begin by width to be sure to get the height without hscroller height
		w.moveBy(-delta, 0);
		w.resizeBy(step, 0);
		w.moveBy(delta + 1, 0);
	}
	var step = w.document.documentElement.scrollTop / 5;
	while(w.document.documentElement.scrollTop) {
		w.moveBy(0, -delta);
		w.resizeBy(0, step);
		w.moveBy(0, delta + 1);
	}
/*
	while(document.documentElement.scrollLeft || document.documentElement.scrollTop) {
		moveBy(-delta, -delta);
		resizeBy((document.documentElement.scrollLeft ? 32 : 0), (document.documentElement.scrollTop ? 32 : 0));
		moveBy(delta + 1, delta + 1);
	}
*/
}

//  OPEN INFO WINDOW
//  ----------------
var ws_infoWindow = 0;
var WS_INFO_SERVER = 'http:/' + '/doc.websico.com';      // Url to find online doc (splitted for compressor)

function ws_openInfo(pageName, anchor) {
    var windowRight = (window.screenX + window.outerWidth) || (window.screenLeft + document.documentElement.clientWidth);
    if (!ws_infoWindow || ws_infoWindow.closed) {
        var windowFeatures = window.screenY ? 'top=' + window.screenY : '';
        windowFeatures += ', left=' + windowRight;
        windowFeatures += ', scrollbars=yes, resizable=yes, location=yes, toolbar=yes';
        windowFeatures += ', width=470';    // Necessary for IE to position the window ?!
        ws_infoWindow = open('', 'ws_info_window', windowFeatures);
		ws_infoWindow.resizeTo(470, window.screen.height * 3/4);   // To work with every browser
    }
    anchor = anchor || 'info';
    ws_infoWindow.location.href = WS_INFO_SERVER + '/' + ws_lang + '/' + pageName + '.html#' + anchor;
    ws_infoWindow.focus();
}

/*
CSS Browser Selector v0.4.0 (Nov 02, 2010)
Rafael Lima (http://rafael.adm.br)
http://rafael.adm.br/css_browser_selector
License: http://creativecommons.org/licenses/by/2.5/
Contributors: http://rafael.adm.br/css_browser_selector#contributors
*/
function css_browser_selector(u){var ua=u.toLowerCase(),is=function(t){return ua.indexOf(t)>-1},g="gecko",w="webkit",s="safari",o="opera",m="mobile",h=document.documentElement,b=[(!(/opera|webtv/i.test(ua))&&/msie\s(\d)/.test(ua))?("ie ie"+RegExp.$1):is("firefox/2")?g+" ff2":is("firefox/3.5")?g+" ff3 ff3_5":is("firefox/3.6")?g+" ff3 ff3_6":is("firefox/3")?g+" ff3":is("gecko/")?g:is("opera")?o+(/version\/(\d+)/.test(ua)?" "+o+RegExp.$1:(/opera(\s|\/)(\d+)/.test(ua)?" "+o+RegExp.$2:"")):is("konqueror")?"konqueror":is("blackberry")?m+" blackberry":is("android")?m+" android":is("chrome")?w+" chrome":is("iron")?w+" iron":is("applewebkit/")?w+" "+s+(/version\/(\d+)/.test(ua)?" "+s+RegExp.$1:""):is("mozilla/")?g:"",is("j2me")?m+" j2me":is("iphone")?m+" iphone":is("ipod")?m+" ipod":is("ipad")?m+" ipad":is("mac")?"mac":is("darwin")?"mac":is("webtv")?"webtv":is("win")?"win"+(is("windows nt 6.0")?" vista":""):is("freebsd")?"freebsd":(is("x11")||is("linux"))?"linux":"","js"]; c = b.join(" "); c=c.toUpperCase();h.className += " "+c; return c;}; css_browser_selector(navigator.userAgent);

