// animwin2.js
// Author: Bernard Chan (2005-2008)
// Animated DHTML Window 

var AnimatedWindow = function() {
	var id = AnimatedWindow.registerInstance(this);
	this._id = id;
};
Object.extend(AnimatedWindow, {
	registerInstance: function(obj) {
		var id = 'animwin.' + (++AnimatedWindow.idCounter);
		AnimatedWindow.activeWindows[id] = obj;
		return id;
	},
	removeInstance: function(id) {
		delete AnimatedWindow.activeWindows[id];
	},
	idCounter: 0,
	activeWindows: {}
});
Object.extend(AnimatedWindow.prototype, {

	// Getters / Setters

	setContentDiv: function(div) {
		this._contentDiv = div;
	},

	setOrigin: function(x, y) {
		this._origin.x = x;
		this._origin.y = y;
	},

	setStepInterval: function(interval) {
		this._stepinterval = interval;
	},

	setSteps: function(steps) {
		this._steps = steps;
	},

	// Methods ************************************************************
	
	expand: function() {
		this._expand(0);
	},

	isExpanding: function() {
		return !!this._expandingFrame;
	},

	getExpandingFrame: function() {
		return this._expandingFrame;
	},

	_processExpansion: function() {
		var frame = this.getExpandingFrame();
		if (this._step >= this._steps) {
			window.clearInterval(this._intervalId);
			this._intervalId = null;
			this._showContent();
			frame.style.visibility = 'hidden';
			document.body.removeChild(frame);
			this._expandingFrame = null;
			if (this.onexpanded) {
				this.onexpanded();
			}
			return;
		}
		var percentopen = this.expandSpeedRegulator();
		var crect = getClientAreaRect();
		var scrollXY = getScrollXY();
		var c_center = {x: scrollXY[0] + crect.width / 2, y: scrollXY[1] + crect.height / 2};
		var cw = percentopen * this._contentDiv.offsetWidth;
		var ch = percentopen * this._contentDiv.offsetHeight;
		var co = { x: this._origin.x + percentopen * (c_center.x - this._origin.x), y: this._origin.y + percentopen * (c_center.y - this._origin.y) };
		setCSSWidth(frame, cw);
		setCSSHeight(frame, ch);
		setCSSLeft(frame, co.x - (cw / 2));
		setCSSTop(frame, co.y - (ch / 2));
		this._step += 1;	
	},

	// Control the way search window will be expanded
	expandSpeedRegulator: function() {
		return Math.sin( Math.PI * Math.sin((Math.PI*this._step)/(2*this._steps)) / 2 );
	},

	// Hide the expanding frame and display the actual window
	_showContent: function() {
		if (this._intervalId != null) {
			return;
		}
		setCenterInWin(this._contentDiv);
		this._contentDiv.style.visibility = 'visible';
		this._displayed = true;
	},

	refresh: function() {
		if (!this.isExpanding()) {
			this._showContent();
		}
	},

	// Shake the displayed window sideways. In reminiscent of GDM. ;-)
	shake: function() {
		var d = this._contentDiv;
		var i = 0;
		var l_m;
		var w_i;
		try {
			l_m = Number(d.style.left.match(/^(\d+)/)[1]);
			w_i = window.setInterval(function() {
				var l_n = l_m + (Math.pow(-1, i) * 15);
				if (i==8) {
					window.clearInterval(w_i);
					l_n = l_m;
				}
				setCSSLeft(d, l_n);	
				i++;
			}, 40);
		} catch (error) {
			// Not a great deal, just don't quiver
		}
	},

	isDisplayed: function() {
		return (this.isExpanding() || this._displayed);
	},

	// Private members
	_id: null,
	_expandingFrame: null,
	_origin: { x: null, y: null },
	_stepinterval: 10,
	_steps: 20,
	_step: 0,
	_contentDiv: null,
	_intervalId: null

});
Object.extend(AnimatedWindow.prototype, (function() {
var windowResizeHandler = function() { 
	for (var w in AnimatedWindow.activeWindows) {
		AnimatedWindow.activeWindows[w].refresh();
	}
};
return {
	// Close the window
	collapse: function() {
		this._contentDiv.style.visibility = 'hidden';
		this._displayed = false;
//		removeEventHandler(this.contentDiv, 'click', cancelEventBubbling);
//		removeEventHandler(document, 'keydown', divKeydownHandler);
//		removeEventHandler(document, 'click', collapseHandler);
		removeEventHandler(window, 'resize', windowResizeHandler);

//		AnimatedWindow.removeInstance(this._id);
//		this._id = null;
	},

	_expand: function(step) {
		var frame = this.getExpandingFrame();
		var win = this;
		if (!frame) {
			// Create the frame 
			var frame = document.createElement('div');
			frame.className = 'expanding_frame';
	////		setEventHandler(content, 'click', cancelEventBubbling);
	////		setEventHandler(document, 'keydown', divKeydownHandler);
	////		setEventHandler(document, 'click', collapseHandler);
			setEventHandler(window, 'resize', windowResizeHandler);

			this._expandingFrame = frame;
			document.body.appendChild(frame);
		}

		this._step = step;
		
		// Make sure we have some reasonable defaults
		if (this._origin.x == null) {
			this._origin.x = getClientAreaRect().width / 2;
		}
		if (this._origin.y == null) {
			this._origin.y = getClientAreaRect().height / 2;
		}

		// If we have an existing interval active, we should cancel it first.
		if (this._intervalId) {
			window.clearInterval(this._intervalId);
		}
		this._intervalId = window.setInterval(function() { win._processExpansion() }, this._stepinterval);
	}
};
})());
