var myUrlJson = "xml/jsonMAG2010.jsp";

// Create the namespace and the conf vars

String.prototype.unescapeHtml = function () {
	if(this.length===0) return;
    var temp = document.createElement("div");
    temp.innerHTML = this;
    var result = temp.childNodes[0].nodeValue;
    temp.removeChild(temp.firstChild);
    return result;
}
String.prototype.stripTags = function () {
    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
}

addEvent("domready", function (){
	if($('blockMagTabs')){
		magTabs = new MagTabs($('blockMagTabs'));
	}

	var request = new Request.JSON(
		{
			url: myUrlJson,
			onComplete: function(jsonObj) {
				//console.log(jsonObj);

				if($('homeCarousel')){
					createBlocHomeCarousel(jsonObj, $('homeCarousel'));
				}


				if($("mySliderHome")){
					createBlocSliderHome(jsonObj, "mySliderHome");
				}

				if($("mySliderPage")){
					createBlocSliderPage(jsonObj, "mySliderPage");
				}

				$$('.pngFix').each(function(){
					pngFix(this);
				});

			}
		}
	).get();

	$$('li').addEvents({
		"mouseenter": function (){$(this).addClass("hover")},
		"mouseleave": function (){$(this).removeClass("hover")}
	})
})

function createBlocHomeCarousel(objJson, block){
	block.empty();
    var contentStyle = block.get('style');
	var myHTMLContent = '';
	if(objJson.mag2010home){
		var myObj = objJson.mag2010home;
		var urlImagePlay = (myObj.play_button.url_img != ""?myObj.play_button.url_img:"/img/mag/btnPlay.png");
		var txtBtnVideo = (myObj.see_video.text != ""?myObj.see_video.text:"Voir la vidéo");

		// creation des contenus pour le carousel HOME
		myHTMLContent += '<div class="blockMagTabsTop">';

		myObj.videos.each(function(el,index){

			myHTMLContent += '<div class="blockMagTabsBtn diapohome'+(index+1)+'" id="diapostep'+(index+1)+'">';
			myHTMLContent += '<div class="bgBlack"></div>';
			myHTMLContent += '<div class="fondDiapo"></div>'
			myHTMLContent += '<div class="containerDiapo">';

			myHTMLContent += '<a href="'+el.url+'" class="btnPlay"><img src="'+urlImagePlay+'" alt="PLAY" class="pngFix" /></a>';
			myHTMLContent += '<div class="imageContainer">';
				myHTMLContent += '<img src="'+el.image+'" alt="" class="pngFix" />';
				myHTMLContent += '<div class="maskImage"><img src="/img/mag/maskImage.png" class="pngFix" /></div>';
			myHTMLContent += "</div>";
			myHTMLContent += '<div class="textContainer">';
			myHTMLContent += '<div class="contentCarousel">';
				myHTMLContent += '<h3 style="' + contentStyle + '">'+el.title+'</h3>';
				myHTMLContent += '<span class="duree" style="' + contentStyle + '">'+el.length+'</span>';
				myHTMLContent += '<div class="description" style="' + contentStyle + '">'+el.description != '' ? el.description.unescapeHtml() : ''+'</div>';
				myHTMLContent += '<div class="btnSeeVideo"><a href="'+el.url+'" title="'+txtBtnVideo+'" class="pngFix"><span class="pngFix">'+txtBtnVideo+'</span></a></div>';
			myHTMLContent += "</div>";
			myHTMLContent += "</div>";

			myHTMLContent += "</div>";
			myHTMLContent += "</div>";
		});

		myHTMLContent += "</div>";

	}
	// ajout au contenu
	block.innerHTML = myHTMLContent;
	magDiapo = new MagDiapos(block);
}

function createBlocSliderHome(objJson, idBlock){
	var slideSize = 158;
	var scrollBy = 6;

	// on cree les li avec les donnes du json
	var myEl = $(idBlock);
	var myContainerLines = myEl.getElement(".innerSlider");
	var myHTMLContentSlider = '';

	if(objJson.mag2010playlist){
		var myIndicateurPageSlider = myEl.getParent().getElement(".indicateurPageSlider");
		var myBtnNext = myEl.getParent().getElements(".nextBtn a");
		var myBtnPrev = myEl.getParent().getElements(".prevBtn a");

		var myObjPlaylist = objJson.mag2010playlist;
		$(myContainerLines).empty();

		var countListeElements = myObjPlaylist.videos.length;
		var countListeElementsRestant = countListeElements%6;
		var countNbrIndicateurs = Math.ceil(countListeElements/6);

		myObjPlaylist.videos.each(function(el){
			//console.log(el);
			myHTMLContentSlider += '<li class="elementSlide">';

			myHTMLContentSlider += '<div class="imageSlider">';
				myHTMLContentSlider += '<div class="maskImage"><a href="'+el.url+'"><img src="/img/mag/maskSlider.png" class="pngFix" alt="" /></a></div>';
				myHTMLContentSlider += '<a href="'+el.url+'"><img src="'+el.image+'" alt="'+el.title+'" class="pngFix" /></a>';
			myHTMLContentSlider += '</div>';

			myHTMLContentSlider += '<div class="text">';
				myHTMLContentSlider += '<span class="desc">'+el.title+'</span><span class="vues">('+el.views+' vues)</span>';
			myHTMLContentSlider += '</div>';

			myHTMLContentSlider += '</li>';
		});
		var countListElementsFull = countListeElements;
		if(countListeElementsRestant != 0){
			for(var i = countListeElementsRestant; i<6; i++){
				countListElementsFull++;
				myHTMLContentSlider += '<li class="elementSlide">&nbsp;</li>';
			}
		}


		//console.log(myHTMLContentSlider)
		myContainerLines.innerHTML = myHTMLContentSlider;


		if($(myIndicateurPageSlider)){
			var indicateursHTML = "";
			//console.log("nbr indicateurs = ",countNbrIndicateurs)
			for(var ind=0; ind<countNbrIndicateurs;ind++){
				indicateursHTML += '<span class="indicateur'+(ind == 0 ? " active" : "")+'">&nbsp;</span>';
			}
			$(myIndicateurPageSlider).innerHTML = indicateursHTML;
		}

		// on genere le slider avec les donnees du json
		var defaultContainerSize = countListElementsFull * slideSize

		var mySliderHome = new SliderCarousel(idBlock,{
			mode: 'horizontal',
			childSelector :'li.elementSlide',
			scrollBy:scrollBy,
			nextBt: '.nextBtn a',
			prevBt: '.prevBtn a',
			loopOnScrollEnd:false,
			defaultContainerSize: defaultContainerSize,
			defaultSlideSize: slideSize
		});
		mySliderHome.onFinish= function () { Notifier.fireEvent("onLayoutChanged"); }
		mySliderHome.go();

		mySliderHome.addEvent('next', function(){
			var monIndicateur = $(idBlock).getParent().getElement(".indicateurPageSlider").getElement("span.active");
			if($(monIndicateur).getNext('span.indicateur')){
				//alert("next")
				//console.log("on deplace l indicateur vers la droite");
				$(monIndicateur).removeClass("active");
				$(monIndicateur).getNext('span.indicateur').addClass('active');
			}

		});
		mySliderHome.addEvent('previous', function(){
			var monIndicateur = $(idBlock).getParent().getElement(".indicateurPageSlider").getElement("span.active");
			var monIndicateur = $(myIndicateurPageSlider).getElement("span.active");
			if($(monIndicateur).getPrevious('span.indicateur')){
				//alert("prev")
				//console.log("on deplace l indicateur vers la gauche")

				$(monIndicateur).removeClass("active");
				$(monIndicateur).getPrevious('span.indicateur').addClass('active');
			}
		});

		$$('li.elementSlide .imageSlider').addEvents({
			"mouseenter": function (){$(this).addClass("hover")},
			"mouseleave": function (){$(this).removeClass("hover")}
		});
		// delete le bloc des page si pas de page ( disabled ne suffit pas a cause du bouton next qui reste en enable quand meme et des rond de page)
		if (countNbrIndicateurs <= 1)
			$("carouselActions").destroy();

	}
}

function createBlocSliderPage(objJson, idBlock){

	// Pour changer la taille en hauteur des elements slider vertical, changer le slideSize à la hauteur de chaque element.
	// et la repercuter sur la CSS a partir de la ligne 1389
	var slideSize = 65;
	var scrollBy = 4;


	// on cree les li avec les donnes du json
	var myEl = $(idBlock);
	var myContainerLinesPage = myEl.getElement(".innerSlider");
	var myHTMLContentSliderPage = '';

	if(objJson.mag2010playlist){
		var myBtnNext = myEl.getParent().getElements(".nextBtn a");
		var myBtnPrev = myEl.getParent().getElements(".prevBtn a");

		var myObjPlaylist = objJson.mag2010playlist;
		$(myContainerLinesPage).empty();

		var countListeElements = myObjPlaylist.videos.length;
		var countListeElementsRestant = countListeElements%4;

		myObjPlaylist.videos.each(function(el){
			//console.log(el);
			myHTMLContentSliderPage += '<li class="elementSlide">';

			myHTMLContentSliderPage += '<div class="imageSlider">';
				myHTMLContentSliderPage += '<div class="maskImage"><a href="'+el.url+'"><img src="/img/mag/maskSlider.png" class="pngFix" alt="" /></a></div>';
				myHTMLContentSliderPage += '<a href="'+el.url+'"><img src="'+el.image+'" class="" alt="'+el.title+'" /></a>';
			myHTMLContentSliderPage += '</div>';

			myHTMLContentSliderPage += '<div class="textSlider">';
				if (el.title.length > 40)
					el.title=el.title.substr(0,37)+' ...';
				myHTMLContentSliderPage += '<span class="title">'+el.title+'</span> - <span class="vues">'+el.views+' vues</span>';
				if (el.description != ''){
					if (el.description.length > 60) {
						el.description=el.description.unescapeHtml().stripTags();
	                    el.description=el.description.substr(0,57)+' ...';
	                } else
	                    el.description=el.description.unescapeHtml();
				}
				myHTMLContentSliderPage += '<div class="desc">'+el.description+'</div>';
			myHTMLContentSliderPage += '</div>';

			myHTMLContentSliderPage += '</li>';
		});
		/*if(countListeElementsRestant != 0){
			for(var i = countListeElementsRestant; i<4; i++){
				myHTMLContentSliderPage += '<li class="elementSlide">&nbsp;</li>';
			}
		}*/


		//console.log(myHTMLContentSlider)
		myContainerLinesPage.innerHTML = myHTMLContentSliderPage;

		// on genere le slider avec les donnees du json

		var defaultSizeSliderPage = (countListeElements < scrollBy)?countListeElements*slideSize:scrollBy*slideSize;
		$('mySliderPage').setStyle("height",defaultSizeSliderPage+"px");
		var defaultContainerSize = countListeElements * slideSize

		var mySliderHome = new SliderCarousel(idBlock,{
			mode: 'vertical',
			childSelector :'li.elementSlide',
			scrollBy: scrollBy,
			nextBt: '.nextBtn a',
			prevBt: '.prevBtn a',
			loopOnScrollEnd:false,
			defaultContainerSize: defaultContainerSize,
			defaultSlideSize: slideSize
		});
		mySliderHome.go();

		$$('li.elementSlide .imageSlider').addEvents({
			"mouseenter": function (){$(this).addClass("hover")},
			"mouseleave": function (){$(this).removeClass("hover")}
		});

		//supprime les bouton ( disabled ne suffit pas a cause du bouton next qui reste en enable quand meme)
		if (countListeElements < 5) {
			$$('.prevBtn').each (function(el){
				el.setStyle('display','none');
			});
			$$('.nextBtn').each (function(el){
				el.setStyle('display','none');
			});
		}
	}
}

var MagTabs = new Class({
	initialize: function (el){
		var _this = this;
		this.el = $(el);
		this.imgs = this.el.getElements('.blockMagTabsBtn');
		this.ctns = this.el.getElements('.blockMagTabsCtn');
		//this.bottom = $(el).getElement('.blockMagTabsBottom');
        if (this.imgs.length > 1)
		    this.imgs[1].set('tween', {"duration": "short"});
		this.currentIndex  = 0;
		this.ImgsDatas = {};
		this.fx = new Fx.Elements(this.el.getElements('.blockMagTabsBtn'), {"duration":"short"});
		this.fx2 = new Fx.Elements(this.el.getElements('.blockMagTabsCtn'), {"duration":"short"});
		this.fx3 = new Fx.Elements(this.el.getElements('.blockMagTabsBtn img'), {"duration":"short"});
        if (this.ctns.length > 1)
		    this.el.getElement(".blockMagTabsBottom").setStyle("height", Math.max(this.ctns[0].offsetHeight, this.ctns[1].offsetHeight, this.ctns[2].offsetHeight));
        else
            this.el.getElement(".blockMagTabsBottom").setStyle("height", this.ctns[0].offsetHeight);
		this.imgs.each(function (el, i){
			el.setAttribute('index', i);
			el.addEvent("mouseenter", function (e){
				var t = $(e.target);
				if(!e.target.hasClass('blockMagTabsBtn')){
					t = t.getParent('.blockMagTabsBtn');
				}
				this.toggle(t.getAttribute('index'))

			}.bind(this))

			el.addEvent("click", function (e){
				var t = $(e.target);
				if(!e.target.hasClass('blockMagTabsBtn')){
					t = t.getParent('.blockMagTabsBtn');
				}
				//this.refreshFlash(t.getAttribute('index'))
				this.refreshFlash(t.getAttribute('ts'))
			}.bind(this))
		}.bind(this));
        if (this.ctns.length > 1)
		    this.toggle("0");




		this.aStamps = [];
		/*new Request({
		//	method: 'get',
		//	url: '/fr/xml/timeStamps.xml',
		//	onSuccess : function(response){
		//		var obj  = new XML2OBJ(this.response.xml).flashmag2010;
		//		_this.onSuccessHandler(obj);
		//	}
		//}).send();*/

	},
	onSuccessHandler : function(o){
		var _this = this;
		//var videos = o('video');
		for (var i=0; i < o.video.length; i++) {
			var video = o.video[i];
			var reg = new RegExp(sIdToChoose);
			if (reg.test(video.med_id)){
				for (var i=0; i < video.timecodes.timecode.length; i++) {
					var timecode = video.timecodes.timecode[i];
					_this.aStamps.push(timecode.txt);
				};
			}
		};
	},

	toggle: function (index){
		this.fx.cancel();
		this.fx2.cancel();
		this.fx3.cancel();
		var oFx = [
			{'height': 120,'width':372,'zIndex': 10,'top': 0},
			{'height': 110,'width':341,'zIndex': 5,'top': 5},
			{'height': 100,'width':310,'zIndex': 1,'top': 10},
			//
			{'opacity': 1},

			{'opacity': 0},

			{'opacity': 0.6},

			{'opacity': 0.3}

		];
		switch(index){
			case "0":
			case 0:
				if(Browser.Engine.tridentrrr && Browser.Engine.version){
					this.el.addClass('onStep1');
					this.el.removeClass('onStep2');
					this.el.removeClass('onStep3');

				}
				else {
					this.fx3.start({'0': oFx[3],'1': oFx[5],'2': oFx[6]})
					this.fx.start({'0': oFx[0],'1': oFx[1],'2': oFx[2]});
					this.fx2.start({'0': oFx[3],'1': oFx[4],'2': oFx[4]})
					this.imgs[1].tween('marginLeft', -154);
				}
				break;
			case "1":
			case 1:
				if(Browser.Engine.tridentrrr && Browser.Engine.version){
					this.el.addClass('onStep2');
					this.el.removeClass('onStep3');
					this.el.removeClass('onStep1');
				}
				else {
					this.fx3.start({'0': oFx[5],'1': oFx[3],'2': oFx[5]})
					this.fx.start({'0': oFx[1],'1': oFx[0],'2': oFx[1]});
					this.fx2.start({'0': oFx[4],'1': oFx[3],'2': oFx[4]})
					this.imgs[1].tween('marginLeft', -186);
				}
				break;
			case "2":
			case 2:
				if(Browser.Engine.tridentrrr && Browser.Engine.version){
				this.el.addClass('onStep3');
				this.el.removeClass('onStep1');
				this.el.removeClass('onStep2');
				}
				else {
					this.fx3.start({'0': oFx[6],'1': oFx[5],'2': oFx[3]})
					this.fx.start({'0': oFx[2],'1': oFx[1],'2': oFx[0]});
					this.fx2.start({'0': oFx[4],'1': oFx[4],'2': oFx[3]})
					this.imgs[1].tween('marginLeft', -194);
				}
				//this.bottom.tween('height', this.ctns[2].offsetHeight);
		}


	},

	refreshFlash: function(index){
		var myFx = new Fx.Scroll($(document.body)).toElement('main');
		//updatePlayerMag2010(this.aStamps[index]);
		updatePlayerMag2010(index);
	}
});

var MagDiapos = new Class({
	initialize: function (el){
		var _this = this;
		this.el = $(el);

		this.imgs = this.el.getElements('.blockMagTabsBtn');

		this.imgs[1].set('tween', {"duration": 700})
		this.currentIndex  = 0;
		this.ImgsDatas = {};
		this.fx = new Fx.Elements(this.el.getElements('.blockMagTabsBtn'), {"duration":700});
		this.fx2 = new Fx.Elements(this.el.getElements('.blockMagTabsBtn .bgBlack'), {"duration":700});
		this.fx3 = new Fx.Elements(this.el.getElements('.blockMagTabsBtn .containerDiapo'), {"duration":700});

		this.imgs.each(function (el, i){
			el.setAttribute('index', i);
			var fxElem = new Fx.Elements(el.getElements(".imageContainer .maskImage"), {"duration":"short"});

			el.addEvent("mouseenter", function (e){
				el.getElements(".imageContainer").addClass("hover");
				var t = $(e.target);
				if(!e.target.hasClass('blockMagTabsBtn')){
					t = t.getParent('.blockMagTabsBtn');
				}
				var myStep = parseInt(t.getAttribute('index'));

				if(this.timerAutoSlide && myStep >= this.stepImage){
					clearInterval(this.timerAutoSlide);
				}

				if(this.timerSwap) clearTimeout(this.timerSwap);
				this.timerSwap = setTimeout(function(){
					_this.goToggle(myStep);
				},300);

			}.bind(this));
			el.addEvent("mouseleave", function (e){
				el.getElements(".imageContainer").removeClass("hover");

				var t = $(e.target);
				if(!e.target.hasClass('blockMagTabsBtn')){
					t = t.getParent('.blockMagTabsBtn');
				}
				var myStep = parseInt(t.getAttribute('index'));
				if(this.timerSwap) clearTimeout(this.timerSwap);
				if(this.timerAutoSlide && myStep >= this.stepImage){
					clearInterval(this.timerAutoSlide);
					this.setTimer();
				}

			}.bind(this))

		}.bind(this));
		this.toggle("0");
		this.stepImage = 0;
		this.aStamps = [];

		this.setTimer();

	},
	goToggle : function(myStep){
		this.toggle(myStep);
		this.stepImage = myStep;
	},
	setTimer : function(){
		var _this = this;
		this.timerAutoSlide  = setInterval(function (){
			_this.nextStep();
		},5000);
	},
	nextStep : function(){
		var myStep = (this.stepImage+1)%3;
		this.toggle(myStep);
		this.stepImage = myStep;
	},
	onSuccessHandler : function(o){
		var _this = this;

		for (var i=0; i < o.video.length; i++) {
			var video = o.video[i];
			var reg = new RegExp(sIdToChoose);
			if (reg.test(video.med_id)){
				for (var i=0; i < video.timecodes.timecode.length; i++) {
					var timecode = video.timecodes.timecode[i];
					_this.aStamps.push(timecode.txt);
				};
			}
		};
	},

	toggle: function (index){
		this.fx.cancel();
		this.fx2.cancel();
		this.fx3.cancel();
		var oFx = [
			{'height': 245,'width':820,'zIndex': 10,'top': 0},
			{'height': 185,'width':60,'zIndex': 5,'top': 27},
			{'height': 125,'width':60,'zIndex': 1,'top': 54},
			//
			{'opacity': 0, "height": 243, "width": 818},

			{'opacity': 1},

			{'opacity': 0.3, "height": 183, "width": 59, "margin-left":1, "margin-right":0},

			{'opacity': 0.6, "height": 123, "width": 59, "margin-left":1, "margin-right":0},
			//
			{'height': 243,'width':818},

			{'height': 183,'width':59},

			{'height': 123,'width':59},

			{'opacity': 0.3, "height": 183, "width": 59, "margin-right":1, "margin-left":0},

			{'opacity': 0.3, "height": 183, "width": 59, "margin-right":1, "margin-left":0}
		];
		switch(index){
			case "0":
			case 0:
				if(Browser.Engine.tridentrrr && Browser.Engine.version){
					this.el.addClass('onStep1');
					this.el.removeClass('onStep2');
					this.el.removeClass('onStep3');

				}
				else {
					this.fx2.start({'0': oFx[3],'1': oFx[5],'2': oFx[6]});
					this.fx3.start({'0': oFx[7],'1': oFx[8],'2': oFx[9]});
					this.fx.start({'0': oFx[0],'1': oFx[1],'2': oFx[2]});
					this.imgs[1].tween('marginLeft', -410);
					this.el.addClass('onStep1');
					this.el.removeClass('onStep2');
					this.el.removeClass('onStep3');
				}
				break;
			case "1":
			case 1:
				if(Browser.Engine.tridentrrr && Browser.Engine.version){
					this.el.addClass('onStep2');
					this.el.removeClass('onStep3');
					this.el.removeClass('onStep1');
				}
				else {
					this.fx2.start({'0': oFx[10],'1': oFx[3],'2': oFx[5]});
					this.fx.start({'0': oFx[1],'1': oFx[0],'2': oFx[1]});
					this.fx3.start({'0': oFx[8],'1': oFx[7],'2': oFx[8]});
					this.imgs[1].tween('marginLeft', -410);
					this.el.addClass('onStep2');
					this.el.removeClass('onStep3');
					this.el.removeClass('onStep1');
				}
				break;
			case "2":
			case 2:
				if(Browser.Engine.tridentrrr && Browser.Engine.version){
					this.el.addClass('onStep3');
					this.el.removeClass('onStep1');
					this.el.removeClass('onStep2');
				}
				else {
					this.fx2.start({'0': oFx[11],'1': oFx[10],'2': oFx[3]});
					this.fx.start({'0': oFx[2],'1': oFx[1],'2': oFx[0]});
					this.fx3.start({'0': oFx[9],'1': oFx[8],'2': oFx[7]});
					this.imgs[1].tween('marginLeft', 350);
					this.el.addClass('onStep3');
					this.el.removeClass('onStep1');
					this.el.removeClass('onStep2');
				}
				//this.bottom.tween('height', this.ctns[2].offsetHeight);
		}
	}
})



/**
**
**/
/*	fixPng :
	@function 	: 	fixe les images de fond png 24 bits sous IE6 (pour la transparent alpha) ainsi que les tags <img>
    @desc 			: 	cette fonction est appelée par la CSS pour un élément qui a un PNG24Bits en background,
							Un élément (<i> dans notre cas) est généré et mis en position:absolute avec z-index:-1 et des largeur/hauteur de 32000px, celui-ci contiendra l'image en PNG.afin de gérer les élément extensible.
							Cette méthode a été utilisée afin de ne page avoir le bug ou certains contenus se retrouve désactivé (liens) lorsqu'on utilise le filter sur un élément.
							L'élément conteneur se verra appliqué un position:relative (si position de base est 'static') et un overflow:hidden afin de bien cacher le le dépassement de l'éménet qui contient l'image.
							Si on ne veut pas utiliser l'overflow:hidden ou on veut utiliser la methode 'crop' il est possible de passer des parametres à la fonction (cf @params)
							Fonctionne aussi avec les tag <img> on le nécessaire est faire pour remplacer l'image, sans la désactiver (cf @additional)
	@use				:   A utiliser dans la CSS, ex :
							.myclass{
								background:url('skin/nav/backgroundnav.png) no-repeat left top;
								filter:expression(pngFix(this));
							}
	@params		:	pngFix(element:HTMLElement, noOverflow:boolean, scale:boolean);
							- element : element HTML : passer  this dans la CSS.
							- noOverflow (true) :	par defaut on utilise un overflow:hidden, sur le parent conteneur, si cela, gêne,
																il suffit de passer la valeur true pour ce parametre, et automatiquement on utilisera un overflow:visible;
							- scale (true): 	par défaut la methode du filter est 'crop', ce qui est le comportement normal d'une image de background.
													Mais pour certaines raisons l'image a besoin de prendre tout le block , ex: une image de 1px répétée.
													Donc pour cela, la seule manière est d'utiliser la méthode 'scale' du imageAlphaLoader.
	@additional	: Gère aussi les tag <img> qui seront automatiquement transformés en image avec transparence PNG.
							En utilisant la méthode de base  (appel au filter), l'image est automatiquement gérée.
							Mais si on veut faire du cas par cas, il suffit de créer une classe CSS appelée pngFix, qui sera ensuite posée sur les tags <img>
								img.pngFix {filter:expression(pngFix(this));}
								<img src="img/myImage.png" class="pngFix" />
	@exemples	:
						- filter:expression(pngFix(this))  //==> mode normal, un layer contenant le png dans le fond, est mis sur l'élément avec comme avantage
																				de pouvoir utiliser une image très grande, et automatiquement,
																				le bloc peut etre extensible en largeur + hauteur.
						- filter:expression(pngFix(this, null, true))  //==> l'image prend toute la taille du bloc, ce qui est utile par exemple pour simuler un png répété sous les autres navigateurs
						- filter:expression(pngFix(this, true))  //==> on ne change que l'overflow par visible, ce qui du coup ne permet plus d'avoir un bloc extensible à 100% en largeur

	@TODO		:
						- Gérer les overflow:auto déclarés par défaut, et  caller automatiquement le layer indiquer cela dans une doc, qu'il faut obligatoirement un élément conteneur.
						- gérer les options en les mettant obligatoirement entre guillement, comme ça on pourra traiter facilement un dictionnaire de parametres type JSON.
						- gérer les background-position en utilisant le sizingMethod 'image '

*/
function pngFix(elm, noOverflow) {

	//elm.style.filter = ' ';
	if (!(document.all && window.print && /MSIE [56]/.test(navigator.userAgent))) return;
	var exec = (function(elm, noOverflow, scale) {
		return function() {


			var options = { noOverflow:noOverflow};
			var repeat = elm.currentStyle.backgroundRepeat.toLowerCase()=='repeat';
			elm.style.filter = ' ';
				// si l'élément est un tag img, on va en faire creer une balise qui encadrera cette image et ensuite traiter la balise comme si c'etait un élément qui avait une image de fond
				if (elm.nodeName.match(/^(IMG|INPUT)$/)) {
					if (!elm.src.match(/.*\.png$/)) return;

					elm.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod='image', src='"+ elm.src + "')";

					elm.width = elm.offsetWidth;
					elm.height = elm.offsetHeight;

					/* recuperation de l'url du pixel transparent */
					var url = elm.currentStyle.backgroundImage.match(/^url\(["'](.*\.gif)["']\)$/); //seulement les .png
					elm.src = url[1];
					elm.className = elm.className.replace(/pngFix/g,'');

				}
				else {
					if (elm.currentStyle.backgroundImage == "" || elm.currentStyle.backgroundImage == "url()") return;
					var url = elm.currentStyle.backgroundImage.match(/^url\(["'](.*\.png)["']\)$/); //seulement les .png
					if (!url || url.length<2) return;
					var pngLayer = document.createElement('i'); // on genere un <i> en position:absolute (layer), qui viendra se placer sous le contenu du div  qui avait besoin du style.
					with(pngLayer.style) {
						if (options.noOverflow) {
							width = elm.offsetWidth + 'px';
							height = elm.offsetHeight + 'px';
						} else {
						 	width = '32000px';
							height = '32000px';
						}
						position = 'absolute';
						zIndex = -1;
						fontSize = '1%';
						filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod='" + (options.noOverflow ? 'crop' : 'image') + "', src='"+url[1]+"')";
						background = 'none'; //forcing car parfois il peut arriver qu'on ai une CSS qui vienne rajouter des images / couleurs de fond
						/* positionnement de l'image en fonction du background-position sur l'element */
						if (!repeat) {
							switch((elm.currentStyle.backgroundPositionX+'').toLowerCase()) {
								case 'left' : left=0; break;
								case 'right' : right = 0; break;
								case 'center' :
									left='50%';
									setTimeout(function(pngLayer) {
										return function() {
											pngLayer.style.marginLeft = -(pngLayer.offsetWidth/2)+'px';
										}
									}(pngLayer), 50);
									break;
								default :
									left = elm.currentStyle.backgroundPositionX;
							}

							switch((elm.currentStyle.backgroundPositionY+'').toLowerCase()) {
								case 'top' : top = 0; break;
								case 'bottom' : bottom = 0; break;
								case 'center' :
									top='50%';
									setTimeout(function(pngLayer) {
										return function() {
											pngLayer.style.marginTop=-(pngLayer.offsetHeight/2)+'px';
										}
									}(pngLayer), 100);
									break;
								default :
									top = elm.currentStyle.backgroundPositionY || 0;
							}
						} else {
							left = 0; //elm.currentStyle.backgroundPositionX +'';
							top = 0; //elm.currentStyle.backgroundPositionY +'';
						}
					}

						/* gestion automatique du sizingMethod='scale' ou sizingMethod='image', ne pouvant pas tester le backgroundRepeat correctement, on passe par une methode un peu plus tricky */
						setTimeout(function(elmN, pngLayerN, repeatN) {
							return function() {
								if (!elmN || elmN.parentNode || !pngLayerN || !pngLayerN.parentNode) return;
								if (pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod=='image') {
									if (pngLayerN.offsetWidth<elmN.offsetWidth && repeatN) {
										pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod='scale';
									} else if (pngLayerN.offsetWidth>elmN.offsetWidth && elm.currentStyle.backgroundPositionX.match(/^(left|0%|0px|0)$/) || elm.currentStyle.backgroundPositionY.match(/^(top|0%|0px|0)$/)){
										pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod='crop';
									}
								} else {
									pngLayerN.sizingMethod = 'image';
								}
								if (elm.currentStyle.width.match(/^(0|[12](%|px)?)$/)) {
									pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod='image';
								}
								if (pngLayerN.style.right != 'auto' && pngLayerN.style.right !='')
									setTimeout(function() {
										pngLayerN.style.right = parseInt(pngLayerN.style.right) - (elm.offsetWidth%2 ? 1 : 0) + 'px';
									}, 50)
							}
						}(elm, pngLayer, repeat), 200);

					with (elm.style) {
						position = elm.currentStyle.position=="static" || elm.currentStyle.position=="" ? 'relative' : position;
						if (elm.currentStyle.overflow!='auto' && elm.currentStyle.overflow!='hidden') overflow = options.noOverflow ? 'visible' : (elm.currentStyle.width.match(/^(0|[12](%|px)?)$/) ? 'visible' : 'hidden');
						backgroundImage = 'none';
					}
					elm.appendChild(pngLayer);

			}
		}
	})(elm, noOverflow);
	try{
		pngFixLoader.useOnload ? pngFixLoader.addFunc(exec) : exec();
	} catch(e) {};
}



/* pngFixLoader
	@unction 		:	objet pour permet le lancement des modifications des png via pngFix en décalé sur le onload de la page.
							cela permet de contourner un bug d'internet explorer qui affiche un message d'erreur si le DOM est modifié pendant le chargement de la page.
*/
var pngFixLoader = {
	useOnload : false, // true : active l'execution du fixPng sur le load, et false, execute le fixPng dès qu'il est appelé par la CSS
	functions : [], // toutes les fonctions à éxécuter sur le onload de la page
	addFunc : function(func) {
		pngFixLoader.functions.push(func);
	},
	launch : function() {
			pngFixLoader.useOnload = false; //une fois la page chargée, il faut laisser s'executer automatiquement la fonction pour d'autres actions (ex : ouverture layer)
			var counter = 1;
			while(pngFixLoader.functions.length>0) {
				//setTimeout(pngFixLoader.functions.pop(), 20*counter);
				pngFixLoader.functions.pop()();
				counter++;
			}
	},
	init : function() {
		if (pngFixLoader.useOnload && window.attachEvent && document.all) {
			window.attachEvent('onload', function() {
				setTimeout(pngFixLoader.launch, 100);
			});
		}
	}
}
pngFixLoader.init();




/*
    XML2OBJ {Class}

    Transforme un xml en object js parametrable

    <monNoeud monAttribut="toto">monTexte</monNoeud>

    @use
        new XML2OBJ("/mon/fichier.xml")
        new XML2OBJ("/mon/fichier.xml", {arrayForcedNode:"item|article"})
        new XML2OBJ(responseXML, {arrayForcedNode:["item", "article"], arrayForcedAttribute:"attr"})

    @param  xml {string|document}
        si string: alors url chargement synchrone du xml (ne marche pas sous webKit)
        si document:  responseXML au onSuccess d'un appel AJAX

    @param options {object}

        @property arrayForcedNode {regexp|array|string}

            si regexp: un object RegExp
            si string: de la forme 'elm' matchera <elm> et pas <elms>
            si array: de la forme ['elm' , 'node', 'root'] matchera strictement les noeuds

            avec arrayForcedNode = "*" toutes les proprietes de l'objet representant des noeuds seront array,
            mais pas les attributes

        @property arrayForcedAttribute {string}
            par defaut, les attributs des nodes deviennent des propriétés de l'object monNoeud.monAttribut = "toto"
            si sette, les attributs se poussent dans un array monNoeud[arrayForcedAttribute][monAttribut] = "toto"

        @ property nodeTextPropertyName {string}
            par defaut, le textContent du noeud se trouve dans monNoeud.txt = monTexte
            si sette devient monNoeud.nodeTextPropertyName = monTexte

        @property tagNamePropertyName {string}
            chaque objet recoit une propriete contenant le nom du noeud,
            valeur par defaut "tag", a ne modifier qu'en cas de conflit.

        @property rootTagPropertyName {string}
            variable contenat le nom du noeud root, par defaut = root
            var json = XML2OBJ(responseXML);
            le noeud racine du XML se pointe comme ceci : json[json.root];



        JSON = {
            root : "structures",
            structures : {...},
            url: "http://mon.xml"
        }
        nous pouvons donc cibler l'element racine comme ceci :  JSON[JSON.root]

    @method getTEXT : retourne l'objet JSON en string (eval())


    @return instance

    les methodes privees _load et _createDocument sont fortement inspirées de xml.js -  http://www.davidflanagan.com/javascript5/
    sourceCode of the Bible, o'Reilly's JS Definitive Guide by David Flanagan
*/

var XML2OBJ = function (){
    this.initialize.apply(this, arguments);
}

XML2OBJ.prototype = {

    constructor : XML2OBJ,

    options : {
        arrayForcedNode: "^$",
        objectForcedAttribute: false,
        arrayForcedAttribute: false,
        nodeTextPropertyName: "txt",
        tagNamePropertyName: "tag",
        rootTagPropertyName: "root"
    },

    initialize: function (sXml, oOptions){

        // setOptions
        this.setOptions(oOptions);

        // creation d'un doc xml
        this.xml = this._load(sXml);

        // vars
        this.cache = {};
        this[this.options.rootTagPropertyName] = this.xml.documentElement.nodeName; // this.root

        // lancement recursion
        this._build(this.xml, this);

        //console.log(this[this.root]);
    },

    //retourne l'objet genere
    getJSON : function (){
        if(!this.json){
            this.json = {
                root : this.root
            };
            this._build(this.xml, this.json);
        }
        return this.json;
    },

    // retourne une chaine text (facon json)
    getTXT : function (oNode){
        if(!oNode) oNode = this.json;
        return this._jsonToString(oNode);
    },

    // construction du json recursive
    _build : function (eNode, oParent){
        for(var i=0,l=eNode.childNodes.length;i<l;i++){
            var node = eNode.childNodes[i];
            if(node.nodeType != 1) continue;
            var oNode = this._createObject(node, oParent);
            this._build(node, oNode);
        }
    },

    // ajout de l'object node dans le json
    _inject: function (oParent, oNode ){

        var forceArray = this.options["arrayForcedNode"].test(oNode[this.options.tagNamePropertyName]);

        // si la propriete n'existe pas on l'a cree
        if(!oParent[oNode[this.options.tagNamePropertyName]] && !forceArray) {
            oParent[oNode[this.options.tagNamePropertyName]] = oNode;
        }
        // si la propriete n'existe pas, et que node est un arrayForcedNode on cree un array
        else if(!oParent[oNode[this.options.tagNamePropertyName]] && forceArray) {
            oParent[oNode[this.options.tagNamePropertyName]] = [oNode];
        }
        // si parent exite comme str , transforme en [] puis push
        else if (oParent[oNode[this.options.tagNamePropertyName]] && !oParent[oNode[this.options.tagNamePropertyName]].push){
            oParent[oNode[this.options.tagNamePropertyName]] = [oParent[oNode[this.options.tagNamePropertyName]], oNode];
        }
        // si parent existe comme [], push
        else if (oParent[oNode[this.options.tagNamePropertyName]] && oParent[oNode[this.options.tagNamePropertyName]].push){
            oParent[oNode[this.options.tagNamePropertyName]].push(oNode);
        }

    },

    // create a object describing the node
    _createObject: function (eNode, oParent){

        var $obj = {};

        // avec arrayForcedAttribute on cree un tableau dans $obj
        var target = this.options.arrayForcedAttribute ? $obj[this.options.arrayForcedAttribute] = [] : $obj
        for(var i=0,A=eNode.attributes,l=A.length;i<l;i++){
            target[A[i].nodeName] =
                this.options.objectForcedAttribute ?
                    this._createAttributeObject(A[i], A[i].nodeValue) :
                    this._evalToBoolean(A[i].nodeValue);
        }

        // stock le contenu text de la balise ou "" si le noeud a des enfants
        var ctn = eNode.text || eNode.textContent;
        //TODO target = var this.options.objectForcedString ? $obj[eNode.nodeName][this.options.nodeTextPropertyName] : $obj[this.options.nodeTextPropertyName];
        $obj[this.options.nodeTextPropertyName] = this._hasChild(eNode) ? "" : ctn;

        // stock le tag
        $obj[this.options['tagNamePropertyName']] = eNode.tagName;
        this._inject(oParent, $obj);
        return $obj;
    },

    _createAttributeObject: function (oNode, sValue){
        var $obj = {};
        $obj[this.options.nodeTextPropertyName] = sValue;
        return $obj;
    },

    // recursive, trasfo de object -> string
    _jsonToString: function (oNode){
        var results = [];
        for(var object in oNode){
            var value = "";
            if(typeof oNode[object] == "string"){
                value = '"'+object+'":"'+this._parseStringProp(oNode[object])+'"';
            }
            else if(typeof oNode[object] == "number"){
                value = '"'+object+'":'+oNode[object];
            }
            else if(oNode[object] && typeof oNode[object].push == "function"){
                var val = [];
                var oSelf = this;
                oNode[object].each(
                    function (el){
                        val.push(oSelf._jsonToString(el));
                    }
                );
                value = '"'+object+'":' + '[' + val.join(', ') + ']'
            }
            else if(typeof oNode[object] == "object"){
                value = '"'+object+'": '+ this._jsonToString(oNode[object]);
            }
            if (typeof value !== "undefined" && value != "") results.push(value);
        };
        return '{' + results.join(', ') + '}';

    },

    // remplace le " par '', le " etant le delimiteur de chaine
    _parseStringProp: function (sProp){
        if(!this.parseRegExp) this.parseRegExp = new RegExp('(")', "g");
        return sProp.replace(this.parseRegExp, "''");
    },


    // tester vitesse avec childNodes
    _hasChild: function (eNode){
        return eNode.getElementsByTagName("*").length == 0 ? false : true;
    },


    // simply load the xml
    _load : function(url) {
        // Create a new document the previously defined function
        // will not work on webKit
        if(typeof url == "string"){
            var xmldoc = this._createDocument();
            xmldoc.async = false;  // We want to load synchronously
            xmldoc.load(url);      // Load and parse
        }
        else {
            if(Browser.Engine.webkit || window.opera){
                var xmldoc = url;
            }
            else {
                var xmldoc = this._createDocument();
                xmldoc.appendChild(url.documentElement);
            }
        }
        return xmldoc;        // Return the document
    },

    _evalToBoolean: function (str){
        return this.options.evalBoolean && str && str.match(/^\s*true|false\s*$/) ? eval(str) : str;
    },

    // create an empty document
    _createDocument : function(rootTagName, namespaceURL) {
        if (!rootTagName) rootTagName = "";
        if (!namespaceURL) namespaceURL = "";

        if (document.implementation && document.implementation.createDocument) {
            // This is the W3C standard way to do it
            return document.implementation.createDocument(namespaceURL, rootTagName, null);
        }
        else { // This is the IE way to do it
            // Create an empty document as an ActiveX object
            // If there is no root element, this is all we have to do
            var doc = new ActiveXObject("MSXML2.DOMDocument");

            // If there is a root tag, initialize the document
            if (rootTagName) {
                // Look for a namespace prefix
                var prefix = "";
                var tagname = rootTagName;
                var p = rootTagName.indexOf(':');
                if (p != -1) {
                    prefix = rootTagName.substring(0, p);
                    tagname = rootTagName.substring(p+1);
                }

                // If we have a namespace, we must have a namespace prefix
                // If we don't have a namespace, we discard any prefix
                if (namespaceURL) {
                    if (!prefix) prefix = "a0"; // What Firefox uses
                }
                else prefix = "";

                // Create the root element (with optional namespace) as a
                // string of text
                var text = "<" + (prefix?(prefix+":"):"") +  tagname +
                    (namespaceURL
                     ?(" xmlns:" + prefix + '="' + namespaceURL +'"')
                     :"") +
                    "/>";
                // And parse that text into the empty document
                doc.loadXML(text);
            }
            return doc;
        }
    },

    setOptions: function (oOpts){
        // permet de passer les options du prototype vers l'instance
        var $obj = this.options;
        this.options = {}
        for(var prop in $obj) this.options[prop] = $obj[prop];
        for(var prop in oOpts) this.options[prop] = oOpts[prop];
        //
        // traitement du arrayForcedNode vers regExp
        if(this.options["arrayForcedNode"] == "*") this.options["arrayForcedNode"] = "[a-zA-Z]*";
        this.options["arrayForcedNode"] = this.toRegExp(this.options["arrayForcedNode"], "");
    },

    toRegExp: function (src, opt){
        if(src.exec) return src;
        var $str = "\\b"+src+"\\b";
        if(src && src.push) $str = src.join("|");
        if(!src) $str = "^$";
        return new RegExp($str, opt)
    },

    toHTML: function (){

    }

}


