/*
 * Region class
 *
 * It controls and manages the displayed regions, wjich can be defined globally or per object.
 * Used by Group controls to mark the controlled objects and the surrounding zone
 *
 * */
function Region( attributes ){// constructor for the main class
	if(this.name==null || !this.name )	{
		this.name='Region';
	}

	// internal variables, used pretty often (internally)
	this._heap=new Array();
	this.attributes={};
	this.initialize(attributes);

	// theese are pretty much static
	this.page=$('documentContainer');
	this.pageDimensions=Element.getDimensions(this.page);

	this.version='1.0.0.0';

	//each Grid has its own event scheduler, used for scheduling grid updates
	this.eventScheduler=new _eventScheduler();

	// create the Region object. It will attach global events and handlers
	this.create();

	return true;
}

// general initialiation function. Called by the contructor.
Region.prototype.initialize=function (attributes){
	this.attributes.X=0;
	this.attributes.Y=0;
	this.attributes.width=0;
	this.attributes.height=0;
	this.attributes.border='1px dashed #B8F624';

	this.attributes.zIndex=5;
	this.attributes.opacity=0.75;
	this.attributes.morphDuration=0.75;
	this.attributes.backgroundColor='#fff';
	this._heap['animationFrame']=0;

	return true;
}

// here we create and attach the Control to the DOM. Also bind events.
Region.prototype.create=function (){

	this.attributes.animateLimit_width=Math.round(this.pageDimensions.width)/4;
	this.attributes.animateLimit_height=Math.round(this.pageDimensions.height)/4;

	return true;
}

Region.prototype.destroy=function (){
	this.eventScheduler.destroy();
	if(this.object){
		$(this.object).remove();
	}

	this._heap=null;
	this.attributes=null;
}

// setup a timer to make some repetitive animations
Region.prototype.animateFrame=function (animate){

	var needAnimation=true;

	if((this.attributes.width<=0 || this.attributes.height<=0 )) needAnimation=false;

	if((this.attributes.width>this.attributes.animateLimit_width || this.attributes.height>this.attributes.animateLimit_height ) && this._heap['animationFrame']==0) needAnimation=false;

	if(needAnimation){
		this._heap['animationFrame']=1-parseInt(this._heap['animationFrame']);

		if(this._heap['animationFrame']){
			$(this.object).setStyle({
										'border':'2px dashed #dcf624',
										'padding':'0px'
									});
		}else{
			$(this.object).setStyle({
										'border':'1px dashed #B8F624',
										'padding':'1px'
									});
		}
	}

	this.eventScheduler.cancel('animateFrame');

	if(animate){
		var multiplier=1;
		if(!needAnimation)multiplier=10;

		if(this._heap['animationFrame']){
			this.eventScheduler.schedule('animateFrame',this.animateFrame.bind(this,true),0.75*multiplier);
		}else{
			this.eventScheduler.schedule('animateFrame',this.animateFrame.bind(this,true),0.25*multiplier);

		}
	}

	return true;
}

Region.prototype.setup=function (settings){
	if(settings==null)settings={};

	if(settings.X2!=null)settings.width=settings.X2-settings.X;
	if(settings.Y2!=null)settings.height=settings.Y2-settings.Y;

	var lastAttributes=Object.clone(this.attributes);

	this.attributes.X=(settings.X!=null?settings.X:this.attributes.X);
	this.attributes.Y=(settings.Y!=null?settings.Y:this.attributes.Y);
	this.attributes.width=(settings.width!=null?settings.width:this.attributes.width);
	this.attributes.height=(settings.height!=null?settings.height:this.attributes.height);
	this.attributes.zIndex=(settings.zIndex!=null?settings.zIndex:this.attributes.zIndex);


	if(this.attributes.width==0 && this.attributes.height==0){
		this.attributes.X=Math.round(lastAttributes.X + lastAttributes.width/2);
		this.attributes.Y=Math.round(lastAttributes.Y + lastAttributes.height/2);
		this.attributes.width=0;
		this.attributes.height=0;
	}

	if(this.object){
		// this.object already exists, no further calls to createElement.
	}else{
		this.object=document.createElement('div');
		this.object.style.display='none';
	}

	if(settings.morph){
		$(this.object).setStyle({
								'position':'absolute',
								'opacity':this.attributes.opacity,
								'border':this.attributes.border,
								'padding':'1px',
								'zIndex': this.attributes.zIndex,
								'backgroundPosition': 'center'
							});
		if(this.effect && this.effect.state!='finished')this.effect.cancel();

		this.effect=new Effect.Morph($(this.object),{
								style:{	'left':this.attributes.X+'px',
										'top':this.attributes.Y+'px',
										'width':this.attributes.width+'px',
										'height':this.attributes.height+'px',
										'backgroundColor':this.attributes.backgroundColor
								},
								duration:this.attributes.morphDuration,
								queue:{position: 'end', scope: 'morphs'}
						}
					);
	}else{
		$(this.object).setStyle({
								'left':this.attributes.X+'px',
								'top':this.attributes.Y+'px',
								'width':this.attributes.width+'px',
								'height':this.attributes.height+'px',
								'position':'absolute',
								'opacity':this.attributes.opacity,
								'border':this.attributes.border,
								'padding':'1px',
								'zIndex': this.attributes.zIndex,
								'backgroundColor':this.attributes.backgroundColor
							});
	}

	$(this.page).insert($(this.object));

	//this.object.style.backgroundImage='';
	return this.object;
}

Region.prototype.show=function (){
	if(this.visible)return false;

	this.visible=true;
	//start the element animation
	this.animateFrame(true);

	return new Effect.Appear($(this.object),{duration:0.25, from:0, to:this.attributes.opacity,queue:{position: 'end', scope: 'show'}});
}

// clears the Region. (hides and resets it)
Region.prototype.hide=function (){
	if(!this.visible)return false;

	this.visible=false;
	//start the element animation
	this.animateFrame(false);
	return new Effect.Fade($(this.object),{duration:0.1, from:this.attributes.opacity, to:0,queue:{position: 'end', scope: 'hide'}});
}