
var Amed = function(){
	var minCompat;
	
	return {
		toString : function(){
			return 'Amed core object 0.3';
		},
		isMinCompat : function(o){
			if(minCompat === undefined){
				if(o === false || !Array.prototype.push || !Object.hasOwnProperty || !document.createElement || !document.getElementsByTagName) minCompat = false;
				else minCompat = true;
			}
			return minCompat;
		}
	};
}();

Amed.DOM = (function(){
	function crawl(node, func){
		if(node.nodeName.toLowerCase() !== 'applet') func(node);
		node = node.firstChild;
		while(node){
			crawl(node, func);
			node = node.nextSibling;
		}
	}
	
	return {
		toString : function(){
			return 'Amed.DOM object 0.1';
		},
		
		ELEMENT_NODE : 1, //noeud élément
		ATTRIBUTE_NODE : 2, //noeud attribut
		TEXT_NODE : 3, //noeud texte
		CDATA_SECTION_NODE : 4, //noeud de section CDATA
		ENTITY_REFERENCE_NODE : 5, //noeud de référence à une entité
		ENTITY_NODE : 6, //noeud d'entité
		PROCESSING_INSTRUCTION_NODE : 7, //noeud d'instruction de traitement
		COMMENT_NODE : 8, //noeud de commentaire
		DOCUMENT_NODE : 9, //noeud de document
		DOCUMENT_TYPE_NODE : 10, //noeud de type de document
		DOCUMENT_FRAGMENT_NODE : 11, //noeud de fragment de document
		NOTATION_NODE : 12, //noeud de notation
		
		$ : function(id){
			return document.getElementById(id);
		},
		hasAttribute : function(node, attrib){
			if(typeof(node)=='string') node = Amed.DOM.$(node);
			if(node.hasAttribute) return node.hasAttribute(attrib);
			if(node.getAttributeNode(attrib)) return true;
			else return false;
		},
		getElementsByAttribute : function(attrib, value, node){
			var results = [], node = node || document.body;
			if(typeof(node)=='string') node = Amed.DOM.$(node);
			if(value == '*') value = false;
			
			var attributeCrawler = function(node){
				if(node.nodeType != Amed.DOM.ELEMENT_NODE) return;
				if(!Amed.DOM.hasAttribute(node, attrib)) return;
				if(value && node.getAttribute(attrib) != value) return;
				results.push(node);
			}
			
			var hrefCrawler = function(node){
				if(node.nodeType != Amed.DOM.ELEMENT_NODE) return;
				if(!Amed.DOM.hasAttribute(node, attrib)) return;
				if(value && node.getAttribute('href', 2) != value) return;
				results.push(node);
			}
			
			var classCrawler = function(node){
				if(node.nodeType != Amed.DOM.ELEMENT_NODE) return;
				if(!Amed.DOM.hasAttribute(node, 'class')) return;
				if(value && !Amed.DOM.hasClassName(node, value)) return;
				results.push(node);
			}
			
			var forCrawler = function(node){
				if(node.nodeType != Amed.DOM.ELEMENT_NODE) return;
				if(!Amed.DOM.hasAttribute(node, 'for')) return;
				if(value && node.getAttribute('htmlFor') != value) return;
				results.push(node);
			}
			
			switch(attrib){
				case 'href' :
					crawl(node, hrefCrawler);
					break;
				case 'class' :
					crawl(node, classCrawler);
					//if(document.attachEvent) crawl(node, classCrawler);
					//else crawl(node, attributeCrawler);
					break;
				case 'for' :
					if(document.attachEvent) crawl(node, forCrawler);
					else crawl(node, attributeCrawler);
					break;
				default :
					crawl(node, attributeCrawler);
					break;
			}
			
			return results;
		},
		getElementsByAttributeNS : function(NS, attrib, value, node){
			return Amed.DOM.getElementsByAttribute(NS + ':' + attrib, value, node);
		},
		hasClassName : function(node, cn){
			if(typeof(node)=='string') node = Amed.DOM.$(node);
			return (node.className && new RegExp('(^|\\s)' + cn + '(\\s|$)').test(node.className));
		},
		addClassName : function(node, cn){
			if(typeof(node)=='string') node = Amed.DOM.$(node);
			if(Amed.DOM.hasClassName(node, cn)) return;
			node.className += node.className ? (' ' + cn) : cn;
		},
		removeClassName : function(node, cn){
			if(typeof(node)=='string') node = Amed.DOM.$(node);
			if(!Amed.DOM.hasClassName(node, cn)) return;

			var cnt = node.className.split(/\s+/), cntl = cnt.length;
			for(var i = 0; i<cntl; ++i){
				if (cnt[i] == cn) cnt.splice(i, 1);
			}
			node.className = cnt.join(' ');
		},
		isAChildOfB : function(a, b){
			try{
				var p = a.parentNode;
				if (typeof(b) != 'string') {
					while (p !== b) p = p.parentNode;
				} else {
					while (p.nodeName != b) p = p.parentNode;
				}
				return true;
			}
			catch(err){
				return false;
			}
		},
		getChildsByTagName: function(parent, tag){
			tag = tag.toUpperCase();
			for(var i = 0, c = parent.childNodes, l = c.length, r = []; i<l; i++) if(c[i].tagName == tag) r.push(c[i]);
			return r;
		},
		getFirstChildByTagName: function(parent, tag){
			tag = tag.toUpperCase();
			for (var i = 0, c = parent.childNodes, l = c.length; i < l; i++) if (c[i].tagName == tag) return c[i];
		},
		getAggregateTextValue: function(node){
			var results = [], node = node || document.body;
			if(typeof(node)=='string') node = Amed.DOM.$(node);
			
			var textCrawler = function(node){
				if(node.nodeType != Amed.DOM.TEXT_NODE) return;
				results.push(node.nodeValue);
			}
			crawl(node, textCrawler);
			
			return results.join(' ');
		},
		build: function(node, attribs, css){
			var n = document.createElement(node);
			for(var i in attribs){
				if (i == 'class') {
					n.className = attribs[i];
				}else if (i == '_text'){
					if(attribs[i]) n.appendChild(document.createTextNode(attribs[i]));
				}else {
					n.setAttribute(i, attribs[i]);
				}		
			}
			for(var i in css){
				if (i == 'opacity' && /*@cc_on!@*/false){
					n.style.filter = 'alpha(opacity=' + css[i]*100 + ')';
				}else if (i == 'float'){
					n.style.cssFloat = css[i];
					n.style.styleFloat = css[i];
				}else {
					n.style[i] = css[i];
				}
			}
			return n;
		}
	};
})();

Amed.BOM = function(){
	
	var sw = function(){ return screen.width; };
	var sh = function(){ return screen.height; };
	
	var saw = function(){ return screen.availWidth; };
	var sah = function(){ return screen.availHeight; };
	
	if (window.innerHeight){
		var vw = function(){ return window.innerWidth; };
		var vh = function(){ return window.innerHeight; };
		
		var scw = function(){ return window.pageXOffset; };
		var sch = function(){ return window.pageYOffset; };
	} else if (document.documentElement && document.documentElement.clientHeight){ // IE 6+ Strict
		var vw = function(){ return document.documentElement.clientWidth; };
		var vh = function(){ return document.documentElement.clientHeight; };
		
		var scw = function(){ return document.documentElement.scrollLeft; };
		var sch = function(){ return document.documentElement.scrollTop; };
	} else if (document.body){ // legacy
		var vw = function(){ return document.body.clientWidth; };
		var vh = function(){ return document.body.clientHeight; };
		
		var scw = function(){ return document.body.scrollLeft; };
		var sch = function(){ return document.body.scrollTop; };
	}
	
	return {
		toString : function(){
			return 'Amed.BOM helper object 0.1';
		},
		getScreenVector : function(){
			return [sw(), sh()];
		},
		getScreenAvailableVector : function(){
			return [saw(), sah()];
		},
		getViewportVector : function(){
			return [vw(), vh()];
		},
		getScrollVector : function(){
			return [scw(), sch()];
		},
		getItemVector : function(item){
			return [item.clientWidth, item.clientHeight];
		},
		getItemPosition : function(item){
			return [item.offsetLeft, item.offsetTop];
		}
	};
}();

Amed.Event = function(){
	var __cache = {}, GUID = 0;
	
	function addToCache(__GUID, evt, func){
		if (!__cache[__GUID]) __cache[__GUID] = {};
		if (!__cache[__GUID][evt]) __cache[__GUID][evt] = [];
		__cache[__GUID][evt].push(func);
	}
	
	function getFromCache(__GUID, evt, func){
		for(var i=0; i<__cache[__GUID][evt].length; i++){
			if(__cache[__GUID][evt][i].handler!=func) continue;
			return __cache[__GUID][evt].splice(i,1)[0];
		}
		return false;
	}
	
	function generateGUID(){
		return ++GUID;
	}
	
	function bindDOMContentEvent(){
		if(arguments.callee.done) return;
		arguments.callee.done = true;
		Amed.Event.DOMLoadCallbackArray = [];
		if(document.addEventListener){
			if(/WebKit/i.test(navigator.userAgent)){
				var __t = setInterval(function(){
					if(/loaded|complete/.test(document.readyState)){
						clearInterval(__t);
						DOMLoadCallback();
					}
				}, 50);
			}else{
				document.addEventListener('DOMContentLoaded', DOMLoadCallback, false);
			}
		}else{
			var __t = setInterval(function(){
				try{ document.documentElement.doScroll('left');	}
				catch(e){ return; }
				clearInterval(__t);
				DOMLoadCallback();
			}, 50);
		}
	}
	
	function bindDOMLoadCallback(func){
		if(Amed.Event.DOMloaded) func();
		else Amed.Event.DOMLoadCallbackArray.push(func);
	}
	
	function DOMLoadCallback(){
		Amed.Event.DOMloaded = true;
		for(var i=0; i<Amed.Event.DOMLoadCallbackArray.length; i++) Amed.Event.DOMLoadCallbackArray[i]();
		delete Amed.Event.DOMLoadCallbackArray;
	}
	
	function internalDelegate(func, el, passArgs, evt){
		if(evt){
			if(el.addEventListener){
				var w = function(e){
					if(e.type == evt || e.eventName == evt) func.apply(el, [e].concat(passArgs));
				};
			}else if(el.attachEvent){
				var w = function(){
					if(window.event.type == evt || window.event.eventName == evt) func.apply(el, [new Amed.Event.EventProxy].concat(passArgs));
				};
			}
			w.handler = func;
			if(!el.__GUID) el.__GUID = generateGUID();
			addToCache(el.__GUID, evt, w);
		}else{
			var w = function(){ func.apply(el, passArgs); };
		}
		return w;
	}
	
	function isSpecial(evt){
		if(evt.match(/:/)) return addCustom;
		if(evt=='DOMContentLoaded') return addDOMContentLoaded;
		return false;
	}
	
	function addCustom(el, evt, func){
		func = internalDelegate(func, el, Array.prototype.slice.call(arguments, 3), evt);
		
		if(el.addEventListener) el.addEventListener('dataavailable', func, false);
		else if(el.attachEvent) el.attachEvent('ondataavailable', func);
	}
	
	function addDOMContentLoaded(el, evt, func){
		func = internalDelegate(func, el, Array.prototype.slice.call(arguments, 3));
		
		bindDOMContentEvent();
		bindDOMLoadCallback(func);
	}
	
	return {
		toString : function(){
			return 'Amed.Event helper object 0.2';
		},
		add : function(el, evt, func){
			if(!Amed.isMinCompat()) return false;
			if(typeof(el)=='string') el = Amed.DOM.$(el);
			
			var special = isSpecial(evt);
			if(special){
				special.apply(this, arguments);
				return true;
			}
			
			func = internalDelegate(func, el, Array.prototype.slice.call(arguments, 3), evt);
			if(el.addEventListener){
				el.addEventListener(evt, func, false);
				return true;
			}else if(el.attachEvent){
				el.attachEvent('on'+evt, func);
				return true;
			}
			return false;
		},
		remove : function(el, evt, func){
			if(typeof(el)=='string') el = Amed.DOM.$(el);
			
			var func = getFromCache(el.__GUID, evt, func);
			if(evt.match(/:/)) evt = 'dataavailable';
			if(el.removeEventListener){
				el.removeEventListener(evt, func, false);
				return true;
			}else if(el.detachEvent){
				el.detachEvent('on'+evt, func);
				return true;
			}
			return false;
		},
		broadcast : function(el, evt, memo){
			if(el == document && document.createEvent && !el.dispatchEvent) el = document.documentElement;
			if(typeof(el)=='string') el = Amed.DOM.$(el);
			
			var event;
			if(document.createEvent){
				event = document.createEvent("HTMLEvents");
				event.initEvent("dataavailable", true, true);
			}else{
				event = document.createEventObject();
				event.eventType = "ondataavailable";
			}
			
			event.eventName = evt;
			event.memo = memo || { };
			
			if(document.createEvent) el.dispatchEvent(event);
			else el.fireEvent(event.eventType, event);
			
			return true;
		},
		delegate : function(func, el){
			return internalDelegate(func, el, Array.prototype.slice.call(arguments, 2), false);
		}
	};
}();

Amed.Event.EventProxy = function(){
	this.preventDefault = function(){ window.event.returnValue = false; };
	this.stopPropagation = function(){ window.event.cancelBubble = true; };
	this.type = window.event.type;
	this.keyCode = window.event.keyCode;
	this.target = window.event.srcElement;
	if(this.type == 'mouseover') this.relatedTarget = window.event.fromElement;
	if(this.type == 'mouseout') this.relatedTarget = window.event.toElement;
	this.clientX = window.event.clientX;
	this.clientY = window.event.clientY;
}

Amed.Event.DummyEvent = function(){
	this.preventDefault = function(){ };
	this.stopPropagation = function(){ };
	this.type = 'dummy';
}

Amed.CSS = function(){
	function camelize(s){
		for(var exp=/-([a-z])/; exp.test(s); s=s.replace(exp,RegExp.$1.toUpperCase()));
		return s;
	}
	
	function getStyleDeclaration(el){
		if(document.defaultView && document.defaultView.getComputedStyle) return document.defaultView.getComputedStyle(el, null);
		else return el.currentStyle;
	}

	return {
		toString : function(){
			return 'Amed.CSS object 0.1';
		},
		getRule : function(el, rule){
			var cssd = getStyleDeclaration(el);
			if(cssd.getPropertyValue) return cssd.getPropertyValue(rule);
			else return cssd[camelize(rule)];
		},
		getRuleAsInt : function(el, rule){
			return (parseInt(Amed.CSS.getRule(el, rule), 10) || 0);
		},
		getTextColor : function(el){
			var c = Amed.CSS.getRule(el, 'color');
			if (/^rgb/.test(c)) {
				var ctemp = c.substring(4, c.length - 1).split(','), c = '';
				for (var i = 0; i < 3; i++) c += Number(ctemp[i]).toString(16);
			}
			else {
				c = c.substr(1);
				if(c.length == 3) c+=c;
			}
			return c;
		}
	}
}();

Amed.Type = function(){
	var isIE = false/*@cc_on || true @*/,
		memtitle;
	
	if(isIE){
		/*
		var flashDummy = [];
			flashDummy[0] = '<object type="application/x-shockwave-flash" data="'
			flashDummy[2] = '" width="';
			flashDummy[4] = '" height="';
			flashDummy[6] = '" alt="" title=""><param name="movie" value="';
			flashDummy[8] = '"/><param name="quality" value="high"/><param name="wmode" value="transparent"/><param name="flashvars" value="';
			flashDummy[10]= '" /></object><span>'
			flashDummy[12]= '</span>';
		*/
		var flashDummy = [];
			flashDummy[0] =  '<embed type="application/x-shockwave-flash" src="';
			flashDummy[2] =  '" quality="best" width="';
			flashDummy[4] =  '" height="';
			flashDummy[6] =  '" flashvars="';
			flashDummy[8] =  '" wmode="transparent"></embed><span>';
			flashDummy[10] = '</span>';
	} else {
		flashDummy = constructFD();
	}
	
	function constructFD(){
		var o = document.createElement('object');
			o.setAttribute('type', 'application/x-shockwave-flash');
			o.appendChild(makeParamNode('quality', 'high'));
			o.appendChild(makeParamNode('wmode', 'transparent'));
		return o;
	}
	function makeParamNode(param, value){
		var p = document.createElement('param');
			p.setAttribute('name', param);
			p.setAttribute('value', value);
		return p;
	}
	function makeFlashVarsNode(fv){
		var serialisation = [];
		for(var i in fv) serialisation.push(i + '=' + fv[i]);
		return makeParamNode('flashvars', serialisation.join('&'));
	}
	function createTypeEl(el, typeFile){
		var elw = getWidth(el),
			elh = getHeight(el),
			fv = {
				'ftext': getTextContent(el),
				'fcolor': '0x' + Amed.CSS.getTextColor(el),
				'fwidth': elw,
				'fheight': elh,
				'fsize': Amed.CSS.getRuleAsInt(el, 'font-size')
			},
			o = flashDummy.cloneNode(true),
			df = document.createDocumentFragment(),
			holder = document.createElement('span');
		if(Amed.DOM.hasAttribute(el, 'amed:flcallback')) fv['ftext'] = fv['ftext'].replace( /href=%22([^%22]*)%22/ ,'href=%22javascript:' + el.getAttribute('amed:flcallback') + '%22');
		
		o.setAttribute('width', elw);
		o.setAttribute('height', elh);
		o.setAttribute('data', typeFile);
		o.appendChild(makeParamNode('movie', typeFile));
		//o.appendChild(makeParamNode('wmode', 'transparent'));
		//o.appendChild(makeParamNode('quality', 'high'));
		o.appendChild(makeFlashVarsNode(fv));
		
		df.appendChild(o);
		holder.appendChild(el.firstChild.cloneNode(true));
		df.appendChild(holder);
		return df;
	}
	
	function IEserializeFlashVars(fv){
		var serialisation = [];
		for(var i in fv) serialisation.push(i + '=' + fv[i]);
		return serialisation.join('&');
	}
	function IEcreateTypeEl(el, typeFile){
		var fv = {
			'ftext': getTextContent(el),
			'fcolor': '0x' + Amed.CSS.getTextColor(el),
			'fwidth': getWidth(el),
			'fheight': getHeight(el),
			'fsize': Amed.CSS.getRuleAsInt(el, 'font-size')
		}
		if(Amed.DOM.hasAttribute(el, 'amed:flCallback')) fv['ftext'] = fv['ftext'].replace( /href=%22([^%22]*)%22/ ,'href=%22javascript:' + el.getAttribute('amed:flcallback') + '%22');
		
		flashDummy[1] = typeFile;
		flashDummy[3] = fv['fwidth'];
		flashDummy[5] = fv['fheight'];
		/*
		flashDummy[7] = typeFile;
		flashDummy[9] = IEserializeFlashVars(fv);
		flashDummy[11] = el.innerHTML;
		*/
		flashDummy[7] = IEserializeFlashVars(fv);
		flashDummy[9] = el.innerHTML;
		return flashDummy.join('');
	}
	
	function getTextContent(el){
		return encodeURI(el.innerHTML).replace('+','__enc_plus__');
	}
	function getWidth(el){
		var w = parseInt(Amed.CSS.getRule(el, 'width'), 10); // ne pas utiliser getRuleAsInt : on veut différencier NaN de 0
		if (isNaN(w)) {
			w = el['offsetWidth']
				- Amed.CSS.getRuleAsInt(el, 'padding-right')
				- Amed.CSS.getRuleAsInt(el, 'padding-left')
				- Amed.CSS.getRuleAsInt(el, 'border-right-width')
				- Amed.CSS.getRuleAsInt(el, 'border-left-width');
		}
		return w;
	}
	function getHeight(el){
		var h = parseInt(Amed.CSS.getRule(el, 'height'), 10); // ne pas utiliser getRuleAsInt : on veut différencier NaN de 0
		if (isNaN(h) || (!h && Amed.CSS.getRule(el, 'display') == 'inline')) {
			h = el['offsetHeight']
				- Amed.CSS.getRuleAsInt(el, 'padding-top')
				- Amed.CSS.getRuleAsInt(el, 'padding-bottom')
				- Amed.CSS.getRuleAsInt(el, 'border-top-width')
				- Amed.CSS.getRuleAsInt(el, 'border-bottom-width');
		}
		return h;
	}
	return {
		toString : function(){
			return 'Amed.Type object 0.1';
		},
		typify : function(el, typeFile){
			Amed.DOM.addClassName(el, 'typified');
			if(isIE){
				var t = IEcreateTypeEl(el, typeFile);
				if(!memtitle) memtitle = document.title; // document fragment identifier bug fix
				el.innerHTML = (t);
				if(window.location.hash != ""){
					setTimeout(function(){ document.title = memtitle; }, 0);
					setTimeout(function(){ document.title = memtitle; }, 15);
					setTimeout(function(){ document.title = memtitle; }, 150);
					setTimeout(function(){ document.title = memtitle; }, 1500);
					setTimeout(function(){ document.title = memtitle; }, 5000);
					setTimeout(function(){ document.title = memtitle; }, 15000);
				}
			} else {
				var t = createTypeEl(el, typeFile);
				while(el.firstChild) el.removeChild(el.firstChild);
				el.appendChild(t);
			}
		}
	}
}();


Amed.Cookie = function(){
	var gs = '_|_',   // group separator
		xs = '_\\|_', // group separator escaped
		defaultTime = 999;
	function r(n){
		var cs = document.cookie.split(';');
		for (var i = cs.length; i--;) {
			while (cs[i].charAt(0)==' ') cs[i] = cs[i].substr(1);
			if (cs[i].indexOf(n) == 0) return cs[i].split('=')[1];
		}
	}
	function w(n, v, d){
		var d = d || defaultTime;
		if(d){
			var gmt = new Date(), e;
			gmt.setTime(gmt.getTime() + (d*24*60*60*1000));
			e = '; expires=' + gmt.toGMTString();
		}
		else var expires = '';
		document.cookie = n + '=' + v + e + '; path=/';
	}
	
	w('ckEnabled', 'true', 1);
	var enabled = Boolean(r('ckEnabled'));
	w('ckEnabled', '', -1);
	
	return{
		isEnabled: enabled,
		read: r,
		write: w,
		del: function(name){
			w(name,'',-1);
		},
		dump: function(name){
			var c = r(name) || '';
			return c.split(gs).slice(1);
		},
		insert: function(name, value, days){
			var c = r(name) || '';
			if(!c.match(RegExp(xs + value + '$|' + xs + value + xs)))
				w(name, c + gs + value, days);
		},
		extract: function(name, value, days){
			var v = r(name).replace(RegExp(xs + value + '$'), '').replace(RegExp(xs + value + xs), gs);
			w(name, v, days);
		}
	}
}();
