/*************************************************

CREATE A FOLDABLE OBJECT
----------------------------------------

Get a DOM element and create a foldable object, like:

	var element=document.getElementById('id');
	element=new foldable(element,target,wMin,wMax,hMin,hMax);

The parameters 

	element : 	the element that calls fold or unfold methods
	target : 	the foldable element 
			for example: element.parentNode or direct load with getElementById, etc...
	wMin :	 the folded horizontal size of the target - use without dimension. 
			In the case, when the property is empty, use the "false" value. 
			for example: element=new foldable(element,target,false,false,hMin,hMax);
	 wMax :	the unfolded horizontal size of the target (follow the rules of wMin)
	 hMin:	the folded vertical size of the target (follow the rules of wMin)
	 hMax:	the unfolded vertical size of the target (follow the rules of wMin)


SET THE ACTIONS AND HANDLERS
-------------------------------------------------

The syntax of the setting 
	
	element.setAction('onclick:unfold')

Possible values for event handling

	- onclick
	- ondblclick
	- onover
	- onout
	- ondown
	- onup

Possibble values for action

	- fold
	- unfold

Use the ":" operator between the event handler and the action.

Use more than one action, for example:

	element.setAction('onover:unfold')
	element.setAction('onout:fold')

The fold/unfold method

	This method switch between two status: first click->fold, second click->unfold, ...
	Available to use with onclick event handler.
	Syntax: element.setAction('onclick:fold/unfold')
	
Possible values for this action

	- fold/unfold : use when the target base position in css is folded
	- unfold/fold : use when the target base position in css is unfolded

The fold/unfold method doesn't work with groups!

THE GROUPS 
-----------------	

Groups are create connection between the caller element and other elements.

The group variables are arrays that contain foldable objects.

	example for using:
	
	1. create foldable objects
		var group1=document.getElementById('container').getElementsByTagName('P');

		for(var i in group1){
			group1[i]=new foldable(...);
			group1[i].setAction('onclick:unfold');
		}

	2.add group1 to group1 elements
		for(var i in group1){
			group1[i].setGroup(group1);
		}

	3.action syntax for using groups
		for(var i in group1){
			group1[i].setAction('onclick:unfold','group:fold')
		}
		
	working of the groups
		
		When the foldable object calls the primary handler, the group action also runs on all group members, 
		except the caller object (if it's member of the group).
		
***************************************************/

function foldable(obj,trg,wMin,wMax,hMin,hMax){

	this.obj=obj; this.step=10;
	
	this.unfold=function(){
			
		var obj=this;	
			
		obj.hFolding=window.clearInterval(this.hFolding);
		obj.hFolding=window.setInterval(function(){
			if(hMax){ trg.offsetHeight<hMax ? 
				trg.style.height=trg.offsetHeight+obj.step+'px' : obj.hFolding=window.clearInterval(obj.hFolding);} },1);

		obj.wFolding=window.clearInterval(this.wFolding);
		obj.wFolding=window.setInterval(function(){
			if(wMax){ trg.offsetWidth<wMax ?
				trg.style.width=trg.offsetWidth+obj.step+'px' : obj.wFolding=window.clearInterval(obj.wFolding);} },1);	
	}
	
	this.fold=function(){
	
		var obj=this;
	
		obj.hFolding=window.clearInterval(this.hFolding);
		obj.hFolding=window.setInterval(function(){
		
			if(hMin){ trg.offsetHeight>hMin+obj.step ?
				trg.style.height=trg.offsetHeight-obj.step+'px' : trg.style.height=hMin+'px';}
			if(hMin){ trg.offsetHeight==hMin ?	
				obj.hFolding=window.clearInterval(obj.hFolding) : false;} },1);
				
		obj.wFolding=window.clearInterval(this.wFolding);
		obj.wFolding=window.setInterval(function(){
		
			if(wMin){ trg.offsetWidth>wMin+obj.step ?
				trg.style.width=trg.offsetWidth-obj.step+'px' : trg.style.width=wMin+'px';}
			if(wMin){ trg.offsetWidth==wMin ?	
				obj.wFolding=window.clearInterval(obj.wFolding) : false;} },1);
	}
	
	this.setGroup=function(group){
		this.group=group;
	}
	
	this.setStep=function(s){
		if(typeof(s)!='undefined' && parseInt(s)>0) this.step=s;
	}
	
	this.setAction=function(actn,group){
	
		var obj=this;
		
		var groupaction=false; 
		var handler=actn.split(':')[0];
		var action=actn.split(':')[1];
		typeof(group)!='undefined' && typeof(obj.group)!='undefined' ? groupaction=group.split(':')[1] : false;
		
		if(handler=='onclick' && action=='fold/unfold' || handler=='onclick' && action=='unfold/fold'){
			obj.stat=action.split('/')[0];
			obj.obj.onclick=function(){
				switch(obj.stat){
					case 'unfold': obj.unfold(); obj.stat='fold'; break;
					case 'fold': obj.fold(); obj.stat='unfold'; break;
				}
			}
		}
		else{
			switch(handler){
				case 'ondblclick' : obj.obj.ondblclick=function(){ eval('obj.'+action+'()'); grAct(); }; break;
				case 'onclick' : obj.obj.onclick=function(){ eval('obj.'+action+'()'); grAct(); }; break;
				case 'onover' : obj.obj.onmouseover=function(){	eval('obj.'+action+'()'); grAct(); }; break;
				case 'onout' : obj.obj.onmouseout=function(){ eval('obj.'+action+'()'); grAct(); }; break;
				case 'ondown' : obj.obj.onmousedown=function(){	eval('obj.'+action+'()'); grAct(); }; break;
				case 'onup' : obj.obj.onmouseup=function(){ eval('obj.'+action+'()'); grAct(); }; break;				
			}
		}
		
		function grAct(){
			if(typeof(obj.group)!='undefined' && groupaction){
				for(var i=0;i<obj.group.length;i++){
					if(obj.group[i]!=obj && groupaction=='fold')obj.group[i].fold();
					if(obj.group[i]!=obj && groupaction=='unfold')obj.group[i].unfold();
				}
			}
		}
	}
}

