/* DWUI (Dexdo Web User Interface)
 * (C) 2008-2009 Jonathan Dextraze
 * Web: http://www.dexdo.com/dwui
 * Last update: June 24, 2009 14:47
 * Requires Prototype JavaScript framework version 1.6.1+ and Scriptaculous Effects v1.8.2
 */

if (typeof Prototype == 'undefined' || !Prototype.Version.match("1.6.1"))
	throw "DWUI require Prototype library >= 1.6.1";

if (typeof Effect == 'undefined')
	throw "DWUI require Scriptaculous Effect";

(function () {
// Configurations
	var idPage		= 'page',
		idLoading	= 'loading',
		idContent	= 'content',
		startPage	= 'news',
		pageHeader	= null,
		pageFooter	= null,
		ajaxPrefix	= 'pages/',
		ajaxSuffix	= '.html',
		imagesPath	= 'images/',
		imagesExt	= '.gif',
		menuIDs		= [],
		imageList	= [],
		errorPage	= 'Une erreur imprévue est survenue. Veuillez réessayer de nouveau.<br>Si cette erreur persiste, veuillez en aviser le webmestre.',
// Variables
		oLoading		= null,
		oContent		= null,
		iTimer			= null,
		imagesMenu		= null,
		preloadedImages = null,
		currentPage		= null,
		DEBUG = false;/*typeof console != 'undefined' && typeof console.log != 'undefined';*/
// Variables globales
	pageOnLoad = Prototype.emptyFunction;
	pageOnUnload = Prototype.emptyFunction;
// Functions
	function pageError(transport) {
		if (DEBUG) console.log("pageError('"+transport+"')");
		
		oContent.update('<div style="position:absolute;left:50%;top:50%;width:400px;height:50px;margin:-25px 0 0 -200px;text-align:center;">' + errorPage + '</div>');
		pageLoaded();
	}
	
	function pageUpdate(transport) {
		var htmlHeader = '', htmlFooter = '';
		
		if (DEBUG) console.log("pageUpdate('", transport, "')");
		
		if (Object.isString(pageHeader)) {
			var t = new Template(pageHeader);
			htmlHeader = t.evaluate({ imagesPath: imagesPath, currentPage: currentPage });
		}

		if (Object.isString(pageFooter)) {
			var t = new Template(pageFooter);
			htmlFooter = t.evaluate({ imagesPath: imagesPath, currentPage: currentPage });
		}
		
		oContent.update(htmlHeader + transport.responseText + htmlFooter);
		preventImageDragAndDrop();
		waitImagesLoadComplete(pageLoaded);
	}

	function pageLoad(page) {
		if (DEBUG) console.log("pageLoad('"+page+"')");
		
		currentPage = page;
		
		new Ajax.Request(ajaxPrefix + page + ajaxSuffix, {
			method: 'get',
			onFailure: typeof arguments[2] == 'function' ? arguments[2] : pageError,
			onSuccess: typeof arguments[1] == 'function' ? arguments[1] : pageUpdate
		});
	}
	
	function hideLoading(delay) {
		if (!oLoading.visible()) return;
		if (Object.isUndefined(delay)) delay = 0.5;
		
		Effect.Fade(idLoading + 'BG', {
			duration: 1.0,
			from: 0.7,
			to: 0,
			delay: delay,
			queue: {
				position: 'end',
				scope: 'loadingBG'
			},
			afterFinish: function() {
				oLoading.hide();
			}
		});
		
		Effect.Fade(idLoading + 'Text', {
			duration: 0.5,
			from: 1,
			to: 0,
			delay: delay + 0.5,
			queue: {
				position: 'end',
				scope: 'loadingText'
			}
		});
	}
	
	function showLoading(delay) {
		if (oLoading.visible()) return;
		if (Object.isUndefined(delay)) delay = 0;
		
		oLoading.visible();
		Effect.Appear(idLoading + 'Text', {
			duration: 0.5,
			from: 0,
			to: 1,
			delay: delay,
			queue: {
				position: 'end',
				scope: 'loadingText'
			}
		});
		
		Effect.Appear(idLoading + 'BG', {
			duration: 1.0,
			from: 0,
			to: 0.6,
			delay: delay + 0.5,
			queue: {
				position: 'end',
				scope: 'loadingBG'
			}
		});
	}

	function pageLoaded() {
		if (DEBUG) console.log("pageLoaded()");
		
		if (!Object.isFunction(pageOnLoad))
			pageOnLoad = Prototype.emptyFunction;

		updateLinks(idContent);

		// Cancel loading animation if we're fast enough
		Effect.Queues.get('loadingText').each(function(e) { if (e.state == 'idle') e.cancel(); });
		Effect.Queues.get('loadingBG').each(function(e) { if (e.state == 'idle') e.cancel(); });
		
		hideLoading();
		
		// TODO faire le pageOnLoad avant la fin de l'animation

		if (!oContent.visible())
			Effect.Appear(idContent, { duration: 1.0, queue: { position: 'end', scope: 'loadingBG' }, afterFinish: pageOnLoad });
		else
			pageOnLoad();
		
		pageOnLoad = Prototype.emptyFunction;
	}

	pageShow = function(page) {	
		if (DEBUG) console.log("pageShow('"+page+"')");
		
		if (oContent.visible())
			Effect.Fade(idContent, { duration: 1.0, queue: 'end' });
			
		showLoading(2);

		pageLoad(page, function(transport) {			
			if (Object.isFunction(pageOnUnload))
				pageOnUnload();
			
			pageOnUnload = Prototype.emptyFunction;
			
			if (DEBUG) console.log(this, transport);
			
			Effect.Fade(idContent, { duration: 0.1, queue: 'end', afterFinish: function() {
				pageUpdate(transport);
			}});
		}, function(transport) {
			Effect.Fade(idContent, { duration: 0.1, queue: 'end', afterFinish: function () {
				pageError(transport);
			}});
		});
	}

	/* Menus and buttons functions */
	function menuOnMouseOver(e) {
		if (DEBUG) console.log("menuOnMouseOver(", e, ")");
		
		var el = e.element();
		el._src = el.src;
		el.src = imagesPath + el.id + '_on' + imagesExt;
	}

	function menuOnMouseOut(e) {
		if (DEBUG) console.log("menuOnMouseOut(", e, ")");
		
		var el = e.element();
		el.src = el._src;
	}
	
	function menuOnClick(e) {
		if (DEBUG) console.log("menuOnClick(", e, ")");
		var ce = e.element();
		ce._src = imagesPath + ce.id + imagesExt;
		
		for (var i = 0; i < menuIDs.length; i++)
		{
			var el = $(menuIDs[i]);
			if (ce != el) {
				el.src = imagesPath + 'blank.gif';
			}
		}
		
		pageShow(ce.id);
	}

	function createMenu() {
		if (DEBUG) console.log("createMenu()");
		
		for (var i = 0; i < menuIDs.length; i++)
		{
			var el = $(menuIDs[i]);
			el.observe('mouseover', menuOnMouseOver);
			el.observe('mouseout', menuOnMouseOut);
			el.observe('click', menuOnClick);
			imageList.push(imagesPath + menuIDs[i] + imagesExt);
			imageList.push(imagesPath + menuIDs[i] + '_on' + imagesExt);
		}
	}

	function preloadImages(callback) {
		if (DEBUG) console.log("preloadImages(", callback, ")");
		
		preloadedImages = Array(imageList.length);
		for (var i = 0; i < imageList.length; i++)
		{
			preloadedImages[i] = new Image();
			preloadedImages[i].loadStatus = 0; // NOT LOADED
			preloadedImages[i].onerror = function(obj) { this.loadStatus = -1; } // ERROR
			preloadedImages[i].onload = function(obj) { this.loadStatus = 1; } // LOADED
			preloadedImages[i].src = imageList[i];
		}
				
		iTimer = setInterval(function() {
			for (var i = 0; i < preloadedImages.length; i++)
			{
				if (preloadedImages[i].loadStatus == 0)
					return;
			}
			clearInterval(iTimer);
			if (Object.isFunction(callback))
				callback();
		}, 100);
	}
	
	function cancelEvent() { return false; }
	
	function preventImageDragAndDrop() {
		for (var i = 0; i < document.images.length; i++)
		{
			// IE Specific
			document.images[i].ondragstart = cancelEvent;
			// All DOM browsers
			document.images[i].onmousedown = cancelEvent;
		}
	}

	function waitImagesLoadComplete(callback) {
		if (DEBUG) console.log("waitImagesLoadComplete('", callback, "')");
		
		// Opera Browser Hack: Opera does'nt load the image if the parent element is not displayed
		if (Prototype.Browser.Opera)
			$(idContent).show();
		
		iTimer = setInterval(function() {
			for (var i = 0; i < document.images.length; i++)
			{			
				if (document.images[i].complete == false)
					return;
			}
			clearInterval(iTimer);
			if (Object.isFunction(callback))
				callback();
		}, 100);
	}

	/* Links */
	function onLinkClick(e) {
		var el = e.element();
			
		if (DEBUG) console.log("onLinkClick(", e, ")");
		
		if (el.tagName.toLowerCase() != 'a')
			el = e.findElement('a');
		
		var i = el.href.indexOf('#');
		if (i >= 0 && el.href.length > 1) {
			pageShow(el.href.substr(i+1));
		} else {
			open(el.href, '_blank');
			e.preventDefault();
		}
	}

	function updateLinks() {
		$$('a').each(function(el) {
			if (el.href.indexOf('http://') == 0 && el.rel != 'lang') {
				el.observe('click', onLinkClick);
			}
		});
	}
	
	function resize() {
		if (DEBUG) console.log(document.viewport.getDimensions());
	}
	
	function loadConfiguration() {
		if (typeof DWUI_Config != 'object')
			return;
		
		idPage		= (typeof DWUI_Config.idPage != 'undefined') ? DWUI_Config.idPage : idPage;
		idLoading	= (typeof DWUI_Config.idLoading != 'undefined') ? DWUI_Config.idLoading : idLoading;
		idContent	= (typeof DWUI_Config.idContent != 'undefined') ? DWUI_Config.idContent : idContent;
		startPage	= (typeof DWUI_Config.startPage != 'undefined') ? DWUI_Config.startPage : startPage;
		pageHeader	= (typeof DWUI_Config.pageHeader != 'undefined') ? DWUI_Config.pageHeader : pageHeader;
		pageFooter	= (typeof DWUI_Config.pageFooter != 'undefined') ? DWUI_Config.pageFooter : pageFooter;
		ajaxPrefix	= (typeof DWUI_Config.ajaxPrefix != 'undefined') ? DWUI_Config.ajaxPrefix : ajaxPrefix;
		ajaxSuffix	= (typeof DWUI_Config.ajaxSuffix != 'undefined') ? DWUI_Config.ajaxSuffix : ajaxSuffix;
		imagesPath	= (typeof DWUI_Config.imagesPath != 'undefined') ? DWUI_Config.imagesPath : imagesPath;
		imagesExt	= (typeof DWUI_Config.imagesExt != 'undefined') ? DWUI_Config.imagesExt : imagesExt;
		menuIDs		= (typeof DWUI_Config.menuIDs != 'undefined') ? DWUI_Config.menuIDs : menuIDs;
		imageList	= (typeof DWUI_Config.imageList != 'undefined') ? DWUI_Config.imageList : imageList;
		errorPage	= (typeof DWUI_Config.errorPage != 'undefined') ? DWUI_Config.errorPage : errorPage;
	}

	function main() {
		if (DEBUG) console.log('main()');
		
		loadConfiguration();
		
		oLoading = $(idLoading);
		oContent = $(idContent);
		
		if (location.hash != '')
			startPage = location.hash.substr(1);
		
		//createMenu();
		updateLinks();
		preventImageDragAndDrop();
			
		preloadImages(function() {			
			if (startPage)
				pageShow(startPage);
			else
				hideLoading();
		});
		
		setTimeout(function() { background(2); }, 30000);
	}
	
	function background(c) {
		var bg1 = $('background1'),
			bg2 = $('background2');
		
		if (c > 6) { c = 1; }
				
		if (bg1.visible()) {		
			bg2.setStyle({ backgroundImage: 'url(images/bg' + c + '.jpg)' });
			Effect.Appear('background2', { duration: 3.0, queue: { position: 'end', scope: 'BG'}, afterFinish: function() {
				bg1.hide();
			}});
		} else {
			bg1.setStyle({ backgroundImage: 'url(images/bg' + c + '.jpg)', display: '' });
			Effect.Fade('background2', { duration: 3.0, queue: { position: 'end', scope: 'BG'}, afterFinish: function() {
				bg2.hide();
			}});
		}
		
		setTimeout(function() { background(c + 1); }, 30000);
	}
	
	Event.observe(window, 'load', main);
	Event.observe(window, 'resize', resize);
})();

var DWUI = { };

DWUI.ImagesBar = function(element, tooltips) {
	// TODO preload slideshow images
	var eTooltip = null,
		eCourrant = null,
		eScroll = null,
		oPosition = null,
		tTooltip = null,
		tSlideshow = null,
		tScroll = null,
		i = 0,
		originalSrc = null,
		pos;
	
	function doSlideShow() {
		eCourrant.src = tooltips[pos].slideshow.filename.replace(/#/, i);
		i++;
		if (i > tooltips[pos].slideshow.end) i = tooltips[pos].slideshow.start;
	}

	function hideTooltip(event) {
		eTooltip.hide();
		Event.stopObserving(eCourrant);
		Event.stopObserving(eTooltip);
		event.stop();
		var el = eCourrant;
		var tmp = pos;
		eCourrant.observe('mouseover', function(e) { showTooltip(el, tmp); });
		clearTimeout(tTooltip);
		if (tooltips[pos].slideshow) {
			clearInterval(tSlideshow);
			eCourrant.src = originalSrc;
		}
		Effect.Fade(eCourrant, { duration: 0.25, from: 1, to: 0.25 });
	}

	function showTooltip(el, p) {
		eCourrant = el;
		pos = p;
		oPosition = el.cumulativeOffset();
		eTooltip.update(tooltips[pos].tooltip);
		eTooltip.setStyle({left: (oPosition.left - el.cumulativeScrollOffset().left) + 'px', top: oPosition.top + 'px'});
		el.observe('mouseout', hideTooltip);
		// TODO onclick -> do something
		el.observe('click', function(e) { if (tooltips[pos].page) pageShow(tooltips[pos].page); hideTooltip(e); });
		el.stopObserving('mouseover');
		Effect.Appear(el, { duration: 0.1, from: 0.25, to: 1, afterFinish: function() { el.removeClassName('transparent'); } });
		tTooltip = setTimeout(function() { eTooltip.show(); }, 500);
		if (tooltips[pos].slideshow) {
			i = tooltips[pos].slideshow.start;
			originalSrc = el.src;
			tSlideshow = setInterval(doSlideShow, 1000);
		}
	}
	
	function doScroll(a, d) {
		if (a) {
			if (d && element.scrollLeft > 0) {
				element.scrollLeft -= 2;
			} else if (!d && element.scrollLeft < 960) {
				element.scrollLeft += 2;
			}
			tScroll = setTimeout(function() { doScroll(a, d); }, 10);
		} else {
			clearTimeout(tScroll);
		}
	}
	
	function init() {
		eTooltip = new Element('div', { id: 'Tooltips' }).setStyle({ position: 'absolute', display: 'none' });
		$(document.body).insert(eTooltip);
		
		var ce = $(element).childElements();		
		var fg = ce[0];
		var fd = ce[2];
		
		fg.observe('mouseover', function() { doScroll(true, true); });
		fg.observe('mouseout', function() { doScroll(false); });
		fd.observe('mouseover', function() { doScroll(true, false); });
		fd.observe('mouseout', function() { doScroll(false); });		
		
		element = ce[1];
		var i = 0;
		element.childElements().each(function(el) {
			var x = i;
			el.observe('mouseover', function() { showTooltip(el, x); });		
			i++;
		});
	}

	init();
};

DWUI.Scroller = function(nomConteneur) {
	var oConteneur = $(nomConteneur),
		tailleBarre = 15,
		oBarre,
		oLigne,
		oCurseur,
		dragging = 0;

	function create() {
		var oDim = oConteneur.getDimensions(),
			oPos = oConteneur.positionedOffset();
		
		oConteneur.setStyle({ overflow: 'hidden' });
		//oConteneur.scrollTop = 0;
				
		// La barre
		oBarre = new Element('div').setStyle({
			position: 'absolute',
			left: (oPos.left + oDim.width) + 'px',
			top: oPos.top + 'px',
			width: tailleBarre + 'px',
			height: oDim.height + 'px'
		});
		
		// La ligne
		oLigne = new Element('div').setStyle({
			position: 'absolute',
			left: ((tailleBarre - 3) / 2) + 'px',
			width: '1px',
			height: oDim.height + 'px',
			backgroundColor: '#FFF',
			borderLeft: '1px solid #AAA',
			borderRight: '1px solid #AAA'
		});
		oBarre.appendChild(oLigne);
		
		// Le curseur		
		oCurseur = new Element('div').setStyle({
			position: 'absolute',
			top: 0,
			width: '15px',
			height: '15px',
			backgroundImage: 'url("images/scroller.png")',
			overflow: 'hidden'
		});
		oBarre.appendChild(oCurseur);
		
		oConteneur.getOffsetParent().appendChild(oBarre);
		
		oCurseur.observe('mousedown', onMouseDown);
		oConteneur.observe('DOMMouseScroll', onMouseScroll);
		oConteneur.observe('mousewheel', onMouseScroll);
	}

	function onMouseScroll(e)
	{
		var delta = 0;
		if (e.wheelDelta) {
			if (e.wheelDelta > 0) {
				delta = -1;
			} else {
				delta = 1;
			}
		} else if (e.detail) {
			delta = e.detail / 3;
		}
		
		if (delta) {
			var pos = parseInt(oCurseur.style.top) + (30 * delta);
			var scrollerMax = (oBarre.offsetHeight - oCurseur.offsetHeight);
			
			if (pos < 0) pos = 0;
			if (pos > scrollerMax) pos = scrollerMax;
			
			oCurseur.style.top = pos + 'px';
			oConteneur.scrollTop = pos * ((oConteneur.scrollHeight - oConteneur.offsetHeight) / scrollerMax);
		}	
		
		Event.stop(e);
	}

	function onMouseDown(e) {
		var top = oConteneur.cumulativeOffset().top;
		dragging = oConteneur.cumulativeOffset().top + (e.pointerY() - oCurseur.cumulativeOffset().top);
		
		document.observe('mouseup', onMouseUp);
		document.observe('mousemove', onMouseMove);
		
		Event.stop(e);
	}
	
	function onMouseUp(e) {
		if (!dragging) return;
		
		document.stopObserving('mouseup', onMouseUp);
		document.stopObserving('mousemove', onMouseMove);
		
		dragging = 0;
	}
	
	function onMouseMove(e) {
		if (!dragging) return;
		
		var pos = e.pointerY() - dragging;
		var scrollerMax = (oBarre.offsetHeight - oCurseur.offsetHeight);
		
		if (pos < 0) pos = 0;
		if (pos > scrollerMax) pos = scrollerMax;
		
		oCurseur.style.top = pos + 'px';
		oConteneur.scrollTop = pos * ((oConteneur.scrollHeight - oConteneur.offsetHeight) / scrollerMax);
	}

	create();
};

DWUI.PopupWindow = function(containerId) {
	var el = $(containerId);
	var c;

	function showPopup($e) {
		var a = $e.findElement('a');
		c = $(a.rel);		
		el.show();
		c.show();
	}

	function hidePopup($e) {
		c.hide();
		el.hide();
	}

	function init() {
		var first = true;
		el.childElements().each(function(e) {
			if (first) { first = false; return; }
			var a = $$('a[rel=' + e.id + ']')[0];
			a.observe('click', showPopup);
		});
		el.observe('click', hidePopup);
	}
	
	init();
};

DWUI.DialogBox = function(ei) {
	var e = $(ei);
	var c;

	function showPopup($e) {
		var el = $e.findElement('a');
		c = $(el.rel);		
		c.show();
		e.show();
	}

	function hidePopup($e) {
		if ($e.element().id != 'dialogBoxBG' && $e.element().className != 'fermer') return;
		c.hide();
		e.hide();
	}

	function init() {
		var skip = 2;
		e.childElements().each(function(el) {
			if (skip) { skip--; return; }
			var a = $$('a[rel=' + el.id + ']')[0];
			a.observe('click', showPopup);
		});
		e.observe('click', hidePopup);
	}
	
	init();
};