/**
 * Net-Createurs DHTML simple effects library
 * showHide = on/off effects
 */

if(typeof(NC)=='undefined') NC={};
NC.showhide= {

	// Returns the library version (what=='') ou its date (what=='date')
	version:function(what) {
		if(typeof(what)=='undefined') var what='';
		if(what.toLowerCase()=='date') return('9 september 2010');
		else if(what.toLowerCase()=='name') return('Net-Createurs FX library: show/hide objects');
		else return('1.1');
	},

	// active() parameters set constructor
	set:function() {
		this.state=new Array();		// Mémo de l'état de chaque objet. Ne pas oublier de l'initialiser si des objets sont ouverts par défaut...
		this.exclusive=true;		// true -> opening a new object closes all other opened objects
		this.closeActiveToo=false;	// (active only when 'exclusive' is true) : true -> the active object can be closed too
		this.closeOpenDelay=0;		// (active only when 'exclusive' is true) : > 0 -> fully close opened object, then wait "delay" msec, then open the new object

		// sliding parameters
		this.xOpenStep=0;			// Sliding step, X axis. 0 = no slide effect
		this.xOpenDelay=5;			// Nb of steps before full speed (1..n)
		this.yOpenStep=0;			// Sliding step, y axis. 0 = no slide effect (1..n)
		this.yOpenDelay=5;

		//  Private vars
		this.open=new Array();
		this.runningProcess=0;				// nb of objects currently opening or closing. 0 -> all the changes are finished
	},

	// Open or close an object (DIV or any other block type tag supporting 'height' and "overflow" attributes)
	// obj = DOM handle or object ID
	// If the object is already opened -> it is closed, and vice-versa
	// param = name of the object containing the parameters
	active:function(obj,param,forced) {
		var params=eval(param),objID=obj;
		params.runningProcess++;		// Tells others that a new process is running
		if(typeof(forced)==undefined) var forced=false;
		if(typeof(obj)=='string') obj=document.getElementById(obj);
		if(obj) {
			if(!obj.id) obj.id='FXshowhide-' + params.state.length;
			var this_object=obj.id, opened=params.state[this_object] ? true : false;
			if(forced || !opened || !params.exclusive || params.closeActiveToo) {
				this.changeImage(params,this_object);		// Modify the active/inactive associated image, if exist
				// Afin d'éviter des débordements au moment du déploiement, on commence par fermer les objets qui doivent l'être
				// Si "closeOpenDelay" est >, alors on attend que la fermeture soit complète avant d'ouvrir le nouvel objet closeOpenDelay msec après
				if(params.exclusive && !opened) {
					for(var i in params.state) {
						if(params.state[i] && i!=this_object) this.active(i,param,true);
					}
				}
				// Open the new active objectf
				params.runningProcess++;
				this.checkDelay(this_object,param,false);
			}
		}
		else if(typeof(objID)=='string' && params.state[objID]) params.state[objID]=false;
		params.runningProcess--;
		return false;
	},

	// Open a new element after checking if a delay is required before
	// If a delay is required -> waits until all others objects are closed, then waits "delay" msec, and then finally opens the object
	checkDelay:function(this_object,param,forced) {
		var params=eval(param),opened=params.state[this_object] ? true : false;
		if(!opened && params.closeOpenDelay>0 && !forced) {
			var ok=true;
			for(var i in params.state) if(params.state[i]) ok=false;
			if(ok) setTimeout("NC.showhide.checkDelay('" + this_object + "','" + param + "',true)",params.closeOpenDelay);
			else setTimeout("NC.showhide.checkDelay('" + this_object + "','" + param + "',false)",50);
		}
		else {
			if(params.xOpenStep!=0 || params.yOpenStep!=0) {
				if(params.xOpenDelay<1) params.xOpenDelay=1;
				if(!params[this_object]) params[this_object]=new Array();
				params['xOpenIncrement']=params.xOpenStep/params.xOpenDelay;
				params[this_object]['xstep']=0;
				if(params.yOpenDelay<1) params.yOpenDelay=1;
				params['yOpenIncrement']=params.yOpenStep/params.yOpenDelay;
				params[this_object]['ystep']=0;
				this.open(this_object,param);
			}
			else {
				obj=document.getElementById(this_object);
				obj.style.display=opened? 'none' : 'block';
				params.state[this_object]=!opened;
			}
		}
	},

	// Change the SRC of the image whose id is img-objID, if exists
	changeImage:function(params,objID) {
		var img=document.getElementById('img-' + objID);
		if(img) {
			var active=params.state[objID] ? false : true,		// The image is changed BEFORE the object status is updated, so what we read is the opposite of the true state
				src=new String(img.src);
			var i=src.lastIndexOf('.');
			if(i!=-1) {
				var name=src.substr(0,i), ext=src.substr(i);
				if(name.substr(name.length-3)=='-on') name=name.substr(0,name.length-3);
				img.src=name + (active ? '-on' : '') + ext;
			}
		}
	},
	
	// Transition effect : slide on/off 
	// param.xopenStep and yOpenStep = sliding step
	open:function(obj,param) {
		var params=eval(param);
		if(typeof(obj)=='string') obj=document.getElementById(obj);
		if(obj) {
			var this_object=obj.id, opened=params.state[this_object] ? true : false;
			if(!params.open[this_object]) {
				/* Initialisations. If the object has not null paddings or margins, we must add an outer div to control the slide, otherwise 
				 * paddings / margins will prevent it have a height/width truely to 0 */
				var	size=NC.tools.objSize(obj);
					style=NC.tools.getStyle(obj),
					padding=this.getValues(style,'padding'),
					margin=this.getValues(style,'margin');
				if(padding[4] || margin[4]) {
					// Must add an outer <div> with no padding / margin
					var newdiv=document.createElement('div');
					obj.style.display='block';
					obj.parentNode.insertBefore(newdiv,obj);
					newdiv.appendChild(obj);
					obj.id=''; newdiv.id=this_object;
					obj=newdiv;
				}
				var style=obj.style;
				style.height=(opened? size[1] : 0) + 'px';
				style.overflow='hidden';
				style.display='block';
				params.open[this_object]= { w0:size[0], h0:size[1], w:parseInt(style.width,10), h:parseInt(style.height,10) };
				if(!params.state[this_object]) params.state[this_object]=false;
			}
			this.openStep(this_object,param);
		}
	},

	// Return the padding or margin values in style, replacing "auto" with 0 and adding a 5th value 'isnull' = true is all padding/margin are equal to 0
	getValues:function(style,cde) {
		var what=new Array('Top','Right','Bottom','Left'),ret=new Array(),x,notnull=false;
		for(var i in what) {
			x=style[cde+what[i]];
			if(x=='auto') x=0; else x=parseInt(x,10);
			ret[ret.length]=x;
			if(x) notnull=true;
		}
		ret[ret.length]=notnull;
		return ret;
	},

	openStep:function(obj,param) {
		var params=eval(param);
		var	obj=document.getElementById(obj),
			this_object=obj.id,
			opened=params.state[this_object] ? true : false,
			h=params.open[this_object].h,
			end=false,
			ystep=params[this_object]['ystep'];
		if(ystep<params.yOpenStep) {
			ystep=ystep+params.yOpenIncrement;
			if(ystep>params.yOpenStep) ystep=params.yOpenStep;
			params[this_object]['ystep']=ystep;
		}
		h+=Math.round(ystep)*(opened ? -1 : 1);
		if(h<=0) { h=0; end=true; }
		else if(h>=params.open[this_object].h0) { h=params.open[this_object].h0; end=true; }
		params.open[this_object].h=h;
		obj.style.height=h+'px';
		if(!end) setTimeout("NC.showhide.openStep('" + this_object + "','" + param + "')",40);
		else {
			params.state[this_object]=!opened;
			params.runningProcess--;
// la fct ci dessous devrait fonctionner mais l'autoslide est remis à 0...
//			if(typeof(NC.autoslide.run)=='function') { for(i in NC.autoslide.names) setTimeout('NC.autoslide.run("' + NC.autoslide.names[i]+'")',100) };	// MAJ des autoSlide
		}	
	}

}

