/*-----------------------------------------------------------------------------------------

	Class: 	Modal
	$Id$
	
-----------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------

	Namespace: u
	Utility methods

-------------------------------------------------------------------------------*/

adobe.u = {
/*-------------------------------------------------------------------------------

	Function: nonEvent
	Non propagating event

	Parameters:
	event - Event instance
	
	Returned Value:
	None
	
	Example:
>	Event.observe("foo", "click", adobe.u.nonEvent);

-------------------------------------------------------------------------------*/
	nonEvent: function (event) {
		return event.stop();
	},
/*-------------------------------------------------------------------------------

	Function: pixelate
	Append "px" to a number

	Parameters:
	integer - integer
	
	Returned Value:
	string
	
	Example:
>	adobe.u.pixelate(1);

-------------------------------------------------------------------------------*/
	pixelate: function(integer) {
		return parseInt(integer)+"px";
	},
/*-------------------------------------------------------------------------------

	Function: getSearchParam
	Get a value defined in the uri search parameter by it's id or all parameters in a hash.

	Parameters:
	id(optional) - string
	
	Returned Value:
	string or hash
	
	Example:
>	adobe.u.getSearchParam("foo");

-------------------------------------------------------------------------------*/
	getSearchParam: (function() {
		var _loadedParams;
		return function(id) {
			var params = _loadedParams || 
			(_loadedParams = window.location.search.toQueryParams());
			return (id) ? params[id] : params;
		}
	})(),
/*-------------------------------------------------------------------------------

	Function: freshenLocation
	Create a location string that would force a browser to check cache.

	Parameters:
	uri - string
	param (optional) - string

	Returned Value:
	string

	Example:
>	adobe.u.freshenLocation("/path"[, "myParam"])

-------------------------------------------------------------------------------*/
	freshenLocation: function(uri, param) {
		var query = "?",
		param = param || "time",
		i = uri.indexOf(query),
		time = query + param + "=" + new Date().getTime();
		
		if(i==-1) {
			return (uri + time);
		} else {
			var parts = adobe.u.unfreshenLocation(uri, param).split("?");
			return parts.join(time + ((parts[parts.length-1] == "") ? "" : "&"));
		}
	},
/*-------------------------------------------------------------------------------

	Function: unfreshenLocation
	Remove the query set by <freshenLocation> from a uri string
	
	Parameters:
	uri - string
	param (optional) - string
	
	Returned Value:
	string
	
	Example:	
>	adobe.u.unfreshenLocation("/path"[, "myParam"])


-------------------------------------------------------------------------------*/
	unfreshenLocation: function(uri, param) {
		var expression = new RegExp("([\\?&]?)"+(param||"time")+"=\\d*&?", "g");
		return uri.replace(expression, "$1");
	},
/*-------------------------------------------------------------------------------

	Function: revolve
	move the position of array items by specified number, wrapping items and keeping the length the same.

	Parameters:
	arr - Array instance
	integer - position or negative integer
	
	Returned Value:
	Array instance passed in
	
	Example:
>	adobe.u.revolve(["a","b","c"], -1)

-------------------------------------------------------------------------------*/
	revolve: function(arr, integer) {
		arr.unshift.apply(arr, arr.splice(integer, arr.length));
		return this;
	},
/*-------------------------------------------------------------------------------

	Function: toInt
	Convert a string to an integer

	Parameters:
	str - String instance
	
	Returned Value:
	integer

	Example:
>	adobe.u.toInt("1")

-------------------------------------------------------------------------------*/
	toInt: function(str) {
		return parseInt(str);
	}
};

/*-------------------------------------------------------------------------------

	Method: toInt

	Returned Value:
	integer

	Example:
>	("1").toInt();

-------------------------------------------------------------------------------*/

String.prototype.toInt = function() {
	return parseInt(this);
}

/*-------------------------------------------------------------------------------

	Method: pixelate
	Append "px" to a number

	Returned Value:
	string

	Example:
>	(1).pixelate();

-------------------------------------------------------------------------------*/

Number.prototype.pixelate = function() {
	return this + "px";
}

Object.extend(Array.prototype, {
	revolve: function(integer) {
		this.unshift.apply(this, this.splice(integer, this.length));
		return this;
	}
});
adobe.use("adobe.u");

adobe.u.link = {
	here: function(element) {
		return (element.href === window.location.href) ? element : null;
	},
	unlink: function(element) {
		element.observe("click", adobe.u.nonEvent);
		element.observe("keypress", adobe.u.nonEvent);
		element.setStyle({cursor: "text", textDecoration: "none"});
		return element;
	},
	relink: function(element) {
		element.stopObserving("click", adobe.u.nonEvent);
		element.stopObserving("keypress", adobe.u.nonEvent);
		element.setStyle({cursor: "", textDecoration: ""});
		return element;
	},
	path: function(element) {
		return (element.pathname.charAt(0) == "/") ? element.pathname : "/"+element.pathname;	
	}
};

Element.addMethods("A", adobe.u.link);
/*-------------------------------------------------------------------------------

	Namespace: u
	Utility methods

-------------------------------------------------------------------------------*/

adobe.u = {
/*-------------------------------------------------------------------------------

	Function: nonEvent
	Non propagating event

	Parameters:
	event - Event instance
	
	Returned Value:
	None
	
	Example:
>	Event.observe("foo", "click", adobe.u.nonEvent);

-------------------------------------------------------------------------------*/
	nonEvent: function (event) {
		return event.stop();
	},
/*-------------------------------------------------------------------------------

	Function: pixelate
	Append "px" to a number

	Parameters:
	integer - integer
	
	Returned Value:
	string
	
	Example:
>	adobe.u.pixelate(1);

-------------------------------------------------------------------------------*/
	pixelate: function(integer) {
		return parseInt(integer)+"px";
	},
/*-------------------------------------------------------------------------------

	Function: getSearchParam
	Get a value defined in the uri search parameter by it's id or all parameters in a hash.

	Parameters:
	id(optional) - string
	
	Returned Value:
	string or hash
	
	Example:
>	adobe.u.getSearchParam("foo");

-------------------------------------------------------------------------------*/
	getSearchParam: (function() {
		var _loadedParams;
		return function(id) {
			var params = _loadedParams || 
			(_loadedParams = window.location.search.toQueryParams());
			return (id) ? params[id] : params;
		}
	})(),
/*-------------------------------------------------------------------------------

	Function: freshenLocation
	Create a location string that would force a browser to check cache.

	Parameters:
	uri - string
	param (optional) - string

	Returned Value:
	string

	Example:
>	adobe.u.freshenLocation("/path"[, "myParam"])

-------------------------------------------------------------------------------*/
	freshenLocation: function(uri, param) {
		var query = "?",
		param = param || "time",
		i = uri.indexOf(query),
		time = query + param + "=" + new Date().getTime();
		
		if(i==-1) {
			return (uri + time);
		} else {
			var parts = adobe.u.unfreshenLocation(uri, param).split("?");
			return parts.join(time + ((parts[parts.length-1] == "") ? "" : "&"));
		}
	},
/*-------------------------------------------------------------------------------

	Function: unfreshenLocation
	Remove the query set by <freshenLocation> from a uri string
	
	Parameters:
	uri - string
	param (optional) - string
	
	Returned Value:
	string
	
	Example:	
>	adobe.u.unfreshenLocation("/path"[, "myParam"])


-------------------------------------------------------------------------------*/
	unfreshenLocation: function(uri, param) {
		var expression = new RegExp("([\\?&]?)"+(param||"time")+"=\\d*&?", "g");
		return uri.replace(expression, "$1");
	},
/*-------------------------------------------------------------------------------

	Function: revolve
	move the position of array items by specified number, wrapping items and keeping the length the same.

	Parameters:
	arr - Array instance
	integer - position or negative integer
	
	Returned Value:
	Array instance passed in
	
	Example:
>	adobe.u.revolve(["a","b","c"], -1)

-------------------------------------------------------------------------------*/
	revolve: function(arr, integer) {
		arr.unshift.apply(arr, arr.splice(integer, arr.length));
		return this;
	},
/*-------------------------------------------------------------------------------

	Function: toInt
	Convert a string to an integer

	Parameters:
	str - String instance
	
	Returned Value:
	integer

	Example:
>	adobe.u.toInt("1")

-------------------------------------------------------------------------------*/
	toInt: function(str) {
		return parseInt(str);
	}
};

/*-------------------------------------------------------------------------------

	Method: toInt

	Returned Value:
	integer

	Example:
>	("1").toInt();

-------------------------------------------------------------------------------*/

String.prototype.toInt = function() {
	return parseInt(this);
}

/*-------------------------------------------------------------------------------

	Method: pixelate
	Append "px" to a number

	Returned Value:
	string

	Example:
>	(1).pixelate();

-------------------------------------------------------------------------------*/

Number.prototype.pixelate = function() {
	return this + "px";
}

Object.extend(Array.prototype, {
	revolve: function(integer) {
		this.unshift.apply(this, this.splice(integer, this.length));
		return this;
	}
});
/*---------------------------------------------------------------------- 
	Namespace: u.element
----------------------------------------------------------------------*/
adobe.u.element = {
/*---------------------------------------------------------------------- 
	Function: create
	Create an element in the domain of another element
	
	Parameters:
	element - node
	name - nodename as string
	attrs(optional) - hash of attributes
	
	Returned Value:
	New Node instance
----------------------------------------------------------------------*/
	create: function(element, name, attrs) {
		var e = Element.getDocument(element).createElement(name);
		return (attrs) ? Object.extend(e, attrs||{}) : e;
	},
/*---------------------------------------------------------------------- 
	Function: getDocument
	Get the owner document with cross-browser support
	
	Parameters:
	element - node
	
	Returned Value:
	Document node
----------------------------------------------------------------------*/
	getDocument: function(element) {
		return element.ownerDocument || element.document;
	},
/*---------------------------------------------------------------------- 
	Function: getParent
	Get the parent node with cross-browser support
	
	Parameters:
	element - node
	
	Returned Value:
	Document node
----------------------------------------------------------------------*/
	getParent: function(element) {
		return (document.body.parentElement) ? element.parentElement : element.parentNode;
	},
/*---------------------------------------------------------------------- 
	Function: getParent
	Get the parent node with cross-browser support
	
	Parameters:
	element - node
	replacement - node
	
	Returned Value:
	Element argument
----------------------------------------------------------------------*/
	swap: function(element, replacement) {
		replacement.parentNode.replaceChild(element.parentNode.replaceChild(replacement, element));
		return element;
	},
/*---------------------------------------------------------------------- 
	Function: getMaxChildHeight
	Get the maximum height of this elements children or of a selection of descendants
	
	Parameters:
	element - node
	selector - string
	
	Returned Value:
	Number
----------------------------------------------------------------------*/
	getMaxChildHeight: function(element, selector) {
		var elements = (selector) ? 
				element.select(selector) : 
				element.childElements();
		
		return elements.inject(0, function(accum, element) {
      			return accum = Math.max(accum, element.scrollHeight)
		});
	},
/*---------------------------------------------------------------------- 
	Function: getTextContent
	Get the textContent property with cross-browser support
	
	Parameters:
	element - node
	
	Returned Value:
	String
----------------------------------------------------------------------*/
	getTextContent: function(element) {
		return element.textContent || element.text || element.innerText || "";
	}
}

Element.addMethods(adobe.u.element);

/*-----------------------------------------------------------------------------------------

Class: Pane
Author:
btapley

-----------------------------------------------------------------------------------------*/
adobe.Pane = (function() {
	
/*-----------------------------------------------------------------------------------------

	Animation

-----------------------------------------------------------------------------------------*/
		
	function _getCoords(element) {
		var element = $(element)||document,
		view, result;
		
		if(element.viewport) {
			view = element.viewport;
			result = view.getScrollOffsets();
		} else {
			view = element;
			result = view.cumulativeOffset();
		}
		
		result.view = view;
		
		return result;
	}
	
	function _setCoords(coords) {
		this.top = coords.top;
		this.left = coords.left;
	}
	
	function _setDimensions(dimensions) {
		this.height = dimensions.height - this.frameOffset;
		this.width = dimensions.width - this.frameOffset;
		return dimensions;
	}
	
	function _getDimensions(element) {
		if(window.opera && typeof element=="object") {
			return { 
				height: window.innerHeight || 0,
				width: element.getWidth() || 0
			}
		} else {
			return { 
				height: element.getHeight() || 0,
				width: element.getWidth() || 0
			};
		}
	}
	
	function _includeDimensions(coords) {
		return Object.extend(_getDimensions(coords.view), coords);
	}
	
	function _centerWidth(coords, offsetCoords) {		
		coords.left = (coords.width < offsetCoords.width) ? coords.left : coords.left + (coords.width/2)-(offsetCoords.width/2);
		return coords;
	}
	
	function _centerHeight(coords, offsetCoords) {
		coords.top = (coords.height < offsetCoords.height) ? coords.top : coords.top + (coords.height/2)-(offsetCoords.height/2);
			
		return coords;
	}
	
	function _alignmentDecoration(alignment, position, offset) {
		if(alignment.indexOf("c") < 0) {
			return position;
		}
	
		position = _includeDimensions(position);
		
		if(alignment.charAt(0) == "c") {
			position = _centerWidth(position, offset);
		}
	
		
		if(alignment.charAt(1) == "c") {
			position = _centerHeight(position, offset);
			
		}
		
		return position;
	}
	
	function _setUpAnimation() {	
		
		if(window.opera && this.height > this.options.height) {
			this.height = this.options.height - this.frameOffset;
		}
	
		var moveToElement = this._moveToElement,
		originElement = this._originElement,
		startAnimPosition = _getCoords(originElement),
		endAnimPosition = _getCoords(moveToElement),
		paneDimensions = { 
			height: this.height, 
			width: this.width
		},
		paneDimensionsWithFrame = { 
			height: this.height + this.frameOffset, 
			width: this.width + this.frameOffset
		};
				
		if(this.options.useOriginSize) {
			startAnimPosition = _includeDimensions(startAnimPosition);
			
		} else {
			startAnimPosition = Object.extend(startAnimPosition, paneDimensions);
		}
		
		/* Setup alignment */
		
		endAnimPosition = _alignmentDecoration(this.alignment, 
						       endAnimPosition, 
						       paneDimensionsWithFrame);
		//console.dir(endAnimPosition);
				
		/* Create Animators */
		
		
		this.an.addSubject(new NumericalStyleSubject(this.chrome, 
							     "opacity", 
							     0, 
							     1));
		
		//if(startAnimPosition.width != paneDimensions.width) {
			this.an.addSubject(new NumericalStyleSubject(this.chrome, 
									"width", 
									startAnimPosition.width, 
									paneDimensions.width));	
		//}
		
		//if(startAnimPosition.height != paneDimensions.height) {
			this.an.addSubject(new NumericalStyleSubject(this.chrome, 
							     		"height", 
							     		startAnimPosition.height, 
							     		paneDimensions.height));	
		//}
		
		//if(startAnimPosition.top != endAnimPosition.top) {
			this.an.addSubject(new NumericalStyleSubject(this.chrome, 
									"top", 
									startAnimPosition.top, 
									endAnimPosition.top));
		//}
		
		//if(startAnimPosition.left != endAnimPosition.left) {
			this.an.addSubject(new NumericalStyleSubject(this.chrome, 
									"left", 
									startAnimPosition.left, 
									endAnimPosition.left));
		//}
	}
	
	function _centerAnimation(element) {		
		
		var parentDimensions = (document.viewport) ? document.viewport.getDimensions() : document.getDimensions();
		var elementDimensions = _getDimensions(element);
				
		var parentScroll = (document.viewport) ? document.viewport.getScrollOffsets() : document.getScrollOffsets();
		var parentScrollHeight = parentScroll[1];
		
		this.width  = elementDimensions.width + this.frameOffset;
		this.height = elementDimensions.height + this.frameOffset;
		
		if(elementDimensions.height > parentDimensions.height) {
			this.height = 	parentDimensions.height/2
		}
		
		var frameLeftOffset = this.frameOffset/2;
		var elementCurrentLeft = element.cumulativeOffset().left - frameLeftOffset;
		var elementCurrentTop = element.cumulativeOffset().top - frameLeftOffset;
		
		var endAnimPosition = {
			left: (parentDimensions.width - this.width)/2,
			top: (parentDimensions.height - this.height)/2	
		}
				
		if(parentScrollHeight > 0) endAnimPosition.top = endAnimPosition.top + parentScrollHeight;
		
		var animator = new Animator({
			onComplete: (function() {
				animator.clearSubjects();
				_setCoords.call(this, endAnimPosition);
			}).bind(this)
		});
		
	
		animator.addSubject(new NumericalStyleSubject(this.chrome, 
									"left", 
									elementCurrentLeft, 
									endAnimPosition.left));
		
		animator.addSubject(new NumericalStyleSubject(this.chrome, 
									"top", 
									elementCurrentTop, 
									endAnimPosition.top));
		
		animator.seekTo(1);
		
	}
	
	function _moveOpenedAnimation(moveToCoords) {         
		_setUpAnimation.call(this);
		
		var endAnimPosition = moveToCoords;
		
		var paneDimensions = { 
			height: this.height, 
			width: this.width
		};		
		       
		var paneDimensionsWithFrame = { 
			height: this.height + this.frameOffset, 
			width: this.width + this.frameOffset
		};
		
		/* Setup alignment */
		
		endAnimPosition = _alignmentDecoration(this.alignment, 
						       endAnimPosition, 
						       paneDimensionsWithFrame);
		              

		if(this.content.down()) {
	   // create resize/recentering on page reload etc
		var firstElement = this.content.down().getWidth();
		var reset = paneDimensionsWithFrame.width - firstElement;
		//endAnimPosition.left = endAnimPosition.left-reset-this.frameOffset;
		}
		
		if((this.top == endAnimPosition.top) && 
		    (this.left == endAnimPosition.left)) {
			return;
		}
	 
		var animator = new Animator({
			onComplete: (function() {
				animator.clearSubjects();
				_setCoords.call(this, endAnimPosition);
			}).bind(this)
		});
		
		if(this.top != endAnimPosition.top) {
			animator.addSubject(new NumericalStyleSubject(this.chrome, 
									"top", 
									this.top, 
									endAnimPosition.top));	
		}
		
		if(this.left != endAnimPosition.left) {
			animator.addSubject(new NumericalStyleSubject(this.chrome, 
							      		"left", 
							      		this.left, 
							      		endAnimPosition.left));
		}
		
		animator.seekTo(1);
	}
	
	function _getResizeTarget(resizeToElement) {
               return _getDimensions((resizeToElement.viewport) ? resizeToElement.viewport : resizeToElement);
	}
	
	function _resizeOpenedAnimation(resizeToDimension) {

		var paneDimensions = { 
			height: this.height, 
			width: this.width
		};
		
		var animator = new Animator({
			onComplete: (function() {
				animator.clearSubjects();
				var dims = _setDimensions.call(this, _getDimensions(this.chrome));
				this.chrome.setStyle(dims);
			}).bind(this)
		});
				
		animator.addSubject(new NumericalStyleSubject(this.chrome, 
							      "width", 
							      this.width, 
							      resizeToDimension.width));
		animator.addSubject(new NumericalStyleSubject(this.chrome, 
							      "height", 
							      this.height, 
							      resizeToDimension.height));
		animator.seekTo(1);
	}
	
	function _resizeToElement(element) {
		
		var paneDimensions = { 
			height: element.getHeight(), 
			width: element.getWidth()
		};
		
		if(adobe.hostEnv.ieV==7) { 
			paneDimensions.width = paneDimensions.width - 48;
			paneDimensions.height = paneDimensions.height - 48;
		}
		
		
		var animator = new Animator({
			onComplete: (function() {
				animator.clearSubjects();
				var dims = _setDimensions.call(this, _getDimensions(this.chrome));
				this.chrome.setStyle(dims);
			}).bind(this)
		});
	
		animator.addSubject(new NumericalStyleSubject(this.chrome, 
							      "width", 
							      this.width, 
							      paneDimensions.width));
		animator.addSubject(new NumericalStyleSubject(this.chrome, 
							      "height", 
							      this.height, 
							      paneDimensions.height));
		animator.seekTo(1);
		
		
		
		this.height = paneDimensions.height;
		this.width = paneDimensions.width;
		

	}
	
	function _setLocation(location){
             this.request = new Ajax.Request(location, {
                method: this.options.method,
                        onComplete: (function(response) {
                                _updateContent.call(this,response.responseText);
                        }).bind(this)
                });
        }

        function _updateContent(content){
            this.cache = content;
            this.content.update(this.cache);
            this.chrome.fire("pane:updated");
        }
/*-----------------------------------------------------------------------------------------

	States

-----------------------------------------------------------------------------------------*/
	
	var _states = {
		CLOSED: 0,
		OPENED: 1,
		CLOSING: 2,
		OPENING: 3,
		UNKNOWN: 4
	};
	
	var _chrome_events = [];
	_chrome_events[_states.CLOSED] = "pane:endclose";
	_chrome_events[_states.OPENED] = "pane:endopen";
	_chrome_events[_states.OPENING] = "pane:startopen";
	_chrome_events[_states.CLOSING] = "pane:startclose";
	_chrome_events[_states.UNKNOWN] = "pane:error";
	
	
	_state_translation = [];
	
	_state_translation[_states.UNKNOWN] = {};
	
	_state_translation[_states.CLOSED] = {
		open: function() {
			if(!this.setOpener()) {
				
				this.nextstate = _states.UNKNOWN;
			}	
			
			this.currentstate = _states.OPENING;
			this.nextstate = _states.OPENED;
			this.chrome.style.visibility="hidden";
			this.opener.insertBefore(this.chrome, this.opener.firstChild);
			_setUpAnimation.call(this);
			this.an.jumpTo(_states.CLOSED);
			this.chrome.style.visibility="visible";
			this.chrome.fire(_chrome_events[this.currentstate]);
			this.an.seekTo(this.nextstate);
		},
		resizeTo: function(dims) {
			_setDimensions.call(this, dims);
		}
	};
	
	_state_translation[_states.OPENING] = {
		close: function() {
			this.content.style.visibility="hidden";
			this.currentstate = _states.CLOSING;
			this.nextstate = _states.CLOSED;
			this.an.seekTo(this.nextstate);
		},
		completeAnimation: function() {
			_setCoords.call(this, _getCoords(this.chrome));
			_setDimensions.call(this, _getDimensions(this.chrome));
		}
	};
	
	_state_translation[_states.OPENED] = {	
		close: function() {			
			this.content.style.visibility="hidden";
			this.currentstate = _states.CLOSING;
			this.nextstate = _states.CLOSED;
			this.chrome.fire(_chrome_events[this.currentstate]);
			this.an.seekTo(this.nextstate);	
			document.fire("pane:close")
		},
		updateLocation : function(location) {
			_setLocation.call(this,location);
			document.fire("pane:updated")
		},
		center: function() {
			_moveOpenedAnimation.call(this, _getCoords(this._moveToElement));
		},
		centerElement: function(element) {
			_centerAnimation.call(this, element);
		},
		moveToElement: function() {
			_moveOpenedAnimation.call(this, _getCoords(this._moveToElement));
		},
		moveTo: function(dims) {
			_moveOpenedAnimation.call(this, dims);
		},
		resizeToElement: function(element) {
			_resizeToElement.call(this, (element));
		},
		resizeTo: function(dims) {     
			_resizeOpenedAnimation.call(this, dims);
		}
	};
	
	_state_translation[_states.CLOSING] = {
		open: function() {
			this.currentstate = _states.OPENING;
			this.nextstate = _states.OPENED;
			this.an.seekTo(this.nextstate);
		},
		completeAnimation: function() {
			this.content.update("");
			this.content.style.visibility="";
			this.an.clearSubjects();
			this.opener.removeChild(this.chrome);
		}
	};
	
/*-----------------------------------------------------------------------------------------

	Export

-----------------------------------------------------------------------------------------*/
	
	return Class.create({
/*-----------------------------------------------------------------------------------------

		Method: initialize
		
		Parameters:
		container - element or undefined
		options - hash object
		
		Options:
		transition - Animator object
		duration - number of milliseconds
		style_container - string
		style_content - string
		style_closebutton - string
		originElement - Element reference
		startAnimPosition - array
		width - number of pixels
		height - number of pixels
		top - number of pixels
		left - number of pixels
		closed - boolean
		resizable - boolean
		url - string
		caching - boolean
		z - integer
		chrome - html string
		
		Returned Value:
		Class instance
		
-----------------------------------------------------------------------------------------*/

		initialize: function(container, options, labels) {
			
			this.chrome = $(container) || new Element("div");
			
			var style_content = "chrome-pane-body",
			style_title = "chrome-pane-title",
			style_frame = "chrome-pane-frame",
			style_closebutton = "chrome-pane-closebutton";						
			
			this.options = Object.extend({
				alignment: "cc",
				caching: false, // dont use with content containing scripts
				closed: true,
				duration: 500,
				frameborder: 24,
				height: 0,
				left: 0,
				maintainAlignment: true,
				method: "get",
				originElement: null,
				resizable: false,
				scrollbars: false,
				style_container: "pane",
				style_content: style_content,
				style_title: style_title,
				style_closebutton: style_closebutton,
				selfcontained : false,
				originElement: null,
				startAnimPosition: null,
				width: 0,
				height: 0,
				top: 0,
				transition: Animator.tx.easeOut,
				useEventOrigin: true,
				useOriginSize: true,
				url: "",
				viewport: document,
				width: 0,
				z: this.getZIndex(),
				chrome: new Template('<div class="'+style_title+'">#{title}<\/div>\
						     <button tabindex="0" class="'+style_closebutton+'">#{close}<\/button>\
						     <div class="'+style_content+'">#{body}<\/div>')
			}, options||{});
			
			this._moveToElement = this.options.viewport;
			this.alignment = this.options.alignment;
			this.alignmentHandler = null;
			this.labels = Object.extend({
				close: "Close",
				body: "",
				title: ""
			}, labels||{});
			
			var parent = this.chrome.parentNode;
			
			if(parent) {
				parent.removeChild(this.chrome);
			}	
			
			this.frameOffset = this.options.frameborder*2;
			
			this.selfcontained = this.options.selfcontained;
			this.top = this.options.top;
			this.left = this.options.left;
			this.height = this.options.height - this.frameOffset;
			this.width = this.options.width - this.frameOffset;
			
			this.setOriginElement(this.options.originElement);
			this._resizeToElement = null;
			this.cache = "";
			
			this.chrome_style = (!this.selfcontained) ? "chrome-pane" :"chrome-pane-crystal"
			
			this.chrome.addClassName(this.chrome_style);
			
			this.chrome.setStyle({
				position: "absolute",
				height: (0).pixelate(),
				width: (0).pixelate(),
				top: this.top,
				left: this.left,
				padding: this.options.frameborder.pixelate()
			});
			
			this.setZIndex(this.options.z);
			
			this.setOpener();
			
			this.chrome.update(this.options.chrome.evaluate(this.labels));
			
			this.content = this.chrome.select("."+this.options.style_content).first();
			
			var boundClickHandle = this.close.bind(this);
			
			var boundKeyHandle = function(event) {
				if(event.keyCode == Event.KEY_RETURN) {
					boundClickHandle();
				}
			}
			
			this.chrome.select("."+this.options.style_closebutton)
				.invoke("observe", "click", boundClickHandle)
				.invoke("observe", "keydown", boundKeyHandle);
			
			this.an = new Animator({
				transition: this.options.transition,
				duration: this.options.duration,
				onComplete: (function() {
					this.translateEvent("completeAnimation");
					this.currentstate = this.nextstate;
					this.nextstate = _states.UNKNOWN;
					this.closed = this.currentstate != _states.CLOSED;
					this.chrome.fire(_chrome_events[this.currentstate]);
					
				}).bind(this)
			});
			
			this.currentstate = _states.CLOSED;
			
			this.nextstate = _states.UNKNOWN;
			
			this.closed = !this.currentstate;
			
			if(!this.options.closed) {
				this.translateEvent("open");
			}
			
			this.request = null;
			this.location;
			this.setLocation(this.options.url);
			
			if(this.options.maintainAlignment) {
				this.maintainAlignment();
			}
		},
		setZIndex: function(index) {
			this.chrome.setStyle({ zIndex: (parseInt(index) || this.getZIndex()) });
		},
		getZIndex: function() {
			return this.chrome.getStyle("z-index") || 0;	
		},
		updateContent: function(content) {
			this.cache = content;
			this.content.update(this.cache);
            this.chrome.fire("pane:updated");
		},
		setOpener: function() {
			if(this.opener) { return this.opener ;}
			return this.opener = this.chrome.getDocument().getElementsByTagName("BODY")[0];
		},
		maintainAlignment: function() {
			
			if(this.alignmentHandler != null) {
				return;	
			}
			
			this.alignmentHandler = (function() {
				this.translateEvent("moveToElement");
			}).bind(this);
			
			Event.observe(window, "resize", this.alignmentHandler);
			
			return;
			
		},
		setOriginElement: function(element) {
			this._originElement = $(element);
		},
		neglectAlignment: function() {
			if(this.alignmentHandler == null) {
				return;	
			}
			
			Event.stopObserving(window, "resize", this.alignmentHandler);
			
			this.alignmentHandler = null;
			
			return;
		},
	/*-----------------------------------------------------------------------------------------

		Method: center
		
		Parameters:
		unset - boolean
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		center: function(width, height) {
			var walign = (width) ? "c" : "l";
			var halign = (height) ? "c" : "t";
			this.alignment = walign + halign;
                        this.translateEvent("center");
		},
		
		
		centerElement: function(element) {
			this.translateEvent("centerElement",element);
		},
/*-----------------------------------------------------------------------------------------

		Method: moveTo
		
		Parameters:
		left - Integer
		top - Integer
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		moveTo: function(left, top) {
			this.translateEvent("moveTo", {
				left: parseInt(left), 
				top: parseInt(top)
			});
		},
/*-----------------------------------------------------------------------------------------

		Method: moveToElement
		
		Parameters:
		element - Element reference
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		moveToElement: function(element) {
			this._moveToElement = $(element);
			this.translateEvent("moveToElement");
		},
/*-----------------------------------------------------------------------------------------

		Method: resizeToElement
		
		Parameters:
		element - Element reference
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		resizeToElement: function(element) {			
			this.translateEvent("resizeToElement", element);
		},
/*-----------------------------------------------------------------------------------------

		Method: resizeTo
		
		Parameters:
		width - Integer
		height - Integer
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/		
		resizeTo: function(width, height) {
			this.translateEvent("resizeTo", {
					    	width: parseInt(width), 
						height: parseInt(height)
			});
		},

        resizeHeight: function(width, height) {
			this.translateEvent("resizeHeight", {
						height: parseInt(height)
			});
		},
/*-----------------------------------------------------------------------------------------	
		
		Method: open
	
		Parameters:
		event - Event instance
		
		Returned Value:
		None
		
-----------------------------------------------------------------------------------------*/
		open: function(event) {			
			if(event && this.options.useEventOrigin) {
				this._originElement = event.element() || this._originElement;
			}
			if(!this._originElement) {
				this._originElement = this.options.viewport;
			}
			this.translateEvent("open");
						
		},
		setToScroll : function(){
		  this.chrome.addClassName('setScroll')
		},
		updateLocation : function(location){
			this.translateEvent("updateLocation",location)

		},
		setLocation: function(location) {
			if(location && !this.location) {                          
				this.observe("pane:endopen", (function() {					
					if(!this.options.caching || !this.cache) {
						this.request = new Ajax.Request(this.location, {
							method: this.options.method,
							onComplete: (function(response) {
								this.updateContent(response.responseText);
							}).bind(this)
						});
					}
				}).bind(this));	
			}
			
			this.location = location;
		},
/*-----------------------------------------------------------------------------------------	

		Method: close
	
		Returned Value:
		None
			
-----------------------------------------------------------------------------------------*/
		close: function() {
			this.translateEvent("close");
		},
/*-----------------------------------------------------------------------------------------	

		Method: translateEvent
		
		Parameters:
		eventname - string
		arg - optional argument
	
		Returned Value:
		None
			
-----------------------------------------------------------------------------------------*/
		translateEvent: function(eventname, arg) {
			try { return (_state_translation[this.currentstate][eventname] || Prototype.emptyFunction).call(this, arg);
			} catch(e) { throw (e); }
		},
/*-----------------------------------------------------------------------------------------

		Method: observe
			
		Parameters:
		eventname - string
		callback - function
		
		Returned Value:
		None
		
-----------------------------------------------------------------------------------------*/
		observe: function(eventname, callback) {
			this.chrome.observe(eventname, callback);
		},
/*-----------------------------------------------------------------------------------------

		Method: ignore
			
		Parameters:
		eventname - string
		callback - function
		
		Returned Value:
		None
		
-----------------------------------------------------------------------------------------*/
		ignore: function(eventname, callback) {
			this.chrome.stopObserving(eventname, callback);
		}
	});
	
})();

adobe.link("/lib/js/animator.js");
adobe.use("adobe.u");
/*-----------------------------------------------------------------------------------------
Class: Shade
Author:
btapley
-----------------------------------------------------------------------------------------*/
adobe.Shade = Class.create((function() {
	var _states = {
		CLOSED: 0,
		OPENED: 1,
		OPENING:2,
		CLOSING:3
	}
	
	var _state_translations = [];
	
	_state_translations[_states.CLOSED] = {
		show: function() {
			this.currentstate = _states.OPENING;
			if(!this.options.scrolling) {
				this.shadedElement.makeClipping();
			}
			this.shadedElement.relativize();
			this.shadedElement.insertBefore(this.shadeElement, this.shadedElement.firstDescendant());
			this.an.seekTo(_states.OPENED);
		}
	};
	
	_state_translations[_states.OPENED] = {
		hide: function() {
			this.currentstate = _states.CLOSING;
			this.an.seekTo(_states.CLOSED);
		}
	};
	
	_state_translations[_states.CLOSING] = {
		show: function() {
			this.currentstate = _states.OPENING;
			this.an.seekTo(_states.OPENED);
		},
		complete: function() {
			this.currentstate = _states.CLOSED;
			this.shadedElement.removeChild(this.shadeElement);
			if(!this.options.scrolling) {
				this.shadedElement.undoClipping();
			}
		}
	};
	
	_state_translations[_states.OPENING] = {
		hide: function() {
			this.currentstate = _states.CLOSING;
			this.an.seekTo(_states.CLOSED);
		},
		complete: function() {
			this.currentstate = _states.OPENED;			
		}
	};
	
	return {
/*-----------------------------------------------------------------------------------------

		Method: initialize
		
		Parameters:
		element - element reference or ID string
		options - hash
		
		Options:
		label - ""
		transition - Transition object, default is Animator.tx.easeInOut
		duration - integer ,default is 400
		opacity - number, default is 0.65
		color - string as hex, default is "#000000"
		z - integer, deault is 1 greater that the shaded element
		scrolling - boolean, default is true
		
		Returned Value:
		Class instance

-----------------------------------------------------------------------------------------*/
		initialize: function(element, options) {
			this.shadedElement = $(element);
			var z = this.shadedElement.getStyle("z-index")+1;
			
			this.options = Object.extend({
				label: "",
				transition: Animator.tx.easeInOut,
				duration: 400,
				opacity: 0.65,
				color: "#000000",
				z: z,
				scrolling: true,
				cursor: "default"
			}, options||{});
			
			this.shadeElement = new Element("div");
			
			this.setLabel(this.options.label);
			this.setCursor(this.options.cursor);

			var offsets = this.shadedElement.positionedOffset();
			
			shadeIEHeight = $$('body')[0].getHeight();
						
			this.shadeElement.setStyle({
				backgroundColor: this.options.color,
				zIndex: this.options.z,
				top: offsets.top.pixelate(),
				left: offsets.left.pixelate(),
				position: "absolute",
				height: ((adobe.hostEnv.ie6) ? 	shadeIEHeight+"px" : "100%"), 
				width: "100%"
			});
			
			this.currentstate = _states.CLOSED;
			this.nextstate;
			
			this.an = new Animator({
				transition: this.options.transition,
				duration: this.options.duration,
				onComplete: this.translateEvent.bind(this, "complete")
			})
			.addSubject(new NumericalStyleSubject(this.shadeElement, 'opacity', 0, this.options.opacity));
			
			this.an.jumpTo(0);
		},
/*-----------------------------------------------------------------------------------------

		Method: translateEvent
		
		Parameters:
		eventname - string
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/			
		translateEvent: function(eventname) {
			try {
				return (_state_translations[this.currentstate][eventname] || Prototype.emptyFunction).call(this);
			} catch(e) {
				throw (e);
			}
		},
		setCursor: function(cursor) {
			this.shadeElement.setStyle({
				cursor: cursor
			});
		},
		setLabel: function(label) {
			this.shadeElement.writeAttribute("title", label);
		},
/*-----------------------------------------------------------------------------------------

		Method: show
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		show: function() {
			if(adobe.hostEnv.ie6) this.shadeElement.style.height = $$('body')[0].getHeight()+"px";
			return this.translateEvent("show");
		},
/*-----------------------------------------------------------------------------------------

		Method: hide
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		hide: function() {
			return this.translateEvent("hide");
		},
/*-----------------------------------------------------------------------------------------

		Method: toggle
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		toggle: function() {
			return this.translateEvent((this.currentstate == _states.CLOSED || 
						    this.currentstate == _states.CLOSING) ? "show" : "hide");
		},
/*-----------------------------------------------------------------------------------------

		Method: observe

		Parameters:
		eventname - string
		func - function
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		observe: function(eventname, func) {
			this.shadeElement.observe(eventname, func);
		},
/*-----------------------------------------------------------------------------------------

		Method: stopObserving
		
		Parameters:
		eventname - string
		func - function
		
		Returned Value:
		None

-----------------------------------------------------------------------------------------*/
		stopObserving: function(eventname, func) {
			this.shadeElement.stopObserving(eventname, func);
		}
	};
})());

adobe.link("/lib/js/animator.js");

adobe.Modal = Class.create({
initialize: function(pane, shade, options) {
this.pane = pane;
this.shade = shade;
this.options = Object.extend({
align: "center",
alignTo: document,
resize: true,
origin: "",
name: "",
observeShade: true
}, options);
switch(this.options.align) {
case "center":
this.pane.center(true, true);
break;
}
this.pane.moveToElement(this.options.alignTo);
if(this.options.resize) {
this.pane.maintainAlignment();
}
this.disableHandler = null;
if(this.options.observeShade) {
this.attachShadeButton();
this.shade.observe("click", this.disable.bind(this));
}
this.shadeCloseHandler = this.shade.hide.bind(this.shade);
this.shadeOpenHandler = this.shade.show.bind(this.shade);
this.pane.observe("pane:startclose", this.shadeCloseHandler);
this.pane.observe("pane:startopen", this.shadeOpenHandler);
document.observe("modal:close", this.disable.bind(this))
document.observe("modal:close", this.shadeCloseHandler);
this.pane.observe("modal:close", this.shadeCloseHandler);
this.pane.observe("modal:close", this.disable.bind(this))
},
createDisableHandler: function() {
if(this.disableHandler == null) { 
this.disableHandler = this.disable.bind(this);	
}
return;
},
destroyDisableHandler: function() {
if(this.disableHandler == null) {
return;
}
this.detachShadeButton();
this.disableHandler = null;
return;
},
attachShadeButton: function() {
if(!this.disableHandler) {
this.createDisableHandler();	
}
this.shade.observe("click", this.disableHandler);
},
detachShadeButton: function() {
this.shade.stopObserving("click", this.disableHandler);
},
enable: function(event) {
this.pane.open(event);
document.fire("modal:opened")
},
disable: function() {
this.pane.close();
document.fire("modal:closed")
}
});
Element.addMethods("A", {
modalize: function(element) {
var element = element;
var q = element.search,
options = q.toQueryParams(),
url = element.path();
if(q) {
url = url + "?" + q;
}
options.width = parseInt(options.width)||640;
options.height = parseInt(options.height)||480;
options.z = parseInt(options.z)||1000;
options.duration = parseInt(options.duration)||400;
options.title = element.readAttribute("title") || "";
options.frameborder = parseInt(options.frameborder);
options.frameborder = (isNaN(options.frameborder) ? 24 : options.frameborder);
options.hideclosebutton = options.hideclosebutton || false;
var chrome = (!options.hideclosebutton) ? 
'<div class="chrome-pane-title">#{title}<\/div><button style="right:6px;top:6px" class="chrome-pane-closebutton">#{close}<\/button>'+((Prototype.Browser.Gecko) ? '<iframe class="chrome-ff2-frame"><\/iframe>' : '')+'<div class="chrome-pane-body">#{body}<\/div>' :
'<div class="chrome-pane-title">#{title}<\/div>'+((Prototype.Browser.Gecko) ? '<iframe class="chrome-ff2-frame"><\/iframe>' : '')+'<div class="chrome-pane-body">#{body}<\/div>';
var shade = new adobe.Shade(document.getElementsByTagName("BODY")[0], {
z: options.z,
duration: options.duration/1.5,
scrolling: true
}),
pane = new adobe.Pane(null, {
width: options.width,
height: options.height,
z: options.z+1,
duration: options.duration,
url: url,
frameborder: options.frameborder,
hideclosebutton : options.hideclosebutton,
chrome: new Template(chrome)
}, {
title: options.title
}),
modal = new adobe.Modal(pane, shade);
element.observe("click", adobe.u.nonEvent);
element.observe("keydown", key_handler);
element.observe("click", modal.enable.bind(modal));
function key_handler(event) {	
if(event.keyCode == Event.KEY_RETURN) {
return adobe.u.nonEvent(event);	
}
}
return element;
}
});

