/* Goofy Boxes by willem.spruijt@gmail.com */
/* This scripts depends on Script.acu.us & Prototype!! */

var sTheme = 'goofy';

var aBoxes = new Array(); /* The shiftable boxes */
var aStaticBoxes = new Array(); /* The static boxes */
var aMinimizedBoxes = new Array(); /* The minimized boxes */

var focusedBox;
var iScreenCenterX;
var iScreenCenterY;
var iScreenWidth;
var iScreenHeight;
var izIndex=0;
var bShiftMode = false;
var bShifting = false;

var iShiftDiff = 10;

function DragBox(width, height, name, aOptions) {
	
	/* Boxes */
	var boxDiv;
	var boxDivHeader;
	var boxDivBody;
	
	/* Sizes & margins */
	this.boxHeight = height;
	this.boxWidth = width;
	this.originalLeft=null;
	this.originalTop=null;
	
	/* Shiftable */
	this.shiftable = true;
	if(aOptions.shiftable == false) this.shiftable=false;
	
	/* Colors */
	if(aOptions.mainColor) 			this.mainColor = aOptions.mainColor; 				else this.mainColor = '#FF0000';
	if(aOptions.backgroundColor)	this.backgroundColor = aOptions.backgroundColor;	else this.backgroundColor = '#FFFFFF';
	
	/* Maximized / Minimized */
	this.minimized = false;
	this.maximized = false;
	
	/* Assign the width & height */
	this.boxDiv = document.createElement('div');
	this.boxDiv.className = 'dragBox';
	this.boxDiv.style.width = width + 'px';
	this.boxDiv.style.height = height + 'px';
	
	/* Generate a random id */
	this.boxDiv.id = 'dragbox_'+Math.floor(Math.random()*100000);

	/* Create header */
	this.boxDivHeader = document.createElement('div');
	this.boxDivHeader.className = 'boxHeader';
	
	var headerLeft = document.createElement('div');
	headerLeft.className = 'headerLeft';
	headerLeft.innerHTML = name;

	$(headerLeft).setStyle({width:'50%',height:'18px',overflow:'hidden'});	
		
	var headerRight = document.createElement('div');
	headerRight.className = 'headerRight';
	
	
	var minLink= document.createElement('a');
	
	$(minLink).addClassName('minLink');

	var minImg = document.createElement('img');
	$(minImg).setStyle({borderWidth:'0px'});
	$(minImg).setStyle({marginRight:'1px'});
	minImg.src = 'goofyboxes/themes/'+sTheme+'/icon_minimize.gif';	
	
	minLink.onclick = new Function('minimizeBox(\''+this.boxDiv.id+'\')');	
	minLink.appendChild(minImg);
	
	var closeLink = document.createElement('a');
	$(closeLink).addClassName('closeLink');
	// closeLink.innerHTML = 'X';
	var closeImg = document.createElement('img');
	$(closeImg).setStyle({borderWidth:'0px'});
	closeImg.src = 'goofyboxes/themes/'+sTheme+'/icon_close.gif';
	
	closeLink.onclick = new Function('closeBox(\''+this.boxDiv.id+'\')');
	closeLink.appendChild(closeImg);

	var maxLink= document.createElement('a');
	$(maxLink).addClassName('maxLink');
	// maxLink.innerHTML = '<>';
	
	var maxImg = document.createElement('img');
	$(maxImg).setStyle({borderWidth:'0px'});
	$(maxImg).setStyle({marginRight:'1px'});
	maxImg.src = 'goofyboxes/themes/'+sTheme+'/icon_maximize.gif';	
	
	maxLink.onclick = new Function('maximizeBox(\''+this.boxDiv.id+'\')');
	maxLink.appendChild(maxImg);
	
	headerRight.appendChild(minLink);
	headerRight.appendChild(maxLink);
	headerRight.appendChild(closeLink);
		
	this.boxDivHeader.appendChild(headerLeft);
	this.boxDivHeader.appendChild(headerRight);
	
	/* Create body box */
	this.boxDivBody = document.createElement('div');
	this.boxDivBody.className = 'boxBody';

	/* hide on default */
	$(this.boxDiv).hide();
		
	/* Bring the box on top */
	izIndex = izIndex + 1;
	this.boxDiv.style.zIndex = izIndex;

	/* Add to global boxes */
	if(this.shiftable) {
		aBoxes[aBoxes.length] = this;
	} else {
		aStaticBoxes[aStaticBoxes.length] = this;
	}
	
	/* Style */
	$(this.boxDiv).setStyle({position:'absolute',
							 border:'solid 1px '+this.mainColor,
							 backgroundColor:this.backgroundColor});
	
	
	$(this.boxDivHeader).setStyle({height:'17px',
								   cursor:'pointer',
								   margin:'2px',
								   backgroundColor:this.mainColor,
								   fontFamily:'arial',
								   fontSize:'12px',
								   color:this.backgroundColor});
	
	$(this.boxDivBody).setStyle({clear:'both'});
	
	$(headerRight).setStyle({cssFloat:'right',
							 margin:'2px'});
							 
	$(headerLeft).setStyle({cssFloat:'left',
							margin:'2px'});							 
	
	/* append */
	this.boxDiv.appendChild(this.boxDivHeader);
	this.boxDiv.appendChild(this.boxDivBody);
	document.body.appendChild(this.boxDiv);
	
	/* Make draggable */
	new Draggable(this.boxDiv, {handle:this.boxDivHeader});	
	
	/* Register original size */	
	this.originalLeft = this.boxDiv.offsetLeft;
	this.originalTop = this.boxDiv.offsetTop;
}

DragBox.prototype.close = function() {
	/* Fade the box away */
	Effect.Shrink(this.boxDiv, {duration:0.5});	
	/* Remove the draggable from the boxlists */
	if(this.minimized) {
		aMinimizedBoxes = aMinimizedBoxes.without(this);
		new AllBoxes().correctMinimizedBoxes();	
	} else {		
		aBoxes = aBoxes.without(this);
	}
}

DragBox.prototype.minimize = function(iMargin) {
	getDocumentCenter();
	
	if(this.minimized) {
		/* If the content is minimized, back to original sizes */
		iMinimizedWidth = this.boxWidth;
		iMinimizedHeight = this.boxHeight;
		offsetLeft = this.originalLeft;
		offsetTop = this.originalTop;			
		this.unminimize();
		this.maximized = false;
		this.showContent();
	} else {			
		/* We want to minimize */
		this.hideContent();
		var headerHeight = this.boxDivHeader.offsetHeight;
							
		var offsetTop = (iScreenHeight - (headerHeight + (2*iMargin) + (aMinimizedBoxes.length*(headerHeight + 6))));
		var offsetLeft = (iScreenWidth - 200);
		var iMinimizedWidth = 200;
		var iMinimizedHeight = (this.boxDivHeader.offsetHeight + (2*iMargin));
		this.minimized = true;
		
		/* Shift it to the right collection of boxes */
		aMinimizedBoxes.push(this);
		aBoxes = aBoxes.without(this);
	}
	
	new Effect.MoveAndResizeTo(this.boxDiv, offsetTop, offsetLeft, iMinimizedWidth, iMinimizedHeight, {duration:0.5});		
}

DragBox.prototype.unminimize = function() {
	/* The box goes out the minimized state */
	this.showContent();
	new Effect.MoveAndResizeTo(this.boxDiv, this.originalTop, this.originalLeft, this.boxWidth, this.boxHeight, {duration:0.5});		
	this.minimized = false;
	
	aMinimizedBoxes = aMinimizedBoxes.without(this); // Yoo, catch!
	aBoxes.push(this); // thanks, m8
	
	new AllBoxes().correctMinimizedBoxes();	
}

DragBox.prototype.hideContent = function () {
	new Effect.Fade(this.boxDivBody, {duration:0.1});
}

DragBox.prototype.showContent = function () {
	new Effect.Appear(this.boxDivBody, {duration:0.1, delay:0.5});
	
}

DragBox.prototype.appear = function() {
	getDocumentCenter();
	
	this.boxDiv.style.left = this.originalLeft +'px';
	this.boxDiv.style.top = this.originalTop +'px';
	
	Effect.Grow(this.boxDiv, {duration:0.5});	
}

DragBox.prototype.maximize = function (offsetLeft, offsetTop, iMargin) {
	getDocumentCenter();
	if(this.maximized && (!this.minimized)) {
		/* Minimize back to original sizes */
		iMaximizedWidth = this.boxWidth;
		iMaximizedHeight = this.boxHeight;

		offsetLeft = this.originalLeft;
		offsetTop = this.originalTop;
		
		this.maximized = false;
	} else {
		/* Maximize */
		var iMaximizedWidth = (iScreenWidth - offsetLeft - (2*iMargin));
		var iMaximizedHeight = (iScreenHeight - offsetTop - (2*iMargin));
		izIndex = izIndex + 1;
		this.boxDiv.style.zIndex = izIndex;
		
		aBoxes.push(this);
		aMinimizedBoxes = aMinimizedBoxes.without(this);
		
		this.maximized = true;	
		this.minimized = false;	
		
		new AllBoxes().correctMinimizedBoxes();
		this.showContent();
	}
	new Effect.MoveAndResizeTo(this.boxDiv, (offsetTop + iMargin), (offsetLeft + iMargin),iMaximizedWidth, iMaximizedHeight, {duration:0.5});
}

DragBox.prototype.setPosition = function(x, y) {
	this.originalLeft = x;
	this.originalTop = y;
}

DragBox.prototype.setBody = function (sHTML) {
	this.boxDivBody.innerHTML = sHTML;
}

/* Drag/ drop control */
var oDragDropObserver = new function() {							
							this.onEnd = function(event,draggable) {
									if(draggable.element.className == 'dragBox') {
										/* Hold the original position of the window of originalizing */
										oBox = getBox(draggable.element.id);									
										if(!oBox.maximized) {
											oBox.originalLeft = oBox.boxDiv.offsetLeft;
											oBox.originalTop = oBox.boxDiv.offsetTop;	
										}
										
										if(oBox.minimized) {
											oBox.unminimize();	
										}
									}
								}
								
							this.onStart = function(event,draggable) {
									if(draggable.element.className == 'dragBox') {									
										/* Bring on the box on top */
										izIndex = izIndex + 1;
										/* Digg into scriptaculous to chage z-index */
										draggable.originalZ = izIndex;								
									}
								}
							}
						
Draggables.addObserver(oDragDropObserver);

/* Controller functions */

function closeBox(boxId) {
	oBox = getBox(boxId);
	oBox.close();
	
}

function minimizeBox(boxId) {
	oBox = getBox(boxId);
	oBox.minimize(3);	
}

function maximizeBox(boxId) {
	oBox = getBox(boxId);
	oBox.maximize(0, 0, 3);	
}

function getBox(boxId) {
	/* Find the DragBox with that id */
	for(i=0;i<aBoxes.length;i++) {
		box = aBoxes[i];
		if(box.boxDiv.id == boxId) return box;		
	}
	/* Didn't find it, look here */
	for(i=0;i<aStaticBoxes.length;i++) {
		box = aStaticBoxes[i];
		if(box.boxDiv.id == boxId) return box;		
	}
	/* Ok, lets give it a last try */
	for(i=0;i<aMinimizedBoxes.length;i++) {
		box = aMinimizedBoxes[i];
		if(box.boxDiv.id == boxId) return box;		
	}
}

/* AllBoxes */
function AllBoxes() {	
	
}

AllBoxes.prototype.minimize = function() {
	while(aBoxes.length > 0) {
		oBox = aBoxes[0];
		if(!oBox.minimized) {	
			oBox.hideContent();					
			/* Calculate the minimized position */
			var headerHeight = (oBox.boxDivHeader.offsetHeight);
			var offSetBottom = (aMinimizedBoxes.length*(headerHeight+6))+headerHeight;
			var iShiftTop = iScreenHeight - offSetBottom - 6; // - margin
			var iShiftLeft = iScreenWidth - 200;			
			new Effect.MoveAndResizeTo(oBox.boxDiv, iShiftTop, iShiftLeft, 200, headerHeight+6, {duration:0.5});
			
			aBoxes = aBoxes.without(oBox); 
			aMinimizedBoxes.push(oBox);
			
			oBox.minimized = true;
		}		
	}
}

AllBoxes.prototype.toShiftMode = function () {
	bShifting = true;
	getDocumentCenter();
	
	var iShiftOffset = ((aBoxes.length * iShiftDiff)/2);
	var iOpacityDiff = (1/aBoxes.length);		
		
	/* Shift all the boxes to a initial position */
	for(i=0;i<aBoxes.length;i++) {
		var oBox = aBoxes[i];
		
		var iShiftTop = iScreenCenterY - (oBox.boxHeight/2) - iShiftOffset;
		var iShiftLeft = iScreenCenterX - (oBox.boxWidth/2) + iShiftOffset;
		
		iShiftOffset = iShiftOffset - iShiftDiff;
		
		izIndex = izIndex + 1;
		oBox.boxDiv.style.zIndex = izIndex;
		
		/* Adjust opacity */
		iOpacity = iOpacityDiff*(i+1);
		oBox.boxDiv.setStyle({opacity:iOpacity});
		
		new Effect.MoveAndResizeTo(oBox.boxDiv, iShiftTop, iShiftLeft, oBox.boxWidth, oBox.boxHeight, {duration:0.5});
	}		
	setTimeout('bShifting = false;', 500);
}

AllBoxes.prototype.shiftNext = function() {
	var iIndex = aBoxes.length-1;
	var oFirstBox = aBoxes[iIndex];
		
	var toLeft = aBoxes[0].boxDiv.offsetLeft;
	var toTop = aBoxes[0].boxDiv.offsetTop;		
	new Effect.MoveAndResizeTo(oFirstBox.boxDiv, toTop, toLeft, oFirstBox.boxWidth, oFirstBox.boxHeight, {duration:0.2, scope:'firstBox'});
				
	var aNewBoxes = new Array();
	aNewBoxes[0] = oFirstBox;
		
	var iOpacityDiff = (1/aBoxes.length);
	oFirstBox.boxDiv.setStyle({opacity:iOpacityDiff});
		
	/* Shift */
	for(i=0;i<(aBoxes.length-1);i++) {
		oBox = aBoxes[i];
		iOpacity = iOpacityDiff * (i+2);
		oBox.boxDiv.setStyle({opacity:iOpacity});
		izIndex = izIndex + 1;
		oBox.boxDiv.style.zIndex = izIndex;
		iShiftedLeft = oBox.boxDiv.offsetLeft - iShiftDiff;
		iShiftedTop = oBox.boxDiv.offsetTop + iShiftDiff;
		
		new Effect.MoveAndResizeTo(oBox.boxDiv, iShiftedTop, iShiftedLeft, oBox.boxWidth, oBox.boxHeight, {duration:0.3});
		aNewBoxes[i+1] = oBox;		
	}

	aBoxes = aNewBoxes;	
}

AllBoxes.prototype.outShiftMode = function() {
	bShifting = true;	
	/* Shift all the boxes to the original position */
	for(i=0;i<aBoxes.length;i++) {
		var oBox = aBoxes[i];
		
		var iShiftTop = oBox.originalTop;
		var iShiftLeft = oBox.originalLeft;
		
		oBox.boxDiv.setStyle({opacity:1});
		
		new Effect.MoveAndResizeTo(oBox.boxDiv, iShiftTop, iShiftLeft, oBox.boxWidth, oBox.boxHeight, {duration:0.5});
	}			
	setTimeout('bShifting = false;', 500);
}

AllBoxes.prototype.correctMinimizedBoxes = function() {
	/* Shift them to where they should be */
	for(i=0;i<aMinimizedBoxes.length;i++) {
			oBox = aMinimizedBoxes[i];
			/* Calculate the minimized position */
			var headerHeight = (oBox.boxDivHeader.offsetHeight);
			var offSetBottom = (i*(headerHeight+6))+headerHeight;
			var iShiftTop = iScreenHeight - offSetBottom - 6; // - margin
			var iShiftLeft = iScreenWidth - 200;			
			new Effect.MoveAndResizeTo(oBox.boxDiv, iShiftTop, iShiftLeft, 200, headerHeight+6, {duration:0.5});			
	}
}
/* Document related function */
function getDocumentCenter() {
  if((!iScreenCenterX) || (!iScreenCenterY)) {	
	  var myWidth = 0, myHeight = 0;
	  if( typeof( window.innerWidth ) == 'number' ) {
	    //Non-IE
	    myWidth = window.innerWidth;
	    myHeight = window.innerHeight;
	  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
	    //IE 6+ in 'standards compliant mode'
	    myWidth = document.documentElement.clientWidth;
	    myHeight = document.documentElement.clientHeight;
	  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
	    //IE 4 compatible
	    myWidth = document.body.clientWidth;
	    myHeight = document.body.clientHeight;
	  }
	iScreenWidth = myWidth;
	iScreenHeight = myHeight;
	iScreenCenterX = (myWidth/2);
	iScreenCenterY = (myHeight/2);
  }
}

/* Keys */
document.onkeydown = function (e) {
	keyPressed = (window.event) ? event.keyCode : e.keyCode;
	if((keyPressed == 17) && !bShiftMode) { // CTRL
		bShiftMode = true;
		new AllBoxes().toShiftMode();		
	} else if (keyPressed == 68) { // D
		new AllBoxes().minimize();
	} else if ((keyPressed == 39) && bShiftMode && !bShifting) { // arrow-right
		new AllBoxes().shiftNext();
	}
}

document.onkeyup = function (e) {	
	keyUp = (window.event) ? event.keyCode : e.keyCode;
	if((keyUp == 17) && bShiftMode && !bShifting) {
		bShiftMode = false;
		new AllBoxes().outShiftMode();
	}
}

window.onresize = function() {
	/* Correct center */
	iScreenCenterX = null;
	iScreenCenterY = null;
	getDocumentCenter();
	
	/* Correct */
	new AllBoxes().correctMinimizedBoxes();
}



