//Begin: /Scripts/mootools-1.2-debug.js

/*
Script: Core.js
	MooTools - My Object Oriented JavaScript Tools.

License:
	MIT-style license.

Copyright:
	Copyright (c) 2006-2007 [Valerio Proietti](http://mad4milk.net/).

Code & Documentation:
	[The MooTools production team](http://mootools.net/developers/).

Inspiration:
	- Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
	- Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
*/

var MooTools = {
	'version': '1.2.0',
	'build': ''
};
      
var Native = function(options){
	options = options || {};

	var afterImplement = options.afterImplement || function(){};
	var generics = options.generics;
	generics = (generics !== false);
	var legacy = options.legacy;
	var initialize = options.initialize;
	var protect = options.protect;
	var name = options.name;

	var object = initialize || legacy;

	object.constructor = Native;
	object.$family = {name: 'native'};
	if (legacy && initialize) object.prototype = legacy.prototype;
	object.prototype.constructor = object;

	if (name){
		var family = name.toLowerCase();
		object.prototype.$family = {name: family};
		Native.typize(object, family);
	}

	var add = function(obj, name, method, force){
		if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method;
		if (generics) Native.genericize(obj, name, protect);
		afterImplement.call(obj, name, method);
		return obj;
	};
	
	object.implement = function(a1, a2, a3){
		if (typeof a1 == 'string') return add(this, a1, a2, a3);
		for (var p in a1) add(this, p, a1[p], a2);
		return this;
	};
	
	object.alias = function(a1, a2, a3){
		if (typeof a1 == 'string'){
			a1 = this.prototype[a1];
			if (a1) add(this, a2, a1, a3);
		} else {
			for (var a in a1) this.alias(a, a1[a], a2);
		}
		return this;
	};

	return object;
};

Native.implement = function(objects, properties){
	for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties);
};

Native.genericize = function(object, property, check){
	if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){
		var args = Array.prototype.slice.call(arguments);
		return object.prototype[property].apply(args.shift(), args);
	};
};

Native.typize = function(object, family){
	if (!object.type) object.type = function(item){
		return ($type(item) === family);
	};
};

Native.alias = function(objects, a1, a2, a3){
	for (var i = 0, j = objects.length; i < j; i++) objects[i].alias(a1, a2, a3);
};

(function(objects){
	for (var name in objects) Native.typize(objects[name], name);
})({'boolean': Boolean, 'native': Native, 'object': Object});

(function(objects){
	for (var name in objects) new Native({name: name, initialize: objects[name], protect: true});
})({'String': String, 'Function': Function, 'Number': Number, 'Array': Array, 'RegExp': RegExp, 'Date': Date});

(function(object, methods){
	for (var i = methods.length; i--; i) Native.genericize(object, methods[i], true);
	return arguments.callee;
})
(Array, ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice', 'toString', 'valueOf', 'indexOf', 'lastIndexOf'])
(String, ['charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'replace', 'search', 'slice', 'split', 'substr', 'substring', 'toLowerCase', 'toUpperCase', 'valueOf']);

function $chk(obj){
	return !!(obj || obj === 0);
};

function $clear(timer){
	clearTimeout(timer);
	clearInterval(timer);
	return null;
};

function $defined(obj){
	return (obj != undefined);
};

function $empty(){};

function $arguments(i){
	return function(){
		return arguments[i];
	};
};

function $lambda(value){
	return (typeof value == 'function') ? value : function(){
		return value;
	};
};

function $extend(original, extended){
	for (var key in (extended || {})) original[key] = extended[key];
	return original;
};

function $unlink(object){
	var unlinked;
	
	switch ($type(object)){
		case 'object':
			unlinked = {};
			for (var p in object) unlinked[p] = $unlink(object[p]);
		break;
		case 'hash':
			unlinked = $unlink(object.getClean());
		break;
		case 'array':
			unlinked = [];
			for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
		break;
		default: return object;
	}
	
	return unlinked;
};

function $merge(){
	var mix = {};
	for (var i = 0, l = arguments.length; i < l; i++){
		var object = arguments[i];
		if ($type(object) != 'object') continue;
		for (var key in object){
			var op = object[key], mp = mix[key];
			mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $merge(mp, op) : $unlink(op);
		}
	}
	return mix;
};

function $pick(){
	for (var i = 0, l = arguments.length; i < l; i++){
		if (arguments[i] != undefined) return arguments[i];
	}
	return null;
};

function $random(min, max){
	return Math.floor(Math.random() * (max - min + 1) + min);
};

function $splat(obj){
	var type = $type(obj);
	return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : [];
};

var $time = Date.now || function(){
	return new Date().getTime();
};

function $try(){
	for (var i = 0, l = arguments.length; i < l; i++){
		try {
			return arguments[i]();
		} catch(e){}
	}
	return null;
};

function $type(obj){
	if (obj == undefined) return false;
	if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name;
	if (obj.nodeName){
		switch (obj.nodeType){
			case 1: return 'element';
			case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
		}
	} else if (typeof obj.length == 'number'){
		if (obj.callee) return 'arguments';
		else if (obj.item) return 'collection';
	}
	return typeof obj;
};

var Hash = new Native({

	name: 'Hash',

	initialize: function(object){
		if ($type(object) == 'hash') object = $unlink(object.getClean());
		for (var key in object) this[key] = object[key];
		return this;
	}

});

Hash.implement({
	
	getLength: function(){
		var length = 0;
		for (var key in this){
			if (this.hasOwnProperty(key)) length++;
		}
		return length;
	},

	forEach: function(fn, bind){
		for (var key in this){
			if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);
		}
	},
	
	getClean: function(){
		var clean = {};
		for (var key in this){
			if (this.hasOwnProperty(key)) clean[key] = this[key];
		}
		return clean;
	}

});

Hash.alias('forEach', 'each');

function $H(object){
	return new Hash(object);
};

Array.implement({

	forEach: function(fn, bind){
		for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this);
	}

});

Array.alias('forEach', 'each');

function $A(iterable){
	if (iterable.item){
		var array = [];
		for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i];
		return array;
	}
	return Array.prototype.slice.call(iterable);
};

function $each(iterable, fn, bind){
	var type = $type(iterable);
	((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind);
};


/*
Script: Browser.js
	The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash.

License:
	MIT-style license.
*/

var Browser = new Hash({
	Engine: {name: 'unknown', version: ''},
	Platform: {name: (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
	Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)},
	Plugins: {}
});

if (window.opera) Browser.Engine = {name: 'presto', version: (document.getElementsByClassName) ? 950 : 925};
else if (window.ActiveXObject) Browser.Engine = {name: 'trident', version: (window.XMLHttpRequest) ? 5 : 4};
else if (!navigator.taintEnabled) Browser.Engine = {name: 'webkit', version: (Browser.Features.xpath) ? 420 : 419};
else if (document.getBoxObjectFor != null) Browser.Engine = {name: 'gecko', version: (document.getElementsByClassName) ? 19 : 18};
Browser.Engine[Browser.Engine.name] = Browser.Engine[Browser.Engine.name + Browser.Engine.version] = true;

if (window.orientation != undefined) Browser.Platform.name = 'ipod';

Browser.Platform[Browser.Platform.name] = true;

Browser.Request = function(){
	return $try(function(){
		return new XMLHttpRequest();
	}, function(){
		return new ActiveXObject('MSXML2.XMLHTTP');
	});
};

Browser.Features.xhr = !!(Browser.Request());

Browser.Plugins.Flash = (function(){
	var version = ($try(function(){
		return navigator.plugins['Shockwave Flash'].description;
	}, function(){
		return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
	}) || '0 r0').match(/\d+/g);
	return {version: parseInt(version[0] || 0 + '.' + version[1] || 0), build: parseInt(version[2] || 0)};
})();

function $exec(text){
	if (!text) return text;
	if (window.execScript){
		window.execScript(text);
	} else {
		var script = document.createElement('script');
		script.setAttribute('type', 'text/javascript');
		script.text = text;
		document.head.appendChild(script);
		document.head.removeChild(script);
	}
	return text;
};

Native.UID = 1;

var $uid = (Browser.Engine.trident) ? function(item){
	return (item.uid || (item.uid = [Native.UID++]))[0];
} : function(item){
	return item.uid || (item.uid = Native.UID++);
};

var Window = new Native({

	name: 'Window',

	legacy: (Browser.Engine.trident) ? null: window.Window,

	initialize: function(win){
		$uid(win);
		if (!win.Element){
			win.Element = $empty;
			if (Browser.Engine.webkit) win.document.createElement("iframe"); //fixes safari 2
			win.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {};
		}
		return $extend(win, Window.Prototype);
	},

	afterImplement: function(property, value){
		window[property] = Window.Prototype[property] = value;
	}

});

Window.Prototype = {$family: {name: 'window'}};

new Window(window);

var Document = new Native({

	name: 'Document',

	legacy: (Browser.Engine.trident) ? null: window.Document,

	initialize: function(doc){
		$uid(doc);
		doc.head = doc.getElementsByTagName('head')[0];
		doc.html = doc.getElementsByTagName('html')[0];
		doc.window = doc.defaultView || doc.parentWindow;
		if (Browser.Engine.trident4) $try(function(){
			doc.execCommand("BackgroundImageCache", false, true);
		});
		return $extend(doc, Document.Prototype);
	},

	afterImplement: function(property, value){
		document[property] = Document.Prototype[property] = value;
	}

});

Document.Prototype = {$family: {name: 'document'}};

new Document(document);

/*
Script: Array.js
	Contains Array Prototypes like copy, each, contains, and remove.

License:
	MIT-style license.
*/

Array.implement({

	every: function(fn, bind){
		for (var i = 0, l = this.length; i < l; i++){
			if (!fn.call(bind, this[i], i, this)) return false;
		}
		return true;
	},

	filter: function(fn, bind){
		var results = [];
		for (var i = 0, l = this.length; i < l; i++){
			if (fn.call(bind, this[i], i, this)) results.push(this[i]);
		}
		return results;
	},
	
	clean: function() {
		return this.filter($defined);
	},

	indexOf: function(item, from){
		var len = this.length;
		for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
			if (this[i] === item) return i;
		}
		return -1;
	},

	map: function(fn, bind){
		var results = [];
		for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this);
		return results;
	},

	some: function(fn, bind){
		for (var i = 0, l = this.length; i < l; i++){
			if (fn.call(bind, this[i], i, this)) return true;
		}
		return false;
	},

	associate: function(keys){
		var obj = {}, length = Math.min(this.length, keys.length);
		for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
		return obj;
	},

	link: function(object){
		var result = {};
		for (var i = 0, l = this.length; i < l; i++){
			for (var key in object){
				if (object[key](this[i])){
					result[key] = this[i];
					delete object[key];
					break;
				}
			}
		}
		return result;
	},

	contains: function(item, from){
		return this.indexOf(item, from) != -1;
	},

	extend: function(array){
		for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
		return this;
	},

	getLast: function(){
		return (this.length) ? this[this.length - 1] : null;
	},

	getRandom: function(){
		return (this.length) ? this[$random(0, this.length - 1)] : null;
	},

	include: function(item){
		if (!this.contains(item)) this.push(item);
		return this;
	},

	combine: function(array){
		for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
		return this;
	},

	erase: function(item){
		for (var i = this.length; i--; i){
			if (this[i] === item) this.splice(i, 1);
		}
		return this;
	},

	empty: function(){
		this.length = 0;
		return this;
	},

	flatten: function(){
		var array = [];
		for (var i = 0, l = this.length; i < l; i++){
			var type = $type(this[i]);
			if (!type) continue;
			array = array.concat((type == 'array' || type == 'collection' || type == 'arguments') ? Array.flatten(this[i]) : this[i]);
		}
		return array;
	},

	hexToRgb: function(array){
		if (this.length != 3) return null;
		var rgb = this.map(function(value){
			if (value.length == 1) value += value;
			return value.toInt(16);
		});
		return (array) ? rgb : 'rgb(' + rgb + ')';
	},

	rgbToHex: function(array){
		if (this.length < 3) return null;
		if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
		var hex = [];
		for (var i = 0; i < 3; i++){
			var bit = (this[i] - 0).toString(16);
			hex.push((bit.length == 1) ? '0' + bit : bit);
		}
		return (array) ? hex : '#' + hex.join('');
	}

});

/*
Script: Function.js
	Contains Function Prototypes like create, bind, pass, and delay.

License:
	MIT-style license.
*/

Function.implement({

	extend: function(properties){
		for (var property in properties) this[property] = properties[property];
		return this;
	},

	create: function(options){
		var self = this;
		options = options || {};
		return function(event){
			var args = options.arguments;
			args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0);
			if (options.event) args = [event || window.event].extend(args);
			var returns = function(){
				return self.apply(options.bind || null, args);
			};
			if (options.delay) return setTimeout(returns, options.delay);
			if (options.periodical) return setInterval(returns, options.periodical);
			if (options.attempt) return $try(returns);
			return returns();
		};
	},

	pass: function(args, bind){
		return this.create({arguments: args, bind: bind});
	},

	attempt: function(args, bind){
		return this.create({arguments: args, bind: bind, attempt: true})();
	},

	bind: function(bind, args){
		return this.create({bind: bind, arguments: args});
	},

	bindWithEvent: function(bind, args){
		return this.create({bind: bind, event: true, arguments: args});
	},

	delay: function(delay, bind, args){
		return this.create({delay: delay, bind: bind, arguments: args})();
	},

	periodical: function(interval, bind, args){
		return this.create({periodical: interval, bind: bind, arguments: args})();
	},

	run: function(args, bind){
		return this.apply(bind, $splat(args));
	}

});

/*
Script: Number.js
	Contains Number Prototypes like limit, round, times, and ceil.

License:
	MIT-style license.
*/

Number.implement({

	limit: function(min, max){
		return Math.min(max, Math.max(min, this));
	},

	round: function(precision){
		precision = Math.pow(10, precision || 0);
		return Math.round(this * precision) / precision;
	},

	times: function(fn, bind){
		for (var i = 0; i < this; i++) fn.call(bind, i, this);
	},

	toFloat: function(){
		return parseFloat(this);
	},

	toInt: function(base){
		return parseInt(this, base || 10);
	}

});

Number.alias('times', 'each');

(function(math){
	var methods = {};
	math.each(function(name){
		if (!Number[name]) methods[name] = function(){
			return Math[name].apply(null, [this].concat($A(arguments)));
		};
	});
	Number.implement(methods);
})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);

/*
Script: String.js
	Contains String Prototypes like camelCase, capitalize, test, and toInt.

License:
	MIT-style license.
*/

String.implement({

	test: function(regex, params){
		return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this);
	},

	contains: function(string, separator){
		return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1;
	},

	trim: function(){
		return this.replace(/^\s+|\s+$/g, '');
	},

	clean: function(){
		return this.replace(/\s+/g, ' ').trim();
	},

	camelCase: function(){
		return this.replace(/-\D/g, function(match){
			return match.charAt(1).toUpperCase();
		});
	},

	hyphenate: function(){
		return this.replace(/[A-Z]/g, function(match){
			return ('-' + match.charAt(0).toLowerCase());
		});
	},

	capitalize: function(){
		return this.replace(/\b[a-z]/g, function(match){
			return match.toUpperCase();
		});
	},

	escapeRegExp: function(){
		return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
	},

	toInt: function(base){
		return parseInt(this, base || 10);
	},

	toFloat: function(){
		return parseFloat(this);
	},

	hexToRgb: function(array){
		var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
		return (hex) ? hex.slice(1).hexToRgb(array) : null;
	},

	rgbToHex: function(array){
		var rgb = this.match(/\d{1,3}/g);
		return (rgb) ? rgb.rgbToHex(array) : null;
	},

	stripScripts: function(option){
		var scripts = '';
		var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(){
			scripts += arguments[1] + '\n';
			return '';
		});
		if (option === true) $exec(scripts);
		else if ($type(option) == 'function') option(scripts, text);
		return text;
	},

	substitute: function(object, regexp){
		return this.replace(regexp || (/\\?\{([^}]+)\}/g), function(match, name){
			if (match.charAt(0) == '\\') return match.slice(1);
			return (object[name] != undefined) ? object[name] : '';
		});
	}

});

/*
Script: Hash.js
	Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects.

License:
	MIT-style license.
*/

Hash.implement({

	has: Object.prototype.hasOwnProperty,

	keyOf: function(value){
		for (var key in this){
			if (this.hasOwnProperty(key) && this[key] === value) return key;
		}
		return null;
	},

	hasValue: function(value){
		return (Hash.keyOf(this, value) !== null);
	},

	extend: function(properties){
		Hash.each(properties, function(value, key){
			Hash.set(this, key, value);
		}, this);
		return this;
	},

	combine: function(properties){
		Hash.each(properties, function(value, key){
			Hash.include(this, key, value);
		}, this);
		return this;
	},

	erase: function(key){
		if (this.hasOwnProperty(key)) delete this[key];
		return this;
	},

	get: function(key){
		return (this.hasOwnProperty(key)) ? this[key] : null;
	},

	set: function(key, value){
		if (!this[key] || this.hasOwnProperty(key)) this[key] = value;
		return this;
	},

	empty: function(){
		Hash.each(this, function(value, key){
			delete this[key];
		}, this);
		return this;
	},

	include: function(key, value){
		var k = this[key];
		if (k == undefined) this[key] = value;
		return this;
	},

	map: function(fn, bind){
		var results = new Hash;
		Hash.each(this, function(value, key){
			results.set(key, fn.call(bind, value, key, this));
		}, this);
		return results;
	},

	filter: function(fn, bind){
		var results = new Hash;
		Hash.each(this, function(value, key){
			if (fn.call(bind, value, key, this)) results.set(key, value);
		}, this);
		return results;
	},

	every: function(fn, bind){
		for (var key in this){
			if (this.hasOwnProperty(key) && !fn.call(bind, this[key], key)) return false;
		}
		return true;
	},

	some: function(fn, bind){
		for (var key in this){
			if (this.hasOwnProperty(key) && fn.call(bind, this[key], key)) return true;
		}
		return false;
	},

	getKeys: function(){
		var keys = [];
		Hash.each(this, function(value, key){
			keys.push(key);
		});
		return keys;
	},

	getValues: function(){
		var values = [];
		Hash.each(this, function(value){
			values.push(value);
		});
		return values;
	},
	
	toQueryString: function(base){
		var queryString = [];
		Hash.each(this, function(value, key){
			if (base) key = base + '[' + key + ']';
			var result;
			switch ($type(value)){
				case 'object': result = Hash.toQueryString(value, key); break;
				case 'array':
					var qs = {};
					value.each(function(val, i){
						qs[i] = val;
					});
					result = Hash.toQueryString(qs, key);
				break;
				default: result = key + '=' + encodeURIComponent(value);
			}
			if (value != undefined) queryString.push(result);
		});
		
		return queryString.join('&');
	}

});

Hash.alias({keyOf: 'indexOf', hasValue: 'contains'});

/*
Script: Event.js
	Contains the Event Native, to make the event object completely crossbrowser.

License:
	MIT-style license.
*/

var Event = new Native({

	name: 'Event',

	initialize: function(event, win){
		win = win || window;
		var doc = win.document;
		event = event || win.event;
		if (event.$extended) return event;
		this.$extended = true;
		var type = event.type;
		var target = event.target || event.srcElement;
		while (target && target.nodeType == 3) target = target.parentNode;
		
		if (type.test(/key/)){
			var code = event.which || event.keyCode;
			var key = Event.Keys.keyOf(code);
			if (type == 'keydown'){
				var fKey = code - 111;
				if (fKey > 0 && fKey < 13) key = 'f' + fKey;
			}
			key = key || String.fromCharCode(code).toLowerCase();
		} else if (type.match(/(click|mouse|menu)/i)){
			doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
			var page = {
				x: event.pageX || event.clientX + doc.scrollLeft,
				y: event.pageY || event.clientY + doc.scrollTop
			};
			var client = {
				x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX,
				y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY
			};
			if (type.match(/DOMMouseScroll|mousewheel/)){
				var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
			}
			var rightClick = (event.which == 3) || (event.button == 2);
			var related = null;
			if (type.match(/over|out/)){
				switch (type){
					case 'mouseover': related = event.relatedTarget || event.fromElement; break;
					case 'mouseout': related = event.relatedTarget || event.toElement;
				}
				if (!(function(){
					while (related && related.nodeType == 3) related = related.parentNode;
					return true;
				}).create({attempt: Browser.Engine.gecko})()) related = false;
			}
		}

		return $extend(this, {
			event: event,
			type: type,
			
			page: page,
			client: client,
			rightClick: rightClick,
			
			wheel: wheel,
			
			relatedTarget: related,
			target: target,
			
			code: code,
			key: key,
			
			shift: event.shiftKey,
			control: event.ctrlKey,
			alt: event.altKey,
			meta: event.metaKey
		});
	}

});

Event.Keys = new Hash({
	'enter': 13,
	'up': 38,
	'down': 40,
	'left': 37,
	'right': 39,
	'esc': 27,
	'space': 32,
	'backspace': 8,
	'tab': 9,
	'delete': 46
});

Event.implement({

	stop: function(){
		return this.stopPropagation().preventDefault();
	},

	stopPropagation: function(){
		if (this.event.stopPropagation) this.event.stopPropagation();
		else this.event.cancelBubble = true;
		return this;
	},

	preventDefault: function(){
		if (this.event.preventDefault) this.event.preventDefault();
		else this.event.returnValue = false;
		return this;
	}

});

/*
Script: Class.js
	Contains the Class Function for easily creating, extending, and implementing reusable Classes.

License:
	MIT-style license.
*/

var Class = new Native({

	name: 'Class',

	initialize: function(properties){
		properties = properties || {};
		var klass = function(empty){
			for (var key in this) this[key] = $unlink(this[key]);
			for (var mutator in Class.Mutators){
				if (!this[mutator]) continue;
				Class.Mutators[mutator](this, this[mutator]);
				delete this[mutator];
			}

			this.constructor = klass;
			if (empty === $empty) return this;
			
			var self = (this.initialize) ? this.initialize.apply(this, arguments) : this;
			if (this.options && this.options.initialize) this.options.initialize.call(this);
			return self;
		};

		$extend(klass, this);
		klass.constructor = Class;
		klass.prototype = properties;
		return klass;
	}

});

Class.implement({

	implement: function(){
		Class.Mutators.Implements(this.prototype, Array.slice(arguments));
		return this;
	}

});

Class.Mutators = {
  
  Implements: function(self, klasses){
  	$splat(klasses).each(function(klass){
  		$extend(self, ($type(klass) == 'class') ? new klass($empty) : klass);
  	});
  },
  
  Extends: function(self, klass){
  	var instance = new klass($empty);
  	delete instance.parent;
  	delete instance.parentOf;

  	for (var key in instance){
  		var current = self[key], previous = instance[key];
  		if (current == undefined){
  			self[key] = previous;
  			continue;
  		}

  		var ctype = $type(current), ptype = $type(previous);
  		if (ctype != ptype) continue;

  		switch (ctype){
  			case 'function': 
  				// this code will be only executed if the current browser does not support function.caller (currently only opera).
  				// we replace the function code with brute force. Not pretty, but it will only be executed if function.caller is not supported.

  				if (!arguments.callee.caller) self[key] = eval('(' + String(current).replace(/\bthis\.parent\(\s*(\))?/g, function(full, close){
  					return 'arguments.callee._parent_.call(this' + (close || ', ');
  				}) + ')');

  				// end "opera" code
  				self[key]._parent_ = previous;
  			  break;
  			case 'object': self[key] = $merge(previous, current);
  		}

  	}

  	self.parent = function(){
  		return arguments.callee.caller._parent_.apply(this, arguments);
  	};

  	self.parentOf = function(descendant){
  		return descendant._parent_.apply(this, Array.slice(arguments, 1));
  	};
  }
  
};


/*
Script: Class.Extras.js
	Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks.

License:
	MIT-style license.
*/

var Chain = new Class({

	chain: function(){
		this.$chain = (this.$chain || []).extend(arguments);
		return this;
	},

	callChain: function(){
		return (this.$chain && this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
	},

	clearChain: function(){
		if (this.$chain) this.$chain.empty();
		return this;
	}

});

var Events = new Class({

	addEvent: function(type, fn, internal){
		type = Events.removeOn(type);
		if (fn != $empty){
			this.$events = this.$events || {};
			this.$events[type] = this.$events[type] || [];
			this.$events[type].include(fn);
			if (internal) fn.internal = true;
		}
		return this;
	},

	addEvents: function(events){
		for (var type in events) this.addEvent(type, events[type]);
		return this;
	},

	fireEvent: function(type, args, delay){
		type = Events.removeOn(type);
		if (!this.$events || !this.$events[type]) return this;
		this.$events[type].each(function(fn){
			fn.create({'bind': this, 'delay': delay, 'arguments': args})();
		}, this);
		return this;
	},

	removeEvent: function(type, fn){
		type = Events.removeOn(type);
		if (!this.$events || !this.$events[type]) return this;
		if (!fn.internal) this.$events[type].erase(fn);
		return this;
	},

	removeEvents: function(type){
		for (var e in this.$events){
			if (type && type != e) continue;
			var fns = this.$events[e];
			for (var i = fns.length; i--; i) this.removeEvent(e, fns[i]);
		}
		return this;
	}

});

Events.removeOn = function(string){
	return string.replace(/^on([A-Z])/, function(full, first) {
		return first.toLowerCase();
	});
};

var Options = new Class({

	setOptions: function(){
		this.options = $merge.run([this.options].extend(arguments));
		if (!this.addEvent) return this;
		for (var option in this.options){
			if ($type(this.options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
			this.addEvent(option, this.options[option]);
			delete this.options[option];
		}
		return this;
	}

});

/*
Script: Element.js
	One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser,
	time-saver methods to let you easily work with HTML Elements.

License:
	MIT-style license.
*/

Document.implement({

	newElement: function(tag, props){
		if (Browser.Engine.trident && props){
			['name', 'type', 'checked'].each(function(attribute){
				if (!props[attribute]) return;
				tag += ' ' + attribute + '="' + props[attribute] + '"';
				if (attribute != 'checked') delete props[attribute];
			});
			tag = '<' + tag + '>';
		}
		return $.element(this.createElement(tag)).set(props);
	},

	newTextNode: function(text){
		return this.createTextNode(text);
	},

	getDocument: function(){
		return this;
	},

	getWindow: function(){
		return this.defaultView || this.parentWindow;
	},

	purge: function(){
		var elements = this.getElementsByTagName('*');
		for (var i = 0, l = elements.length; i < l; i++) Browser.freeMem(elements[i]);
	}

});

var Element = new Native({

	name: 'Element',

	legacy: window.Element,

	initialize: function(tag, props){
		var konstructor = Element.Constructors.get(tag);
		if (konstructor) return konstructor(props);
		if (typeof tag == 'string') return document.newElement(tag, props);
		return $(tag).set(props);
	},

	afterImplement: function(key, value){
		if (!Array[key]) Elements.implement(key, Elements.multi(key));
		Element.Prototype[key] = value;
	}

});

Element.Prototype = {$family: {name: 'element'}};

Element.Constructors = new Hash;

var IFrame = new Native({

	name: 'IFrame',

	generics: false,

	initialize: function(){
		var params = Array.link(arguments, {properties: Object.type, iframe: $defined});
		var props = params.properties || {};
		var iframe = $(params.iframe) || false;
		var onload = props.onload || $empty;
		delete props.onload;
		props.id = props.name = $pick(props.id, props.name, iframe.id, iframe.name, 'IFrame_' + $time());
		iframe = new Element(iframe || 'iframe', props);
		var onFrameLoad = function(){
			var host = $try(function(){
				return iframe.contentWindow.location.host;
			});
			if (host && host == window.location.host){
				var win = new Window(iframe.contentWindow);
				var doc = new Document(iframe.contentWindow.document);
				$extend(win.Element.prototype, Element.Prototype);
			}
			onload.call(iframe.contentWindow, iframe.contentWindow.document);
		};
		(!window.frames[props.id]) ? iframe.addListener('load', onFrameLoad) : onFrameLoad();
		return iframe;
	}

});

var Elements = new Native({

	initialize: function(elements, options){
		options = $extend({ddup: true, cash: true}, options);
		elements = elements || [];
		if (options.ddup || options.cash){
			var uniques = {}, returned = [];
			for (var i = 0, l = elements.length; i < l; i++){
				var el = $.element(elements[i], !options.cash);
				if (options.ddup){
					if (uniques[el.uid]) continue;
					uniques[el.uid] = true;
				}
				returned.push(el);
			}
			elements = returned;
		}
		return (options.cash) ? $extend(elements, this) : elements;
	}

});

Elements.implement({

	filter: function(filter, bind){
		if (!filter) return this;
		return new Elements(Array.filter(this, (typeof filter == 'string') ? function(item){
			return item.match(filter);
		} : filter, bind));
	}

});

Elements.multi = function(property){
	return function(){
		var items = [];
		var elements = true;
		for (var i = 0, j = this.length; i < j; i++){
			var returns = this[i][property].apply(this[i], arguments);
			items.push(returns);
			if (elements) elements = ($type(returns) == 'element');
		}
		return (elements) ? new Elements(items) : items;
	};
};

Window.implement({

	$: function(el, nocash){
		if (el && el.$family && el.uid) return el;
		var type = $type(el);
		return ($[type]) ? $[type](el, nocash, this.document) : null;
	},

	$$: function(selector){
		if (arguments.length == 1 && typeof selector == 'string') return this.document.getElements(selector);
		var elements = [];
		var args = Array.flatten(arguments);
		for (var i = 0, l = args.length; i < l; i++){
			var item = args[i];
			switch ($type(item)){
				case 'element': item = [item]; break;
				case 'string': item = this.document.getElements(item, true); break;
				default: item = false;
			}
			if (item) elements.extend(item);
		}
		return new Elements(elements);
	},

	getDocument: function(){
		return this.document;
	},

	getWindow: function(){
		return this;
	}

});

$.string = function(id, nocash, doc){
	id = doc.getElementById(id);
	return (id) ? $.element(id, nocash) : null;
};

$.element = function(el, nocash){
	$uid(el);
	if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){
		var proto = Element.Prototype;
		for (var p in proto) el[p] = proto[p];
	};
	return el;
};

$.object = function(obj, nocash, doc){
	if (obj.toElement) return $.element(obj.toElement(doc), nocash);
	return null;
};

$.textnode = $.whitespace = $.window = $.document = $arguments(0);

Native.implement([Element, Document], {

	getElement: function(selector, nocash){
		return $(this.getElements(selector, true)[0] || null, nocash);
	},

	getElements: function(tags, nocash){
		tags = tags.split(',');
		var elements = [];
		var ddup = (tags.length > 1);
		tags.each(function(tag){
			var partial = this.getElementsByTagName(tag.trim());
			(ddup) ? elements.extend(partial) : elements = partial;
		}, this);
		return new Elements(elements, {ddup: ddup, cash: !nocash});
	}

});

Element.Storage = {

	get: function(uid){
		return (this[uid] || (this[uid] = {}));
	}

};

Element.Inserters = new Hash({

	before: function(context, element){
		if (element.parentNode) element.parentNode.insertBefore(context, element);
	},

	after: function(context, element){
		if (!element.parentNode) return;
		var next = element.nextSibling;
		(next) ? element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context);
	},

	bottom: function(context, element){
		element.appendChild(context);
	},

	top: function(context, element){
		var first = element.firstChild;
		(first) ? element.insertBefore(context, first) : element.appendChild(context);
	}

});

Element.Inserters.inside = Element.Inserters.bottom;

Element.Inserters.each(function(value, key){

	var Key = key.capitalize();

	Element.implement('inject' + Key, function(el){
		value(this, $(el, true));
		return this;
	});

	Element.implement('grab' + Key, function(el){
		value($(el, true), this);
		return this;
	});

});

Element.implement({

	getDocument: function(){
		return this.ownerDocument;
	},

	getWindow: function(){
		return this.ownerDocument.getWindow();
	},

	getElementById: function(id, nocash){
		var el = this.ownerDocument.getElementById(id);
		if (!el) return null;
		for (var parent = el.parentNode; parent != this; parent = parent.parentNode){
			if (!parent) return null;
		}
		return $.element(el, nocash);
	},

	set: function(prop, value){
		switch ($type(prop)){
			case 'object':
				for (var p in prop) this.set(p, prop[p]);
				break;
			case 'string':
				var property = Element.Properties.get(prop);
				(property && property.set) ? property.set.apply(this, Array.slice(arguments, 1)) : this.setProperty(prop, value);
		}
		return this;
	},

	get: function(prop){
		var property = Element.Properties.get(prop);
		return (property && property.get) ? property.get.apply(this, Array.slice(arguments, 1)) : this.getProperty(prop);
	},

	erase: function(prop){
		var property = Element.Properties.get(prop);
		(property && property.erase) ? property.erase.apply(this, Array.slice(arguments, 1)) : this.removeProperty(prop);
		return this;
	},

	match: function(tag){
		return (!tag || Element.get(this, 'tag') == tag);
	},

	inject: function(el, where){
		Element.Inserters.get(where || 'bottom')(this, $(el, true));
		return this;
	},

	wraps: function(el, where){
		el = $(el, true);
		return this.replaces(el).grab(el, where);
	},

	grab: function(el, where){
		Element.Inserters.get(where || 'bottom')($(el, true), this);
		return this;
	},

	appendText: function(text, where){
		return this.grab(this.getDocument().newTextNode(text), where);
	},

	adopt: function(){
		Array.flatten(arguments).each(function(element){
			element = $(element, true);
			if (element) this.appendChild(element);
		}, this);
		return this;
	},

	dispose: function(){
		return (this.parentNode) ? this.parentNode.removeChild(this) : this;
	},

	clone: function(contents, keepid){
		switch ($type(this)){
			case 'element':
				var attributes = {};
				for (var j = 0, l = this.attributes.length; j < l; j++){
					var attribute = this.attributes[j], key = attribute.nodeName.toLowerCase();
					if (Browser.Engine.trident && (/input/i).test(this.tagName) && (/width|height/).test(key)) continue;
					var value = (key == 'style' && this.style) ? this.style.cssText : attribute.nodeValue;
					if (!$chk(value) || key == 'uid' || (key == 'id' && !keepid)) continue;
					if (value != 'inherit' && ['string', 'number'].contains($type(value))) attributes[key] = value;
				}
				var element = new Element(this.nodeName.toLowerCase(), attributes);
				if (contents !== false){
					for (var i = 0, k = this.childNodes.length; i < k; i++){
						var child = Element.clone(this.childNodes[i], true, keepid);
						if (child) element.grab(child);
					}
				}
				return element;
			case 'textnode': return document.newTextNode(this.nodeValue);
		}
		return null;
	},

	replaces: function(el){
		el = $(el, true);
		el.parentNode.replaceChild(this, el);
		return this;
	},

	hasClass: function(className){
		return this.className.contains(className, ' ');
	},

	addClass: function(className){
		if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
		return this;
	},

	removeClass: function(className){
		this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean();
		return this;
	},

	toggleClass: function(className){
		return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
	},

	getComputedStyle: function(property){
		if (this.currentStyle) return this.currentStyle[property.camelCase()];
		var computed = this.getWindow().getComputedStyle(this, null);
		return (computed) ? computed.getPropertyValue([property.hyphenate()]) : null;
	},

	empty: function(){
		$A(this.childNodes).each(function(node){
			Browser.freeMem(node);
			Element.empty(node);
			Element.dispose(node);
		}, this);
		return this;
	},

	destroy: function(){
		Browser.freeMem(this.empty().dispose());
		return null;
	},

	getSelected: function(){
		return new Elements($A(this.options).filter(function(option){
			return option.selected;
		}));
	},

	toQueryString: function(){
		var queryString = [];
		this.getElements('input, select, textarea').each(function(el){
			if (!el.name || el.disabled) return;
			var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){
				return opt.value;
			}) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value;
			$splat(value).each(function(val){
				if (val) queryString.push(el.name + '=' + encodeURIComponent(val));
			});
		});
		return queryString.join('&');
	},

	getProperty: function(attribute){
		var EA = Element.Attributes, key = EA.Props[attribute];
		var value = (key) ? this[key] : this.getAttribute(attribute, 2);
		return (EA.Bools[attribute]) ? !!value : (key) ? value : value || null;
	},

	getProperties: function(){
		var args = $A(arguments);
		return args.map(function(attr){
			return this.getProperty(attr);
		}, this).associate(args);
	},

	setProperty: function(attribute, value){
		var EA = Element.Attributes, key = EA.Props[attribute], hasValue = $defined(value);
		if (key && EA.Bools[attribute]) value = (value || !hasValue) ? true : false;
		else if (!hasValue) return this.removeProperty(attribute);
		(key) ? this[key] = value : this.setAttribute(attribute, value);
		return this;
	},

	setProperties: function(attributes){
		for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);
		return this;
	},

	removeProperty: function(attribute){
		var EA = Element.Attributes, key = EA.Props[attribute], isBool = (key && EA.Bools[attribute]);
		(key) ? this[key] = (isBool) ? false : '' : this.removeAttribute(attribute);
		return this;
	},

	removeProperties: function(){
		Array.each(arguments, this.removeProperty, this);
		return this;
	}

});

(function(){

var walk = function(element, walk, start, match, all, nocash){
	var el = element[start || walk];
	var elements = [];
	while (el){
		if (el.nodeType == 1 && (!match || Element.match(el, match))){
			elements.push(el);
			if (!all) break;
		}
		el = el[walk];
	}
	return (all) ? new Elements(elements, {ddup: false, cash: !nocash}) : $(elements[0], nocash);
};

Element.implement({

	getPrevious: function(match, nocash){
		return walk(this, 'previousSibling', null, match, false, nocash);
	},

	getAllPrevious: function(match, nocash){
		return walk(this, 'previousSibling', null, match, true, nocash);
	},

	getNext: function(match, nocash){
		return walk(this, 'nextSibling', null, match, false, nocash);
	},

	getAllNext: function(match, nocash){
		return walk(this, 'nextSibling', null, match, true, nocash);
	},

	getFirst: function(match, nocash){
		return walk(this, 'nextSibling', 'firstChild', match, false, nocash);
	},

	getLast: function(match, nocash){
		return walk(this, 'previousSibling', 'lastChild', match, false, nocash);
	},

	getParent: function(match, nocash){
		return walk(this, 'parentNode', null, match, false, nocash);
	},

	getParents: function(match, nocash){
		return walk(this, 'parentNode', null, match, true, nocash);
	},

	getChildren: function(match, nocash){
		return walk(this, 'nextSibling', 'firstChild', match, true, nocash);
	},

	hasChild: function(el){
		el = $(el, true);
		return (!!el && $A(this.getElementsByTagName(el.tagName)).contains(el));
	}

});

})();

Element.Properties = new Hash;

Element.Properties.style = {

	set: function(style){
		this.style.cssText = style;
	},

	get: function(){
		return this.style.cssText;
	},

	erase: function(){
		this.style.cssText = '';
	}

};

Element.Properties.tag = {get: function(){
	return this.tagName.toLowerCase();
}};

Element.Properties.href = {get: function(){
	return (!this.href) ? null : this.href.replace(new RegExp('^' + document.location.protocol + '\/\/' + document.location.host), '');
}};

Element.Properties.html = {set: function(){
	return this.innerHTML = Array.flatten(arguments).join('');
}};

Native.implement([Element, Window, Document], {

	addListener: function(type, fn){
		if (this.addEventListener) this.addEventListener(type, fn, false);
		else this.attachEvent('on' + type, fn);
		return this;
	},

	removeListener: function(type, fn){
		if (this.removeEventListener) this.removeEventListener(type, fn, false);
		else this.detachEvent('on' + type, fn);
		return this;
	},

	retrieve: function(property, dflt){
		var storage = Element.Storage.get(this.uid);
		var prop = storage[property];
		if ($defined(dflt) && !$defined(prop)) prop = storage[property] = dflt;
		return $pick(prop);
	},

	store: function(property, value){
		var storage = Element.Storage.get(this.uid);
		storage[property] = value;
		return this;
	},

	eliminate: function(property){
		var storage = Element.Storage.get(this.uid);
		delete storage[property];
		return this;
	}

});

Element.Attributes = new Hash({
	Props: {'html': 'innerHTML', 'class': 'className', 'for': 'htmlFor', 'text': (Browser.Engine.trident) ? 'innerText' : 'textContent'},
	Bools: ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readonly', 'multiple', 'selected', 'noresize', 'defer'],
	Camels: ['value', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap']
});

Browser.freeMem = function(item){
	if (!item) return;
	try{
	    if (Browser.Engine.trident && (/object/i).test(item.tagName)){
		    for (var p in item){
			    if (typeof item[p] == 'function') item[p] = $empty;
		    }
		    Element.dispose(item);
	    }
	    if (item.uid && item.removeEvents) item.removeEvents();
	}catch(ex){
	    //Do nothing I think
	}
};

(function(EA){

	var EAB = EA.Bools, EAC = EA.Camels;
	EA.Bools = EAB = EAB.associate(EAB);
	Hash.extend(Hash.combine(EA.Props, EAB), EAC.associate(EAC.map(function(v){
		return v.toLowerCase();
	})));
	EA.erase('Camels');

})(Element.Attributes);

window.addListener('unload', function(){
	window.removeListener('unload', arguments.callee);
	document.purge();
	if (Browser.Engine.trident) CollectGarbage();
});

/*
Script: Element.Event.js
	Contains Element methods for dealing with events, and custom Events.

License:
	MIT-style license.
*/

Element.Properties.events = {set: function(events){
	this.addEvents(events);
}};

Native.implement([Element, Window, Document], {

	addEvent: function(type, fn){
		var events = this.retrieve('events', {});
		events[type] = events[type] || {'keys': [], 'values': []};
		if (events[type].keys.contains(fn)) return this;
		events[type].keys.push(fn);
		var realType = type, custom = Element.Events.get(type), condition = fn, self = this;
		if (custom){
			if (custom.onAdd) custom.onAdd.call(this, fn);
			if (custom.condition){
				condition = function(event){
					if (custom.condition.call(this, event)) return fn.call(this, event);
					return false;
				};
			}
			realType = custom.base || realType;
		}
		var defn = function(){
			return fn.call(self);
		};
		var nativeEvent = Element.NativeEvents[realType] || 0;
		if (nativeEvent){
			if (nativeEvent == 2){
				defn = function(event){
					event = new Event(event, self.getWindow());
					if (condition.call(self, event) === false) event.stop();
				};
			}
			this.addListener(realType, defn);
		}
		events[type].values.push(defn);
		return this;
	},

	removeEvent: function(type, fn){
		var events = this.retrieve('events');
		if (!events || !events[type]) return this;
		var pos = events[type].keys.indexOf(fn);
		if (pos == -1) return this;
		var key = events[type].keys.splice(pos, 1)[0];
		var value = events[type].values.splice(pos, 1)[0];
		var custom = Element.Events.get(type);
		if (custom){
			if (custom.onRemove) custom.onRemove.call(this, fn);
			type = custom.base || type;
		}
		return (Element.NativeEvents[type]) ? this.removeListener(type, value) : this;
	},

	addEvents: function(events){
		for (var event in events) this.addEvent(event, events[event]);
		return this;
	},

	removeEvents: function(type){
		var events = this.retrieve('events');
		if (!events) return this;
		if (!type){
			for (var evType in events) this.removeEvents(evType);
			events = null;
		} else if (events[type]){
			while (events[type].keys[0]) this.removeEvent(type, events[type].keys[0]);
			events[type] = null;
		}
		return this;
	},

	fireEvent: function(type, args, delay){
		var events = this.retrieve('events');
		if (!events || !events[type]) return this;
		events[type].keys.each(function(fn){
		    if(fn)fn.create({'bind': this, 'delay': delay, 'arguments': args})();
		}, this);
		return this;
	},

	cloneEvents: function(from, type){
		from = $(from);
		var fevents = from.retrieve('events');
		if (!fevents) return this;
		if (!type){
			for (var evType in fevents) this.cloneEvents(from, evType);
		} else if (fevents[type]){
			fevents[type].keys.each(function(fn){
				this.addEvent(type, fn);
			}, this);
		}
		return this;
	}

});

Element.NativeEvents = {
	click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
	mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
	mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
	keydown: 2, keypress: 2, keyup: 2, //keyboard
	focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements
	load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
	error: 1, abort: 1, scroll: 1 //misc
};

(function(){

var $check = function(event){
	var related = event.relatedTarget;
	if (related == undefined) return true;
	if (related === false) return false;
	return ($type(this) != 'document' && related != this && related.prefix != 'xul' && !this.hasChild(related));
};

Element.Events = new Hash({

	mouseenter: {
		base: 'mouseover',
		condition: $check
	},

	mouseleave: {
		base: 'mouseout',
		condition: $check
	},

	mousewheel: {
		base: (Browser.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel'
	}

});

})();

/*
Script: Element.Style.js
	Contains methods for interacting with the styles of Elements in a fashionable way.

License:
	MIT-style license.
*/

Element.Properties.styles = {set: function(styles){
	this.setStyles(styles);
}};

Element.Properties.opacity = {

	set: function(opacity, novisibility){
		if (!novisibility){
			if (opacity == 0){
				if (this.style.visibility != 'hidden') this.style.visibility = 'hidden';
			} else {
				if (this.style.visibility != 'visible') this.style.visibility = 'visible';
			}
		}
		if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1;
		if (Browser.Engine.trident) this.style.filter = (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')';
		this.style.opacity = opacity;
		this.store('opacity', opacity);
	},

	get: function(){
		return this.retrieve('opacity', 1);
	}

};

Element.implement({
	
	setOpacity: function(value){
		return this.set('opacity', value, true);
	},
	
	getOpacity: function(){
		return this.get('opacity');
	},

	setStyle: function(property, value){
		switch (property){
			case 'opacity': return this.set('opacity', parseFloat(value));
			case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat';
		}
		property = property.camelCase();
		if ($type(value) != 'string'){
			var map = (Element.Styles.get(property) || '@').split(' ');
			value = $splat(value).map(function(val, i){
				if (!map[i]) return '';
				return ($type(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
			}).join(' ');
		} else if (value == String(Number(value))){
			value = Math.round(value);
		}
		this.style[property] = value;
		return this;
	},

	getStyle: function(property){
		switch (property){
			case 'opacity': return this.get('opacity');
			case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat';
		}
		property = property.camelCase();
		var result = this.style[property];
		if (!$chk(result)){
			result = [];
			for (var style in Element.ShortStyles){
				if (property != style) continue;
				for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s));
				return result.join(' ');
			}
			result = this.getComputedStyle(property);
		}
		if (result){
			result = String(result);
			var color = result.match(/rgba?\([\d\s,]+\)/);
			if (color) result = result.replace(color[0], color[0].rgbToHex());
		}
		if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(result)))){
			if (property.test(/^(height|width)$/)){
				var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
				values.each(function(value){
					size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
				}, this);
				return this['offset' + property.capitalize()] - size + 'px';
			}
			if (Browser.Engine.presto && String(result).test('px')) return result;
			if (property.test(/(border(.+)Width|margin|padding)/)) return '0px';
		}
		return result;
	},

	setStyles: function(styles){
		for (var style in styles) this.setStyle(style, styles[style]);
		return this;
	},

	getStyles: function(){
		var result = {};
		Array.each(arguments, function(key){
			result[key] = this.getStyle(key);
		}, this);
		return result;
	}

});

Element.Styles = new Hash({
	left: '@px', top: '@px', bottom: '@px', right: '@px',
	width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
	backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
	fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
	margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
	borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
	zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
});

Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};

['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
	var Short = Element.ShortStyles;
	var All = Element.Styles;
	['margin', 'padding'].each(function(style){
		var sd = style + direction;
		Short[style][sd] = All[sd] = '@px';
	});
	var bd = 'border' + direction;
	Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
	var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
	Short[bd] = {};
	Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
	Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
	Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
});


/*
Script: Element.Dimensions.js
	Contains methods to work with size, scroll, or positioning of Elements and the window object.

License:
	MIT-style license.

Credits:
	- Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).
	- Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html).
*/

(function(){

Element.implement({

	scrollTo: function(x, y){
		if (isBody(this)){
			this.getWindow().scrollTo(x, y);
		} else {
			this.scrollLeft = x;
			this.scrollTop = y;
		}
		return this;
	},

	getSize: function(){
		if (isBody(this)) return this.getWindow().getSize();
		return {x: this.offsetWidth, y: this.offsetHeight};
	},

	getScrollSize: function(){
		if (isBody(this)) return this.getWindow().getScrollSize();
		return {x: this.scrollWidth, y: this.scrollHeight};
	},

	getScroll: function(){
		if (isBody(this)) return this.getWindow().getScroll();
		return {x: this.scrollLeft, y: this.scrollTop};
	},

	getScrolls: function(){
		var element = this, position = {x: 0, y: 0};
		while (element && !isBody(element)){
			position.x += element.scrollLeft;
			position.y += element.scrollTop;
			element = element.parentNode;
		}
		return position;
	},
	
	getOffsetParent: function(){
		var element = this;
		if (isBody(element)) return null; 
		if (!Browser.Engine.trident) return element.offsetParent;
		while ((element = element.parentNode) && !isBody(element)){ 
			if (styleString(element, 'position') != 'static') return element;
		} 
		return null;
	},

	getOffsets: function(){
		var element = this, position = {x: 0, y: 0};
		if (isBody(this)) return position;

		while (element && !isBody(element)){
			position.x += element.offsetLeft;
			position.y += element.offsetTop;

			if (Browser.Engine.gecko){
				if (!borderBox(element)){
					position.x += leftBorder(element);
					position.y += topBorder(element);
				}
				var parent = element.parentNode;
				if (parent && styleString(parent, 'overflow') != 'visible'){
					position.x += leftBorder(parent);
					position.y += topBorder(parent);
				}
			} else if (element != this && (Browser.Engine.trident || Browser.Engine.webkit)){
				position.x += leftBorder(element);
				position.y += topBorder(element);
			}

			element = element.offsetParent;
			if (Browser.Engine.trident){
				while (element && !element.currentStyle.hasLayout) element = element.offsetParent;
			}
		}
		if (Browser.Engine.gecko && !borderBox(this)){
			position.x -= leftBorder(this);
			position.y -= topBorder(this);
		}
		return position;
	},

	getPosition: function(relative){
		if (isBody(this)) return {x: 0, y: 0};
		var offset = this.getOffsets(), scroll = this.getScrolls();
		var position = {x: offset.x - scroll.x, y: offset.y - scroll.y};
		var relativePosition = (relative && (relative = $(relative))) ? relative.getPosition() : {x: 0, y: 0};
		return {x: position.x - relativePosition.x, y: position.y - relativePosition.y};
	},

	getCoordinates: function(element){
		if (isBody(this)) return this.getWindow().getCoordinates();
		var position = this.getPosition(element), size = this.getSize();
		var obj = {left: position.x, top: position.y, width: size.x, height: size.y};
		obj.right = obj.left + obj.width;
		obj.bottom = obj.top + obj.height;
		return obj;
	},

	computePosition: function(obj){
		return {left: obj.x - styleNumber(this, 'margin-left'), top: obj.y - styleNumber(this, 'margin-top')};
	},

	position: function(obj){
		return this.setStyles(this.computePosition(obj));
	}

});

Native.implement([Document, Window], {

	getSize: function(){
		var win = this.getWindow();
		if (Browser.Engine.presto || Browser.Engine.webkit) return {x: win.innerWidth, y: win.innerHeight};
		var doc = getCompatElement(this);
		return {x: doc.clientWidth, y: doc.clientHeight};
	},

	getScroll: function(){
		var win = this.getWindow();
		var doc = getCompatElement(this);
		return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
	},

	getScrollSize: function(){
		var doc = getCompatElement(this);
		var min = this.getSize();
		return {x: Math.max(doc.scrollWidth, min.x), y: Math.max(doc.scrollHeight, min.y)};
	},

	getPosition: function(){
		return {x: 0, y: 0};
	},

	getCoordinates: function(){
		var size = this.getSize();
		return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
	}

});

// private methods

var styleString = Element.getComputedStyle;

function styleNumber(element, style){
	return styleString(element, style).toInt() || 0;
};

function borderBox(element){
	return styleString(element, '-moz-box-sizing') == 'border-box';
};

function topBorder(element){
	return styleNumber(element, 'border-top-width');
};

function leftBorder(element){
	return styleNumber(element, 'border-left-width');
};

function isBody(element){
	return (/^(?:body|html)$/i).test(element.tagName);
};

function getCompatElement(element){
	var doc = element.getDocument();
	return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
};

})();

//aliases

Native.implement([Window, Document, Element], {

	getHeight: function(){
		return this.getSize().y;
	},

	getWidth: function(){
		return this.getSize().x;
	},

	getScrollTop: function(){
		return this.getScroll().y;
	},

	getScrollLeft: function(){
		return this.getScroll().x;
	},

	getScrollHeight: function(){
		return this.getScrollSize().y;
	},

	getScrollWidth: function(){
		return this.getScrollSize().x;
	},

	getTop: function(){
		return this.getPosition().y;
	},

	getLeft: function(){
		return this.getPosition().x;
	}

});

/*
Script: Selectors.js
	Adds advanced CSS Querying capabilities for targeting elements. Also includes pseudoselectors support.

License:
	MIT-style license.
*/

Native.implement([Document, Element], {
	
	getElements: function(expression, nocash){
		expression = expression.split(',');
		var items, local = {};
		for (var i = 0, l = expression.length; i < l; i++){
			var selector = expression[i], elements = Selectors.Utils.search(this, selector, local);
			if (i != 0 && elements.item) elements = $A(elements);
			items = (i == 0) ? elements : (items.item) ? $A(items).concat(elements) : items.concat(elements);
		}
		return new Elements(items, {ddup: (expression.length > 1), cash: !nocash});
	}
	
});

Element.implement({
	
	match: function(selector){
		if (!selector) return true;
		var tagid = Selectors.Utils.parseTagAndID(selector);
		var tag = tagid[0], id = tagid[1];
		if (!Selectors.Filters.byID(this, id) || !Selectors.Filters.byTag(this, tag)) return false;
		var parsed = Selectors.Utils.parseSelector(selector);
		return (parsed) ? Selectors.Utils.filter(this, parsed, {}) : true;
	}
	
});

var Selectors = {Cache: {nth: {}, parsed: {}}};

Selectors.RegExps = {
	id: (/#([\w-]+)/),
	tag: (/^(\w+|\*)/),
	quick: (/^(\w+|\*)$/),
	splitter: (/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),
	combined: (/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)["']?(.*?)["']?)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)
};

Selectors.Utils = {
	
	chk: function(item, uniques){
		if (!uniques) return true;
		var uid = $uid(item);
		if (!uniques[uid]) return uniques[uid] = true;
		return false;
	},
	
	parseNthArgument: function(argument){
		if (Selectors.Cache.nth[argument]) return Selectors.Cache.nth[argument];
		var parsed = argument.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);
		if (!parsed) return false;
		var inta = parseInt(parsed[1]);
		var a = (inta || inta === 0) ? inta : 1;
		var special = parsed[2] || false;
		var b = parseInt(parsed[3]) || 0;
		if (a != 0){
			b--;
			while (b < 1) b += a;
			while (b >= a) b -= a;
		} else {
			a = b;
			special = 'index';
		}
		switch (special){
			case 'n': parsed = {a: a, b: b, special: 'n'}; break;
			case 'odd': parsed = {a: 2, b: 0, special: 'n'}; break;
			case 'even': parsed =  {a: 2, b: 1, special: 'n'}; break;
			case 'first': parsed = {a: 0, special: 'index'}; break;
			case 'last': parsed = {special: 'last-child'}; break;
			case 'only': parsed = {special: 'only-child'}; break;
			default: parsed = {a: (a - 1), special: 'index'};
		}
		
		return Selectors.Cache.nth[argument] = parsed;
	},
	
	parseSelector: function(selector){
		if (Selectors.Cache.parsed[selector]) return Selectors.Cache.parsed[selector];
		var m, parsed = {classes: [], pseudos: [], attributes: []};
		while ((m = Selectors.RegExps.combined.exec(selector))){
			var cn = m[1], an = m[2], ao = m[3], av = m[4], pn = m[5], pa = m[6];
			if (cn){
				parsed.classes.push(cn);
			} else if (pn){
				var parser = Selectors.Pseudo.get(pn);
				if (parser) parsed.pseudos.push({parser: parser, argument: pa});
				else parsed.attributes.push({name: pn, operator: '=', value: pa});
			} else if (an){
				parsed.attributes.push({name: an, operator: ao, value: av});
			}
		}
		if (!parsed.classes.length) delete parsed.classes;
		if (!parsed.attributes.length) delete parsed.attributes;
		if (!parsed.pseudos.length) delete parsed.pseudos;
		if (!parsed.classes && !parsed.attributes && !parsed.pseudos) parsed = null;
		return Selectors.Cache.parsed[selector] = parsed;
	},
	
	parseTagAndID: function(selector){
		var tag = selector.match(Selectors.RegExps.tag);
		var id = selector.match(Selectors.RegExps.id);
		return [(tag) ? tag[1] : '*', (id) ? id[1] : false];
	},
	
	filter: function(item, parsed, local){
		var i;
		if (parsed.classes){
			for (i = parsed.classes.length; i--; i){
				var cn = parsed.classes[i];
				if (!Selectors.Filters.byClass(item, cn)) return false;
			}
		}
		if (parsed.attributes){
			for (i = parsed.attributes.length; i--; i){
				var att = parsed.attributes[i];
				if (!Selectors.Filters.byAttribute(item, att.name, att.operator, att.value)) return false;
			}
		}
		if (parsed.pseudos){
			for (i = parsed.pseudos.length; i--; i){
				var psd = parsed.pseudos[i];
				if (!Selectors.Filters.byPseudo(item, psd.parser, psd.argument, local)) return false;
			}
		}
		return true;
	},
	
	getByTagAndID: function(ctx, tag, id){
		if (id){
			var item = (ctx.getElementById) ? ctx.getElementById(id, true) : Element.getElementById(ctx, id, true);
			return (item && Selectors.Filters.byTag(item, tag)) ? [item] : [];
		} else {
			return ctx.getElementsByTagName(tag);
		}
	},
	
	search: function(self, expression, local){
		var splitters = [];
		
		var selectors = expression.trim().replace(Selectors.RegExps.splitter, function(m0, m1, m2){
			splitters.push(m1);
			return ':)' + m2;
		}).split(':)');
		
		var items, match, filtered, item;
		
		for (var i = 0, l = selectors.length; i < l; i++){
			
			var selector = selectors[i];
			
			if (i == 0 && Selectors.RegExps.quick.test(selector)){
				items = self.getElementsByTagName(selector);
				continue;
			}
			
			var splitter = splitters[i - 1];
			
			var tagid = Selectors.Utils.parseTagAndID(selector);
			var tag = tagid[0], id = tagid[1];

			if (i == 0){
				items = Selectors.Utils.getByTagAndID(self, tag, id);
			} else {
				var uniques = {}, found = [];
				for (var j = 0, k = items.length; j < k; j++) found = Selectors.Getters[splitter](found, items[j], tag, id, uniques);
				items = found;
			}
			
			var parsed = Selectors.Utils.parseSelector(selector);
			
			if (parsed){
				filtered = [];
				for (var m = 0, n = items.length; m < n; m++){
					item = items[m];
					if (Selectors.Utils.filter(item, parsed, local)) filtered.push(item);
				}
				items = filtered;
			}
			
		}
		
		return items;
		
	}
	
};

Selectors.Getters = {
	
	' ': function(found, self, tag, id, uniques){
		var items = Selectors.Utils.getByTagAndID(self, tag, id);
		for (var i = 0, l = items.length; i < l; i++){
			var item = items[i];
			if (Selectors.Utils.chk(item, uniques)) found.push(item);
		}
		return found;
	},
	
	'>': function(found, self, tag, id, uniques){
		var children = Selectors.Utils.getByTagAndID(self, tag, id);
		for (var i = 0, l = children.length; i < l; i++){
			var child = children[i];
			if (child.parentNode == self && Selectors.Utils.chk(child, uniques)) found.push(child);
		}
		return found;
	},
	
	'+': function(found, self, tag, id, uniques){
		while ((self = self.nextSibling)){
			if (self.nodeType == 1){
				if (Selectors.Utils.chk(self, uniques) && Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id)) found.push(self);
				break;
			}
		}
		return found;
	},
	
	'~': function(found, self, tag, id, uniques){
		
		while ((self = self.nextSibling)){
			if (self.nodeType == 1){
				if (!Selectors.Utils.chk(self, uniques)) break;
				if (Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id)) found.push(self);
			} 
		}
		return found;
	}
	
};

Selectors.Filters = {
	
	byTag: function(self, tag){
		return (tag == '*' || (self.tagName && self.tagName.toLowerCase() == tag));
	},
	
	byID: function(self, id){
		return (!id || (self.id && self.id == id));
	},
	
	byClass: function(self, klass){
		return (self.className && self.className.contains(klass, ' '));
	},
	
	byPseudo: function(self, parser, argument, local){
		return parser.call(self, argument, local);
	},
	
	byAttribute: function(self, name, operator, value){
		var result = Element.prototype.getProperty.call(self, name);
		if (!result) return false;
		if (!operator || value == undefined) return true;
		switch (operator){
			case '=': return (result == value);
			case '*=': return (result.contains(value));
			case '^=': return (result.substr(0, value.length) == value);
			case '$=': return (result.substr(result.length - value.length) == value);
			case '!=': return (result != value);
			case '~=': return result.contains(value, ' ');
			case '|=': return result.contains(value, '-');
		}
		return false;
	}
	
};

Selectors.Pseudo = new Hash({
	
	// w3c pseudo selectors
	
	empty: function(){
		return !(this.innerText || this.textContent || '').length;
	},
	
	not: function(selector){
		return !Element.match(this, selector);
	},
	
	contains: function(text){
		return (this.innerText || this.textContent || '').contains(text);
	},
	
	'first-child': function(){
		return Selectors.Pseudo.index.call(this, 0);
	},
	
	'last-child': function(){
		var element = this;
		while ((element = element.nextSibling)){
			if (element.nodeType == 1) return false;
		}
		return true;
	},
	
	'only-child': function(){
		var prev = this;
		while ((prev = prev.previousSibling)){
			if (prev.nodeType == 1) return false;
		}
		var next = this;
		while ((next = next.nextSibling)){
			if (next.nodeType == 1) return false;
		}
		return true;
	},
	
	'nth-child': function(argument, local){
		argument = (argument == undefined) ? 'n' : argument;
		var parsed = Selectors.Utils.parseNthArgument(argument);
		if (parsed.special != 'n') return Selectors.Pseudo[parsed.special].call(this, parsed.a, local);
		var count = 0;
		local.positions = local.positions || {};
		var uid = $uid(this);
		if (!local.positions[uid]){
			var self = this;
			while ((self = self.previousSibling)){
				if (self.nodeType != 1) continue;
				count ++;
				var position = local.positions[$uid(self)];
				if (position != undefined){
					count = position + count;
					break;
				}
			}
			local.positions[uid] = count;
		}
		return (local.positions[uid] % parsed.a == parsed.b);
	},
	
	// custom pseudo selectors
	
	index: function(index){
		var element = this, count = 0;
		while ((element = element.previousSibling)){
			if (element.nodeType == 1 && ++count > index) return false;
		}
		return (count == index);
	},
	
	even: function(argument, local){
		return Selectors.Pseudo['nth-child'].call(this, '2n+1', local);
	},

	odd: function(argument, local){
		return Selectors.Pseudo['nth-child'].call(this, '2n', local);
	}
	
});

/*
Script: Domready.js
	Contains the domready custom event.

License:
	MIT-style license.
*/

Element.Events.domready = {

	onAdd: function(fn){
		if (Browser.loaded) fn.call(this);
	}

};

(function(){
	
	var domready = function(){
		if (Browser.loaded) return;
		Browser.loaded = true;
		window.fireEvent('domready');
		document.fireEvent('domready');
	};
	
	switch (Browser.Engine.name){

		case 'webkit': (function(){
			(['loaded', 'complete'].contains(document.readyState)) ? domready() : arguments.callee.delay(50);
		})(); break;

		case 'trident':
			var temp = document.createElement('div');
			(function(){
				($try(function(){
					temp.doScroll('left');
					return $(temp).inject(document.body).set('html', 'temp').dispose();
				})) ? domready() : arguments.callee.delay(50);
			})();
		break;
		
		default:
			window.addEvent('load', domready);
			document.addEvent('DOMContentLoaded', domready);

	}
	
})();

/*
Script: JSON.js
	JSON encoder and decoder.

License:
	MIT-style license.

See Also:
	<http://www.json.org/>
*/

var JSON = new Hash({

	encode: function(obj){
		switch ($type(obj)){
			case 'string':
				return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"';
			case 'array':
				return '[' + String(obj.map(JSON.encode).filter($defined)) + ']';
			case 'object': case 'hash':
				var string = [];
				Hash.each(obj, function(value, key){
					var json = JSON.encode(value);
					if (json) string.push(JSON.encode(key) + ':' + json);
				});
				return '{' + string + '}';
			case 'number': case 'boolean': return String(obj);
			case false: return 'null';
		}
		return null;
	},

	$specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'},

	$replaceChars: function(chr){
		return JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16);
	},

	decode: function(string, secure){
		if ($type(string) != 'string' || !string.length) return null;
		if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
		return eval('(' + string + ')');
	}

});

Native.implement([Hash, Array, String, Number], {

	toJSON: function(){
		return JSON.encode(this);
	}

});


/*
Script: Cookie.js
	Class for creating, loading, and saving browser Cookies.

License:
	MIT-style license.

Credits:
	Based on the functions by Peter-Paul Koch (http://quirksmode.org).
*/

var Cookie = new Class({

	Implements: Options,

	options: {
		path: false,
		domain: false,
		duration: false,
		secure: false,
		document: document
	},

	initialize: function(key, options){
		this.key = key;
		this.setOptions(options);
	},

	write: function(value){
		value = encodeURIComponent(value);
		if (this.options.domain) value += '; domain=' + this.options.domain;
		if (this.options.path) value += '; path=' + this.options.path;
		if (this.options.duration){
			var date = new Date();
			date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
			value += '; expires=' + date.toGMTString();
		}
		if (this.options.secure) value += '; secure';
		this.options.document.cookie = this.key + '=' + value;
		return this;
	},

	read: function(){
		var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)');
		return (value) ? decodeURIComponent(value[1]) : null;
	},

	dispose: function(){
		new Cookie(this.key, $merge(this.options, {duration: -1})).write('');
		return this;
	}

});

Cookie.write = function(key, value, options){
	return new Cookie(key, options).write(value);
};

Cookie.read = function(key){
	return new Cookie(key).read();
};

Cookie.dispose = function(key, options){
	return new Cookie(key, options).dispose();
};

/*
Script: Swiff.js
	Wrapper for embedding SWF movies. Supports (and fixes) External Interface Communication.

License:
	MIT-style license.

Credits:
	Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject.
*/

var Swiff = new Class({

	Implements: [Options],

	options: {
		id: null,
		height: 1,
		width: 1,
		container: null,
		properties: {},
		params: {
			quality: 'high',
			allowScriptAccess: 'always',
			wMode: 'transparent',
			swLiveConnect: true
		},
		callBacks: {},
		vars: {}
	},

	toElement: function(){
		return this.object;
	},

	initialize: function(path, options){
		this.instance = 'Swiff_' + $time();

		this.setOptions(options);
		options = this.options;
		var id = this.id = options.id || this.instance;
		var container = $(options.container);

		Swiff.CallBacks[this.instance] = {};

		var params = options.params, vars = options.vars, callBacks = options.callBacks;
		var properties = $extend({height: options.height, width: options.width}, options.properties);

		var self = this;

		for (var callBack in callBacks){
			Swiff.CallBacks[this.instance][callBack] = (function(option){
				return function(){
					return option.apply(self.object, arguments);
				};
			})(callBacks[callBack]);
			vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack;
		}

		params.flashVars = Hash.toQueryString(vars);
		if (Browser.Engine.trident){
			properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
			params.movie = path;
		} else {
			properties.type = 'application/x-shockwave-flash';
			properties.data = path;
		}
		var build = '<object id="' + id + '"';
		for (var property in properties) build += ' ' + property + '="' + properties[property] + '"';
		build += '>';
		for (var param in params){
			if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />';
		}
		build += '</object>';
		this.object =  ((container) ? container.empty() : new Element('div')).set('html', build).firstChild;
	},

	replaces: function(element){
		element = $(element, true);
		element.parentNode.replaceChild(this.toElement(), element);
		return this;
	},

	inject: function(element){
		$(element, true).appendChild(this.toElement());
		return this;
	},

	remote: function(){
		return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments));
	}

});

Swiff.CallBacks = {};

Swiff.remote = function(obj, fn){
	var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascript">' + __flash__argumentsToXML(arguments, 2) + '</invoke>');
	return eval(rs);
};

/*
Script: Fx.js
	Contains the basic animation logic to be extended by all other Fx Classes.

License:
	MIT-style license.
*/

var Fx = new Class({

	Implements: [Chain, Events, Options],

	options: {
		/*
		onStart: $empty,
		onCancel: $empty,
		onComplete: $empty,
		*/
		fps: 50,
		unit: false,
		duration: 500,
		link: 'ignore',
		transition: function(p){
			return -(Math.cos(Math.PI * p) - 1) / 2;
		}
	},

	initialize: function(options){
		this.subject = this.subject || this;
		this.setOptions(options);
		this.options.duration = Fx.Durations[this.options.duration] || this.options.duration.toInt();
		var wait = this.options.wait;
		if (wait === false) this.options.link = 'cancel';
	},

	step: function(){
		var time = $time();
		if (time < this.time + this.options.duration){
			var delta = this.options.transition((time - this.time) / this.options.duration);
			this.set(this.compute(this.from, this.to, delta));
		} else {
			this.set(this.compute(this.from, this.to, 1));
			this.complete();
		}
	},

	set: function(now){
		return now;
	},

	compute: function(from, to, delta){
		return Fx.compute(from, to, delta);
	},

	check: function(caller){
		if (!this.timer) return true;
		switch (this.options.link){
			case 'cancel': this.cancel(); return true;
			case 'chain': this.chain(caller.bind(this, Array.slice(arguments, 1))); return false;
		}
		return false;
	},

	start: function(from, to){
		if (!this.check(arguments.callee, from, to)) return this;
		this.from = from;
		this.to = to;
		this.time = 0;
		this.startTimer();
		this.onStart();
		return this;
	},

	complete: function(){
		if (this.stopTimer()) this.onComplete();
		return this;
	},

	cancel: function(){
		if (this.stopTimer()) this.onCancel();
		return this;
	},

	onStart: function(){
		this.fireEvent('start', this.subject);
	},

	onComplete: function(){
		this.fireEvent('complete', this.subject);
		if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
	},

	onCancel: function(){
		this.fireEvent('cancel', this.subject).clearChain();
	},

	pause: function(){
		this.stopTimer();
		return this;
	},

	resume: function(){
		this.startTimer();
		return this;
	},

	stopTimer: function(){
		if (!this.timer) return false;
		this.time = $time() - this.time;
		this.timer = $clear(this.timer);
		return true;
	},

	startTimer: function(){
		if (this.timer) return false;
		this.time = $time() - this.time;
		this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this);
		return true;
	}

});

Fx.compute = function(from, to, delta){
	return (to - from) * delta + from;
};

Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000};


/*
Script: Fx.CSS.js
	Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements.

License:
	MIT-style license.
*/

Fx.CSS = new Class({

	Extends: Fx,

	//prepares the base from/to object

	prepare: function(element, property, values){
		values = $splat(values);
		var values1 = values[1];
		if (!$chk(values1)){
			values[1] = values[0];
			values[0] = element.getStyle(property);
		}
		var parsed = values.map(this.parse);
		return {from: parsed[0], to: parsed[1]};
	},

	//parses a value into an array

	parse: function(value){
		value = $lambda(value)();
		value = (typeof value == 'string') ? value.split(' ') : $splat(value);
		return value.map(function(val){
			val = String(val);
			var found = false;
			Fx.CSS.Parsers.each(function(parser, key){
				if (found) return;
				var parsed = parser.parse(val);
				if ($chk(parsed)) found = {value: parsed, parser: parser};
			});
			found = found || {value: val, parser: Fx.CSS.Parsers.String};
			return found;
		});
	},

	//computes by a from and to prepared objects, using their parsers.

	compute: function(from, to, delta){
		var computed = [];
		(Math.min(from.length, to.length)).times(function(i){
			computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});
		});
		computed.$family = {name: 'fx:css:value'};
		return computed;
	},

	//serves the value as settable

	serve: function(value, unit){
		if ($type(value) != 'fx:css:value') value = this.parse(value);
		var returned = [];
		value.each(function(bit){
			returned = returned.concat(bit.parser.serve(bit.value, unit));
		});
		return returned;
	},

	//renders the change to an element

	render: function(element, property, value, unit){
		element.setStyle(property, this.serve(value, unit));
	},

	//searches inside the page css to find the values for a selector

	search: function(selector){
		if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
		var to = {};
		Array.each(document.styleSheets, function(sheet, j){
			var href = sheet.href;
			if (href && href.contains('://') && !href.contains(document.domain)) return;
			var rules = sheet.rules || sheet.cssRules;
			Array.each(rules, function(rule, i){
				if (!rule.style) return;
				var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){
					return m.toLowerCase();
				}) : null;
				if (!selectorText || !selectorText.test('^' + selector + '$')) return;
				Element.Styles.each(function(value, style){
					if (!rule.style[style] || Element.ShortStyles[style]) return;
					value = String(rule.style[style]);
					to[style] = (value.test(/^rgb/)) ? value.rgbToHex() : value;
				});
			});
		});
		return Fx.CSS.Cache[selector] = to;
	}

});

Fx.CSS.Cache = {};

Fx.CSS.Parsers = new Hash({

	Color: {
		parse: function(value){
			if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);
			return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
		},
		compute: function(from, to, delta){
			return from.map(function(value, i){
				return Math.round(Fx.compute(from[i], to[i], delta));
			});
		},
		serve: function(value){
			return value.map(Number);
		}
	},

	Number: {
		parse: parseFloat,
		compute: Fx.compute,
		serve: function(value, unit){
			return (unit) ? value + unit : value;
		}
	},

	String: {
		parse: $lambda(false),
		compute: $arguments(1),
		serve: $arguments(0)
	}

});


/*
Script: Fx.Tween.js
	Formerly Fx.Style, effect to transition any CSS property for an element.

License:
	MIT-style license.
*/

Fx.Tween = new Class({

	Extends: Fx.CSS,

	initialize: function(element, options){
		this.element = this.subject = $(element);
		this.parent(options);
	},

	set: function(property, now){
		if (arguments.length == 1){
			now = property;
			property = this.property || this.options.property;
		}
		this.render(this.element, property, now, this.options.unit);
		return this;
	},

	start: function(property, from, to){
		if (!this.check(arguments.callee, property, from, to)) return this;
		var args = Array.flatten(arguments);
		this.property = this.options.property || args.shift();
		var parsed = this.prepare(this.element, this.property, args);
		return this.parent(parsed.from, parsed.to);
	}

});

Element.Properties.tween = {

	set: function(options){
		var tween = this.retrieve('tween');
		if (tween) tween.cancel();
		return this.eliminate('tween').store('tween:options', $extend({link: 'cancel'}, options));
	},

	get: function(options){
		if (options || !this.retrieve('tween')){
			if (options || !this.retrieve('tween:options')) this.set('tween', options);
			this.store('tween', new Fx.Tween(this, this.retrieve('tween:options')));
		}
		return this.retrieve('tween');
	}

};

Element.implement({

	tween: function(property, from, to){
		this.get('tween').start(arguments);
		return this;
	},

	fade: function(how){
		var fade = this.get('tween'), o = 'opacity', toggle;
		how = $pick(how, 'toggle');
		switch (how){
			case 'in': fade.start(o, 1); break;
			case 'out': fade.start(o, 0); break;
			case 'show': fade.set(o, 1); break;
			case 'hide': fade.set(o, 0); break;
			case 'toggle':
				var flag = this.retrieve('fade:flag', this.get('opacity') == 1);
				fade.start(o, (flag) ? 0 : 1);
				this.store('fade:flag', !flag);
				toggle = true;
			break;
			default: fade.start(o, arguments);
		}
		if (!toggle) this.eliminate('fade:flag');
		return this;
	},

	highlight: function(start, end){
		if (!end){
			end = this.retrieve('highlight:original', this.getStyle('background-color'));
			end = (end == 'transparent') ? '#fff' : end;
		}
		var tween = this.get('tween');
		tween.start('background-color', start || '#ffff88', end).chain(function(){
			this.setStyle('background-color', this.retrieve('highlight:original'));
			tween.callChain();
		}.bind(this));
		return this;
	}

});


/*
Script: Fx.Morph.js
	Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules.

License:
	MIT-style license.
*/

Fx.Morph = new Class({

	Extends: Fx.CSS,

	initialize: function(element, options){
		this.element = this.subject = $(element);
		this.parent(options);
	},

	set: function(now){
		if (typeof now == 'string') now = this.search(now);
		for (var p in now) this.render(this.element, p, now[p], this.options.unit);
		return this;
	},

	compute: function(from, to, delta){
		var now = {};
		for (var p in from) now[p] = this.parent(from[p], to[p], delta);
		return now;
	},

	start: function(properties){
		if (!this.check(arguments.callee, properties)) return this;
		if (typeof properties == 'string') properties = this.search(properties);
		var from = {}, to = {};
		for (var p in properties){
			var parsed = this.prepare(this.element, p, properties[p]);
			from[p] = parsed.from;
			to[p] = parsed.to;
		}
		return this.parent(from, to);
	}

});

Element.Properties.morph = {

	set: function(options){
		var morph = this.retrieve('morph');
		if (morph) morph.cancel();
		return this.eliminate('morph').store('morph:options', $extend({link: 'cancel'}, options));
	},

	get: function(options){
		if (options || !this.retrieve('morph')){
			if (options || !this.retrieve('morph:options')) this.set('morph', options);
			this.store('morph', new Fx.Morph(this, this.retrieve('morph:options')));
		}
		return this.retrieve('morph');
	}

};

Element.implement({

	morph: function(props){
		this.get('morph').start(props);
		return this;
	}

});

/*
Script: Fx.Transitions.js
	Contains a set of advanced transitions to be used with any of the Fx Classes.

License:
	MIT-style license.

Credits:
	Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, modified and optimized to be used with MooTools.
*/

(function(){

	var old = Fx.prototype.initialize;

	Fx.prototype.initialize = function(options){
		old.call(this, options);
		var trans = this.options.transition;
		if (typeof trans == 'string' && (trans = trans.split(':'))){
			var base = Fx.Transitions;
			base = base[trans[0]] || base[trans[0].capitalize()];
			if (trans[1]) base = base['ease' + trans[1].capitalize() + (trans[2] ? trans[2].capitalize() : '')];
			this.options.transition = base;
		}
	};

})();

Fx.Transition = function(transition, params){
	params = $splat(params);
	return $extend(transition, {
		easeIn: function(pos){
			return transition(pos, params);
		},
		easeOut: function(pos){
			return 1 - transition(1 - pos, params);
		},
		easeInOut: function(pos){
			return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2;
		}
	});
};

Fx.Transitions = new Hash({

	linear: $arguments(0)

});

Fx.Transitions.extend = function(transitions){
	for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
};

Fx.Transitions.extend({

	Pow: function(p, x){
		return Math.pow(p, x[0] || 6);
	},

	Expo: function(p){
		return Math.pow(2, 8 * (p - 1));
	},

	Circ: function(p){
		return 1 - Math.sin(Math.acos(p));
	},

	Sine: function(p){
		return 1 - Math.sin((1 - p) * Math.PI / 2);
	},

	Back: function(p, x){
		x = x[0] || 1.618;
		return Math.pow(p, 2) * ((x + 1) * p - x);
	},

	Bounce: function(p){
		var value;
		for (var a = 0, b = 1; 1; a += b, b /= 2){
			if (p >= (7 - 4 * a) / 11){
				value = - Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b;
				break;
			}
		}
		return value;
	},

	Elastic: function(p, x){
		return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
	}

});

['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
	Fx.Transitions[transition] = new Fx.Transition(function(p){
		return Math.pow(p, [i + 2]);
	});
});


/*
Script: Request.js
	Powerful all purpose Request Class. Uses XMLHTTPRequest.

License:
	MIT-style license.
*/

var Request = new Class({

	Implements: [Chain, Events, Options],

	options: {
		/*onRequest: $empty,
		onSuccess: $empty,
		onFailure: $empty,
		onException: $empty,*/
		url: '',
		data: '',
		headers: {
			'X-Requested-With': 'XMLHttpRequest',
			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
		},
		async: true,
		format: false,
		method: 'post',
		link: 'ignore',
		isSuccess: null,
		emulation: true,
		urlEncoded: true,
		encoding: 'utf-8',
		evalScripts: false,
		evalResponse: false
	},

	initialize: function(options){
		this.xhr = new Browser.Request();
		this.setOptions(options);
		this.options.isSuccess = this.options.isSuccess || this.isSuccess;
		this.headers = new Hash(this.options.headers);
	},

	onStateChange: function(){
		if (this.xhr.readyState != 4 || !this.running) return;
		this.running = false;
		this.status = 0;
		$try(function(){
			this.status = this.xhr.status;
		}.bind(this));
		if (this.options.isSuccess.call(this, this.status)){
			this.response = {text: this.xhr.responseText, xml: this.xhr.responseXML};
			this.success(this.response.text, this.response.xml);
		} else {
			this.response = {text: null, xml: null};
			this.failure();
		}
		this.xhr.onreadystatechange = $empty;
	},

	isSuccess: function(){
		return ((this.status >= 200) && (this.status < 300));
	},

	processScripts: function(text){
		if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return $exec(text);
		return text.stripScripts(this.options.evalScripts);
	},

	success: function(text, xml){
		this.onSuccess(this.processScripts(text), xml);
	},
	
	onSuccess: function(){
		this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
	},
	
	failure: function(){
		this.onFailure();
	},

	onFailure: function(){
		this.fireEvent('complete').fireEvent('failure', this.xhr);
	},

	setHeader: function(name, value){
		this.headers.set(name, value);
		return this;
	},

	getHeader: function(name){
		return $try(function(){
			return this.xhr.getResponseHeader(name);
		}.bind(this));
	},

	check: function(caller){
		if (!this.running) return true;
		switch (this.options.link){
			case 'cancel': this.cancel(); return true;
			case 'chain': this.chain(caller.bind(this, Array.slice(arguments, 1))); return false;
		}
		return false;
	},

	send: function(options){
		if (!this.check(arguments.callee, options)) return this;
		this.running = true;

		var type = $type(options);
		if (type == 'string' || type == 'element') options = {data: options};

		var old = this.options;
		options = $extend({data: old.data, url: old.url, method: old.method}, options);
		var data = options.data, url = options.url, method = options.method;

		switch ($type(data)){
			case 'element': data = $(data).toQueryString(); break;
			case 'object': case 'hash': data = Hash.toQueryString(data);
		}

		if (this.options.format){
			var format = 'format=' + this.options.format;
			data = (data) ? format + '&' + data : format;
		}

		if (this.options.emulation && ['put', 'delete'].contains(method)){
			var _method = '_method=' + method;
			data = (data) ? _method + '&' + data : _method;
			method = 'post';
		}

		if (this.options.urlEncoded && method == 'post'){
			var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
			this.headers.set('Content-type', 'application/x-www-form-urlencoded' + encoding);
		}

		if (data && method == 'get'){
			url = url + (url.contains('?') ? '&' : '?') + data;
			data = null;
		}

		this.xhr.open(method.toUpperCase(), url, this.options.async);

		this.xhr.onreadystatechange = this.onStateChange.bind(this);

		this.headers.each(function(value, key){
			if (!$try(function(){
				this.xhr.setRequestHeader(key, value);
				return true;
			}.bind(this))) this.fireEvent('exception', [key, value]);
		}, this);

		this.fireEvent('request');
		this.xhr.send(data);
		if (!this.options.async) this.onStateChange();
		return this;
	},

	cancel: function(){
		if (!this.running) return this;
		this.running = false;
		this.xhr.abort();
		this.xhr.onreadystatechange = $empty;
		this.xhr = new Browser.Request();
		this.fireEvent('cancel');
		return this;
	}

});

(function(){

var methods = {};
['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){
	methods[method] = function(){
		var params = Array.link(arguments, {url: String.type, data: $defined});
		return this.send($extend(params, {method: method.toLowerCase()}));
	};
});

Request.implement(methods);

})();

Element.Properties.send = {
	
	set: function(options){
		var send = this.retrieve('send');
		if (send) send.cancel();
		return this.eliminate('send').store('send:options', $extend({
			data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action')
		}, options));
	},

	get: function(options){
		if (options || !this.retrieve('send')){
			if (options || !this.retrieve('send:options')) this.set('send', options);
			this.store('send', new Request(this.retrieve('send:options')));
		}
		return this.retrieve('send');
	}

};

Element.implement({

	send: function(url){
		var sender = this.get('send');
		sender.send({data: this, url: url || sender.options.url});
		return this;
	}

});


/*
Script: Request.HTML.js
	Extends the basic Request Class with additional methods for interacting with HTML responses.

License:
	MIT-style license.
*/

Request.HTML = new Class({

	Extends: Request,

	options: {
		update: false,
		evalScripts: true,
		filter: false
	},

	processHTML: function(text){
		var match = text.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
		text = (match) ? match[1] : text;
		
		var container = new Element('div');
		
		return $try(function(){
			var root = '<root>' + text + '</root>', doc;
			if (Browser.Engine.trident){
				doc = new ActiveXObject('Microsoft.XMLDOM');
				doc.async = false;
				doc.loadXML(root);
			} else {
				doc = new DOMParser().parseFromString(root, 'text/xml');
			}
			root = doc.getElementsByTagName('root')[0];
			for (var i = 0, k = root.childNodes.length; i < k; i++){
				var child = Element.clone(root.childNodes[i], true, true);
				if (child) container.grab(child);
			}
			return container;
		}) || container.set('html', text);
	},

	success: function(text){
		var options = this.options, response = this.response;
		
		response.html = text.stripScripts(function(script){
			response.javascript = script;
		});
		
		var temp = this.processHTML(response.html);
		
		response.tree = temp.childNodes;
		response.elements = temp.getElements('*');
		
		if (options.filter) response.tree = response.elements.filter(options.filter);
		if (options.update) $(options.update).empty().adopt(response.tree);
		if (options.evalScripts) $exec(response.javascript);
		
		this.onSuccess(response.tree, response.elements, response.html, response.javascript);
	}

});

Element.Properties.load = {
	
	set: function(options){
		var load = this.retrieve('load');
		if (load) send.cancel();
		return this.eliminate('load').store('load:options', $extend({data: this, link: 'cancel', update: this, method: 'get'}, options));
	},

	get: function(options){
		if (options || ! this.retrieve('load')){
			if (options || !this.retrieve('load:options')) this.set('load', options);
			this.store('load', new Request.HTML(this.retrieve('load:options')));
		}
		return this.retrieve('load');
	}

};

Element.implement({
	
	load: function(){
		this.get('load').send(Array.link(arguments, {data: Object.type, url: String.type}));
		return this;
	}

});


/*
Script: Request.JSON.js
	Extends the basic Request Class with additional methods for sending and receiving JSON data.

License:
	MIT-style license.
*/

Request.JSON = new Class({

	Extends: Request,

	options: {
		secure: true
	},

	initialize: function(options){
		this.parent(options);
		this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'});
	},

	success: function(text){
		this.response.json = JSON.decode(text, this.options.secure);
		this.onSuccess(this.response.json, text);
	}

});


//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2008 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

/*
Script: Fx.Slide.js
	Effect to slide an element in and out of view.

License:
	MIT-style license.
*/

Fx.Slide = new Class({

	Extends: Fx,

	options: {
		mode: 'vertical',
		overflow: 'hidden'
	},

	initialize: function(element, options){
		this.addEvent('complete', function(){
			this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0);
			if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper);
		}, true);
		this.element = this.subject = $(element);
		this.parent(options);
		var wrapper = this.element.retrieve('wrapper');
		this.wrapper = wrapper || new Element('div', {
			styles: $extend(this.element.getStyles('margin', 'position'), {'overflow': this.options.overflow})
		}).wraps(this.element);
		this.element.store('wrapper', this.wrapper).setStyle('margin', 0);
		this.now = [];
		this.open = true;
	},

	vertical: function(){
		this.margin = 'margin-top';
		this.layout = 'height';
		this.offset = this.element.offsetHeight;
	},

	horizontal: function(){
		this.margin = 'margin-left';
		this.layout = 'width';
		this.offset = this.element.offsetWidth;
	},

	set: function(now){
		this.element.setStyle(this.margin, now[0]);
		this.wrapper.setStyle(this.layout, now[1]);
		return this;
	},

	compute: function(from, to, delta){
		var now = [];
		var x = 2;
		x.times(function(i){
			now[i] = Fx.compute(from[i], to[i], delta);
		});
		return now;
	},

	start: function(how, mode){
		if (!this.check(arguments.callee, how, mode)) return this;
		this[mode || this.options.mode]();
		var margin = this.element.getStyle(this.margin).toInt();
		var layout = this.wrapper.getStyle(this.layout).toInt();
		var caseIn = [[margin, layout], [0, this.offset]];
		var caseOut = [[margin, layout], [-this.offset, 0]];
		var start;
		switch (how){
			case 'in': start = caseIn; break;
			case 'out': start = caseOut; break;
			case 'toggle': start = (this.wrapper['offset' + this.layout.capitalize()] == 0) ? caseIn : caseOut;
		}
		return this.parent(start[0], start[1]);
	},

	slideIn: function(mode){
		return this.start('in', mode);
	},

	slideOut: function(mode){
		return this.start('out', mode);
	},

	hide: function(mode){
		this[mode || this.options.mode]();
		this.open = false;
		return this.set([-this.offset, 0]);
	},

	show: function(mode){
		this[mode || this.options.mode]();
		this.open = true;
		return this.set([0, this.offset]);
	},

	toggle: function(mode){
		return this.start('toggle', mode);
	}

});

Element.Properties.slide = {

	set: function(options){
		var slide = this.retrieve('slide');
		if (slide) slide.cancel();
		return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options));
	},
	
	get: function(options){
		if (options || !this.retrieve('slide')){
			if (options || !this.retrieve('slide:options')) this.set('slide', options);
			this.store('slide', new Fx.Slide(this, this.retrieve('slide:options')));
		}
		return this.retrieve('slide');
	}

};

Element.implement({

	slide: function(how, mode){
		how = how || 'toggle';
		var slide = this.get('slide'), toggle;
		switch (how){
			case 'hide': slide.hide(mode); break;
			case 'show': slide.show(mode); break;
			case 'toggle':
				var flag = this.retrieve('slide:flag', slide.open);
				slide[(flag) ? 'slideOut' : 'slideIn'](mode);
				this.store('slide:flag', !flag);
				toggle = true;
			break;
			default: slide.start(how, mode);
		}
		if (!toggle) this.eliminate('slide:flag');
		return this;
	}

});


/*
Script: Fx.Scroll.js
	Effect to smoothly scroll any element, including the window.

License:
	MIT-style license.
*/

Fx.Scroll = new Class({

	Extends: Fx,

	options: {
		offset: {'x': 0, 'y': 0},
		wheelStops: true
	},

	initialize: function(element, options){
		this.element = this.subject = $(element);
		this.parent(options);
		var cancel = this.cancel.bind(this, false);

		if ($type(this.element) != 'element') this.element = $(this.element.getDocument().body);

		var stopper = this.element;

		if (this.options.wheelStops){
			this.addEvent('start', function(){
				stopper.addEvent('mousewheel', cancel);
			}, true);
			this.addEvent('complete', function(){
				stopper.removeEvent('mousewheel', cancel);
			}, true);
		}
	},

	set: function(){
		var now = Array.flatten(arguments);
		this.element.scrollTo(now[0], now[1]);
	},

	compute: function(from, to, delta){
		var now = [];
		var x = 2;
		x.times(function(i){
			now.push(Fx.compute(from[i], to[i], delta));
		});
		return now;
	},

	start: function(x, y){
		if (!this.check(arguments.callee, x, y)) return this;
		var offsetSize = this.element.getSize(), scrollSize = this.element.getScrollSize();
		var scroll = this.element.getScroll(), values = {x: x, y: y};
		for (var z in values){
			var max = scrollSize[z] - offsetSize[z];
			if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
			else values[z] = scroll[z];
			values[z] += this.options.offset[z];
		}
		return this.parent([scroll.x, scroll.y], [values.x, values.y]);
	},

	toTop: function(){
		return this.start(false, 0);
	},

	toLeft: function(){
		return this.start(0, false);
	},

	toRight: function(){
		return this.start('right', false);
	},

	toBottom: function(){
		return this.start(false, 'bottom');
	},

	toElement: function(el){
		var position = $(el).getPosition(this.element);
		return this.start(position.x, position.y);
	}

});


/*
Script: Fx.Elements.js
	Effect to change any number of CSS properties of any number of Elements.

License:
	MIT-style license.
*/

Fx.Elements = new Class({

	Extends: Fx.CSS,

	initialize: function(elements, options){
		this.elements = this.subject = $$(elements);
		this.parent(options);
	},

	compute: function(from, to, delta){
		var now = {};
		for (var i in from){
			var iFrom = from[i], iTo = to[i], iNow = now[i] = {};
			for (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta);
		}
		return now;
	},

	set: function(now){
		for (var i in now){
			var iNow = now[i];
			for (var p in iNow) this.render(this.elements[i], p, iNow[p], this.options.unit);
		}
		return this;
	},

	start: function(obj){
		if (!this.check(arguments.callee, obj)) return this;
		var from = {}, to = {};
		for (var i in obj){
			var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {};
			for (var p in iProps){
				var parsed = this.prepare(this.elements[i], p, iProps[p]);
				iFrom[p] = parsed.from;
				iTo[p] = parsed.to;
			}
		}
		return this.parent(from, to);
	}

});

/*
Script: Drag.js
	The base Drag Class. Can be used to drag and resize Elements using mouse events.

License:
	MIT-style license.
*/

var Drag = new Class({

	Implements: [Events, Options],

	options: {/*
		onBeforeStart: $empty,
		onStart: $empty,
		onDrag: $empty,
		onCancel: $empty,
		onComplete: $empty,*/
		snap: 6,
		unit: 'px',
		grid: false,
		style: true,
		limit: false,
		handle: false,
		invert: false,
		preventDefault: false,
		modifiers: {x: 'left', y: 'top'}
	},

	initialize: function(){
		var params = Array.link(arguments, {'options': Object.type, 'element': $defined});
		this.element = $(params.element);
		this.document = this.element.getDocument();
		this.setOptions(params.options || {});
		var htype = $type(this.options.handle);
		this.handles = (htype == 'array' || htype == 'collection') ? $$(this.options.handle) : $(this.options.handle) || this.element;
		this.mouse = {'now': {}, 'pos': {}};
		this.value = {'start': {}, 'now': {}};
		
		this.selection = (Browser.Engine.trident) ? 'selectstart' : 'mousedown';
		
		this.bound = {
			start: this.start.bind(this),
			check: this.check.bind(this),
			drag: this.drag.bind(this),
			stop: this.stop.bind(this),
			cancel: this.cancel.bind(this),
			eventStop: $lambda(false)
		};
		this.attach();
	},

	attach: function(){
		this.handles.addEvent('mousedown', this.bound.start);
		return this;
	},

	detach: function(){
		this.handles.removeEvent('mousedown', this.bound.start);
		return this;
	},

	start: function(event){
		if (this.options.preventDefault) event.preventDefault();
		this.fireEvent('beforeStart', this.element);
		this.mouse.start = event.page;
		var limit = this.options.limit;
		this.limit = {'x': [], 'y': []};
		for (var z in this.options.modifiers){
			if (!this.options.modifiers[z]) continue;
			if (this.options.style) this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt();
			else this.value.now[z] = this.element[this.options.modifiers[z]];
			if (this.options.invert) this.value.now[z] *= -1;
			this.mouse.pos[z] = event.page[z] - this.value.now[z];
			if (limit && limit[z]){
				for (var i = 2; i--; i){
					if ($chk(limit[z][i])) this.limit[z][i] = $lambda(limit[z][i])();
				}
			}
		}
		if ($type(this.options.grid) == 'number') this.options.grid = {'x': this.options.grid, 'y': this.options.grid};
		this.document.addEvents({mousemove: this.bound.check, mouseup: this.bound.cancel});
		this.document.addEvent(this.selection, this.bound.eventStop);
	},

	check: function(event){
		if (this.options.preventDefault) event.preventDefault();
		var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
		if (distance > this.options.snap){
			this.cancel();
			this.document.addEvents({
				mousemove: this.bound.drag,
				mouseup: this.bound.stop
			});
			this.fireEvent('start', this.element).fireEvent('snap', this.element);
		}
	},

	drag: function(event){
		if (this.options.preventDefault) event.preventDefault();
		this.mouse.now = event.page;
		for (var z in this.options.modifiers){
			if (!this.options.modifiers[z]) continue;
			this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
			if (this.options.invert) this.value.now[z] *= -1;
			if (this.options.limit && this.limit[z]){
				if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){
					this.value.now[z] = this.limit[z][1];
				} else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){
					this.value.now[z] = this.limit[z][0];
				}
			}
			if (this.options.grid[z]) this.value.now[z] -= (this.value.now[z] % this.options.grid[z]);
			if (this.options.style) this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit);
			else this.element[this.options.modifiers[z]] = this.value.now[z];
		}
		this.fireEvent('drag', this.element);
	},

	cancel: function(event){
		this.document.removeEvent('mousemove', this.bound.check);
		this.document.removeEvent('mouseup', this.bound.cancel);
		if (event){
			this.document.removeEvent(this.selection, this.bound.eventStop);
			this.fireEvent('cancel', this.element);
		}
	},

	stop: function(event){
		this.document.removeEvent(this.selection, this.bound.eventStop);
		this.document.removeEvent('mousemove', this.bound.drag);
		this.document.removeEvent('mouseup', this.bound.stop);
		if (event) this.fireEvent('complete', this.element);
	}

});

Element.implement({
	
	makeResizable: function(options){
		return new Drag(this, $merge({modifiers: {'x': 'width', 'y': 'height'}}, options));
	}

});

/*
Script: Drag.Move.js
	A Drag extension that provides support for the constraining of draggables to containers and droppables.

License:
	MIT-style license.
*/

Drag.Move = new Class({

	Extends: Drag,

	options: {
		droppables: [],
		container: false
	},

	initialize: function(element, options){
		this.parent(element, options);
		this.droppables = $$(this.options.droppables);
		this.container = $(this.options.container);
		if (this.container && $type(this.container) != 'element') this.container = $(this.container.getDocument().body);
		element = this.element;
		
		var current = element.getStyle('position');
		var position = (current != 'static') ? current : 'absolute';
		if (element.getStyle('left') == 'auto' || element.getStyle('top') == 'auto') element.position(element.getPosition(element.offsetParent));
		
		element.setStyle('position', position);
		
		this.addEvent('start', function(){
			this.checkDroppables();
		}, true);
	},

	start: function(event){
		if (this.container){
			var el = this.element, cont = this.container, ccoo = cont.getCoordinates(el.offsetParent), cps = {}, ems = {};

			['top', 'right', 'bottom', 'left'].each(function(pad){
				cps[pad] = cont.getStyle('padding-' + pad).toInt();
				ems[pad] = el.getStyle('margin-' + pad).toInt();
			}, this);

			var width = el.offsetWidth + ems.left + ems.right, height = el.offsetHeight + ems.top + ems.bottom;
			var x = [ccoo.left + cps.left, ccoo.right - cps.right - width];
			var y = [ccoo.top + cps.top, ccoo.bottom - cps.bottom - height];

			this.options.limit = {x: x, y: y};
		}
		this.parent(event);
	},

	checkAgainst: function(el){
		el = el.getCoordinates();
		var now = this.mouse.now;
		return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
	},

	checkDroppables: function(){
		var overed = this.droppables.filter(this.checkAgainst, this).getLast();
		if (this.overed != overed){
			if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
			if (overed){
				this.overed = overed;
				this.fireEvent('enter', [this.element, overed]);
			} else {
				this.overed = null;
			}
		}
	},

	drag: function(event){
		this.parent(event);
		if (this.droppables.length) this.checkDroppables();
	},

	stop: function(event){
		this.checkDroppables();
		this.fireEvent('drop', [this.element, this.overed]);
		this.overed = null;
		return this.parent(event);
	}

});

Element.implement({

	makeDraggable: function(options){
		return new Drag.Move(this, options);
	}

});


/*
Script: Hash.Cookie.js
	Class for creating, reading, and deleting Cookies in JSON format.

License:
	MIT-style license.
*/

Hash.Cookie = new Class({

	Extends: Cookie,

	options: {
		autoSave: true
	},

	initialize: function(name, options){
		this.parent(name, options);
		this.load();
	},

	save: function(){
		var value = JSON.encode(this.hash);
		if (!value || value.length > 4096) return false; //cookie would be truncated!
		if (value == '{}') this.dispose();
		else this.write(value);
		return true;
	},

	load: function(){
		this.hash = new Hash(JSON.decode(this.read(), true));
		return this;
	}

});

Hash.Cookie.implement((function(){
	
	var methods = {};
	
	Hash.each(Hash.prototype, function(method, name){
		methods[name] = function(){
			var value = method.apply(this.hash, arguments);
			if (this.options.autoSave) this.save();
			return value;
		};
	});
	
	return methods;
	
})());

/*
Script: Color.js
	Class for creating and manipulating colors in JavaScript. Supports HSB -> RGB Conversions and vice versa.

License:
	MIT-style license.
*/

var Color = new Native({
  
	initialize: function(color, type){
		if (arguments.length >= 3){
			type = "rgb"; color = Array.slice(arguments, 0, 3);
		} else if (typeof color == 'string'){
			if (color.match(/rgb/)) color = color.rgbToHex().hexToRgb(true);
			else if (color.match(/hsb/)) color = color.hsbToRgb();
			else color = color.hexToRgb(true);
		}
		type = type || 'rgb';
		switch (type){
			case 'hsb':
				var old = color;
				color = color.hsbToRgb();
				color.hsb = old;
			break;
			case 'hex': color = color.hexToRgb(true); break;
		}
		color.rgb = color.slice(0, 3);
		color.hsb = color.hsb || color.rgbToHsb();
		color.hex = color.rgbToHex();
		return $extend(color, this);
	}

});

Color.implement({

	mix: function(){
		var colors = Array.slice(arguments);
		var alpha = ($type(colors.getLast()) == 'number') ? colors.pop() : 50;
		var rgb = this.slice();
		colors.each(function(color){
			color = new Color(color);
			for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
		});
		return new Color(rgb, 'rgb');
	},

	invert: function(){
		return new Color(this.map(function(value){
			return 255 - value;
		}));
	},

	setHue: function(value){
		return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
	},

	setSaturation: function(percent){
		return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
	},

	setBrightness: function(percent){
		return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
	}

});

function $RGB(r, g, b){
	return new Color([r, g, b], 'rgb');
};

function $HSB(h, s, b){
	return new Color([h, s, b], 'hsb');
};

function $HEX(hex){
	return new Color(hex, 'hex');
};

Array.implement({

	rgbToHsb: function(){
		var red = this[0], green = this[1], blue = this[2];
		var hue, saturation, brightness;
		var max = Math.max(red, green, blue), min = Math.min(red, green, blue);
		var delta = max - min;
		brightness = max / 255;
		saturation = (max != 0) ? delta / max : 0;
		if (saturation == 0){
			hue = 0;
		} else {
			var rr = (max - red) / delta;
			var gr = (max - green) / delta;
			var br = (max - blue) / delta;
			if (red == max) hue = br - gr;
			else if (green == max) hue = 2 + rr - br;
			else hue = 4 + gr - rr;
			hue /= 6;
			if (hue < 0) hue++;
		}
		return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
	},

	hsbToRgb: function(){
		var br = Math.round(this[2] / 100 * 255);
		if (this[1] == 0){
			return [br, br, br];
		} else {
			var hue = this[0] % 360;
			var f = hue % 60;
			var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
			var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
			var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
			switch (Math.floor(hue / 60)){
				case 0: return [br, t, p];
				case 1: return [q, br, p];
				case 2: return [p, br, t];
				case 3: return [p, q, br];
				case 4: return [t, p, br];
				case 5: return [br, p, q];
			}
		}
		return false;
	}

});

String.implement({

	rgbToHsb: function(){
		var rgb = this.match(/\d{1,3}/g);
		return (rgb) ? hsb.rgbToHsb() : null;
	},
	
	hsbToRgb: function(){
		var hsb = this.match(/\d{1,3}/g);
		return (hsb) ? hsb.hsbToRgb() : null;
	}

});


/*
Script: Group.js
	Class for monitoring collections of events

License:
	MIT-style license.
*/

var Group = new Class({

	initialize: function(){
		this.instances = Array.flatten(arguments);
		this.events = {};
		this.checker = {};
	},

	addEvent: function(type, fn){
		this.checker[type] = this.checker[type] || {};
		this.events[type] = this.events[type] || [];
		if (this.events[type].contains(fn)) return false;
		else this.events[type].push(fn);
		this.instances.each(function(instance, i){
			instance.addEvent(type, this.check.bind(this, [type, instance, i]));
		}, this);
		return this;
	},

	check: function(type, instance, i){
		this.checker[type][i] = true;
		var every = this.instances.every(function(current, j){
			return this.checker[type][j] || false;
		}, this);
		if (!every) return;
		this.checker[type] = {};
		this.events[type].each(function(event){
			event.call(this, this.instances, instance);
		}, this);
	}

});


/*
Script: Assets.js
	Provides methods to dynamically load JavaScript, CSS, and Image files into the document.

License:
	MIT-style license.
*/

var Asset = new Hash({

	javascript: function(source, properties){
		properties = $extend({
			onload: $empty,
			document: document,
			check: $lambda(true)
		}, properties);
		
		var script = new Element('script', {'src': source, 'type': 'text/javascript'});
		
		var load = properties.onload.bind(script), check = properties.check, doc = properties.document;
		delete properties.onload; delete properties.check; delete properties.document;
		
		script.addEvents({
			load: load,
			readystatechange: function(){
				if (['loaded', 'complete'].contains(this.readyState)) load();
			}
		}).setProperties(properties);
		
		
		if (Browser.Engine.webkit419) var checker = (function(){
			if (!$try(check)) return;
			$clear(checker);
			load();
		}).periodical(50);
		
		return script.inject(doc.head);
	},

	css: function(source, properties){
		return new Element('link', $merge({
			'rel': 'stylesheet', 'media': 'screen', 'type': 'text/css', 'href': source
		}, properties)).inject(document.head);
	},

	image: function(source, properties){
		properties = $merge({
			'onload': $empty,
			'onabort': $empty,
			'onerror': $empty
		}, properties);
		var image = new Image();
		var element = $(image) || new Element('img');
		['load', 'abort', 'error'].each(function(name){
			var type = 'on' + name;
			var event = properties[type];
			delete properties[type];
			image[type] = function(){
				if (!image) return;
				if (!element.parentNode){
					element.width = image.width;
					element.height = image.height;
				}
				image = image.onload = image.onabort = image.onerror = null;
				event.delay(1, element, element);
				element.fireEvent(name, element, 1);
			};
		});
		image.src = element.src = source;
		if (image && image.complete) image.onload.delay(1);
		return element.setProperties(properties);
	},

	images: function(sources, options){
		options = $merge({
			onComplete: $empty,
			onProgress: $empty
		}, options);
		if (!sources.push) sources = [sources];
		var images = [];
		var counter = 0;
		sources.each(function(source){
			var img = new Asset.image(source, {
				'onload': function(){
					options.onProgress.call(this, counter, sources.indexOf(source));
					counter++;
					if (counter == sources.length) options.onComplete();
				}
			});
			images.push(img);
		});
		return new Elements(images);
	}

});

/*
Script: Sortables.js
	Class for creating a drag and drop sorting interface for lists of items.

License:
	MIT-style license.
*/

var Sortables = new Class({

	Implements: [Events, Options],

	options: {/*
		onSort: $empty,
		onStart: $empty,
		onComplete: $empty,*/
		snap: 4,
		opacity: 1,
		clone: false,
		revert: false,
		handle: false,
		constrain: false
	},

	initialize: function(lists, options){
		this.setOptions(options);
		this.elements = [];
		this.lists = [];
		this.idle = true;
		
		this.addLists($$($(lists) || lists));
		if (!this.options.clone) this.options.revert = false;
		if (this.options.revert) this.effect = new Fx.Morph(null, $merge({duration: 250, link: 'cancel'}, this.options.revert));
	},

	attach: function(){
		this.addLists(this.lists);
		return this;
	},

	detach: function(){
		this.lists = this.removeLists(this.lists);
		return this;
	},

	addItems: function(){
		Array.flatten(arguments).each(function(element){
			this.elements.push(element);
			var start = element.retrieve('sortables:start', this.start.bindWithEvent(this, element));
			(this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start);
		}, this);
		return this;
	},

	addLists: function(){
		Array.flatten(arguments).each(function(list){
			this.lists.push(list);
			this.addItems(list.getChildren());
		}, this);
		return this;
	},

	removeItems: function(){
		var elements = [];
		Array.flatten(arguments).each(function(element){
			elements.push(element);
			this.elements.erase(element);
			var start = element.retrieve('sortables:start');
			(this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start);
		}, this);
		return $$(elements);
	},

	removeLists: function(){
		var lists = [];
		Array.flatten(arguments).each(function(list){
			lists.push(list);
			this.lists.erase(list);
			this.removeItems(list.getChildren());
		}, this);
		return $$(lists);
	},

	getClone: function(event, element){
		if (!this.options.clone) return new Element('div').inject(document.body);
		if ($type(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);
		return element.clone(true).setStyles({
			'margin': '0px',
			'position': 'absolute',
			'visibility': 'hidden',
			'width': element.getStyle('width')
		}).inject(this.list).position(element.getPosition(element.getOffsetParent()));
	},

	getDroppables: function(){
		var droppables = this.list.getChildren();
		if (!this.options.constrain) droppables = this.lists.concat(droppables).erase(this.list);
		return droppables.erase(this.clone).erase(this.element);
	},

	insert: function(dragging, element){
		var where = 'inside';
		if (this.lists.contains(element)){
			this.list = element;
			this.drag.droppables = this.getDroppables();
		} else {
			where = this.element.getAllPrevious().contains(element) ? 'before' : 'after';
		}
		this.element.inject(element, where);
		this.fireEvent('sort', [this.element, this.clone]);
	},

	start: function(event, element){
		if (!this.idle) return;
		this.idle = false;
		this.element = element;
		this.opacity = element.get('opacity');
		this.list = element.getParent();
		this.clone = this.getClone(event, element);
		
		this.drag = new Drag.Move(this.clone, {
			snap: this.options.snap,
			container: this.options.constrain && this.element.getParent(),
			droppables: this.getDroppables(),
			onSnap: function(){
				event.stop();
				this.clone.setStyle('visibility', 'visible');
				this.element.set('opacity', this.options.opacity || 0);
				this.fireEvent('start', [this.element, this.clone]);
			}.bind(this),
			onEnter: this.insert.bind(this),
			onCancel: this.reset.bind(this),
			onComplete: this.end.bind(this)
		});
		
		this.clone.inject(this.element, 'before');
		this.drag.start(event);
	},

	end: function(){
		this.drag.detach();
		this.element.set('opacity', this.opacity);
		if (this.effect){
			var dim = this.element.getStyles('width', 'height');
			var pos = this.clone.computePosition(this.element.getPosition(this.clone.offsetParent));
			this.effect.element = this.clone;
			this.effect.start({
				top: pos.top,
				left: pos.left,
				width: dim.width,
				height: dim.height,
				opacity: 0.25
			}).chain(this.reset.bind(this));
		} else {
			this.reset();
		}
	},

	reset: function(){
		this.idle = true;
		this.clone.destroy();
		this.fireEvent('complete', this.element);
	},

	serialize: function(){
		var params = Array.link(arguments, {modifier: Function.type, index: $defined});
		var serial = this.lists.map(function(list){
			return list.getChildren().map(params.modifier || function(element){
				return element.get('id');
			}, this);
		}, this);
		
		var index = params.index;
		if (this.lists.length == 1) index = 0;
		return $chk(index) && index >= 0 && index < this.lists.length ? serial[index] : serial;
	}

});

/*
Script: Tips.js
	Class for creating nice tips that follow the mouse cursor when hovering an element.

License:
	MIT-style license.
*/

var Tips = new Class({

	Implements: [Events, Options],

	options: {
		onShow: function(tip){
			tip.setStyle('visibility', 'visible');
		},
		onHide: function(tip){
			tip.setStyle('visibility', 'hidden');
		},
		showDelay: 100,
		hideDelay: 100,
		className: null,
		offsets: {x: 16, y: 16},
		fixed: false
	},

	initialize: function(){
		var params = Array.link(arguments, {options: Object.type, elements: $defined});
		this.setOptions(params.options || null);
		
		this.tip = new Element('div').inject(document.body);
		
		if (this.options.className) this.tip.addClass(this.options.className);
		
		var top = new Element('div', {'class': 'tip-top'}).set('html','&nbsp;').inject(this.tip);
		this.container = new Element('div', { 'class': 'tip ModalPopupContent' }).inject(this.tip);
		var bottom = new Element('div', {'class': 'tip-bottom'}).set('html','&nbsp;').inject(this.tip);

		this.tip.setStyles({position: 'absolute', top: 0, left: 0, visibility: 'hidden'});
		
		if (params.elements) this.attach(params.elements);
	},
	
	attach: function(elements){
		$$(elements).each(function(element){
			var title = element.retrieve('tip:title', element.get('title'));
			var text = element.retrieve('tip:text', element.get('rel') || element.get('href'));
			var enter = element.retrieve('tip:enter', this.elementEnter.bindWithEvent(this, element));
			var leave = element.retrieve('tip:leave', this.elementLeave.bindWithEvent(this, element));
			element.addEvents({mouseenter: enter, mouseleave: leave});
			if (!this.options.fixed){
				var move = element.retrieve('tip:move', this.elementMove.bindWithEvent(this, element));
				element.addEvent('mousemove', move);
			}
			element.store('tip:native', element.get('title'));
			element.erase('title');
		}, this);
		return this;
	},
	
	detach: function(elements){
		$$(elements).each(function(element){
			element.removeEvent('mouseenter', element.retrieve('tip:enter') || $empty);
			element.removeEvent('mouseleave', element.retrieve('tip:leave') || $empty);
			element.removeEvent('mousemove', element.retrieve('tip:move') || $empty);
			element.eliminate('tip:enter').eliminate('tip:leave').eliminate('tip:move');
			var original = element.retrieve('tip:native');
			if (original) element.set('title', original);
		});
		return this;
	},
	
	elementEnter: function(event, element){
		
		$A(this.container.childNodes).each(Element.dispose);
		
		var title = element.retrieve('tip:title');
		
		if (title){
			this.titleElement = new Element('div', {'class': 'tip-title Title'}).inject(this.container);
			this.fill(this.titleElement, title);
		}
		
		var text = element.retrieve('tip:text');
		if (text){
			this.textElement = new Element('div', {'class': 'tip-text'}).inject(this.container);
			this.fill(this.textElement, text);
		}
		
		this.timer = $clear(this.timer);
		this.timer = this.show.delay(this.options.showDelay, this);

		this.position((!this.options.fixed) ? event : {page: element.getPosition()});
	},
	
	elementLeave: function(event){
		$clear(this.timer);
		this.timer = this.hide.delay(this.options.hideDelay, this);
	},
	
	elementMove: function(event){
		this.position(event);
	},
	
	position: function(event){
		var size = window.getSize(), scroll = window.getScroll();
		var tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight};
		var props = {x: 'left', y: 'top'};
		for (var z in props){
			var pos = event.page[z] + this.options.offsets[z];
			if ((pos + tip[z] - scroll[z]) > size[z]) pos = event.page[z] - this.options.offsets[z] - tip[z];
			this.tip.setStyle(props[z], pos);
		}
	},
	
	fill: function(element, contents){
		(typeof contents == 'string') ? element.set('html', contents) : element.adopt(contents);
	},

	show: function(){
		this.fireEvent('show', this.tip);
	},

	hide: function(){
		this.fireEvent('hide', this.tip);
	}

});

/*
Script: SmoothScroll.js
	Class for creating a smooth scrolling effect to all internal links on the page.

License:
	MIT-style license.
*/

var SmoothScroll = new Class({

	Extends: Fx.Scroll,

	initialize: function(options, context){
		context = context || document;
		var doc = context.getDocument(), win = context.getWindow();
		this.parent(doc, options);
		this.links = (this.options.links) ? $$(this.options.links) : $$(doc.links);
		var location = win.location.href.match(/^[^#]*/)[0] + '#';
		this.links.each(function(link){
			if (link.href.indexOf(location) != 0) return;
			var anchor = link.href.substr(location.length);
			if (anchor && $(anchor)) this.useLink(link, anchor);
		}, this);
		if (!Browser.Engine.webkit419) this.addEvent('complete', function(){
			win.location.hash = this.anchor;
		}, true);
	},

	useLink: function(link, anchor){
		link.addEvent('click', function(event){
			this.anchor = anchor;
			this.toElement(anchor);
			event.stop();
		}.bind(this));
	}

});

/*
Script: Slider.js
	Class for creating horizontal and vertical slider controls.

License:
	MIT-style license.
*/

var Slider = new Class({

	Implements: [Events, Options],

	options: {/*
		onChange: $empty,
		onComplete: $empty,*/
		onTick: function(position){
			if(this.options.snap) position = this.toPosition(this.step);
			this.knob.setStyle(this.property, position);
		},
		snap: false,
		offset: 0,
		range: false,
		wheel: false,
		steps: 100,
		mode: 'horizontal'
	},

	initialize: function(element, knob, options){
		this.setOptions(options);
		this.element = $(element);
		this.knob = $(knob);
		this.previousChange = this.previousEnd = this.step = -1;
		this.element.addEvent('mousedown', this.clickedElement.bind(this));
		if (this.options.wheel) this.element.addEvent('mousewheel', this.scrolledElement.bindWithEvent(this));
		var offset, limit = {}, modifiers = {'x': false, 'y': false};
		switch (this.options.mode){
			case 'vertical':
				this.axis = 'y';
				this.property = 'top';
				offset = 'offsetHeight';
				break;
			case 'horizontal':
				this.axis = 'x';
				this.property = 'left';
				offset = 'offsetWidth';
		}
		this.half = this.knob[offset] / 2;
		this.full = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
		this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0;
		this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps;
		this.range = this.max - this.min;
		this.steps = this.options.steps || this.full;
		this.stepSize = Math.abs(this.range) / this.steps;
		this.stepWidth = this.stepSize * this.full / Math.abs(this.range) ;
		
		this.knob.setStyle('position', 'relative').setStyle(this.property, - this.options.offset);
		modifiers[this.axis] = this.property;
		limit[this.axis] = [- this.options.offset, this.full - this.options.offset];
		this.drag = new Drag(this.knob, {
			snap: 0,
			limit: limit,
			modifiers: modifiers,
			onDrag: this.draggedKnob.bind(this),
			onStart: this.draggedKnob.bind(this),
			onComplete: function(){
				this.draggedKnob();
				this.end();
			}.bind(this)
		});
		if (this.options.snap) {
			this.drag.options.grid = Math.ceil(this.stepWidth);
			this.drag.options.limit[this.axis][1] = this.full;
		}
	},

	set: function(step){
		if (!((this.range > 0) ^ (step < this.min))) step = this.min;
		if (!((this.range > 0) ^ (step > this.max))) step = this.max;
		
		this.step = Math.round(step);
		this.checkStep();
		this.end();
		this.fireEvent('tick', this.toPosition(this.step));
		return this;
	},

	clickedElement: function(event){
		var dir = this.range < 0 ? -1 : 1;
		var position = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half;
		position = position.limit(-this.options.offset, this.full -this.options.offset);
		
		this.step = Math.round(this.min + dir * this.toStep(position));
		this.checkStep();
		this.end();
		this.fireEvent('tick', position);
	},
	
	scrolledElement: function(event){
		var mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0);
		this.set(mode ? this.step - this.stepSize : this.step + this.stepSize);
		event.stop();
	},

	draggedKnob: function(){
		var dir = this.range < 0 ? -1 : 1;
		var position = this.drag.value.now[this.axis];
		position = position.limit(-this.options.offset, this.full -this.options.offset);
		this.step = Math.round(this.min + dir * this.toStep(position));
		this.checkStep();
	},

	checkStep: function(){
		if (this.previousChange != this.step){
			this.previousChange = this.step;
			this.fireEvent('change', this.step);
		}
	},

	end: function(){
		if (this.previousEnd !== this.step){
			this.previousEnd = this.step;
			this.fireEvent('complete', this.step + '');
		}
	},

	toStep: function(position){
		var step = (position + this.options.offset) * this.stepSize / this.full * this.steps;
		return this.options.steps ? Math.round(step -= step % this.stepSize) : step;
	},

	toPosition: function(step){
		return (this.full * Math.abs(this.min - step)) / (this.steps * this.stepSize) - this.options.offset;
	}

});

/*
Script: Scroller.js
	Class which scrolls the contents of any Element (including the window) when the mouse reaches the Element's boundaries.

License:
	MIT-style license.
*/

var Scroller = new Class({

	Implements: [Events, Options],

	options: {
		area: 20,
		velocity: 1,
		onChange: function(x, y){
			this.element.scrollTo(x, y);
		}
	},

	initialize: function(element, options){
		this.setOptions(options);
		this.element = $(element);
		this.listener = ($type(this.element) != 'element') ? $(this.element.getDocument().body) : this.element;
		this.timer = null;
		this.coord = this.getCoords.bind(this);
	},

	start: function(){
		this.listener.addEvent('mousemove', this.coord);
	},

	stop: function(){
		this.listener.removeEvent('mousemove', this.coord);
		this.timer = $clear(this.timer);
	},

	getCoords: function(event){
		this.page = (this.listener.get('tag') == 'body') ? event.client : event.page;
		if (!this.timer) this.timer = this.scroll.periodical(50, this);
	},

	scroll: function(){
		var size = this.element.getSize(), scroll = this.element.getScroll(), pos = this.element.getPosition(), change = {'x': 0, 'y': 0};
		for (var z in this.page){
			if (this.page[z] < (this.options.area + pos[z]) && scroll[z] != 0)
				change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
			else if (this.page[z] + this.options.area > (size[z] + pos[z]) && size[z] + size[z] != scroll[z])
				change[z] = (this.page[z] - size[z] + this.options.area - pos[z]) * this.options.velocity;
		}
		if (change.y || change.x) this.fireEvent('change', [scroll.x + change.x, scroll.y + change.y]);
	}

});

/*
Script: Accordion.js
	An Fx.Elements extension which allows you to easily create accordion type controls.

License:
	MIT-style license.
*/

var Accordion = new Class({

	Extends: Fx.Elements,

	options: {/*
		onActive: $empty,
		onBackground: $empty,*/
		display: 0,
		show: false,
		height: true,
		width: false,
		opacity: true,
		fixedHeight: false,
		fixedWidth: false,
		wait: false,
		alwaysHide: false
	},

	initialize: function(){
		var params = Array.link(arguments, {'container': Element.type, 'options': Object.type, 'togglers': $defined, 'elements': $defined});
		this.parent(params.elements, params.options);
		this.togglers = $$(params.togglers);
		this.container = $(params.container);
		this.previous = -1;
		if (this.options.alwaysHide) this.options.wait = true;
		if ($chk(this.options.show)){
			this.options.display = false;
			this.previous = this.options.show;
		}
		if (this.options.start){
			this.options.display = false;
			this.options.show = false;
		}
		this.effects = {};
		if (this.options.opacity) this.effects.opacity = 'fullOpacity';
		if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';
		if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';
		for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]);
		this.elements.each(function(el, i){
			if (this.options.show === i){
				this.fireEvent('active', [this.togglers[i], el]);
			} else {
				for (var fx in this.effects) el.setStyle(fx, 0);
			}
		}, this);
		if ($chk(this.options.display)) this.display(this.options.display);
	},

	addSection: function(toggler, element, pos){
		toggler = $(toggler);
		element = $(element);
		var test = this.togglers.contains(toggler);
		var len = this.togglers.length;
		this.togglers.include(toggler);
		this.elements.include(element);
		if (len && (!test || pos)){
			pos = $pick(pos, len - 1);
			toggler.inject(this.togglers[pos], 'before');
			element.inject(toggler, 'after');
		} else if (this.container && !test){
			toggler.inject(this.container);
			element.inject(this.container);
		}
		var idx = this.togglers.indexOf(toggler);
		toggler.addEvent('click', this.display.bind(this, idx));
		if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});
		if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});
		element.fullOpacity = 1;
		if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;
		if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;
		element.setStyle('overflow', 'hidden');
		if (!test){
			for (var fx in this.effects) element.setStyle(fx, 0);
		}
		return this;
	},

	display: function(index){
		index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
		if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this;
		this.previous = index;
		var obj = {};
		this.elements.each(function(el, i){
			obj[i] = {};
			var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0));
			this.fireEvent(hide ? 'background' : 'active', [this.togglers[i], el]);
			for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]];
		}, this);
		return this.start(obj);
	}

});




//End: /Scripts/mootools-1.2-debug.js
//Begin: /Scripts/mootools-extensions.js


/* EXTENSIONS FROM CLIENTCIDE.COM */

/*
Script: Browser.Extras.js
Extends the Window native object to include methods useful in managing the window location and urls.

License:
http://www.clientcide.com/wiki/cnet-libraries#license
*/

$extend(Browser, {
    getHost: function(url) {
        url = $pick(url, window.location.href);
        var host = url;
        if (url.test('http://')) {
            url = url.substring(url.indexOf('http://') + 7, url.length);
            if (url.test(':')) url = url.substring(0, url.indexOf(":"));
            if (url.test('/')) return url.substring(0, url.indexOf('/'));
            return url;
        }
        return false;
    },
    getSecurityDomain: function(){ //eli did this
        //simple function that matches the beginning of a URL
        //in a string and then returns the domain.
        var urlpattern = new RegExp("(http|ftp|https)://(.*?)/.*$");
        var parsedurl = window.location.href.match(urlpattern);
        //console.log(parsedurl[2]);
        var start = parsedurl[2].indexOf('corbis');
        var end = (parsedurl[2].indexOf('.com')>=0) ? parsedurl[2].indexOf('.com')+4 : parsedurl[2].indexOf('.pre') + 4;
        var length = parseInt(end-start);
        var returnstr = parsedurl[2].substr(start, length);
        
        return returnstr;
    
    },
    // added by Chris
    isHttps: function(url) {
        url = $pick(url, window.location.href);
        return url.test('https://');
    },
    // added by Chris
    getCookiePath: function(url) {
        url = $pick(url, window.location.href);
        var host = url;
        if (url.test('http://')) {
            url = url.substring(url.indexOf('http://') + 7, url.length);
            if (url.test(':')) url = url.substring(url.indexOf(":") + 1, url.length);
            if (url.test('/')) url = url.substring(url.indexOf('/') + 1, url.length);
            if (url.test('/')) url = url.substring(0, url.indexOf('/'));
            return url;
        }
        return false;
    },
    getQueryStringValue: function(key, url) {
        try {
            return Browser.getQueryStringValues(url)[key];
        } catch (e) { return null; }
    },
    getQueryStringValues: function(url) {
        var qs = $pick(url, window.location.search, '').split('?')[1]; //get the query string
        if (!$chk(qs)) return {};
        if (qs.test('#')) qs = qs.substring(0, qs.indexOf('#'));
        try {
            if (qs) return qs.parseQuery();
        } catch (e) {
            return null;
        }
        return {}; //if there isn't one, return null
    },
    getPort: function(url) {
        url = $pick(url, window.location.href);
        var re = new RegExp(':([0-9]{4})');
        var m = re.exec(url);
        if (m == null) return false;
        else {
            var port = false;
            m.each(function(val) {
                if ($chk(parseInt(val))) port = val;
            });
        }
        return port;
    },
    redraw: function(element) {
        var n = document.createTextNode(' ');
        this.adopt(n);
        (function() { n.dispose() }).delay(1);
        return this;
    },
    ieVersion: 0,
    getInternetExplorerVersion: function()
    {
        if(this.ieVersion) {
            return this.ieVersion;
        }
        var rv = -1;
        if (navigator.appName == 'Microsoft Internet Explorer')
        {
        var ua = navigator.userAgent;
        var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null)
          rv = parseFloat( RegExp.$1 );
        }
        this.ieVersion = rv;
        return rv;
    }
});
window.addEvent('domready', function() {
    var count = 0;
    //this is in case domready fires before string.extras loads
    function setQs() {
        function retry() {
            count++;
            if (count < 20) setQs.delay(50);
        };
        try {
            if (!Browser.getQueryStringValues()) retry();
            else Browser.qs = Browser.getQueryStringValues();
        } catch (e) {
            retry();
        }
    }
    setQs();
});

/*
Script: Hash.Extras.js
Extends the Hash native object to include getFromPath which allows a path notation to child elements.

License:
http://www.clientcide.com/wiki/cnet-libraries#license
*/

Hash.implement({
    getFromPath: function(notation) {
        var source = this.getClean();
        notation.replace(/\[([^\]]+)\]|\.([^.[]+)|[^[.]+/g, function(match) {
            if (!source) return;
            var prop = arguments[2] || arguments[1] || arguments[0];
            source = (prop in source) ? source[prop] : null;
            return match;
        });
        return source;
    },
    cleanValues: function(method) {
        method = method || $defined;
        this.each(function(v, k) {
            if (!method(v)) this.erase(k);
        }, this);
        return this;
    },
    run: function() {
        var args = $arguments;
        this.each(function(v, k) {
            if ($type(v) == "function") v.run(args);
        });
    }
});

/*
Script: String.Extras.js
Extends the String native object to include methods useful in managing various kinds of strings (query strings, urls, html, etc).

License:
http://www.clientcide.com/wiki/cnet-libraries#license
*/
String.implement({
    stripTags: function() {
        return this.replace(/<\/?[^>]+>/gi, '');
    },
    parseQuery: function(encodeKeys, encodeValues) {
        encodeKeys = $pick(encodeKeys, true);
        encodeValues = $pick(encodeValues, true);
        var vars = this.split(/[&;]/);
        var rs = {};
        if (vars.length) vars.each(function(val) {
            var keys = val.split('=');
            if (keys.length && keys.length == 2) {
                rs[(encodeKeys) ? encodeURIComponent(keys[0]) : keys[0]] = (encodeValues) ? encodeURIComponent(keys[1]) : keys[1];
            }
        });
        return rs;
    },
    tidy: function() {
        var txt = this.toString();
        $each({
            "[\xa0\u2002\u2003\u2009]": " ",
            "\xb7": "*",
            "[\u2018\u2019]": "'",
            "[\u201c\u201d]": '"',
            "\u2026": "...",
            "\u2013": "-",
            "\u2014": "--",
            "\uFFFD": "&raquo;"
        }, function(value, key) {
            txt = txt.replace(new RegExp(key, 'g'), value);
        });
        return txt;
    },
    cleanQueryString: function(method) {
        return this.split("&").filter(method || function(set) {
            return $chk(set.split("=")[1]);
        }).join("&");
    },
    findAllEmails: function() {
        return this.match(new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", "gi")) || [];
    }
});


Chain.implement({
    runChain: function() {
        if (this.$chain.length > 0) {
            this.callChain();
            this.runChain();
        };
    }

});


/****************************
    FROM CHRIS 
 ****************************/

Native.implement([Element, Window, Document], {
    hasEvent: function(type) {
        var events = this.retrieve('events', {});
        if (events && events[type]) return true;
        else return false;
    }
});
/* PRIVATES MUTATOR 
Class mutator to build in private/public methods 
from an imported superclass/native, etc
    
Kind of cool because you can bind multiple
contexts on one class instance

if you want an example, see Chris
*/

/* PRIVATE CLASS EXAMPLES - see Chris */

Class.Mutators.Privates = function(self, privates) {

    var getTempOptions = function() {
        var tempOptions = {
            setup: "public", // defaults to public methods
            methods: "" // defaults to empty
        };
        return tempOptions;
    };

    var MethodSetup = function(setupType, privateObject, tempOptions) {

        var tmpMethods = [];

        if (setupType == "specific" || setupType == "allExcept") {
            if (tempOptions.methods.length > 0) tmpMethods = tempOptions.methods.split(' ');
        }

        // list of protected functions/objects.
        var protectedItems = ["initialize", "options", "parent", "$family", "prototype", "constructor", "Privates"];

        for (var name in privateObject) {
            if (protectedItems.contains(name)) continue;
            var failed = false;
            switch (setupType) {
                case "public":
                    if (name.substr(0, 2).contains("__")) failed = true;
                    break;
                case "specific":
                    if (!tmpMethods.contains(name)) failed = true;
                    break;
                case "allExcept":
                    if (tmpMethods.contains(name)) failed = true;
                    break;
            }

            if (failed) {
                //this[name] = function(pName) { throw "[PRIVATE]: " + pName; } .pass(name);
                continue;
            }

            if (typeof (privateObject[name]) == 'function') {
                // we are only binding functions. 
                // so if you have internal variables/objects you want to access
                // you need to write accessor functions
                //console.log($type(privateObject[name]));
                this[name] = privateObject[name].bind(privateObject);
            }
        }
    };

    var temp = new Hash(privates);

    temp.each(function(val, key) {

        var tmpOpt = getTempOptions(); // get some base options

        //console.log(val.objRef.$family.name);
        //console.log(val.objRef.prototype);
        //console.log(val.objRef);

        // setup init options if any
        var initOptions = (val.initWith) ? val.initWith : {};

        // initialize object if we need to
        if (val.objRef.$family.name == "class" || val.objRef.$family.name == "native") val.objRef = new val.objRef(initOptions);
        // need to add condition in for supported Natives

        val.objRef.parent = self; // tell the objRef what the master parent is
        //if (Browser.Engine.trident) val.objRef.prototype.parent = self; // if IE, parent binding is different (why??)

        if (val.setup) tmpOpt.setup = val.setup;
        if (val.methods) tmpOpt.methods = val.methods;
        var methodBind;

        if (key == "self") {
            methodBind = self; // bind right onto the original object
        } else {
            if (typeof (self[key]) == "undefined" || self[key] == null) self[key] = {};
            methodBind = self[key]; // bind onto a key of the original object
        }
        MethodSetup.bind(methodBind).pass([tmpOpt.setup, val.objRef, tmpOpt]).run();
    });

    delete self.Privates;

}


$FRAG = new Class({

    fragment: null,


    initialize: function() {

        this.fragment = document.createDocumentFragment();

    },

    append: function() {
        var args = Array.flatten(arguments);
        for (var i = 0, l = args.length; i < l; i++) {
            var item = args[i];
            switch ($type(item)) {
                case 'element':
                    this.fragment.appendChild(item);
                    break;
                case 'string':
                    item = $(item);
                    this.fragment.appendChild(item);
                    break;

            }

        }
    },

    empty: function() {
        delete this.fragment;
        this.initialize();
    }

});

// lets extend mootools tips
Tips.implement({
    //lets override the default attach method
    attach: function(elements) {
        var items = ($type(elements) == 'array') ? elements : $$(elements);
        items.each(function(element) {
            var title = element.retrieve('tip:title', this.options.title || element.get('title'));
            var text = element.retrieve('tip:text', this.options.text || element.get('rel') || element.get('href'));
            var enter = element.retrieve('tip:enter', this.elementEnter.bindWithEvent(this, element));
            var leave = element.retrieve('tip:leave', this.elementLeave.bindWithEvent(this, element));
            element.addEvents({ mouseenter: enter, mouseleave: leave });
            if (!this.options.fixed) {
                var move = element.retrieve('tip:move', this.elementMove.bindWithEvent(this, element));
                element.addEvent('mousemove', move);
            }
            element.store('tip:native', element.get('title'));
            element.erase('title');
        }, this);
        return this;
    },
    //also override the detach method, since it was missing the tip:text elimination
    detach: function(elements){
		$$(elements).each(function(element){
			element.removeEvent('mouseenter', element.retrieve('tip:enter') || $empty);
			element.removeEvent('mouseleave', element.retrieve('tip:leave') || $empty);
			element.removeEvent('mousemove', element.retrieve('tip:move') || $empty);
			element.eliminate('tip:enter').eliminate('tip:leave').eliminate('tip:move').eliminate('tip:text');
			var original = element.retrieve('tip:native');
			if (original) element.set('title', original);
		});
		return this;
	}


});
//End: /Scripts/mootools-extensions.js
//Begin: /Scripts/native-extensions.js

/* EXTENSIONS OF NATIVE JAVASCRIPT OBJECTS */

// helper enhancements to Native objects

Array.implement({
    batchRun: false,
    /*
    this is a function to help free up memory
    when looping through LARGE arrays
        
    process: function to be run
    delay: delay time (defaults to 100)
    context: if you want to bind something to process
    */
    chunk: function(process, delay, context, Complete, batch) {
        var delayTime = ($type(delay) == 'number') ? delay : 100;
        var items = this.concat();
        if (items.length == this.length && batch) {
            //console.log('going to batch!');
            this.batchBase = batch;
            this.batchCount = 0;
            this.batchDelay = delayTime;
            this.batchRun = true;
        }
        setTimeout(function() {
            if (this.batchRun) {
                //console.log('still in batch');
                //console.log(this.batchBase + ' | ' + this.batchCount);
                if (this.batchCount == this.batchBase) {
                    this.batchCount = 0;
                    delayTime = this.batchDelay;
                } else {
                    delayTime = 0;
                    this.batchCount++;
                }
                //console.log('delay: ' + delayTime);
            }
            //console.log('ArrayLength: ' + items.length);
            var itemsLength = items.length - 1;
            var item = items.shift();
            if (context) process.bind(context);

            if (!this.stopChunkProcess) process.pass(item).run();

            if (items.length > 0 && !this.stopChunkProcess) {
                if (delayTime == 0) {
                    arguments.callee.bind(this).run();
                } else {
                    setTimeout(arguments.callee.bind(this), delayTime);
                }
            }
            if (this.stopChunkProcess) {
                items.empty();
                this.stopChunkProcess = false;
            }
            //console.log(items);

            if (itemsLength == 0 && $type(Complete) == "function") {
                Complete.run();
            }

        } .bind(this), delayTime);

    },

    stopChunk: function() {
        this.stopChunkProcess = true;
    },

    flip: function() {
        this.reverse();
        return this;
    }
});

String.implement({

    // *     example 1: string.empty(null);
    // *     returns 1: true
    // *     example 2: string.empty(undefined);
    // *     returns 2: true
    // *     example 3: string.empty([]);
    // *     returns 3: true
    // *     example 4: string.empty({});
    // *     returns 4: true
    isEmpty: function() {

        var key;

        if (this === ""
            || this === 0
            || this === "0"
            || this === null
            || this === false
            || this === undefined
        ) {
            return true;
        }
        if (typeof this == 'object') {
            for (key in this) {
                return false;
            }
            return true;
        }
        return false;
    },

    // *     example 1: "kevin's birthday".addslashes();
    // *     returns 1: 'kevin\'s birthday'
    addslashes: function() {
        return (this + '').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0");
    },

    // *     example 1: 'Kevin\'s code'.stripslashes();
    // *     returns 1: "Kevin's code"
    stripslashes: function() {
        return (this + '').replace('/\0/g', '0').replace('/\(.)/g', '$1');
    },

    // *     example 1: 'Kevin van Zonneveld'.strtoupper();
    // *     returns 1: 'KEVIN VAN ZONNEVELD'
    strtoupper: function() {
        return (this + '').toUpperCase();
    },

    // *     example 1: 'Kevin van Zonneveld'.strtolower();
    // *     returns 1: 'kevin van zonneveld'
    strtolower: function() {
        return (this + '').toLowerCase();
    },

    // *     example 1: 'Kevin van Zonneveld'.strrev();
    // *     returns 1: 'dlevennoZ nav niveK'
    strrev: function() {
        var str = this;
        var ret = '', i = 0;

        str += '';
        for (i = str.length - 1; i >= 0; i--) {
            ret += str.charAt(i);
        }

        return ret;
    },

    // *     example 1: '<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>'.strip_tags('<i><b>');
    // *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
    // *     example 2: '<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>'.strip_tags('<p>');
    // *     returns 2: '<p>Kevin van Zonneveld</p>'
    // *     example 3: "<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>".strip_tags("<a>");
    // *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
    strip_tags: function(allowed_tags) {

        var str = this;
        var key = '', tag = '', allowed = false;
        var matches = allowed_array = [];
        var allowed_keys = {};

        var replacer = function(search, replace, str) {
            return str.split(search).join(replace);
        };

        // Build allowes tags associative array
        if (allowed_tags) {
            allowed_array = allowed_tags.match(/([a-zA-Z]+)/gi);
        }

        str += '';

        // Match tags
        matches = str.match(/(<\/?[^>]+>)/gi);

        // Go through all HTML tags
        for (key in matches) {
            if (isNaN(key)) {
                // IE7 Hack
                continue;
            }

            // Save HTML tag
            html = matches[key].toString();

            // Is tag not in allowed list? Remove from str!
            allowed = false;

            // Go through all allowed tags
            for (k in allowed_array) {
                // Init
                allowed_tag = allowed_array[k];
                i = -1;

                if (i != 0) { i = html.toLowerCase().indexOf('<' + allowed_tag + '>'); }
                if (i != 0) { i = html.toLowerCase().indexOf('<' + allowed_tag + ' '); }
                if (i != 0) { i = html.toLowerCase().indexOf('</' + allowed_tag); }

                // Determine
                if (i == 0) {
                    allowed = true;
                    break;
                }
            }

            if (!allowed) {
                str = replacer(html, "", str); // Custom replace. No regexing
            }
        }

        return str;
    },

    substr: function(f_start, f_length) {
        // Returns part of a string  
        // 
        // version: 810.1317
        // discuss at: http://phpjs.org/functions/substr
        // +     original by: Martijn Wieringa
        // +     bugfixed by: T.Wild
        // +      tweaked by: Onno Marsman
        // *       example 1: 'abcdef'.substr(0, -1);
        // *       returns 1: 'abcde'

        var f_string = this.concat();

        f_string += '';

        if (f_start < 0) {
            f_start += f_string.length;
        }

        if (f_length == undefined) {
            f_length = f_string.length;
        } else if (f_length < 0) {
            f_length += f_string.length;
        } else {
            f_length += f_start;
        }

        if (f_length < f_start) {
            f_length = f_start;
        }

        return f_string.substring(f_start, f_length);
    },

    endsWith: function(str) {
        return (this.match(str + "$") == str);
    },

    startsWith: function(str) {
        return (this.match("^" + str) == str);
    }


});


//End: /Scripts/native-extensions.js
//Begin: /Scripts/helper-functions.js


/****************************************************
    GENERIC HELPER FUNCTIONS
***************************************************/

// ADDED BY CHRIS
// FIX FOR BROWSERS WHO DON'T HAVE FIREBUG
(function(m, i) {
    // Prevent calls to Firebug from causing errors
    // Only write to console if in DEV
    // Don't write if in HTTPS
    // Add a surrogate if widnow.console doesn't exist
    if (currentEnvironment.toUpperCase() != 'DEV' || Browser.isHttps() || !window.console) {
        try
        {
            window.console = {};
            for (i = 0; i < 16; i += 1) {
                window.console[m[i]] = function() { };
            }
        }
        catch(ex)
        {}
    }
})('log debug info warn error assert dir dirxml group groupEnd time timeEnd count trace profile profileEnd'.split(' '));

// helper functions
// Use the exit function to cancel out any odd updatepanel javascript errors
function exit() {
    // http://kevin.vanzonneveld.net
    // +   original by: Brett Zamir
    // %        note 1: Should be considered expirimental. Please comment on this function.
    // *     example 1: exit();
    // *     returns 1: null


    var i;
    window.addEvent('error', function(e) { e.preventDefault(); e.stopPropagation(); }, false);

    var handlers = [
        'copy', 'cut', 'paste',
        'beforeunload', 'blur', 'change', 'click', 'contextmenu', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll',
        'DOMNodeInserted', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMNodeInsertedIntoDocument', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMElementNameChanged', 'DOMAttributeNameChanged', 'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'online', 'offline', 'textInput',
        'abort', 'close', 'dragdrop', 'load', 'paint', 'reset', 'select', 'submit', 'unload'
    ];

    for (i = 0; i < handlers.length; i++) {
        window.addEvent(handlers[i], stopPropagation, true);
    }

}


function utf8_encode(string) {
    // Encodes an ISO-8859-1 string to UTF-8  
    // 
    // version: 812.316
    // discuss at: http://phpjs.org/functions/utf8_encode
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: sowberry
    // +    tweaked by: Jack
    // +   bugfixed by: Onno Marsman
    // +   improved by: Yves Sucaet
    // +   bugfixed by: Onno Marsman
    // *     example 1: utf8_encode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'
    string = (string + '').replace(/\r\n/g, "\n").replace(/\r/g, "\n");

    var utftext = "";
    var start, end;
    var stringl = 0;

    start = end = 0;
    stringl = string.length;
    for (var n = 0; n < stringl; n++) {
        var c1 = string.charCodeAt(n);
        var enc = null;

        if (c1 < 128) {
            end++;
        } else if ((c1 > 127) && (c1 < 2048)) {
            enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
        } else {
            enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
        }
        if (enc != null) {
            if (end > start) {
                utftext += string.substring(start, end);
            }
            utftext += enc;
            start = end = n + 1;
        }
    }

    if (end > start) {
        utftext += string.substring(start, string.length);
    }

    return utftext;
}

function utf8_decode(str_data) {
    // Converts a UTF-8 encoded string to ISO-8859-1  
    // 
    // version: 903.421
    // discuss at: http://phpjs.org/functions/utf8_decode
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +      input by: Aman Gupta
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Norman "zEh" Fuchs
    // +   bugfixed by: hitwork
    // +   bugfixed by: Onno Marsman
    // +      input by: Brett Zamir
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: utf8_decode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'
    var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;

    str_data += '';

    while (i < str_data.length) {
        c1 = str_data.charCodeAt(i);
        if (c1 < 128) {
            tmp_arr[ac++] = String.fromCharCode(c1);
            i++;
        } else if ((c1 > 191) && (c1 < 224)) {
            c2 = str_data.charCodeAt(i + 1);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = str_data.charCodeAt(i + 1);
            c3 = str_data.charCodeAt(i + 2);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }

    return tmp_arr.join('');
}

//End: /Scripts/helper-functions.js
//Begin: /Scripts/excanvas-compressed.js

if(!window.CanvasRenderingContext2D){(function(){var I=Math,i=I.round,L=I.sin,M=I.cos,m=10,A=m/2,Q={init:function(a){var b=a||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var c=this;b.attachEvent("onreadystatechange",function(){c.r(b)})}},r:function(a){if(a.readyState=="complete"){if(!a.namespaces["s"]){a.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var b=a.createStyleSheet();b.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}";
var c=a.getElementsByTagName("canvas");for(var d=0;d<c.length;d++){if(!c[d].getContext){this.initElement(c[d])}}}},q:function(a){var b=a.outerHTML,c=a.ownerDocument.createElement(b);if(b.slice(-2)!="/>"){var d="/"+a.tagName,e;while((e=a.nextSibling)&&e.tagName!=d){e.removeNode()}if(e){e.removeNode()}}a.parentNode.replaceChild(c,a);return c},initElement:function(a){a=this.q(a);a.getContext=function(){if(this.l){return this.l}return this.l=new K(this)};a.attachEvent("onpropertychange",V);a.attachEvent("onresize",
W);var b=a.attributes;if(b.width&&b.width.specified){a.style.width=b.width.nodeValue+"px"}else{a.width=a.clientWidth}if(b.height&&b.height.specified){a.style.height=b.height.nodeValue+"px"}else{a.height=a.clientHeight}return a}};function V(a){var b=a.srcElement;switch(a.propertyName){case "width":b.style.width=b.attributes.width.nodeValue+"px";b.getContext().clearRect();break;case "height":b.style.height=b.attributes.height.nodeValue+"px";b.getContext().clearRect();break}}function W(a){var b=a.srcElement;
if(b.firstChild){b.firstChild.style.width=b.clientWidth+"px";b.firstChild.style.height=b.clientHeight+"px"}}Q.init();var R=[];for(var E=0;E<16;E++){for(var F=0;F<16;F++){R[E*16+F]=E.toString(16)+F.toString(16)}}function J(){return[[1,0,0],[0,1,0],[0,0,1]]}function G(a,b){var c=J();for(var d=0;d<3;d++){for(var e=0;e<3;e++){var g=0;for(var h=0;h<3;h++){g+=a[d][h]*b[h][e]}c[d][e]=g}}return c}function N(a,b){b.fillStyle=a.fillStyle;b.lineCap=a.lineCap;b.lineJoin=a.lineJoin;b.lineWidth=a.lineWidth;b.miterLimit=
a.miterLimit;b.shadowBlur=a.shadowBlur;b.shadowColor=a.shadowColor;b.shadowOffsetX=a.shadowOffsetX;b.shadowOffsetY=a.shadowOffsetY;b.strokeStyle=a.strokeStyle;b.d=a.d;b.e=a.e}function O(a){var b,c=1;a=String(a);if(a.substring(0,3)=="rgb"){var d=a.indexOf("(",3),e=a.indexOf(")",d+1),g=a.substring(d+1,e).split(",");b="#";for(var h=0;h<3;h++){b+=R[Number(g[h])]}if(g.length==4&&a.substr(3,1)=="a"){c=g[3]}}else{b=a}return[b,c]}function S(a){switch(a){case "butt":return"flat";case "round":return"round";
case "square":default:return"square"}}function K(a){this.a=J();this.m=[];this.k=[];this.c=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=m*1;this.globalAlpha=1;this.canvas=a;var b=a.ownerDocument.createElement("div");b.style.width=a.clientWidth+"px";b.style.height=a.clientHeight+"px";b.style.overflow="hidden";b.style.position="absolute";a.appendChild(b);this.j=b;this.d=1;this.e=1}var j=K.prototype;j.clearRect=function(){this.j.innerHTML=
"";this.c=[]};j.beginPath=function(){this.c=[]};j.moveTo=function(a,b){this.c.push({type:"moveTo",x:a,y:b});this.f=a;this.g=b};j.lineTo=function(a,b){this.c.push({type:"lineTo",x:a,y:b});this.f=a;this.g=b};j.bezierCurveTo=function(a,b,c,d,e,g){this.c.push({type:"bezierCurveTo",cp1x:a,cp1y:b,cp2x:c,cp2y:d,x:e,y:g});this.f=e;this.g=g};j.quadraticCurveTo=function(a,b,c,d){var e=this.f+0.6666666666666666*(a-this.f),g=this.g+0.6666666666666666*(b-this.g),h=e+(c-this.f)/3,l=g+(d-this.g)/3;this.bezierCurveTo(e,
g,h,l,c,d)};j.arc=function(a,b,c,d,e,g){c*=m;var h=g?"at":"wa",l=a+M(d)*c-A,n=b+L(d)*c-A,o=a+M(e)*c-A,f=b+L(e)*c-A;if(l==o&&!g){l+=0.125}this.c.push({type:h,x:a,y:b,radius:c,xStart:l,yStart:n,xEnd:o,yEnd:f})};j.rect=function(a,b,c,d){this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath()};j.strokeRect=function(a,b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.stroke()};j.fillRect=function(a,
b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.fill()};j.createLinearGradient=function(a,b,c,d){var e=new H("gradient");return e};j.createRadialGradient=function(a,b,c,d,e,g){var h=new H("gradientradial");h.n=c;h.o=g;h.i.x=a;h.i.y=b;return h};j.drawImage=function(a,b){var c,d,e,g,h,l,n,o,f=a.runtimeStyle.width,k=a.runtimeStyle.height;a.runtimeStyle.width="auto";a.runtimeStyle.height="auto";var q=a.width,r=a.height;a.runtimeStyle.width=
f;a.runtimeStyle.height=k;if(arguments.length==3){c=arguments[1];d=arguments[2];h=(l=0);n=(e=q);o=(g=r)}else if(arguments.length==5){c=arguments[1];d=arguments[2];e=arguments[3];g=arguments[4];h=(l=0);n=q;o=r}else if(arguments.length==9){h=arguments[1];l=arguments[2];n=arguments[3];o=arguments[4];c=arguments[5];d=arguments[6];e=arguments[7];g=arguments[8]}else{throw"Invalid number of arguments";}var s=this.b(c,d),t=[],v=10,w=10;t.push(" <g_vml_:group",' coordsize="',m*v,",",m*w,'"',' coordorigin="0,0"',
' style="width:',v,";height:",w,";position:absolute;");if(this.a[0][0]!=1||this.a[0][1]){var x=[];x.push("M11='",this.a[0][0],"',","M12='",this.a[1][0],"',","M21='",this.a[0][1],"',","M22='",this.a[1][1],"',","Dx='",i(s.x/m),"',","Dy='",i(s.y/m),"'");var p=s,y=this.b(c+e,d),z=this.b(c,d+g),B=this.b(c+e,d+g);p.x=Math.max(p.x,y.x,z.x,B.x);p.y=Math.max(p.y,y.y,z.y,B.y);t.push("padding:0 ",i(p.x/m),"px ",i(p.y/m),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",x.join(""),", sizingmethod='clip');")}else{t.push("top:",
i(s.y/m),"px;left:",i(s.x/m),"px;")}t.push(' ">','<g_vml_:image src="',a.src,'"',' style="width:',m*e,";"," height:",m*g,';"',' cropleft="',h/q,'"',' croptop="',l/r,'"',' cropright="',(q-h-n)/q,'"',' cropbottom="',(r-l-o)/r,'"'," />","</g_vml_:group>");this.j.insertAdjacentHTML("BeforeEnd",t.join(""))};j.stroke=function(a){var b=[],c=O(a?this.fillStyle:this.strokeStyle),d=c[0],e=c[1]*this.globalAlpha,g=10,h=10;b.push("<g_vml_:shape",' fillcolor="',d,'"',' filled="',Boolean(a),'"',' style="position:absolute;width:',
g,";height:",h,';"',' coordorigin="0 0" coordsize="',m*g," ",m*h,'"',' stroked="',!a,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',d,'"',' path="');var l={x:null,y:null},n={x:null,y:null};for(var o=0;o<this.c.length;o++){var f=this.c[o];if(f.type=="moveTo"){b.push(" m ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="lineTo"){b.push(" l ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="close"){b.push(" x ")}else if(f.type=="bezierCurveTo"){b.push(" c ");
var k=this.b(f.x,f.y),q=this.b(f.cp1x,f.cp1y),r=this.b(f.cp2x,f.cp2y);b.push(i(q.x),",",i(q.y),",",i(r.x),",",i(r.y),",",i(k.x),",",i(k.y))}else if(f.type=="at"||f.type=="wa"){b.push(" ",f.type," ");var k=this.b(f.x,f.y),s=this.b(f.xStart,f.yStart),t=this.b(f.xEnd,f.yEnd);b.push(i(k.x-this.d*f.radius),",",i(k.y-this.e*f.radius)," ",i(k.x+this.d*f.radius),",",i(k.y+this.e*f.radius)," ",i(s.x),",",i(s.y)," ",i(t.x),",",i(t.y))}if(k){if(l.x==null||k.x<l.x){l.x=k.x}if(n.x==null||k.x>n.x){n.x=k.x}if(l.y==
null||k.y<l.y){l.y=k.y}if(n.y==null||k.y>n.y){n.y=k.y}}}b.push(' ">');if(typeof this.fillStyle=="object"){var v={x:"50%",y:"50%"},w=n.x-l.x,x=n.y-l.y,p=w>x?w:x;v.x=i(this.fillStyle.i.x/w*100+50)+"%";v.y=i(this.fillStyle.i.y/x*100+50)+"%";var y=[];if(this.fillStyle.p=="gradientradial"){var z=this.fillStyle.n/p*100,B=this.fillStyle.o/p*100-z}else{var z=0,B=100}var C={offset:null,color:null},D={offset:null,color:null};this.fillStyle.h.sort(function(T,U){return T.offset-U.offset});for(var o=0;o<this.fillStyle.h.length;o++){var u=
this.fillStyle.h[o];y.push(u.offset*B+z,"% ",u.color,",");if(u.offset>C.offset||C.offset==null){C.offset=u.offset;C.color=u.color}if(u.offset<D.offset||D.offset==null){D.offset=u.offset;D.color=u.color}}y.pop();b.push("<g_vml_:fill",' color="',D.color,'"',' color2="',C.color,'"',' type="',this.fillStyle.p,'"',' focusposition="',v.x,", ",v.y,'"',' colors="',y.join(""),'"',' opacity="',e,'" />')}else if(a){b.push('<g_vml_:fill color="',d,'" opacity="',e,'" />')}else{b.push("<g_vml_:stroke",' opacity="',
e,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',S(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',d,'" />')}b.push("</g_vml_:shape>");this.j.insertAdjacentHTML("beforeEnd",b.join(""));this.c=[]};j.fill=function(){this.stroke(true)};j.closePath=function(){this.c.push({type:"close"})};j.b=function(a,b){return{x:m*(a*this.a[0][0]+b*this.a[1][0]+this.a[2][0])-A,y:m*(a*this.a[0][1]+b*this.a[1][1]+this.a[2][1])-A}};j.save=function(){var a={};N(this,a);
this.k.push(a);this.m.push(this.a);this.a=G(J(),this.a)};j.restore=function(){N(this.k.pop(),this);this.a=this.m.pop()};j.translate=function(a,b){var c=[[1,0,0],[0,1,0],[a,b,1]];this.a=G(c,this.a)};j.rotate=function(a){var b=M(a),c=L(a),d=[[b,c,0],[-c,b,0],[0,0,1]];this.a=G(d,this.a)};j.scale=function(a,b){this.d*=a;this.e*=b;var c=[[a,0,0],[0,b,0],[0,0,1]];this.a=G(c,this.a)};j.clip=function(){};j.arcTo=function(){};j.createPattern=function(){return new P};function H(a){this.p=a;this.n=0;this.o=
0;this.h=[];this.i={x:0,y:0}}H.prototype.addColorStop=function(a,b){b=O(b);this.h.push({offset:1-a,color:b})};function P(){}G_vmlCanvasManager=Q;CanvasRenderingContext2D=K;CanvasGradient=H;CanvasPattern=P})()};

//End: /Scripts/excanvas-compressed.js
//Begin: /Scripts/CorbisUI.js

/*

  |:::::::::::::;;::::::::::::::::::|
  |:::::::::::'~||~~~``:::::::::::::|
  |::::::::'   .':     o`:::::::::::|
  |:::::::' oo | |o  o    ::::::::::|
  |::::::: 8  .'.'    8 o  :::::::::|
  |::::::: 8  | |     8    :::::::::|
  |::::::: _._| |_,...8    :::::::::|
  |::::::'~--.   .--. `.   `::::::::|
  |:::::'     =8     ~  \ o ::::::::|
  |::::'       8._ 88.   \ o::::::::|
  |:::'   __. ,.ooo~~.    \ o`::::::|
  |:::   . -. 88`78o/:     \  `:::::|
  |::'     /. o o \ ::      \88`::::|   "Join us or die."
  |:;     o|| 8 8 |d.        `8 `:::|
  |:.       - ^ ^ -'           `-`::|
  |::.                          .:::|
  |:::::.....           ::'     ``::|
  |::::::::-'`-        88          `|
  |:::::-'.          -       ::     |
  |:-~. . .                   :     |
  | .. .   ..:   o:8      88o       |
  |. .     :::   8:P     d888. . .  |
  |.   .   :88   88      888'  . .  |
  |   o8  d88P . 88   ' d88P   ..   |
  |  88P  888   d8P   ' 888         |
  |   8  d88P.'d:8  .- dP~ o8       |   Darth Javascript (1)
  |      888   888    d~ o888    LS |
  |_________________________________|

*/

/****************************************************
Corbis Javascript namespace intialization
	
=============================================
Chris Esler, 2008-01-01
=============================================
****************************************************/


// CORBIS UI NAMESPACE SETUP
if (!CorbisUI) {
    var CorbisUI = {}
}
CorbisUI.version = '0.0.1';
CorbisUI.registry = {
    Id: [],
    deferred: [],
    includes: []
};

// Get language code
CorbisUI.language = null;
if (Cookie.read("Profile")) {
    CorbisUI.language = Cookie.read("Profile").substring(Cookie.read("Profile").indexOf("Culture=") + 11);
}
        
    
CorbisUI.forKomodo = 'asDaSdalkNVa1234123lncasFioasCllk109Gh324KL';
    
// define global variable namespace
CorbisUI.GlobalVars = {};

CorbisUI.debug = false;

CorbisUI.dirs = {};

CorbisUI.options =  {};
CorbisUI.options.environment = 'browser';

    // Placeholder for DomCache - which uses CachingClass
CorbisUI.DomCache = null;

    // Placeholder for the main QueueManager instance - which uses QueueManagerClass
CorbisUI.QueueManager = null;

CorbisUI.init = function(options) {
        
        //console.log('calling CorbisUI.init()');
        if ($type(options) == 'object') this.options = $merge(this.options, options);



        // initialize DomCache
        CorbisUI.DomCache = new CorbisUI.CachingClass();

        // initialize QueueManager
        CorbisUI.QueueManager = new CorbisUI.QueuingManagerClass();

        // add some default queues
        CorbisUI.QueueManager.addQueue('domReady', { runOnDomReady: true });
        CorbisUI.QueueManager.addQueue('afterDomReady');


        // if in http mode, then run cookie events 
        if (Browser.getHost()) {

            // initialize js serializer
            CorbisUI.JSSerializer = new CorbisUI.JSSerializer();

            // initialize CookieEvents
            if (Browser.getHost()) CorbisUI.CookieEvents = new CorbisUI.CookieEvents();

            // run cookie events
            CorbisUI.QueueManager.afterDomReady.addItem('cookieEvents', CorbisUI.CookieEvents.runCookieEvents.bind(CorbisUI.CookieEvents));

        }

        // setup event for afterDomReady queue
        window.addEvent('load', function() {
            CorbisUI.QueueManager.runQueue('afterDomReady');
        });
    };



/***************************************************************************
    Splitting out some namespaces to make this more manageable
    
    bootstrap : /Scripts/CorbisUI-BOOTSTRAP.js
    
    CorbisUI.QueueManagerClass : /Scripts/CorbisUI.QueueingClasses.js
    CorbisUI.QueuListClass : /Scripts/CorbisUI.QueueingClasses.js
    
    CorbisUI.CachingClass : /Scripts/CorbisUI.CachingClass.js
    CorbisUI.CookieEvents : /Scripts/CorbisUI.CookieEvents.js
    CorbisUI.JSSerializer : /Scripts/CorbisUI.JSSerializer.js
    CorbisUI.MethodFailed : /Scripts/CorbisUI.MethodFailed.js
    CorbisUI.Auth : /Scripts/CorbisUI.Auth.js
    CorbisUI.GlobalNav : /Scripts/CorbisUI.GlobalNav.js
    CorbisUI.ImageGroups : /Scripts/CorbisUI.ImageGroups.js
    CorbisUI.ExpressCheckout : /Scripts/CorbisUI.ExpressCheckout.js
    CorbisUI.Legal : /Scripts/CorbisUI.Legal.js
    CorbisUI.EnlargementTimerSearch : /Scripts/CorbisUI.EnlargementTimerSearch.js
    CorbisUI.MSOSearch : /Scripts/CorbisUI.MSOSearch.js
    CorbisUI.Watermark : /Scripts/CorbisUI.Watermark.js
    CorbisUI.CustomerService : /Scripts/CorbisUI.CustomerService.js
    CorbisUI.MyProfile : /Scripts/CorbisUI.MyProfile.js
    CorbisUI.Pricing : /Scripts/CorbisUI.Pricing.js
    CorbisUI.FormUtilities : /Scripts/CorbisUI.FormUtilities.js
    
****************************************************************************/

//End: /Scripts/CorbisUI.js
//Begin: /Scripts/CorbisUI.QueueingClasses.js

/****************************************************
    Corbis UI Queueing Classes
    
    This file doesn't quite follow the pattern
    of the other CorbisUI.js files since it has 
    multiple classes with a different namespaces
    than the filename. This is ok. Just wanted
    one file for this to put all Queueing classes.
***************************************************/


/****************************************************
QUEUE CLASSES
- QueueManagerClass
- QueueListClass
	
Basic mechanism to create queues to run in 
sequence. Useful for DomReady or page OnLoad
events. But can be useful to setup basic macros
that can be rerun if a QueuList has been setup 
as being able to rerun. Othewise the queue will
run once and destroy itself.
	
See Chris for more info.
****************************************************/

/****************************************************
QUEUE MANAGER CLASS
    
Class that manages ALL queues.
****************************************************/
CorbisUI.QueuingManagerClass = new Class({
    queueList: null,

    hashMerge: 'each get has set getKeys getLength',

    initialize: function() {
        this.queueList = new Hash({});

        // lets merge some of the Hash's methods onto 'this'
        // and bind it to the queueList hash
        this.hashMerge.split(' ').each(function(item) {
            this[item] = this.queueList[item].bind(this.queueList);
        }, this);
    },

    // UTILITY: CHECK IF A QUEUE EXISTS
    //
    // type: (string) the name of your queue list
    //
    queueExists: function(type) {
        if (!this.has(type) && !this[type]) return false;
        return true;
    },

    // CREATE A NEW QUEUE LIST
    //
    //    type: (string) the name of your queue list
    // options: (object) see QueueListClass.options for possible variables
    //
    addQueue: function(type, options) {

        if (!this.queueExists(type)) {
            // create a rudimentary getter
            // example
            // if you create a new queue like:
            //      CorbisUI.QueueManager.addQueue('bob');
            // you can access it like this:
            //      CorbisUI.QueueManager.bob.<QueueListClass Methods>
            //
            this.set(type, function(el) { return this[el]; } .pass(type, this));
            this[type] = new CorbisUI.QueueListClass(type, this, options);
            //this[type].parentObj.bind(this);
        }
        return this[type];
    },

    // REMOVE A QUEUE LIST - destroys a particular queue
    //
    // type: (string) name of the queue list
    //
    removeQueue: function(type) {
        if (this.queueExists(type)) {
            this[type] = false;
            this.queueList.erase(type);
        }
    },

    /* =======================================
    SHORTCUTS TO QueueListClass methods 
    ======================================= 
    */

    // ADD A QUEUE LIST ITEM - shortcut to QueueListClass.set
    //
    //            type: (string) name of the queue list
    //             key: (string) name of the queue list item
    //            func: (function) function mapped to queue list item
    // overrideIfFound: (boolean) if true, it will reset the function
    //
    addQueueItem: function(type, key, func, overrideIfFound) {
        if (this.queueExists(type)) this[type].set(key, func, overrideIfFound);
    },

    // REMOVE A QUEUE LIST ITEM - shortcut to QueueListClass.erase
    //
    // type: (string) name of the queue list
    //  key: (string) name of the queue list item
    //
    removeQueueItem: function(type, key) {
        if (this.queueExists(type)) this[type].erase(key);
    },

    // REMOVE A QUEUE LIST ITEM - shortcut to QueueListClass.erase
    //
    //     type: (string) name of the queue list
    //  options: (object) object options { delay: true/false, delayTime: (int)}
    //           if delay is true, and no delayTime set, it defaults to 100ms
    //
    runQueue: function(type, options) {
        if (this.queueExists(type)) this[type].run(options);
    },

    // RUN SINGLE QUEUE ITEM
    // run a single item in a queue list
    // this is used only for queues that are rerunQueues 
    //
    //     queue: (string) name of the queue list
    // queueItem: (string) name of the queue list item
    runQueueItem: function(queue, queueItem) {
        if (this.queueExists(type)) this[type].runItem(queueItem);
    }

});

/****************************************************
QUEUE LIST CLASS
        
Class that manages runable items in a Queue.
This gets initiated from the QueueManagerClass
via the method addQueue.
    
Options available
- canRerun : (boolean) Whether a queue can be rerun.
Queue will always exist until told to
destroy itself explicitly. 
Defaults to false
- delay : (boolean) Whether a queue should delay
between each queue function when running.
Defaults to false.
- delayTime : (int) Time in milliseconds for delay.
Defaults to 100ms if delay=true and
delayTime is not set.
-runOnDomReady : (boolean) Flag as to whether 
queue should run on dom ready.
Defaults to false.
****************************************************/
CorbisUI.QueueListClass = new Class({
    Implements: [Options],
    options: {
        canRerun: false,
        delay: false,
        delayTime: 0,
        runOnDomReady: false
    },

    hashMerge: 'each has keyOf hasValue extend combine erase get empty include map filter every some getClean getKeys getValues getLength',

    queueItems: null, // placeholder for items hash
    listName: null, // name of list

    parentObj: null, // reference to the queuemanager instance that called it
    // this gets bound in the queuemanager after QueueListClass instance created

    // alias placeholders
    addItem: null,
    destroy: null,

    // INITIALIZE QUEUE LIST
    initialize: function(name, parentObj, options) {
        if (options) this.setOptions(options);
        if (this.options.delay && this.options.delayTime == 0) this.options.delayTime = 100;

        this.listName = name;
        this.queueItems = new Hash({});
        this.parentObj = parentObj;

        // alias destroy method - see QueueManagerClass.removeQueue
        this.destroy = parentObj.removeQueue.bind(parentObj).pass(this.listName);

        // lets merge some of the Hash's methods onto 'this'
        // and bind it to the queueItems hash
        this.hashMerge.split(' ').each(function(item) {
            this[item] = this.queueItems[item].bind(this.queueItems);
        }, this);

        // setup domready if the option is on
        if (this.options.runOnDomReady) this.setupDomReady();

        // setup some aliases
        this.addItem = this.set;

    },

    // ADD A QUEUE LIST ITEM
    //
    //             key: (string) name of the queue list item
    //            func: (function) function mapped to queue list item
    // overrideIfFound: (boolean) if true, it will reset the function
    //
    set: function(key, func, overrideIfFound) {
        if ($type(func) != "function") {
            throw "QueueListClass ERROR: the queue item is not a function. Fixit please.";
            return false;
        }
        this.queueItems.set(key, func);
        return this;
    },

    // RUN QUEUE LIST - runs through entire queue list
    //
    //  options: (object) object options { delay: true/false, delayTime: (int)}
    //           if delay is true, and no delayTime set, it defaults to 100ms
    //
    run: function(options) {

        var tempOptions = this.options;
        if (options) $merge(tempOptions, options);
        if (tempOptions.delay && tempOptions.delayTime == 0) tempOptions.delayTime = 100;

        if (this.getLength() > 0) {
            this.each(function(value, key) { (function() { value.run() }).delay(tempOptions.delayTime); });
        }

        // if this queue is not rerunnable, then destroy it
        if (!this.options.canRerun) this.destroy();
    },

    // RUN SINGLE QUEUE ITEM
    // run a single item in a queue list
    // this is used only for queues that are rerunQueues 
    //
    // queueItem: (string) name of the queue list item
    runItem: function(queueItem) {
        var runItem = this.queueItems.get(queueItem);
        if (runItem != null) runItem.run();
        return this;
    },

    // RUN A SEQUENCE
    // run queue items in the sequence entered
    //
    // arguments: name of the queue list items in the order you want them run
    // example - INSTANCE.runSequence('bob','fred','tony');
    //
    runSequence: function() {
        for (var i = 0; i < arguments.length; i++) {
            var runItem = this.queueItems.get(arguments[i]);
            if (runItem != null) {
                (function(value) { value.run() }).pass(runItem).delay(this.options.delayTime);
            }
        }
        return this;
    },

    // DESTROY QUEUE LIST
    //
    // This will destroy this instance
    //
    //        destroy: function() {
    //            this.parentObj.removeQueue(this.listName); // say goodbye to your little friend
    //        },

    // SET THE DELAY
    //
    // If you forgot to set your delay, you can do it here
    //
    setDelay: function(delayTime) {
        this.options.delay = (delayTime > 0) ? true : false;
        this.options.delayTime = (this.options.delay) ? delayTime : 0;
        return this;
    },

    // SET IF IT CAN RERUN
    //
    // If you forgot to set whether the queue can rerun, you can do it here
    //
    setRerun: function(canI) {
        this.options.canRerun = canI;
        return this;
    },

    runOnDomReady: function() {
        this.options.runOnDomReady = true;
        return this;
    },

    setupDomReady: function() {
        window.addEvent('domready', this.run.bind(this));
    }

});


// MAKING ALIASES TO WORK WITH NEW CLASS
// instead of calling CorbisUI.QueueManager.<method>
// you can call CorbisUI.<method>
// more or less to deal with pre-QueueManagerClass calls

CorbisUI.addQueueItem = function(type, key, func) {
    CorbisUI.QueueManager.addQueueItem(type, key, func);
};

CorbisUI.removeQueueItem = function(type, key) {
    CorbisUI.QueueManager.removeQueueItem(type, key);
};

CorbisUI.addQueue = function(type, canRerun) {
    var item = CorbisUI.QueueManager.addQueue(type);
    if (canRerun) item.setRerun(canRerun);
};

CorbisUI.runQueue = function(type, delay, delayTime) {
    var tempOptions = { delay: false, delayTime: 0 };
    if (delay) tempOptions.delay = true;
    if (delayTime > 0) tempOptions.delay = delayTime;
    CorbisUI.QueueManager.runQueue(type, tempOptions);
};

CorbisUI.runQueueItem = function(queue, queueItem) {
    CorbisUI.QueueManager.runQueueItem(type, queueItem);
}
// END QUEUE ALIASES
//End: /Scripts/CorbisUI.QueueingClasses.js
//Begin: /Scripts/CorbisUI.CachingClass.js

/****************************************************
    Corbis UI Caching Class
***************************************************/

/****************************************************
CACHING CLASS
        
utility class to cache dom elements that are accessed a lot
        
NOTE: the bulk add is really only for items with an ID,
but there is a method for storing collections/objects
as key,value(the collection or object) which can be
added individually.
        
CorbisUI.DomCache uses this. But you can create
your own caches if that makes it easier for
you to manage.
            
****************************************************/
CorbisUI.CachingClass = new Class({
    cache: null,

    initialize: function() {
        this.cache = new Hash({});
    },

    // this is for adding items that have ID's
    add: function(items) {
        if ($type(items) == 'string') {
            this.cache.set(items, $(items));
        }
        else if ($type(items) == 'array') {
            items.each(function(item) {
                if ($type(item) == 'string') this.cache.set(item, $(item));
            }, this);
        }
    },

    // want to cache an object?
    //    key: (string) name of the object
    // object: (object) the object to be stored
    addObject: function(key, object) {
        this.cache.set(key, object);
    },

    // key: accessor name for cache
    // value: the collection
    // TODO: right now you can add collections one at at time. 
    // need to make it so you can batch add
    addCollection: function(key, collection) {
        this.cache.set(key, collection);
    },

    // items: (string/array) items to fetch
    // reset: (boolean) will force an item to be recached with $()
    get: function(items, reset) {

        if ($type(items) == 'string') {
            if (!this.cache.has(items) || reset) this.add(items);
            return this.cache.get(items);
        }
        else if ($type(items) == 'array') {
            var returnItems = {};
            items.each(function(item) {
                if (!this.cache.has(item) || reset) this.add(item);
                returnItems[item] = this.cache.get(item);
            }, this);
            return returnItems;
        }
    },

    remove: function(items) {
        if ($type(items) == 'string') {
            if (this.cache.has(item)) this.cache.erase(items);
        }
        else if ($type(items) == 'array') {
            items.each(function(item) {
                if (this.cache.has(item)) this.cache.erase(item);
            }, this);

        }
        return;
    },

    has: function(key) {
        return this.cache.has(key) && this.cache[key] != null;
    },

    emptyCache: function() {
        this.cache.empty();
    }

});
//End: /Scripts/CorbisUI.CachingClass.js
//Begin: /Scripts/CorbisUI.CookieEvents.js

/****************************************************
    Corbis UI Cookie Events
***************************************************/

/****************************************************
COOKIE EVENTS
            
Utility to store javascript in a cookie. 
This was created to address problems of anonymous
users attempting to do something, who are prompted
to login. The page refreshes, an the original
event is lost. This way we can programmatically
leapfrog the intended event over the page refresh.
        
NOTE: uses CorbisUI.JSSerializer to serialize
javascript objects into XML string to be stored
in cookie.
        
See Chris for more info/examples.
            
****************************************************/

CorbisUI.CookieEvents = new Class({
    cookie: null,
    cookieData: [],

    cookieOptions: {
        domain: "",
        path: "/"
    },

    initialize: function() {
        //console.profile();
        //this.cookieOptions.domain = (Browser.getHost().contains(CookieDomain)) ? CookieDomain : ".corbis.pre";

        //this.cookieOptions.path = (Browser.getCookiePath().toLowerCase() == "default.aspx") ? "/" : "/" + Browser.getCookiePath();

        this.cookie = new Cookie('CorbisCJ', this.cookieOptions);
        //this.cookieData = [];



        if (this.cookie.read() == null) {
            this.cookie.write(CorbisUI.JSSerializer.serialize({ "data": [] }, 'CookieEvents'));
        } else {
            var cdata = CorbisUI.JSSerializer.deserialize(this.cookie.read());
            //console.log(cdata);
            if (!$type(cdata.data)) cdata.data = [];
            this.cookieData.combine(cdata.data);
        }
        //console.profileEnd();
    },
    addCookieEvent: function(func, funcVars) {
        var cdata = CorbisUI.JSSerializer.deserialize(this.cookie.read());
        //console.log(cdata);
        if(cdata && cdata.data) {
            this.cookieData.combine(cdata.data);
        }
        var temp = {};

        temp.runMe = func;
        if (funcVars) temp.vars = funcVars;

        this.cookieData.include(temp);
        this.cookie.write(CorbisUI.JSSerializer.serialize({ "data": this.cookieData }, 'CookieEvents'));
    },

    runCookieEvents: function() {
        if (this.cookieData.length > 0) {
            //console.log('RUNNING COOKIE EVENTS');
            //console.log(this.cookieData.getKeys());
            this.cookieData.each(function(item, key) {
                //console.log('--<' + key + '>');
                if (item.runMe) {
                    (function() {
                        //alert('runme!');
                        this.runMe();
                    } .bind(item)).delay(1000);
                }
            });
            this.cookieData.empty();
        }
        this.cookie.write(CorbisUI.JSSerializer.serialize({ "data": [] }, 'CookieEvents'));
    },

    addCookieEvent_altPath: function(path, func, funcVars) {

        var tmpOptions = this.cookieOptions;
        tmpOptions.path = path;

        var cookie = new Cookie('CorbisCJ', tmpOptions);

        var cdata = CorbisUI.JSSerializer.deserialize(cookie.read());
        //console.log(cdata);
        this.cookieData.combine(cdata.data);

        var temp = {};

        temp.runMe = func;
        if (funcVars) temp.vars = funcVars;

        var cookieData = [];

        if (cookie.read() == null) {
            cookie.write(CorbisUI.JSSerializer.serialize({ "data": [] }, 'CookieEvents'));
        } else {
            var cdata = CorbisUI.JSSerializer.deserialize(cookie.read());
            //console.log(cdata);
            cookieData.combine(cdata.data);
        }

        cookieData.include(temp);
        cookie.write(CorbisUI.JSSerializer.serialize({ "data": cookieData }, 'CookieEvents'));
    }

});

//End: /Scripts/CorbisUI.CookieEvents.js
//Begin: /Scripts/CorbisUI.JSSerializer.js

/****************************************************
    Corbis UI JS Serializer
***************************************************/


/****************************************************
JS SERIALIZER 
                
Utility to serialize a javascript object into
XML string. 
        
Can serialize the following:
- string
- array
- date
- object
- function (serializes function as XML CDATA)
        
USED BY: CorbisUI.CookieEvents
        
Mainly built because you can't normally store
javascript in a cookie. But you can store XML
string. 
        
See Chris for more info.
            
****************************************************/

/** EXAMPLES

// TO SERIALIZE
var test = CorbisUI.JSSerializer.serialize({
runMe: function(){ 
this.cool(); 
},
cool: function(){ 
alert(this.myString); 
},
myString: 'wassup foo!',
myNumber: 2567,
myBoolean: true,
myObject: {
secondObject: "howdy"
},
myArray: ["bob","debbie"],
myDate: new Date()
});
    
// test obj serialized looks like this
        
"<undefined type="object">
<runMe type="function">
<![CDATA[function () { this.cool(); }]]>
</runMe>
<cool type="function">
<![CDATA[function () { alert(this.myString); }]]>
</cool>
<myString type="string">wassup foo!</myString>
<myNumber type="number">2567</myNumber>  
<myBoolean type="boolean">true</myBoolean>  
<myObject type="object">  
<secondObject type="string">howdy</secondObject>
</myObject> 
<myArray type="array">
<index0 type="string">bob</index0>
<index1 type="string">debbie</index1>  
</myArray>  
<myDate type="date">Wednesday, February 25, 2009 9:03:46 AM</myDate> 
</undefined> "
    
this can now be stored in cookie.
        
// TO DESERIALIZE
var deser = CorbisUI.JSSerializer.deserialize(test);
        
deser will now be a usable javascript object
*/

CorbisUI.JSSerializer = new Class({
    Implements: [Options],
    options: {
        use_encryption: false,
        use_compress: false
    },
    isIE: false,
    isMoz: false,

    initialize: function(options) {
        if (options) this.setOptions(options);
        this.isIE = Browser.Engine.trident;
        this.isMoz = Browser.Engine.gecko;
    },
    /**
    * Serialize a JS object into an XML String for storage / transmission
    * (i.e. cookie, download etc.)
    * 
    * objectToSerialize (object) : The object to be serialized
    *        objectName (object) : (Optional) Name of the object being passed in
    *       indentSpace (object) : (Optional) Use this as an indentSpace
    *
    * returns a xml string specifying the object
    */
    serialize: function(objectToSerialize, objectName, indentSpace) {
        //console.log('serialize');
        indentSpace = indentSpace ? indentSpace : '';

        var type = this.GetTypeName(objectToSerialize).toLowerCase();

        var s = indentSpace + '<' + objectName + ' type="' + type + '">';

        switch (type) {
            case "number":
            case "string":
            case "boolean":
                s += objectToSerialize;
                break;

            case "date":
                s += objectToSerialize.toLocaleString();
                break;

            case "function":
                s += "\n";
                s += "<![CDATA[" + objectToSerialize + "]]>";
                s += indentSpace;
                break;

            case "array":

                s += "\n";

                objectToSerialize.each(function(item, index) {
                    s += this.serialize(item, 'index' + index, indentSpace + "   ");
                }, this);


                s += indentSpace;
                break;

            default:
                if (type != 'null') {
                    s += "\n";
                    for (var name in objectToSerialize) {
                        s += this.serialize(objectToSerialize[name], name, indentSpace + "   ");
                    }
                    s += indentSpace;
                } 
                break;
        }

        s += "</" + objectName + ">\n";

        return s;
    },

    /**
    * Deserialize a serialized XML object into a javascript object
    * Uses deserial recursively to rebuild the javascript 
    *
    * SEE: deserial
    *
    * XmlText (String) : xml string to be deserialized
    *
    * return Object
    */
    deserialize: function(XmlText) {
        //console.log('deserialize');
        var _doc = this.getDom(XmlText);
        if(!_doc) {
            return null;
        }
        return this.deserial(_doc.childNodes[0]);
    },

    /**
    * Get the DOM object from an XML doc
    * NB: Works for IE and Mozilla
    *
    * strXml (String) : xml string to be deserialized
    *
    * returns (Dom parser) appropriate to browser
    */
    getDom: function(strXml) {
        if(!strXml) return null;
        //console.log('getDom');
        if (!this.isIE) var parser = new DOMParser();
        var _doc = (this.isIE) ? new ActiveXObject("Msxml2.DOMDocument.3.0") : parser.parseFromString(strXml, "text/xml");

        if (this.isIE) _doc.loadXML(strXml);

        return _doc;
    },

    /**
    * Deserialize an XML DOM object into a javascript object
    * 
    * NOTE: This function uses recursion
    *
    * domObject (Object) : The DOM object to deserialize into a JS Object
    */
    deserial: function(domObject) {
        //console.log('deserial');
        var retObj;
        var nodeType = this.getNodeType(domObject);

        if (this.isSimpleVar(nodeType)) {
            var simpleReturn = (this.isIE) ? this.StringToObject(domObject.text, nodeType) : this.StringToObject(domObject.textContent, nodeType);
            return simpleReturn;
        }

        switch (nodeType) {
            case "array":
                return this.deserializeArray(domObject);
                break;

            case "function":
                return this.deserializeFunction(domObject);
                break;

            case "object":
            default:
                try {
                    retObj = eval("new " + nodeType + "()");
                } catch (e) {
                    // create generic class
                    retObj = new Object();
                }
                break;
        }


        for (var i = 0; i < domObject.childNodes.length; i++) {
            var Node = domObject.childNodes[i];
            retObj[Node.nodeName] = this.deserial(Node);
        }

        return retObj;
    },

    /**
    * Check if the current element is one of the primitive data types
    *
    * type (String) : The "type" attribute of the current node
    *
    * returns (boolean)
    */
    isSimpleVar: function(type) {
        //console.log('isSimpleVar');
        var criteria = ["number", "string", "boolean", "date"];
        if (criteria.contains(type)) return true;

        return false;
    },

    /**
    * Convert a string to an object
    *
    * text (String) : The text to parse into the new object
    * type (String) : The type of object that you wish to parse TO
    */
    StringToObject: function(text, type) {
        //console.log('StringToObject: ' + type);
        var retObj = null;

        switch (type) {

            case "number":
                var outNum = (text.contains('.')) ? text.toFloat() : text.toInt();
                return outNum;

            case "string":
                return text;

            case "date":
                return new Date(text);

            case "boolean":

                if (text == "true" || text == "True") {
                    return true;
                }
                else {
                    return false;
                }

                return parseBool(text);
        }

        return retObj;
    },

    /**
    * Get the name of an object by extracting it from it's constructor attribute
    *
    * obj (Object) : The object for which the name is to be found
    *
    * returned classname (string)
    */
    getClassName: function(obj) {
        //console.log('getClassName');
        try {

            var ClassName = obj.constructor.toString();
            var functionIndex = ClassName.indexOf("function");
            if (functionIndex != -1) {
                var leftParenthesisIndex = ClassName.indexOf('(');
                if (leftParenthesisIndex != -1)
                    return ClassName.substring(functionIndex + 8, leftParenthesisIndex).replace(/ /g, '');
            }
            return "NULL";
        }
        catch (e) {
            return "NULL";
        }
    },

    /**
    * Get the type of Object by checking against the Built-in objects.
    * If no built in object is found, call getClassName
    *
    * SEE: getClassName
    *
    * obj (Object) - The object for which the type is to be found
    * 
    * returns type (String)
    */
    GetTypeName: function(obj) {
        //console.log('GetTypeName');
        var type = $type(obj);
        if (this.isSimpleVar(type)) return type;
        type = this.getClassName(obj);
        return type;
    },

    /**
    * Deserialize an Array
    *
    * node (XML String) - The node to deserialize into an Array
    *
    *   returns the deserialized Array 
    */
    deserializeArray: function(node) {
        //console.log('deserializeArray');
        retObj = [];

        // Cycle through the array's TOP LEVEL children
        while (child = node.firstChild) {

            // delete child so it's children aren't recursed
            node.removeChild(node.firstChild);

            var nodeType = this.getNodeType(child);

            if (this.isSimpleVar(nodeType)) {
                retObj[retObj.length] = this.getTextContent(child);
            } else {
                var tmp = this.getTextContent(child);
                if (tmp.trim() != '') retObj[retObj.length] = this.deserial(child)
            }
        }
        return retObj;
    },

    /**
    * Deserialize a Function
    * node (XML String) - The node to deserialize into a Function
    *
    * returns the deserialized Function
    */
    deserializeFunction: function(func) {
        //console.log('deserializeFunction');
        var funcText = this.getTextContent(func);
        if (func && funcText) {
            // JSON hack to get functions converted correctly
            var tmp = JSON.decode("{\"tmp\":" + funcText.trim() + "}");
            return tmp.tmp;
        }
    },

    /**
    * Get the type attribute of an element if there is one,
    * otherwise return generic 'object'
    * 
    * NOTE: This function is used on the resulting serialized XML and not on
    *       any actual javascript object
    *
    * node (XML) - The node for which the type is to be found
    *
    * returns string of node attribute "type"
    */
    getNodeType: function(node) {
        //console.log('getNodeType');
        var nodeType = "object";

        if (node.attributes != null && node.attributes.length != 0) {
            var tmp = node.attributes.getNamedItem("type");
            if (tmp != null) nodeType = node.attributes.getNamedItem("type").nodeValue;
        }

        return nodeType;
    },

    /**
    * Get text content
    *
    * obj (XML Node) : the xml node to get the text content of
    * 
    * returns (string) of text content
    */
    getTextContent: function(obj) {
        //console.log('getTextContent');
        var funcText = (Browser.Engine.trident) ? obj.firstChild.text : obj.textContent;
        return funcText;
    }


});
//End: /Scripts/CorbisUI.JSSerializer.js
//Begin: /Scripts/CorbisUI-BOOTSTRAP.js


/****************************************************
Based in part on QooxDoo bootstrap
http://www.qooxdoo.org
	
- modified heavily to to workwith mootools
- in both browser and server-side enviroments
	
=============================================
Chris Esler, 2008-01-01
=============================================
****************************************************/

bootstrap = new Class({

    Implements: [Options, Chain],

    options: {
        environment: 'browser'
    },

    initialize: function(options) {
        this.setOptions(options);

        $extend(this, CorbisUI);

        CorbisUI = this;

        //setup bootstrap core
        this.defineClass("CorbisUI.app", {
            statics: {
                LOADSTART: new Date,

                time: function() {
                    return new Date().getTime();
                },

                since: function() {
                    return this.time() - this.LOADSTART;
                }

            }
        });

    },

    // quick way to fetch object from registry
    getObject: function(name) {
        return this.registry.Class[name];
    },

    // method to create namespace and bind it onto the object
    // see defineClass for structure example
    createNamespace: function(name, object) {
        var splits = name.split(".");
        var parent = this;
        var part = splits[0];

        for (var i = 0, len = splits.length - 1; i < len; i++, part = splits[i]) {
            if (i == 0) continue;
            if (!parent[part]) {
                parent = parent[part] = {};
            } else {
                parent = parent[part];
            }
        }

        // get general parent name
        var PNsplits = name.split(".");
        PNsplits.pop();
        var parentName = PNsplits.join(".");

        // add some utility values to object
        var helpers = {
            identifier: {
                'classname': name,
                'basename': part,
                'parentname': parentName
            }
        }

        // extend object with utilities
        if ($type(object.prototype) == "class") {
            object.implement(helpers);
        } else {
            $extend(object, helpers);
        }

        // bridge to make qooxdoo-like
        // object assignment work with mootools
        var tempObject = {};
        tempObject[part] = object;

        // store object
        $extend(parent, tempObject);

        // return last part name (e.g. classname)
        return part;

    },

    // method to dynamically add item to namespace (qooxdoo style)
    //
    // example: assuming CorbisUI is main namespace
    //   
    //    CorbisUI.defineClass("CorbisUI.TEST",
    //    {
    //    	
    //	    // just a container
    //	    // can be function, obect, class, or variable (string/int)
    //	    statics : function(){
    //	        alert('test');
    //	    },
    //    	
    //	    defer : function(statics) {
    //	        // can add domready stuff here
    //	        // cleanup memory
    //	        statics = $lambda(false);
    //	    }
    //    });
    defineClass: function(name, config) {

        var parent = this;

        if (!config) {
            config = { statics: {} };
        };

        if (!config.statics) {
            config.statics = {};
        };

        // create the namespace
        this.createNamespace(name, config.statics);

        // deferring is to run things after namespace is 
        // created. kind of like deferred initialization.
        if (config.defer) {
            config.defer(config.statics);
        }

        // clear up memory
        config = $lambda(false);

    }

});

// startup bootstrap
new bootstrap(CorbisUI.options);

// init CorbisUI namespace engine
CorbisUI.init();

if (!CorbisUI.debug) console.log = function() { };
//End: /Scripts/CorbisUI-BOOTSTRAP.js
//Begin: /Scripts/CorbisUI.NameSpace.js

CorbisUI.NameSpace = (function() {
    var init = new Class({

        initialize: function() { },

        register: function(name, options) {

            if (!options) options = {};

            var data = name.split('.');
            var method = data.getLast();

            var parent = window;
            var name;
            var objRef = null;
            var aliasForce = options.ForceAlias || false;

            data.each(function(item, idx) {
                //console.log($type(options.BasedOn));
                name = (idx === 0) ? item : name + '.' + item;

                var test;
                if (options.Type && item === method && !parent[item]) {

                    var objectTypeKey = options.Type.toLowerCase() + "Object";
                    if ($type(this[objectTypeKey]) === 'class') {
                        test = new this[objectTypeKey](name, objRef);
                    } else {
                        test = new this.genericObject(name, objRef);
                    }

                } else if ((options.Alias && item === method && !parent[item])||(options.Alias && item === method && aliasForce)) {
                    // quick way to alias things
                    test = options.Alias;

                } else {
                    test = new CorbisUI.NameSpace.namespaceObject(name, objRef);
                }
                if (aliasForce && item === method) {
                    parent = parent[item] =  test;
                } else {

                    parent = parent[item] = parent[item] || test;
                }
                objRef = parent;

            }, this);

        },

        genericObject: new Class({

            __typeName: null,
            __parent: null,

            initialize: function(type, refObj) {
                this.__typeName = type;
                if (typeof (refObj) === "object") {
                    this.__parent = refObj;
                }

            },

            getName: function() {
                return this.__typeName;
            }
        })

    });
    return new init();
})();

/*****************************
 * ADD EXTENSIONS
 *****************************/

$extend(CorbisUI.NameSpace,{
    namespaceObject: new Class({

        Extends: CorbisUI.NameSpace.genericObject,
                
        __namespace: true,

        initialize: function(type, refObj) {
        this.parent(type, refObj);
        }

    })
});

$extend(CorbisUI.NameSpace, {
    enumObject: new Class({

        Extends: CorbisUI.NameSpace.genericObject,

        __enum: true,

        dictionary: null,

        hashMerge: 'get has set getKeys',

        initialize: function(name, refObj) {
            this.parent(name, refObj);

            this.dictionary = new Hash({});
            this.hashMerge.split(' ').each(function(item) {
                this[item] = this.dictionary[item].bind(this.dictionary);
            }, this);
        },

        setDictionary: function(obj, arr) {
            //this.dictionary.combine(obj);
            var temp = new Hash(obj);
            var i = 0;
            temp.each(function(val, key) {
                this[key] = val;
                this.dictionary.set(val, arr[i]);
                i = i + 1;
            }, this);
        },

        toLocalizedString: function(val) {
            return this.dictionary.get(val);
        },

        parse: function(item) {
            //console.log('CALLING ENUM PARSE');
            return this[item];
        }

    })
});



/*****************************
 * EXAMPLES
 *****************************
CorbisUI.NameSpace.register('Corbis.Test.Enum',{Type: "enum"});

Corbis.Test.Enum.setDictionary(
{
Unknown: 0,
Ok: 1,
ContactUs: 2,
ContactOutline: 4,
PricedByAE: 8,
AsPerContract: 16,
UpdateUse: 32,
DisplayPrice: 64,
CountryOrCurrencyError: 128,
CustomPriceExpired: 256,
NotEcommerceEnabled: 512
},
[
'Unknown',
'OK',
'Contact us',
'Contact Outline',
'Priced by A.E.',
'Per contract',
'Update use',
'Display price',
'Country or currency error',
'Custom price expired',
'Not ecommerce enabled'
]
);

// If you want to alias something

CorbisUI.NameSpace.register('Corbis.Test.Dictionary',{Alias: Corbis.Test.Enum});

*/

//End: /Scripts/CorbisUI.NameSpace.js
//Begin: /Scripts/CorbisUI.ServiceManager.js

// SERVICE MANAGER
CorbisUI.ServiceManager = (function() {
    var init = new Class({
        managerList: null,

        // because we are emulating the MS Ajax webservice calls
        // and we are aliasing this to Corbis.Web.UI
        // we have to tell MS scripts that this is a namespace
        __namespace: true,

        // flag for whether a page is using legacy MS webservice calls
        oldServiceExists: false,

        hashMerge: 'get has set getKeys',

        initialize: function() {
            this.managerList = new Hash({});

            // lets merge some of the Hash's methods onto 'this'
            // and bind it to the queueList hash
            this.hashMerge.split(' ').each(function(item) {
                this[item] = this.managerList[item].bind(this.managerList);
            }, this);
            // create some shortcuts
            this.webspaceList = this.getKeys;

        },
        /*
        name: (string) service name - 'Checkout.CartScriptService.MoveItemWithInCart'
        options: (object) xhr options that gets passed down to the service method when its created  
        */
        defineService: function(name, options) {
            // check if the service already exists
            if (!this.serviceExists(name)) {
                var args = name.split('.');
                var webspace = args.shift();
                if (typeof (this[webspace]) == "undefined") {
                    // create the webspace
                    this.managerList.set(webspace, new CorbisUI.ServiceManager.WebSpace(webspace));
                    // bind webspace onto manager object
                    this[webspace] = this.get(webspace);
                }
                // now lets add the servicespace
                if (!options) options = {};
                this[webspace].addServiceSpace(args, options);

                // this is to ensure backward compatibility
                // with pages we haven't taken out all of the
                // webservices. Once we get rid of ALL the 
                // webservices in ALL pages, we can take this out
                window.addEvent('domready', function(webspace) {

                    if (CorbisUI.ServiceManager.oldServiceExists) {

                        var delayTime = (Browser.Engine.trident) ? 100 : 10;
                        //console.log('OLD SERVICE EXISTS: ' + webspace);
                        (function() { CorbisUI.NameSpace.register('Corbis.Web.UI.' + webspace, { Alias: CorbisUI.ServiceManager[webspace] }); }).delay(delayTime);
                    }

                } .pass(webspace));

                // return this so you can chain defining services
                return this;
            } else {
                //throw "SERVICE ALREADY EXISTS: " + name;
            }
        },

        // check if a service method has been defined
        serviceExists: function(name) {
            var args = name.split('.');
            var webspace = args[0], servicespace = args[1], servicemethod = args[2];

            var serviceExists = true;

            if (!this.managerList.has(webspace)) serviceExists = false;
            if (serviceExists && !this.get(webspace).has(servicespace)) serviceExists = false;
            if (serviceExists && !this.get(webspace).get(servicespace).has(servicemethod)) serviceExists = false;

            return serviceExists;

        }

    });
    return new init();
})();

// create an alias so all old calls to Corbis.Web.UI point to CorbisUI.ServiceManager
window.addEvent('domready', function() {
    if (typeof (Corbis) === "undefined" || typeof (Corbis.Web) === "undefined" || typeof (Corbis.Web.UI) === "undefined") {
        CorbisUI.NameSpace.register('Corbis.Web.UI', { Alias: CorbisUI.ServiceManager });
    } else {
        CorbisUI.ServiceManager.oldServiceExists = true;
    }
});

// CLASS FOR SERVICE WEBSPACE 
CorbisUI.ServiceManager.WebSpace = new Class({
    serviceList: null, // placeholder for hash
    hashMerge: 'get has set getKeys',
    name: null, //webspace name
    initialize: function(name) {
        this.name = name;
        this.serviceList = new Hash({});
        this.hashMerge.split(' ').each(function(item) {
            this[item] = this.serviceList[item].bind(this.serviceList);
        }, this);
        // create some shortcuts
        this.listServices = this.getKeys;
    },
    addServiceSpace: function(args, options) {
        var servicespace = args.shift(); // get service space name
        if (typeof (this[servicespace]) == "undefined") {
            // create the service space
            this.serviceList.set(servicespace, new CorbisUI.ServiceManager.ServiceSpace(servicespace, this));
            // bind servicespace onto webspace object
            this[servicespace] = this.get(servicespace);
        }
        // now lets add the service method
        this[servicespace].addServiceMethod(args, options);
    }
});

// CLASS FOR SERVICE SPACE
CorbisUI.ServiceManager.ServiceSpace = new Class({
    methodList: null, // placeholder for hash
    hashMerge: 'get has set getKeys',
    webspace: null, // placeholder for the webspace object
    name: null, // servicespace name
    defaultUserContext: null, // placeholder for default context
    defaultFailedCallback: null,
    defaultSuccessCallback: null,
    _staticInstance: {},
    initialize: function(name, refobj) {
        this.name = name;
        this.webspace = refobj; // store reference to webspace object
        this.methodList = new Hash({});
        this.hashMerge.split(' ').each(function(item) {
            this[item] = this.methodList[item].bind(this.methodList);
        }, this);

        // create some shortcuts
        this.listMethods = this.getKeys;
        this.getMethod = this.get;
    },

    addServiceMethod: function(args, options) {
        var servicemethod = args.shift(); //gets service method name
        if (typeof (this[servicemethod]) == "undefined") {
            // create the method object
            this.methodList.set(servicemethod, new CorbisUI.ServiceManager.ServiceMethod(servicemethod, this, options));
            // bind service method object run function into service space
            this[servicemethod] = this.get(servicemethod).runMethod.bind(this.get(servicemethod));
            this._staticInstance[servicemethod] = this.get(servicemethod).runMethod.bind(this.get(servicemethod));
        }
    },

    set_defaultUserContext: function(objRef) {
        this.defaultUserContext = objRef;
    },

    get_defaultUserContext: function() {
        return this.defaultUserContext;
    },

    get_path: function() {
        var url = '/' + this.webspace.name + '/' + this.name + '.asmx';
        return url;
    },

    set_defaultFailedCallback: function(obj) {
        this.defaultFailedCallback = obj;
    },

    get_defaultFailedCallback: function() {
        return this.defaultFailedCallback;
    },

    set_defaultSuccessCallback: function(obj) {
        this.defaultSuccessCallback = obj;
    },

    get_defaultSuccessCallback: function() {
        return this.defaultSuccessCallback;
    },

    /********************************* 
    *  DEFAULT RESPONSE FUNCTIONS
    **********************************/

    onSuccess: function(results, context, methodName) {
        // a nice black hole
    },

    onFailure: function(results, context, methodName) {
        // another nice blackhole
    }

});

// CLASS FOR SERVICE METHOD - most of the magic happens here
CorbisUI.ServiceManager.ServiceMethod = new Class({

    /********************************* 
    *  SETUP VARIABLES
    **********************************/
    Implements: Options,

    xhr: null, // placeholder for REQUEST object

    defaultUserContext: null, // placeholder for default context
    defaultFailedCallback: null,
    defaultSuccessCallback: null,

    basics: ["onSuccess", "onFailure", "userContext"],

    options: {
        responseType: "JSON", // XML, JSON, or HTML - defaults to JSON
        method: 'post',
        secure: false,
        submissionTemplate: [],
        async: true,
        sendOnly: false,
        noCache: true // flag whether you want some caching trickery
        // MAYBE? add a datatype check object that is similar to submissionTemplate
    },

    servicespace: null, // placeholder for the servicespace object
    name: null, // service method name

    /********************************* 
    *  OBJECT INITIALIZATION
    **********************************/

    initialize: function(name, refobj, options) {
        this.name = name;
        this.servicespace = refobj; // store reference to servicespace object
        this.setOptions(options);

        // combine their submission options with the 'basics'
        // basically we add onSuccess, onFailure, and userContext 
        // to the submission template as a default
        this.options.submissionTemplate = this.options.submissionTemplate.combine(this.basics);
    },

    /********************************* 
    *  BOUND FUNCTIONS
    **********************************/

    runMethod: function() {

        //if (Browser.Engine.trident) alert('RUNNING: ' + this.get_path());

        // setup some basic things
        var data = new Hash();
        var onSuccess = null;
        var onFailure = null;
        var context = null;

        if (this.defaultFailedCallback != null) {
            onFailure = this.defaultFailedCallback;
        } else if (this.servicespace.defaultFailedCallback != null) {
            onFailure = this.servicespace.defaultFailedCallback;
        }

        if (this.defaultSuccessCallback != null) {
            onSuccess = this.defaultSuccessCallback;
        } else if (this.servicespace.defaultSuccessCallback != null) {
            onSuccess = this.servicespace.defaultSuccessCallback;
        }

        // convert arguments to real array
        var args = Array.prototype.slice.call(arguments);

        args.each(function(item, idx, arr) {

            // get data key
            var dataKey = this.options.submissionTemplate[idx];

            // do some filtering
            switch (dataKey) {
                case "onSuccess":
                    if ($type(item) == "function") onSuccess = item;
                    break;
                case "onFailure":
                    if ($type(item) == "function") onFailure = item;
                    break;
                case "userContext":
                    context = item;
                    break;
                default:
                    // add to data object
                    data.set(dataKey, item);
                    break;
            }

        }, this);

        // attempting to do some trickery to overcome IE sometimes cacheing
        if (this.options.noCache) data.set('noCache', new Date().getTime());

        // setup XHR

        var XHR = this.generate_XHR_Object();
        var options = this.generate_XHR_Options(data.getClean(), onSuccess, onFailure, context, XHR);

        XHR.setOptions(options);

        //if (typeof (onInvoke) === "function") {
        //onInvoke(this.servicespace, this);
        //}

        // send off to the service
        XHR.send();

    },

    /*************************************** 
    *  PROXY OBJECT
    *  basically a storage object
    *  that acts like a bridge between
    *  service manager and server response
    ****************************************/

    proxy: new Class({

        refObj: null, // reference to service method instance

        xhr: null,

        bridge: {
            success: null, // success reference
            failure: null  // failure reference
        },

        context: null, // placeholder for context

        response: null, // placeholder for response

        initialize: function(process) {
            this.bridge.success = process.onSuccess;
            this.bridge.failure = process.onFailure;
            //console.log('wassup ninja');
        },

        proxy_SUCCESS: function() {
            //console.log(arguments);
            //console.log(this.xhr);
            this.response = arguments;
            this.refObj.process_SUCCESS(this);
        },

        proxy_FAILURE: function(response) {
            this.response = response;
            this.refObj.process_FAILURE(this);
        },

        get_webRequest: function() {
            return this.refObj;
        },

        get_statusCode: function() {
            return this.xhr.status;
        }

    }),


    /********************************* 
    *  PROCESS FUNCTIONS
    **********************************/

    process_SUCCESS: function(proxy) {

        // this is to emulate MS Ajax functionality
        // this has to be called before calling callback
        if (typeof (onComplete) === "function") {
            onComplete(proxy, this);
        }

        // now pass response to callback
        proxy.bridge.success(this.parse_XHR_ResponseSuccess(proxy.response), proxy.context, this.name);


        delete proxy;

    },

    process_FAILURE: function(proxy) {

        // this is to emulate MS Ajax functionality
        // this has to be called before calling callback
        if (typeof (onComplete) === "function") {
            onComplete(proxy, this);
        }

        // now pass response to callback
        proxy.bridge.failure(this.parse_XHR_ResponseFailure(proxy.response), proxy.context, this.name);

        delete proxy;
    },

    /********************************* 
    *  HELPER FUNCTIONS
    **********************************/

    // parse the response Success
    // success sends back an array generally
    parse_XHR_ResponseSuccess: function(resp) {
        switch (this.options.responseType) {
            case "JSON":
                var data = (resp.length) ? resp[0] : resp;
                var response = JSON.decode(data);

                if (response.hasOwnProperty('d')) response = response.d;
                // return the response
                return response;
                break;
            case "HTML":
                return resp[3];
                break;
            default:
                return resp[0];
                break;
        }
    },

    // parse the response Failure
    // failure sends back an object
    // should check all failure responses
    parse_XHR_ResponseFailure: function(resp) {
        console.log(resp);
        switch (this.options.responseType) {
            case "JSON":
                var response = this.convert_XHR_JSONResponseFailure(resp);
                return response;
                break;
            case "HTML":
                return resp.responseText;
                break;
            default:
                return resp.responseXML;
                break;
        }
    },

    // convert response failure object to standard error output
    // this is purely to emulate what happens now
    convert_XHR_JSONResponseFailure: function(resp) {
        var returnData = {
            "_exceptionType": null,
            "_message": null,
            "_stackTrace": null,
            "_statusCode": null,
            "_statusMessage": null,
            "_timedOut": false
        };
        if(resp && resp.responseText) {
            var data = JSON.decode(resp.responseText);
            returnData._exceptionType = data.ExceptionType;
            returnData._message = data.Message;
            returnData._stackTrace = data.StackTrace;
            returnData._timedOut = (data.TimedOut) ? true : false;
        }
        if(resp && resp.status && resp.statusText) {
            returnData._statusCode = resp.status;
            returnData._statusMessage = resp.statusText;
        }
        return returnData;
    },

    // do all the fancy options setup
    generate_XHR_Options: function(data, onSuccess, onFailure, context, xhr) {

        // setup options object
        var xhr_options = {};
        xhr_options.async = this.options.async;
        xhr_options.method = this.options.method;
        xhr_options.url = this.get_path();
        xhr_options.data = this.generate_XHR_DataObject(data);
        xhr_options.urlEncoded = false;

        // store bridge references
        var process = {};
        process.onSuccess = (onSuccess != null && !this.options.sendOnly) ? onSuccess : this.servicespace.onSuccess;
        process.onFailure = (onFailure != null) ? onFailure : this.servicespace.onFailure;

        // setup proxy reference object
        var proxy = new this.proxy(process);
        proxy.refObj = this; // store reference to method instance in proxy object
        proxy.xhr = xhr;
        if (context != null) {
            // store context if its not null
            proxy.context = context;
        } else {
            // else, store the service method default context, and if not that then try the servicespace default context
            proxy.context = (this.defaultUserContext != null) ? this.defaultUserContext : this.servicespace.defaultUserContext;
        }

        // setup service success and failure methods, bound to proxy object
        xhr_options.onSuccess = proxy.proxy_SUCCESS.bind(proxy);
        xhr_options.onFailure = proxy.proxy_FAILURE.bind(proxy);

        if (typeof (onInvoke) === "function") {
            xhr_options.onRequest = function(service, method) { onInvoke(service, method); } .pass([this.servicespace, this]);
        }

        return xhr_options;

    },

    // a smarter data object
    generate_XHR_DataObject: function(data) {
        switch (this.options.responseType) {
            case "JSON":
                return JSON.encode(data);
                break;
            default:
                return data;
                break;
        }

    },

    // generate the XHR object
    generate_XHR_Object: function(options) {
        switch (this.options.responseType) {
            case "JSON":
                var req = new Request(options);
                req.setHeader('Content-Type', 'application/json; charset=utf-8');
                return req;
                break;
            case "HTML":
                return new Request.HTML(options);
                break;
            default:
                return new Request(options);
                break;
        }

    },

    // generate the service URL
    get_path: function() {
        var url = this.servicespace.get_path() + '/' + this.name;
        return url;
    },

    set_defaultUserContext: function(objRef) {
        this.defaultUserContext = objRef;
    },

    get_defaultUserContext: function() {
        return this.defaultUserContext;
    },

    set_defaultFailedCallback: function(obj) {
        this.defaultFailedCallback = obj;
    },

    get_defaultFailedCallback: function() {
        return this.defaultFailedCallback;
    },

    set_defaultSuccessCallback: function(obj) {
        this.defaultSuccessCallback = obj;
    },

    get_defaultSuccessCallback: function() {
        return this.defaultSuccessCallback;
    },

    /*
    set_webRequest: function(request) {
    this.__webRequest = request;
    },
    */

    get_request: function() {
        return this;
    },

    get_webRequest: function() {
        return this;
    },

    get_url: function() {
        return this.get_path();
    },

    get_self: function() {
        return this;
    },

    set_body: function(value) {
        // black hole for now
    }




});


/*

CorbisUI.ServiceManager.defineService('Registration.SignInStatus.SignInState',{fetchOnly: true, async: false, responseType: "XML"});
CorbisUI.ServiceManager.Registration.SignInStatus.SignInState(); // call service


CorbisUI.ServiceManager.defineService('Search.SearchScriptService.GetCartMediaUidList',{sendOnly: true});
CorbisUI.ServiceManager.Search.SearchScriptService.GetCartMediaUidList(); // call service


// complicated examples

CorbisUI.ServiceManager.defineService('Search.SearchScriptService.AddSearchItemToLightboxNew',{
    submissionTemplate: [ "corbisId", "mediaUid", "lightboxId" ]
});
// call service
CorbisUI.ServiceManager.Search.SearchScriptService.AddSearchItemToLightboxNew("42-17690208", "df4c5d72-1d72-4fb5-9653-5d850be25465", "7802003", CorbisUI.Handlers.Lightbox.addToResponseNew, CorbisUI.MethodFailed);
CorbisUI.ServiceManager.Search.SearchScriptService.AddSearchItemToLightboxNew("42-17690208", "df4c5d72-1d72-4fb5-9653-5d850be25465", "7802003", CorbisUI.Handlers.Lightbox.addToResponseNew, CorbisUI.Handlers.Lightbox.methodFailed);

// original call
Corbis.Web.UI.Search.SearchScriptService.AddSearchItemToLightboxNew("42-17690208", "df4c5d72-1d72-4fb5-9653-5d850be25465", "7802003", CorbisUI.Handlers.Lightbox.addToResponseNew, CorbisUI.MethodFailed);

CorbisUI.ServiceManager.defineService('Search.SearchScriptService.DeleteProductFromLightbox',{
    submissionTemplate: [ "lightboxId", "productUid" ]
});
// call service
CorbisUI.ServiceManager.Search.SearchScriptService.DeleteProductFromLightbox("7802003", "df4c5d72-1d72-4fb5-9653-5d850be25465");

CorbisUI.ServiceManager.defineService('Search.SearchScriptService.GetLightBoxItemsV2',{
    submissionTemplate: [ "lightboxId" ]
});
// call service
CorbisUI.ServiceManager.Search.SearchScriptService.GetLightBoxItemsV2("7802003", CorbisUI.Handlers.Lightbox.getLightboxItemsResponse, CorbisUI.Handlers.Lightbox.methodFailed);

*/

//End: /Scripts/CorbisUI.ServiceManager.js
//Begin: /Scripts/CorbisUI.MethodFailed.js

/****************************************************
    Corbis UI Method failed
***************************************************/

/* GENERIC METHOD FAILED FUNCTION 
*
* This arose out of a need to see more
* error details. You can use this or your
* custom methodFailed function.
*
* Example of usage:
 
function AddToCart(corbisId) {
var cartItem = $(parent.document).getElement('span.corbisID[text=' + corbisId + ']').getParent().getParent().retrieve('objectReference');
        
// args to pass is optional. This is additional info to what the service failure provides.
// args within methodArgs have to be preceeded with underscore '_'
var argsToPass = {
methodArgs: {
_script: 'Cart.js',
_method: 'CorbisUI.Cart.Handler.moveItemToPriced',
_corbisId: corbisId
}
};
// if not using argsToPass, then don't need next line
CorbisUI.MethodFailed.bind(argsToPass);
Corbis.Web.UI.Checkout.CartScriptService.GetPricedPricingDisplay(cartItem.productUID, CorbisUI.Cart.Handler.GetPricedPricingDisplayCallback, CorbisUI.MethodFailed, cartItem);
}
    
*
**********************************************************/

CorbisUI.MethodFailed = function(results, context, methodName) {
    if (Browser.getHost().contains('.pre') && CorbisUI.debug) {

        //console.log(context.toSource());
        //console.log(this.methodArgs);

        var BGColor1 = '#eeeeee';
        var BGColor2 = '#fafafa';
        var FONTcolor1 = 'brown';
        var FONTcolor2 = 'green';
        var alternateBG;
        var alternateFont;

        var title = (self.name == '') ? 'METHOD FAILED: Console' : 'METHOD FAILED: Console_' + self.name;

        var _debug_console = window.open("", "METHOD FAILED", "width=680,height=600,resizable,scrollbars=yes");

        _debug_console.document.write("<HTML><TITLE>" + title + "</TITLE><BODY bgcolor=#ffffff>");

        _debug_console.document.write("<table border=0 width=100%>");
        _debug_console.document.write("<tr bgcolor=#cccccc><th colspan=2>MONARCH Method Failure Debug Console</th></tr>");
        _debug_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>Method Name:</b></td></tr>");
        _debug_console.document.write("<tr bgcolor=" + BGColor1 + "><td colspan=2><font color='" + FONTcolor1 + "'>" + methodName + "</font></td></tr>");

        if (this.methodArgs) {
            _debug_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>Method Args:</b></td></tr>");

            for (name in this.methodArgs) {

                if (name != '_stackTrace' && name.substr(0, 1) == "_") {
                    alternateBG = (alternateBG == BGColor1) ? BGColor2 : BGColor1;
                    alternateFont = (alternateFont == FONTcolor1) ? FONTcolor2 : FONTcolor1;
                    _debug_console.document.write("<tr bgcolor='" + alternateBG + "'>");
                    _debug_console.document.write("<td align='right' width='15%' style='color:" + alternateFont + ";'>");
                    _debug_console.document.write("<b style=\"font-weight: bold;\">" + name + "</b>");
                    _debug_console.document.write("</td>");
                    _debug_console.document.write("<td align='left' style='padding-left: 10px; color:" + alternateFont + ";'>");
                    _debug_console.document.write(this.methodArgs[name]);
                    _debug_console.document.write("</td>");
                    _debug_console.document.write("</tr>");
                }
            }
            alternateBG = BGColor1;
        }

        _debug_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>Result Data:</b></td></tr>");

        for (name in results) {

            if (name != '_stackTrace' && name.substr(0, 1) == "_") {
                alternateBG = (alternateBG == BGColor1) ? BGColor2 : BGColor1;
                alternateFont = (alternateFont == FONTcolor1) ? FONTcolor2 : FONTcolor1;
                _debug_console.document.write("<tr bgcolor='" + alternateBG + "'>");
                _debug_console.document.write("<td align='right' width='15%' style='color:" + alternateFont + ";'>");
                _debug_console.document.write("<b style=\"font-weight: bold;\">" + name + "</b>");
                _debug_console.document.write("</td>");
                _debug_console.document.write("<td align='left' style='padding-left: 10px; color:" + alternateFont + ";'>");
                _debug_console.document.write(results[name]);
                _debug_console.document.write("</td>");
                _debug_console.document.write("</tr>");
            }
        }

        if (results._stackTrace) {
            _debug_console.document.write("<tr bgcolor=#cccccc><th colspan=2>STACKTRACE</th></tr>");
            _debug_console.document.write("<tr bgcolor=#cccccc><td colspan=2><textarea style='width: 100%; height: 350px;'>" + results._stackTrace + "</textarea></td></tr>");
        }

        _debug_console.document.write("</table>");
        _debug_console.document.write("</BODY></HTML>");
        _debug_console.document.close();
    } else {
        alert('ERROR [' + methodName + '] : ' + results._message);
    }
}
// alias methodFailed to CorbisUI.MethodFailed
methodFailed = CorbisUI.MethodFailed;


//End: /Scripts/CorbisUI.MethodFailed.js
//Begin: /Scripts/CorbisUI.Auth.js

/****************************************************
    Corbis UI Auth
***************************************************/

// * CorbisUI.Auth Namespace
// * Provides authentication methods for site
// * TravisO

CorbisUI.Auth = {
    ActionTypes: {
        Reload: 'reload',
        ReturnUrl: 'returnUrl',
        Execute: 'execute',
        None: 'none'
    },

    SignInLevels: {
        None: -1,
        Anonymous: 0,
        AutoLoggedIn: 1,
        LoggedIn: 2
    },

    currentSignInLevel: null,

    OpenSSLSignIn: function(actionType, actionArg) {
        var signIn = HttpsUrl + '/Registration/SignIn.aspx?' + actionType + "=" + escape(actionArg);
        if (window.location.protocol == 'https:') {
            signIn += '&protocol=https';
        }
        var dlgWidth = 650;
        var g_firefox = document.getElementById && !document.all;
        if (g_firefox) {
            OpenNewIModal(signIn, dlgWidth, 170, 'secureSignIn');
            if (window.location.protocol != 'https:') {
                // Firefox bug:  Sometimes the iFrame doesn't load.  Attach an onload event to this to check; wait 5 seconds for load
                setTimeout('CorbisUI.Auth.FirefoxLoadCheck()', 3000);
            }
        } else {
            OpenNewIModal(signIn, dlgWidth, 170, 'secureSignIn');
        }
    },

    GetSignInLevel: function() {
        var returnValue = 0;
        
        var req = new Request({
            async: false,
            method: 'post',
            url: "/my-account/SignInState",
            onSuccess: function(state) {
                CorbisUI.Auth.currentSignInLevel = parseInt(state);
            }
        }).send();
        
        return CorbisUI.Auth.currentSignInLevel;
    },

    Check: function(signInLevel, actionType, actionArg) {
        if (signInLevel == null) { signInLevel = this.SignInLevels.LoggedIn; }
        if (actionType == null) { actionType = this.ActionTypes.Reload; }
        var currentSignInLevel = this.GetSignInLevel();
        if (currentSignInLevel < signInLevel) {
            this.OpenSSLSignIn(actionType, actionArg);
        } else {
            switch (actionType) {
                case this.ActionTypes.Reload:
                    window.location = window.location;
                    break;
                case this.ActionTypes.ReturnUrl:
                    window.location = actionArg;
                    break;
                case this.ActionTypes.Execute:
                    eval(actionArg);
                    break;
            }
        }
    },

    Go: function(url) {
        if (window.opener) {
            window.opener.location = url;
            window.close();
        } else {
            parent.window.location = url;
            window.location = url;
        }
    },

    FirefoxLoadCheck: function() {
        try {
            // if loaded, this code will return an error since it can't get to the document in an SSL iFrame
            var oIframe = document.getElementById("secureSignInWindow_iframe");
            var oDoc = oIframe.contentWindow || oIframe.contentDocument;
            if (oDoc.document) {
                oDoc = oDoc.document;
            }
            oDoc.body.style.backgroundColor = oDoc.body.style.backgroundColor;
            oIframe.src = oIframe.src + "#";
            // if opening page is loading under https, this won't throw an error.
            if (window.location.protocol != 'https:') {
                setTimeout('CorbisUI.Auth.FirefoxLoadCheck()', 3000);
            }
        } catch (e)
        { }
    },

    SetErrorStyle: function(height) {
        var windowId = 'secureSignIn';
        ResizeIModal(windowId, height);
    },
    SetErrorStyleXY: function(w, h) {
        var windowId = 'secureSignIn';
        ResizeIModalXY(windowId, w, h);
    }
}

CorbisUI.Auth.currentSignInLevel = CorbisUI.Auth.SignInLevels.None;
//End: /Scripts/CorbisUI.Auth.js
//Begin: /Scripts/CorbisUI.GlobalNav.js

/****************************************************
Corbis UI Global Nav
***************************************************/

CorbisUI.GlobalNav = {
    ShowLanguages: function(show) {
        var div = $('languageSelectorMenu');
        var divBottom = $$('#languageSelectorMenu .LanguageMenuBottom');
        var divDropShadow = $('languageSelectorMenuDropShadow');

        if (show) {
            if (div) {
                div.setStyle('display', 'block');
                var coords = divBottom[0].getCoordinates();
                if (divDropShadow) {
                    divDropShadow.setStyle('display', 'block');
                    divDropShadow.setStyle('position', 'absolute');
                    divDropShadow.setStyle('right', 14);
                    divDropShadow.setStyle('top', 36);
                    divDropShadow.setStyle('width', coords.width);
                    divDropShadow.setStyle('height', coords.height);
                }
            }
        } else {
            div.setStyle('display', 'none');
            divDropShadow.setStyle('display', 'none');
        }
    },
    SetupBrowseNav: function() {


        //Find the 'Motion' link in dropdown and turn it white
        if ($('dropDownMenuDiv') != null) {
            var spanList = $('dropDownMenuDiv').getElements('span');
            spanList.each(function(el) {

                if (el.id.indexOf('Creative') >= 0) {
                    var theLink = el.getParent().getParent();
                    theLink.href = "javascript:void(0);";
                    theLink.setStyle('cursor', 'default');
                    theLink.addEvents('click', function() { return false; });
                }
                if (el.id.indexOf('Editorial') >= 0) {
                    var theLink = el.getParent().getParent();
                    theLink.href = "javascript:void(0);";
                    theLink.setStyle('cursor', 'default');
                    theLink.addEvents('click', function() { return false; });
                }
                if (el.id.indexOf('Motion') >= 0) {
                    var theLink = el.getParent().getParent();
                    theLink.setProperty('target', '_blank');
                    theLink.href = "http://www.corbismotion.com?cid=browse";
                    el.setStyle('color', 'white');
                    el.getParent().getParent().addEvent('mouseover', function() {
                        el.getParent().getParent().getParent().addClass('MotionHover');
                    });
                    el.getParent().getParent().addEvent('mouseout', function() {
                        el.getParent().getParent().getParent().removeClass('MotionHover');
                    });
                }

            });
        }
    },
    ChangeMotionLinkColor: function() {

    },
    RefreshSignInStatus: function() {
        var SignInStatusReq = new Request({
            method: 'post',
            url: '/src/Authentication/SignInStatusRefresh.aspx',
            onSuccess: function(response) {
                if ($('SignInStatus')) {
                    $('SignInStatus').set('html', response);
                }
                if (window.opener) {
                    try {
                        var openerDocument = $(window.opener.document);
                        var signInStatus = openerDocument.getElement('#SignInStatus');
                        if (signInStatus) {
                            signInStatus.set('html', response);
                        }
                    }
                    catch (e) { }
                }
            }
        }).send();
    },
    RefreshCartStatus: function(gotoCart) {
        new Request({
            method: 'post',
            url: '/src/Navigation/CheckoutControlRefresh.aspx',
            onSuccess: function(response) {
                if ($('CheckoutWidget')) {
                    $('CheckoutWidget').set('html', response);
                }
                if (gotoCart) {
                    GoToCart();
                }
                else {
                    if (window.opener) {
                        try {
                            var openerDocument = $(window.opener.document);
                            var checkoutWidget = openerDocument.getElement('#CheckoutWidget');
                            if (checkoutWidget) {
                                checkoutWidget.set('html', response);
                            }
                        }
                        catch (e) { }
                    }
                }
            }
        }).send();
    },
    RefreshGlobalNav: function() {
        this.RefreshSignInStatus();
        this.RefreshCartStatus();
        try {
            // Bubble up to any parent windows
            if (parent.window.location != window.location) {
                parent.CorbisUI.GlobalNav.RefreshGlobalNav();
            }
        } catch (ex) { }
    },
    SessionTimedOut: function() {
        MochaUI.Windows.instances.each(function(instance) {
            MochaUI.CloseModal(instance.options.id.replace("Window", ""));
        });
        OpenModal('sessionTimeout');
    }
};



CorbisUI.GlobalNav.BrowseMenus = {

    menu: {
        creative: ['BrowseCreativeTitle', 'dropDownMenuCreativeDivWindow'],
        editorial: ['BrowseEditorialTitle', 'dropDownMenuEditorialDivWindow']
    },

    mouseOverCreative: false,
    mouseOverEditorial: false,

    create: function(contentElement) {
        var id = contentElement + 'Window';
        var el = $(contentElement);

        el.setStyle('display', 'block');
        var elDimensions = el.getCoordinates();

        var properties = {
            title: '',
            collapsible: false,
            minimizable: false,
            bodyBgColor: [68, 68, 68],
            headerStartColor: [68, 68, 68],
            headerStopColor: [68, 68, 68],
            useCanvasControls: false,
            cornerRadius: 6,
            headerHeight: 4,
            footerHeight: 4,
            padding: 0,
            scrollbars: false,
            closable: false,
            type: 'window',
            id: el.getProperty('id') + "Window",
            height: elDimensions.height,
            width: elDimensions.width,
            x: elDimensions.left - 15,
            y: elDimensions.top + 10,
            content: '',
            draggable: false,
            resizable: false,
            shadowBlur: 2
        };

        MochaUI.NewWindowFromDiv(el, properties);
        $(id + '_titleBar').setStyle('background', 'transparent');
        $(id + '_contentWrapper').setStyle('background', 'transparent');

        $(id).setStyle('display', 'none');
    },

    wire: function() {

        this.create('dropDownMenuCreativeDiv');
        this.create('dropDownMenuEditorialDiv');

        var self = this;

        this.menu.creative.each(function(element) {
            $(element).addEvent('mouseenter', function() {
                setTimeout('CorbisUI.GlobalNav.BrowseMenus.show("dropDownMenuCreativeDiv")', 250);
                CorbisUI.GlobalNav.BrowseMenus.mouseOverCreative = true;
            });
            $(element).addEvent('mouseleave', function() {
                setTimeout('CorbisUI.GlobalNav.BrowseMenus.hide("dropDownMenuCreativeDiv")', 250);
                CorbisUI.GlobalNav.BrowseMenus.mouseOverCreative = false;
            });
        });

        this.menu.editorial.each(function(element) {
            $(element).addEvent('mouseenter', function() {
                setTimeout('CorbisUI.GlobalNav.BrowseMenus.show("dropDownMenuEditorialDiv")', 250);
                CorbisUI.GlobalNav.BrowseMenus.mouseOverEditorial = true;
            });
            $(element).addEvent('mouseleave', function() {
                setTimeout('CorbisUI.GlobalNav.BrowseMenus.hide("dropDownMenuEditorialDiv")', 250);
                CorbisUI.GlobalNav.BrowseMenus.mouseOverEditorial = false;
            });
        });
    },

    show: function(menu) {
        var creative = menu.contains('Creative');

        if (creative && !this.mouseOverCreative) {
            return;
        }
        else if (!creative && !this.mouseOverEditorial) {
            return;
        }

        var leftTab = creative ? 'leftCreativeMenuTab' : 'leftEditorialMenuTab';
        var rightTab = creative ? 'rightCreativeMenuTab' : 'rightEditorialMenuTab';
        var middle = creative ? 'BrowseCreativeTitle' : 'BrowseEditorialTitle';

        $(middle).setStyle('background', 'url(/Images/menu-tab-middle.png) repeat-x 0px -5px');

        if (Browser.Engine.trident4) {
            $(leftTab).setStyle('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src="/Images/menu-tab-left.png", sizingMethod="scale")');
            $(leftTab).setStyle('position', 'relative');
            $(leftTab).setStyle('top', '-4px');
            $(rightTab).setStyle('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src="/Images/menu-tab-right.png", sizingMethod="scale")');
            $(rightTab).setStyle('position', 'relative');
            $(rightTab).setStyle('top', '-4px');
        }
        else {
            $(leftTab).setStyle('background', 'url(/Images/menu-tab-left.png) 0px -5px');
            $(rightTab).setStyle('background', 'url(/Images/menu-tab-right.png) -5px -5px');
        }

        var modal = $(menu + 'Window');

        if (Browser.Engine.trident4) {
            var coords = creative ? $('leftCreativeMenuTab').getCoordinates() : $('leftEditorialMenuTab').getCoordinates();
        
            modal.setStyle('left', coords.left + 2);
            modal.setStyle('top', coords.top + 39);
        }

        modal.setStyle('display', 'block');
        // Make sure it shows in front of MSO layer
        modal.setStyle('z-index', '999998');
    },

    hide: function(menu) {

        var creative = menu.contains('Creative');

        if (creative && this.mouseOverCreative) {
            return;
        }
        else if (!creative && this.mouseOverEditorial) {
            return;
        }

        var modal = $(menu + 'Window');
        modal.setStyle('display', 'none');

        var leftTab = creative ? 'leftCreativeMenuTab' : 'leftEditorialMenuTab';
        var rightTab = creative ? 'rightCreativeMenuTab' : 'rightEditorialMenuTab';
        var middle = creative ? 'BrowseCreativeTitle' : 'BrowseEditorialTitle';

        $(middle).setStyle('background', '');

        if (Browser.Engine.trident4) {
            $(leftTab).setStyle('filter', '');
            $(leftTab).setStyle('position', '');
            $(leftTab).setStyle('top', '');
            $(rightTab).setStyle('filter', '');
            $(rightTab).setStyle('position', '');
            $(rightTab).setStyle('top', '');
        }
        else {
            $(leftTab).setStyle('background', '');
            $(rightTab).setStyle('background', '');
        }
    }
};

window.addEvent('domready', function() {
    if ($('BrowseCreativeTitle')) {
        CorbisUI.GlobalNav.BrowseMenus.wire(); 
    }
});

//End: /Scripts/CorbisUI.GlobalNav.js
//Begin: /Scripts/CorbisUI.ImageGroups.js

/****************************************************
    Corbis UI Image Groups
***************************************************/


CorbisUI.ImageGroups = {
    vars: {
        parentElement: null,
        ele: null,
        imageEle: null,
        products: null,
        icon: null,
        capContainer: null,
        prodBlock: null,
        emptydiv: null,
        productResults: null
    },

    initialize: function() {
        this.vars.parentElement = $('SearchColumnedContent');
        this.vars.ele = this.vars.parentElement.getElement('.hideCaptionWrapper');
        this.vars.imageEle = this.vars.parentElement.getElement('.captionBtnHide');
        this.vars.products = $('ProductResults');
        this.vars.icon = $('captionIconHideDiv');
        this.vars.capContainer = $('captionContainer');
        this.vars.prodBlock = $('productBlock');
        this.vars.emptydiv = $('emptyDiv');
    },

    addToCart: function(corbisId) {
        this.initialize();

        if (CorbisUI.Auth.GetSignInLevel() < CorbisUI.Auth.SignInLevels.AutoLoggedIn) {
            CorbisUI.Auth.Check(CorbisUI.Auth.SignInLevels.AutoLoggedIn, CorbisUI.Auth.ActionTypes.Execute, "CorbisUI.ImageGroups.addToCart('" + corbisId + "')");
        } else {
            /*
            var product = this.vars.products.getElement('span[corbisid=' + corbisId + ']');
            if (product) {
            (new CorbisUI.SearchModels.ProductBlock(product)).addProductToCart();
            }
            */
            CorbisUI.Handlers.Cart.addProductToCart(corbisId);
        }
    },

    toggleCaption: function() {
        this.initialize();

        if (this.vars.ele.getStyle('visibility') == 'visible' || this.vars.ele.getStyle('display') == 'block') {

            $('HideCaptionBody').fade('out');
            var myEffect = new Fx.Morph(this.vars.ele, { duration: 'short', transition: Fx.Transitions.Sine.easeOut });

            myEffect.start({
                'height': [505, 1],
                'visibility': 'hidden' //Morphs the 'height' style from 505px to 0px.
            });

            this.vars.icon.setProperty('class', 'captionIconShow');
            this.vars.imageEle.getElement('.labelDivShow').removeClass('displayNone');
            this.vars.imageEle.getElement('.labelDivHide').addClass('displayNone');
            this.vars.ele.setStyles({ 'float': 'right', 'display': 'inline-block' });
            this.vars.products.getElement('.hideCaptionWrapper').addClass('displayNone');
            //this.vars.capContainer.setStyles({ marginTop: '0px', marginBottom: '0px' });
            if (this.vars.emptydiv != null) {
                if (Browser.Engine.trident)
                    this.vars.emptydiv.setStyle('height', 0);
                else
                    this.vars.emptydiv.setStyle('height', 30);
            }
            this.vars.products.setStyles({
                'float': 'left',
                'marginTop': 5,
                'minHeight': 450,
                'fontSize': 10,
                'fontWeight': 'bold',
                'marginRight': 0,
                'display': 'inline-block'
            });
            if (this.vars.prodBlock != null) {
                this.vars.products.getElement('.productBlock').setStyle('padding', '3px');
            }

        }


        if ($('HideCaptionBody').getStyle('visibility') == 'hidden') {

            $('HideCaptionBody').fade('in');
            var myEffect = new Fx.Morph(this.vars.ele, { duration: 'short', transition: Fx.Transitions.Sine.easeIn });

            myEffect.start({
                'height': [505], //Morphs the 'height' style from the current to  505px.
                'visibility': 'visible'
            });

            this.vars.icon.setProperty('class', 'captionIconHide');
            this.vars.imageEle.getElement('.labelDivHide').removeClass('displayNone');
            this.vars.imageEle.getElement('.labelDivShow').addClass('displayNone');
            this.vars.products.getElement('.hideCaptionWrapper').removeClass('displayNone');
            //this.vars.capContainer.setStyles({ marginTop: '0px', marginBottom: '0px' });
            if (this.vars.emptydiv != null) {
                if (Browser.Engine.trident)
                    this.vars.emptydiv.setStyle('height', 0);
                else
                    this.vars.emptydiv.setStyle('height', 30);
            }
            this.vars.products.setStyles({
                'float': 'left',
                'marginTop': 5,
                'minHeight': 450,
                'fontSize': 10,
                'fontWeight': 'bold',
                'marginRight': 140
            });
            if (this.vars.prodBlock != null) {
                this.vars.products.getElement('.productBlock').setStyle('padding', '20px 5px 0 0');
            }
        }
    }
}

var captionMover = new Class({
    defaultTop: null,
    initialize: function() {
        window.addEvent('resize', this.resizingEvent.bindWithEvent(this));
        window.addEvent('domready', this.resizingEvent.bindWithEvent(this));
    },

    resizingEvent: function() {
        var productBlock = $('ProductResults');
        var productBlockCoord = productBlock.getCoordinates();
        if (productBlock.getElement('.hideCaptionWrapper')) {
            var CD = productBlock.getElement('.hideCaptionWrapper');
            var CDc = CD.getCoordinates();

            var rightmargin = productBlockCoord.width % 189;
            //console.log(rightmargin);
            if (Browser.Engine.trident) {
                if (rightmargin > 168) {
                    // make an adjustment when the rightmargin calculation was between 180 and 189. why?? idunno
                    CD.setStyle('margin-right', rightmargin - 171 + 11);
                }
                else {
                    CD.setStyle('margin-right', rightmargin + 27);
                }
            }
            else {
                if (rightmargin > 180) {
                    // make an adjustment when the rightmargin calculation was between 180 and 189. why?? idunno
                    CD.setStyle('margin-right', rightmargin - 171);
                }
                else {
                    CD.setStyle('margin-right', rightmargin + 16);
                }
            }
        }
    }
});



//End: /Scripts/CorbisUI.ImageGroups.js
//Begin: /Scripts/CorbisUI.ExpressCheckout.js

/****************************************************
    Corbis UI Express Checkout
***************************************************/

// Express Checkout
// Putting this here due to the number of calls needed to the parent page
// Travis O
var cvcHadFocus = false;
CorbisUI.ExpressCheckout = {
    vars: {
        DateFormat: null,
        DateSeparator: null,
        licenseDateAlreadyUpdated: false,
        IsDirty: null,
        OriginalProjectName: null,
        RequiredText: null,
        ProjectField: null,
        JobField: null,
        PurchaseOrderField: null,
        LicenseeField: null,
        ASCCompliant: null,
        LicenseType: null,
        PriceLabel: null,
        PriceCode: null,
        HidAttributeUID: null,
        HidAttributeValueUID: null,
        HidProductUid: null,
        PaymentMethodBox: null,
        ThePaymentMethodId: null,
        ThePaymentType: null,
        CardExpired: null,
        MyPricingList: null,
        ThumbTips: null,
        SavedUsageDropdown: null,
        FavoriteUseLabel: null,
        LicenseDetails: null,
        CorbisID: null,
        AjaxLoader: null,
        AjaxUpdater: null,
        AjaxMessage: null,
        SavedUseTitle: null,
        SavedUseValue: null,
        SavedUsageText: null,
        SavedUsageTruncated: null,
        PricedStartDateTextBox: null,
        PricedByAEStartDateTextBox: null,
        AlreadyPricedTextBox: null,
        DefaultDate: null,
        ImageThumbnail: null,
        ContractType: null,
        PromoCodeBox: null,
        LoadPricingText: null,
        LoadLicensingText: null,
        PurchaseButton: null,
        //  CreditCardCVC: null,
        LightboxId: 0,
        HidPaymentMethod: null,
        CorporateID: null,
        CreditCardUID: null,
        PriceCodeDiv: null,
        TotalCodeDiv: null,
        TotalPrice: null

    },
    //    FixValidationCodeCursor: function(over, elem) {
    //        if ((document.activeElement.id && document.activeElement.id == CorbisUI.ExpressCheckout.vars.CreditCardCVC.get('id'))) {
    //            cvcHadFocus = true;
    //            if (over) {
    //                CorbisUI.ExpressCheckout.vars.CreditCardCVC.blur();
    //                return;
    //            }
    //        }
    //        if (cvcHadFocus) {
    //            CorbisUI.ExpressCheckout.vars.CreditCardCVC.focus();
    //            cvcHadFocus = false;
    //        }
    //    },
    registerTooltips: function(isFirstTime) {
        $('aspnetForm').getAllNext('.TIP-license-details').destroy();
        var tipShowDelay = 500;
        var tipHideDelay = 100;
        var tipShowMethod = "in";
        var tipHideMethod = "out";
        if (Browser.Engine.trident) {
            tipShowDelay = 0;
            tipHideDelay = 0;
            tipShowMethod = "show";
            tipHideMethod = "hide";
        }
        this.vars.ThumbTips = new Tips('.thumbWrap', {
            showDelay: tipShowDelay,
            hideDelay: tipHideDelay,
            offsets: { x: -340, y: -130 },
            className: 'TIP-license-details mochaContent',
            onHide: function(tip) {
                tip.fade(tipHideMethod);
            },
            onShow: function(tip) {
                tip.fade(tipShowMethod);
            }
        });
    },

    Resize: function() {
        if (Browser.Engine.trident) { IEAddHeight = "10"; } else { IEAddHeight = 0; }

        var iFrames = $$('iframe');
        var iDo = iFrames[0];
        iDo.src = CorbisUI.ExpressCheckout.getParentProtocolBasedURL() + "/Common/IFrameTunnel.aspx?windowid=expressCheckout&action=execute&actionArg=ResizeIModal('expressCheckout'," + (parseInt(GetDocumentHeight()) + parseInt(IEAddHeight)) + ")&noclose=true";
    },

    setupRFRepeater: function() {
        var delay = 0;
        if (Browser.Engine.trident) delay = 400;

        if (this.vars.HidAttributeValueUID.value != null && this.vars.HidAttributeValueUID.value != "") {
            var rowFlag = this.vars.HidAttributeValueUID.value;
            (function() {

                var parrent = $('repeaterInnerDiv').getElement("input[value=" + rowFlag + "]");
                if (parrent) {
                    parrent = parrent.getNext('ul');
                    var savedRow = parrent.getParent();
                    savedRow.setStyle('color', 'black');
                    savedRow.setStyle('cursor', 'pointer');
                    CorbisUI.ExpressCheckout.vars.MyPricingList.pricingListClick(parrent);
                    CorbisUI.ExpressCheckout.vars.DataChanged = false;
                }
            }).delay(delay);
        };

    },


    lockStep2: function() {
        //console.log('lock step 2');
        $$('.selectUse')[0].set('opacity', .66);
        $$('.selectUse .mask')[0].setStyle('display', '');
    },

    unlockStep2: function() {
        //console.log('unlockStep2');
        $$('.selectUse')[0].set('opacity', 1);
        $$('.selectUse .mask')[0].setStyle('display', 'none');
    },

    lockStep3: function() {
        //console.log('lock step 3');
        this.lockPromoButton();
        $$('.purchaseInfo')[0].set('opacity', .66);
        $$('.purchaseInfo .mask')[0].setStyle('display', '');

    },
    unlockStep3: function() {
        if (this.CheckLicenseeFieldValid()) {
            this.unlockPromoButton();
            CorbisUI.ExpressCheckout.vars.PromoCodeBox.disabled = false;
            $$('.purchaseInfo')[0].set('opacity', 1);
            $$('.purchaseInfo .mask')[0].setStyle('display', 'none');
            this.ShowCCSecurityMessage();
        }
    },
    lockStep4: function() {
        //console.log('lock stp4');
        //LOCK PURCHASE BUTTON
        //if (!this.vars.PurchaseButton.hasClass('DisabledGlassButton')) 
        //setGlassButtonDisabled(this.vars.PurchaseButton, true)

        this.vars.PurchaseButton.set('opacity', .66);
        $$('.purchaseButtonMask')[0].setStyle('display', '');
        this.vars.PurchaseButton.disabled = true;
    },
    unlockStep4: function() {
        //UNLOCK THE PURCHASE BUTTON
        //console.log('unlockStep4');

        //if (this.vars.PurchaseButton.hasClass('DisabledGlassButton'))
        //setGlassButtonDisabled(this.vars.PurchaseButton, false);
        this.vars.PurchaseButton.set('opacity', 1);
        $$('.purchaseButtonMask')[0].setStyle('display', 'none');
        this.vars.PurchaseButton.disabled = false;
        var gb = CorbisUI.ExpressCheckout.vars.PromoCodeButton;
        CorbisUI.ExpressCheckout.setPromoButtonDisabled(gb, true);

    },
    lockPromoButton: function() {
        //LOCK THE PROMO BUTTON
        //console.log('lockPromoButton');
        //CorbisUI.ExpressCheckout.togglePromoButtonDisabled();
        CorbisUI.ExpressCheckout.vars.PromoCodeBox.disabled = true;
        setOutlineButtonDisabled(CorbisUI.ExpressCheckout.vars.PromoCodeButton, true);
    },
    unlockPromoButton: function() {
        //UNLOCK THE PROMO BUTTON
        //console.log('unlockPromoButton');
        //CorbisUI.ExpressCheckout.togglePromoButtonDisabled();
        setOutlineButtonDisabled(CorbisUI.ExpressCheckout.vars.PromoCodeButton, false);
    },
    validatePromoButton: function(promoBoxText) {
        //Confirm checkboxes are checked
        var checkboxList = $('purchaseCheckboxes').getElements("span.ImageCheckbox input");
        var passed = null;
        checkboxList.each(function(el) {
            //Loop through checkboxes to see if both are checked
            if (el.checked == true)
                passed += 1;
            else
                passed = 0;
        });
        //Confirm promoBox has a value and that a payment method is selected
        if (promoBoxText != '') {
            this.unlockPromoButton();
        } else {
            this.lockPromoButton();
            var gb = CorbisUI.ExpressCheckout.vars.PromoCodeButton;
            CorbisUI.ExpressCheckout.setPromoButtonDisabled(gb, true);
        }
    },
    isValidStartDate: function(startDate) {
        return CorbisUI.ExpressCheckout.ConvertToDateUsingLocaleFormat(startDate) >= new Date().setHours(0, 0, 0, 0);
    },
    doValidateStartDate: function() {
        if (CorbisUI.ExpressCheckout.vars.LicenseType == 'RF') {
            //There is no license start date for RF images always return true for validation
            return true;
        }
        if (CorbisUI.ExpressCheckout.vars.licenseStartDate == null || CorbisUI.ExpressCheckout.vars.licenseStartDate == "") {
            CorbisUI.ExpressCheckout.vars.licenseStartDate = CorbisUI.ExpressCheckout.GetStartDate();
        }
        if (CorbisUI.ExpressCheckout.vars.licenseStartDate == null || CorbisUI.ExpressCheckout.vars.licenseStartDate == "") {
            return false;
        }
        var warningMode = CorbisUI.ExpressCheckout.ConvertToDateUsingLocaleFormat(CorbisUI.ExpressCheckout.vars.licenseStartDate) < new Date().setHours(0, 0, 0, 0);
        if (warningMode) {
            $('errorBlock').setStyle('display', 'block');
            $$('.StartDate').each(function(el) { el.addClass('WarningMode'); });
            this.Resize();
        }
        else {
            $('errorBlock').setStyle('display', 'none');
            $$('.StartDate').each(function(el) { el.removeClass('WarningMode'); });
        }
        return (!warningMode);
    },
    validateStep3: function() {
        if (CorbisUI.ExpressCheckout.vars.CardExpired == 'True') {
            this.lockStep4();
            return;
        }
        var checkboxList = $('purchaseCheckboxes').getElements("span.ImageCheckbox input");
        var passed = null;
        checkboxList.each(function(el) {
            //Loop through checkboxes to see if both are checked
            if (el.checked == true)
                passed += 1;
            else
                passed = 0;
        });
        //IF both checkboxes have been checked (restrictions,license agreement) and a valid payment method is selected, call step4 unlocker
        var testPaymentMethod = this.vars.PaymentMethodBox[this.vars.PaymentMethodBox.selectedIndex].value;
        if (passed > 1 && (testPaymentMethod != 'none' && testPaymentMethod != 'Add New') && this.vars.PaymentMethodBox.options[this.vars.PaymentMethodBox.selectedIndex].getAttribute('creditapproved') != "False") {
            this.unlockStep4();
        } else {
            if (this.vars.PaymentMethodBox.options[this.vars.PaymentMethodBox.selectedIndex].getAttribute('creditapproved') == "False")
                OpenModal('CoporateAccountCreditReview');

            this.lockStep4();
        }

    },
    validateStep2: function() {
        // remove the keyup event from licensee
        if (this.vars.LicenseeField) {
            this.vars.LicenseeField.removeEvents('keyup');
        }
        // RF validation
        if ($$('.SubTitle span')[0].hasClass('RF_green')) {

            if (this.vars.HidAttributeValueUID.value.length == 0 || this.vars.HidAttributeValueUID.value == "00000000-0000-0000-0000-000000000000") {
                this.lockStep3();
            } else {
                this.unlockStep3();
            }
        } else {
            // RM validation
            if (this.doValidateStartDate(this.GetStartDate())) {
                if (CorbisUI.ExpressCheckout.vars.PricedByAE == 'True') {
                    this.unlockStep3();
                }
                else {
                    // Check if it's already priced or a saveed usage has been selected
                    if ((CorbisUI.ExpressCheckout.vars.AlreadyPriced == 'True' ||
                        CorbisUI.ExpressCheckout.vars.SavedUsageDropdown.selectedIndex > 0) && (this.isValidStartDate(this.GetStartDate()))) {
                        this.unlockStep3();
                    } else {
                        // not valid
                        this.lockStep3();
                    }
                }
            }
            else {
                this.lockStep3();
            }
        }

    },
    ConvertToDateUsingLocaleFormat: function(dateString) {
        var dateParts = CorbisUI.ExpressCheckout.vars.DateFormat.split(CorbisUI.ExpressCheckout.vars.DateSeparator);
        var mm, dd, yyyy;
        try {
            var dateValues = dateString.split(CorbisUI.ExpressCheckout.vars.DateSeparator);
            for (var i = 0; i < dateParts.length; i++) {
                if (dateParts[i].indexOf('M') > -1) {
                    mm = dateValues[i];
                }
                if (dateParts[i].indexOf('y') > -1) {
                    yyyy = dateValues[i];
                }
                if (dateParts[i].indexOf('d') > -1) {
                    dd = dateValues[i];
                }
            }
            return new Date(mm + "/" + dd + "/" + yyyy);
        } catch (ex) {
            return null;
        }
    },
    ConvertToDateStringUsingLocaleFormat: function(dateString) {
        //This function should be moved to common/util namespace
        var dateParts = CorbisUI.ExpressCheckout.vars.DateFormat.split(CorbisUI.ExpressCheckout.vars.DateSeparator);
        var finalstr = null;
        var tempstr = null;
        if (typeof (dateString) == 'string') {
            try {
                var dateValues = dateString.split(CorbisUI.ExpressCheckout.vars.DateSeparator);
                for (var i = 0; i < dateParts.length; i++) {
                    if (dateParts[i].indexOf('M') > -1) {
                        tempstr = dateValues[i];
                    }
                    if (dateParts[i].indexOf('y') > -1) {
                        tempstr = dateValues[i];
                    }
                    if (dateParts[i].indexOf('d') > -1) {
                        tempstr = dateValues[i];
                    }
                    if (finalstr == null) {
                        finalstr = tempstr;
                    } else {
                        finalstr += CorbisUI.ExpressCheckout.vars.DateSeparator + tempstr;
                    }
                }
            } catch (ex) {
                return false;
            }
        }
        if (typeof (dateString) == 'number') {
            dateString = new Date(dateString);
            try {
                for (var i = 0; i < dateParts.length; i++) {
                    if (dateParts[i].indexOf('M') > -1) {
                        tempstr = dateString.getMonth() + 1;
                    }
                    if (dateParts[i].indexOf('y') > -1) {
                        tempstr = dateString.getFullYear();
                    }
                    if (dateParts[i].indexOf('d') > -1) {
                        tempstr = dateString.getDate();
                    }
                    if (finalstr == null) {
                        tempstr = tempstr;
                        finalstr = tempstr;
                    } else {
                        finalstr += CorbisUI.ExpressCheckout.vars.DateSeparator + tempstr;
                    }
                }
            } catch (ex) {
                return false;
            }
        }


        var finaldateParts = finalstr.split(CorbisUI.ExpressCheckout.vars.DateSeparator);
        for (var i = 0; i < finaldateParts.length; i++) {
            if (isNaN(finaldateParts[i])) {
                return "";
            }
        }

        return finalstr;
    },
    handleLicenseDateChange: function(elem) {
        if (elem != null) {
            CorbisUI.ExpressCheckout.vars.licenseStartDate = CorbisUI.ExpressCheckout.ConvertToDateStringUsingLocaleFormat(elem.value);
            CorbisUI.ExpressCheckout.UpdateStartDate(CorbisUI.ExpressCheckout.vars.licenseStartDate);
        }
        //Check if the date is string or date type and do string conversion accordingly

        CorbisUI.ExpressCheckout.validateStep2();
        if (CorbisUI.ExpressCheckout.isValidStartDate(CorbisUI.ExpressCheckout.vars.licenseStartDate)) {
            CorbisUI.ExpressCheckout.UpdateStartDate(CorbisUI.ExpressCheckout.vars.licenseStartDate);
            var hidProductUid = CorbisUI.ExpressCheckout.vars.HidProductUid.value;
            //console.log('RMProductUidCheck RMProductUidCheck ' + hidProductUid);
            //If not blank ProductUid
            if (hidProductUid != '00000000-0000-0000-0000-000000000000' && hidProductUid != '') {
                if ($('licenseStartDateDiv') != null) {
                    $('licenseStartDateDiv').innerHTML = CorbisUI.ExpressCheckout.vars.licenseStartDate;
                }
            }
            $('errorBlock').setStyle('display', 'none');
            $$('.StartDate').each(function(el) { el.removeClass('WarningMode'); });
        } else {
            $('errorBlock').setStyle('display', 'block');
            $$('.StartDate').each(function(el) { el.addClass('WarningMode'); });
            this.Resize();
        }
    },
    validateStartDate: function(sender, args) {
        CorbisUI.ExpressCheckout.vars.licenseStartDate = CorbisUI.ExpressCheckout.ConvertToDateStringUsingLocaleFormat(sender._selectedDate.setHours(0, 0, 0, 0));
        CorbisUI.ExpressCheckout.UpdateStartDate(CorbisUI.ExpressCheckout.vars.licenseStartDate);
        CorbisUI.ExpressCheckout.validateStep2();
        CorbisUI.ExpressCheckout.handleLicenseDateChange(null);
    },
    validateStep1: function(event) {

        if (event) {

            if (event.target.id.indexOf('projectField') > -1) {
                if (this.vars.ProjectField.value.trim().length == 0) {
                    this.vars.ProjectField.value = this.vars.OriginalProjectName;
                }
                this.vars.IsDirty = true;

            }
            if (event.target.id.indexOf('jobField') > -1) {
                this.vars.IsDirty = true;

            }
            if (event.target.id.indexOf('poField') > -1) {
                this.vars.IsDirty = true;

            }
            if (event.target.id.indexOf('licenseeField') > -1) {
                this.vars.IsDirty = true;
                if (this.vars.LicenseeField.value.trim().length == 0 || this.vars.LicenseeField.value == this.vars.RequiredText) {
                    this.vars.LicenseeField.setStyle('background-color', '#ffffcc');
                    this.lockStep2();
                    this.lockStep3();
                    this.lockStep4();

                } else {
                    this.vars.LicenseeField.setStyle('background-color', '#ffffff');
                    this.unlockStep2();
                    this.validateStep2();
                }
            }

        } else {
            //console.log(this.vars.LicenseeField.value);
            //console.log(this.vars.RequiredText);

            if (this.vars.LicenseeField.value.trim().length == 0 || this.vars.LicenseeField.value == this.vars.RequiredText) {
                this.lockStep2();
                this.lockStep3();
                this.lockStep4();

            } else {
                this.vars.LicenseeField.setStyle('background-color', '#ffffff');
                this.unlockStep2();
                this.validateStep2();

            }
        }


    },
    ValidateProjectASCText: function() {

        var req = new Request.HTML({
            method: 'post',
            url: "/Checkout/CheckoutService.asmx/ValidateProjectEncoding",
            data: {
                'projectName': CorbisUI.ExpressCheckout.vars.ProjectField.value,
                'projectNameClientId': CorbisUI.ExpressCheckout.vars.ProjectField.id,
                'jobNumber': CorbisUI.ExpressCheckout.vars.JobField.value,
                'jobNumberClientId': CorbisUI.ExpressCheckout.vars.JobField.id,
                'poNumber': CorbisUI.ExpressCheckout.vars.PurchaseOrderField.value,
                'poNumberClientId': CorbisUI.ExpressCheckout.vars.PurchaseOrderField.id,
                'licensee': CorbisUI.ExpressCheckout.vars.LicenseeField.value,
                'licenseeClientId': CorbisUI.ExpressCheckout.vars.LicenseeField.id
            },
            onRequest: function() {

            },
            onSuccess: function(responseTree, responseElements, responseHtml) {

                this.fireEvent('ajaxSuccess', responseTree);
                var errorIndex = responseHtml.indexOf('<ScriptServiceValidationError');
                if (errorIndex == -1) {
                    CorbisUI.ExpressCheckout.ASCCompliant = "True";
                    $$('.projectWrap input').each(function(el) {
                        el.setStyle('background-color', '#ffffff');
                    });

                    if (CorbisUI.ExpressCheckout.CheckLicenseeFieldValid() == true) {
                        CorbisUI.ExpressCheckout.unlockStep2();

                    }

                    CorbisUI.ExpressCheckout.validateStep3();
                    $("projectValidate").addClass('displayNone');
                    CorbisUI.ExpressCheckout.Resize();

                    //Call final form validation
                    CorbisUI.ExpressCheckout.submitValidationCheck();


                } else {
                    CorbisUI.ExpressCheckout.ASCCompliant = "False";
                    var result;
                    if (Browser.Engine.trident) {
                        result = responseElements.filter('scriptservicevalidationerror');

                    } else {
                        var test = responseHtml.split('?>');
                        test.shift();
                        test = (test.length == 1) ? test[0] : test.join('?>');

                        var ser = new CorbisUI.JSSerializer();
                        test = ser.getDom(test);

                        result = $(test).getElements('ScriptServiceValidationError');

                    }
                    $$('.projectWrap input').each(function(el) {
                        el.setStyle('background-color', '#ffffff');
                    });
                    if (result.length > 0) {
                        CorbisUI.ExpressCheckout.lockStep2();
                        CorbisUI.ExpressCheckout.lockStep3();
                        $("projectValidate").removeClass('displayNone');
                        CorbisUI.ExpressCheckout.Resize();

                    }
                    result.each(function(item) {
                        if (item.getElement('ClientId')) {
                            var elId = item.getElement('ClientId').get('text');
                            //console.log('elId: ' + elId);
                            $(elId).setStyle('background-color', '#ffffcc');
                        }
                    }, this);


                }

            },
            onFailure: function(response) {
                //Message? This would only be a failure to call the Service, not an invalid response
            }

        }).send();
    },
    CheckLicenseeFieldValid: function() {
        return !(this.vars.LicenseeField.value.trim().length == 0 || this.vars.LicenseeField.value == this.vars.RequiredText);
    },

    trimFields: function(event) {
        if (event.target.id.indexOf('licenseeField') > -1) {
            if (this.vars.LicenseeField.value.trim().length == 0) {
                this.vars.LicenseeField.value = '';
            }
        }
    },

    setupPanels: function() {
        CorbisUI.Watermark.initialize();
        this.setupForm1Validation();
        this.lockStep2();
        this.lockStep3();
        this.lockStep4();
        this.lockPromoButton();
        window.setTimeout("CorbisUI.ExpressCheckout.Resize()", 500);
    },
    setupForm1Validation: function() {
        this.vars.OriginalProjectName = this.vars.ProjectField.value;

        this.vars.ProjectField.addEvent('change', function(event) { CorbisUI.ExpressCheckout.validateStep1(event); });

        this.vars.LicenseeField.addEvent('change', function(event) { CorbisUI.ExpressCheckout.trimFields(event); });
        this.vars.LicenseeField.addEvent('blur', function(event) { CorbisUI.ExpressCheckout.validateStep1(event); });
        this.vars.LicenseeField.addEvent('keyup', function(event) { CorbisUI.ExpressCheckout.validateStep1(event); });

        this.vars.JobField.addEvent('change', function(event) { CorbisUI.ExpressCheckout.validateStep1(event); });

        this.vars.PurchaseOrderField.addEvent('change', function(event) { CorbisUI.ExpressCheckout.validateStep1(event); });

        this.vars.HidAttributeValueUID.addEvent('change', function() { CorbisUI.ExpressCheckout.validateStep2(); });
        this.vars.HidProductUid.addEvent('change', function() { CorbisUI.ExpressCheckout.validateStep2(); });
    },
    getProtocol: function() {
        if (window.location.protocol == "https:")
            return "https";
        return "http";
    },
    OpenExpressCheckoutModal: function(corbisId, productUid, lightboxId, caller) {
        if (caller == null) {
            caller = "NotSet";
        }
        var expressCheckoutPage = HttpsUrl + '/Checkout/ExpressCheckout.aspx?corbisId=' + corbisId + "&protocol=" + CorbisUI.ExpressCheckout.getProtocol() + "&caller=" + caller;
        if (typeof (productUid) != undefined) {
            expressCheckoutPage += "&productUid=" + productUid;

            if (typeof (lightboxId) != undefined) {
                expressCheckoutPage += "&LightboxId=" + lightboxId;
            }
        }

        OpenNewIModal(expressCheckoutPage, 960, 630, 'expressCheckout');
    },

    openCreateNewUsage: function(corbisId) {
        // need to use double quotes to pass parameters as encodeURIComponent will not
        // escape single quotes, but they're OK in the query string
        var exec = "CorbisUI.ExpressCheckout.hideExpressCheckoutAndShowCreateNewUsage(\"" +
            corbisId + "\", \"" +
            encodeURIComponent(CorbisUI.ExpressCheckout.vars.ProjectField.value.trim()) + "\", \"" +
            encodeURIComponent(CorbisUI.ExpressCheckout.vars.JobField.value.trim()) + "\", \"" +
            encodeURIComponent(CorbisUI.ExpressCheckout.vars.PurchaseOrderField.value.trim()) + "\", \"" +
            encodeURIComponent(CorbisUI.ExpressCheckout.vars.LicenseeField.value.trim()) + "\")";
        var iFrames = $$('iframe');
        var iDo = iFrames[0];
        iDo.src = CorbisUI.ExpressCheckout.getParentProtocolBasedURL() + "/Common/IFrameTunnel.aspx?windowId=expressCheckout&action=execute&noclose=true&actionArg=" + escape(exec);
    },

    hideExpressCheckoutAndShowCreateNewUsage: function(corbisId, projectName, jobNumber, poNumber, licensee) {
        var pricingUrl = "/Pricing/RMPricing.aspx?ParentPage=ExpressCheckout&CorbisId=" + corbisId +
            "&projectName=" + projectName +
            "&jobNumber=" + jobNumber +
            "&poNumber=" + poNumber +
            "&licensee=" + licensee;
        //console.log(pricingUrl);
        // Hide express checkout
        HideModal('expressCheckout');
        // Show RM pricing, for now...
        PriceImage(pricingUrl, 700, 545);
    },

    closeCreateNewUsageAndShowExpressCheckout: function() {
        CloseModal('pricing');
        MochaUI.ShowModal('expressCheckout');
        var noProdUid = $('expressCheckoutWindow_iframe').src;
        noProdUid = noProdUid.replace("productUid", "oldPuid");
        noProdUid = noProdUid.replace("&isNewUsage=True", "");
        $('expressCheckoutWindow_iframe').src = noProdUid + "&isNewUsage=True&refresh=" + Math.random();
    },
    getCurrentProtocolBasedURL: function() {
        if (window.location.protocol == "https:") {
            return HttpsUrl;
        }
        return HttpUrl;
    },
    getParentProtocolBasedURL: function() {
        try {
            return ParentProtocol;
        } catch (ex) {

        }
    },

    // Called from the iFrame itself
    DoCloseExpressCheckoutModal: function() {
        var iFrames = $$('iframe');
        var iDo = iFrames[0];
        iDo.src = CorbisUI.ExpressCheckout.getParentProtocolBasedURL() + "/Common/IFrameTunnel.aspx?windowId=expressCheckout&action=close";
    },
    CloseExpressCheckoutModal: function(element) {
        if (this.vars.IsDirty) {
            OpenCloseWarning('confirmClose', element);
        } else {
            this.DoCloseExpressCheckoutModal();
        }
    },

    OpenUrlInParent: function(url) {
        var iFrames = $$('iframe');
        var iDo = iFrames[0];
        iDo.src = CorbisUI.ExpressCheckout.getParentProtocolBasedURL() + "/Common/IFrameTunnel.aspx?windowId=expressCheckout&action=returnurl&actionArg=" + url;
    },

    Open: function(mediaUid, productUid, lightboxId, caller) {
        CorbisUI.Auth.Check(CorbisUI.Auth.SignInLevels.LoggedIn, CorbisUI.Auth.ActionTypes.Execute, "CorbisUI.ExpressCheckout.OpenExpressCheckoutModal('" + mediaUid + "','" + productUid + "','" + lightboxId + "','" + caller + "')");
    },

    OpenLegal: function() {
        var exec = "CorbisUI.Legal.OpenPolicyIModal()";
        var iFrames = $$('iframe');
        var iDo = iFrames[0];
        iDo.src = CorbisUI.ExpressCheckout.getParentProtocolBasedURL() + "/Common/IFrameTunnel.aspx?windowId=expressCheckout&action=execute&noclose=true&actionArg=" + escape(exec);
    },

    ShowCCSecurityMessage: function() {
        if (CorbisUI.ExpressCheckout.vars.showCCSecurityMessage == "True") {
            OpenModal('ccSecurityMessage');
            CorbisUI.ExpressCheckout.vars.showCCSecurityMessage = "False";
        }
    },

    ShowSelectPaymentError: function() {
        if ($('paymentMethodSelect').value == "none") {
            $$('#selectPaymentBlock').addClass('WarningMode');
            $$('#selectPaymentBlock').setStyle('display', 'block');
        }
    },

    // bug 20680 and check function RefreshPaymentMethods in ExpressCheckout.js
    RemoveSelectPaymentError: function() {
        $$('#selectPaymentBlock').removeClass('WarningMode');
        $$('#selectPaymentBlock').setStyle('display', '');
    },
    // bug 20678 and check function RefreshPaymentMethods in ExpressCheckout.js
    RemoveExpiredCreditCardError: function() {        
        $('CreditCardExpiryError').addClass('displayNone');
    }
}

//End: /Scripts/CorbisUI.ExpressCheckout.js
//Begin: /Scripts/CorbisUI.Legal.js

/****************************************************
    Corbis UI Legal
***************************************************/

// TODO: the name 'legal' could be seen as a misnomer because I am using the class to affect the modal in "Request Image Research".
CorbisUI.Legal = {
    vars: {
        SAM: null,
        policy: null,
        base: null,
        printBase: null,
        printContent: null,
        cleanPrintContent: null,
        WinPrint: null,
        g_firefox: null,
        imprint: null,
        allLinks: null
    },

    initialize: function() {
        this.vars.SAM = '/Legal/SiteUsageAgreement.aspx';
        this.vars.policy = '/Legal/PrivacyPolicy.aspx';
        this.vars.RIR = '/CustomerService/RequestImageResearch.aspx';
        this.vars.base = $('getAcrobat');
        this.vars.printBase = $('aspnetForm');
        this.vars.printContent = this.vars.printBase.getElement('.contentWrapper');
        this.vars.g_firefox = document.getElementById && !document.all;
        this.vars.imprint = '/Legal/Imprint.aspx';
        //this.vars.allLinks = this.vars.printContent.innerHTML.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a\>)/g;
    },

    OpenSAMIModal: function() {
        this.initialize();
        OpenNewIModal(this.vars.SAM, 600, 600, 'SiteUsageAgreementModal');
    },

    OpenPolicyIModal: function() {
        this.initialize();
        OpenNewIModal(this.vars.policy, 600, 600, 'PrivacyPolicyModal');
    },

    OpenImprintIModal: function() {
        this.initialize();
        OpenNewIModal(this.vars.imprint, 600, 600, 'ImprintModal');
    },

    OpenRIRIModal: function() {
        this.initialize();
        OpenNewIModal(this.vars.RIR, 600, 500, 'RequestImageResearchModal');
    },

    HideRequestImageResearchModal: function() {
        parent.MochaUI.CloseModal('RequestImageResearchModal');
    },    

    HideSiteUsageAgreementModal: function() {
        parent.MochaUI.CloseModal('SiteUsageAgreementModal');
    },

    HidePrivacyPolicyModal: function() {
        MochaUI.CloseModal('PrivacyPolicyModal');
    },

    HideImprintModal: function() {
        parent.MochaUI.CloseModal('ImprintModal');
    },

    CloseAgreementOpenPolicy: function() {
        this.HideSiteUsageAgreementModal();
        this.OpenPolicyIModal();
    },
    HideRequestImageResearchModal: function() {
        parent.MochaUI.CloseModal('RequestImageResearchModal');
    },

    OpenAcrobatReaderPopup: function(link) {
        new CorbisUI.Popup('getAcrobat', {
            showModalBackground: false,
            centerOverElement: link,
            closeOnLoseFocus: true,
            positionVert: 'top',
            positionHoriz: 'right'
        });
        this.initialize();
        this.vars.base.getElement('.FormButtons').setStyle('margin-top', 5);
    },
    CallPrintWindow: function() {  
        var url = window.location.toString();
        url += url.indexOf('?') != -1 ? '&' : '?';
        window.open('' + url + 'print', '', 'top=0, left=0, height=700, width=800, status=no, menubar=no, resizable=yes, scrollbars=yes, toolbar=no, location=no, directories=no');
    },

    CallPrint: function() {
        this.initialize();

        this.vars.WinPrint = window.open('', '', 'top=0, left=0, height=700, width=800, status=no, menubar=no, resizable=yes, scrollbars=yes, toolbar=no, location=no, directories=no');
        this.vars.WinPrint.document.open();
        this.vars.WinPrint.document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head><title>');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.SiteUsageAgreement.text.windowTitleMsg);
        this.vars.WinPrint.document.write('</title><link href="/Stylesheets/MasterBase.css" rel="stylesheet" type="text/css" media="all" /></head>');
        this.vars.WinPrint.document.write('<body id="siteUsageAgreement" class="printVersion">');
        this.vars.WinPrint.document.write('<img id="Logo" src="../Images/corbis-logo_sm.gif" alt="');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.SiteUsageAgreement.text.altTextMsg);
        this.vars.WinPrint.document.write('" />');
        //Bug fix 17900 begins
        //this.vars.WinPrint.document.write('<h1>Site Usage Agreement</h1>');
        this.vars.WinPrint.document.write('<h1>');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.SiteUsageAgreement.text.siteUsageAgreementHeadingText);
        this.vars.WinPrint.document.write('</h1>');
        //Bug fix 17900 ends
        
        this.vars.WinPrint.document.write('<div id="clearMe"></div>');
        if (this.vars.g_firefox) {
            this.vars.WinPrint.document.write(this.vars.printContent.innerHTML
            .replace('<a href="mailto:service@corbis.com">', "")
            .replace(/<a [^>]*>([^<]*)<\/a>/gi, "<u>$1</u>"));
        }
        else {
            this.vars.WinPrint.document.write(this.vars.printContent.innerHTML
            .replace('<A href="mailto:service@corbis.com">service@corbis.com</A>', "service@corbis.com")
            .replace(/<a [^>]*>([^<]*)<\/a>/gi, "<u>&dollar;1</u>"));
        }

        this.vars.WinPrint.document.write('<p id="copyright">');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.SiteUsageAgreement.text.copyrightMsg);
        this.vars.WinPrint.document.write('</p></body></html>');

        this.vars.WinPrint.document.close();
        this.vars.WinPrint.focus();
        this.vars.WinPrint.print();
        //this.vars.WinPrint.close();
    },

    //TODO: This is written following the other examples of Printer Friendly Version for Privacy Policy and Site Usage Agreement
    //but all the print versions for Privacy Policy,Site Usage Agreement and Imprint needs to be rewritten.
    CallImprint: function() {
        this.initialize();

        this.vars.WinPrint = window.open('', '', 'top=0, left=0, height=700, width=800, status=no, menubar=no, resizable=yes, scrollbars=yes, toolbar=no, location=no, directories=no');
        this.vars.WinPrint.document.open();
        this.vars.WinPrint.document.write('<html><head><title>');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.Imprint.text.WindowTitleText);
        this.vars.WinPrint.document.write('</title><style type="text/css" media="all">'
        + 'body{margin:10px 10px 10px 10px;height:100%;color:#000000;background-color:#FFFFFF;font:normal 11px "Tahoma", Verdana, Tahoma, Arial, sans-serif; line-height:16px;}'
        + 'p{margin:0px 0px 1.2em;}'
        + 'a{color:#4385C0;text-decoration:none;}'
        + 'a:visited{color:#4385C0;text-decoration:none;}'
        + 'a:hover, a.context_link:hover, a.link_light:hover{color:#4385C0;text-decoration:underline;}'
        + '</style></head>'
        );
        this.vars.WinPrint.document.write('<body>');
        this.vars.WinPrint.document.write('<img id="Logo" src="../Images/corbis-logo_sm.gif" align="absmiddle" alt="');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.Imprint.text.WindowTitleText);
        this.vars.WinPrint.document.write('" />');
        this.vars.WinPrint.document.write('<div style="font-size:18px;font-family:Trebuchet MS;color:#666666;margin-left:20px;margin-top:25px;display:inline-block;">');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.Imprint.text.WindowTitleText);
        this.vars.WinPrint.document.write('</div>');
        this.vars.WinPrint.document.write('<div style="clear:both;margin-top:10px;" />');
        this.vars.WinPrint.document.write('<br />');
        if (this.vars.g_firefox) {
            this.vars.WinPrint.document.write(this.vars.printContent.innerHTML
            .replace('<img src="../Images/en-US/clickseal.gif" style="border-width: 0px;">', "")
            .replace(/<a [^>]*>([^<]*)<\/a>/gi, "<u>$1</u>"));
        }
        else {
            this.vars.WinPrint.document.write(this.vars.printContent.innerHTML
            .replace('<IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" src="../Images/en-US/clickseal.gif">', "")
            .replace(/<a [^>]*>([^<]*)<\/a>/gi, "<u>$1</u>"));
        }
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.Imprint.text.copyrightMsg);
        this.vars.WinPrint.document.write('</body></html>');
        this.vars.WinPrint.document.close();
        this.vars.WinPrint.focus();
        this.vars.WinPrint.print();
        //this.vars.WinPrint.close();
    },

    CallPrintPolicy: function() {
        this.initialize();

        this.vars.WinPrint = window.open('', '', 'top=0, left=0, height=700, width=800, status=no, menubar=no, resizable=yes, scrollbars=yes, toolbar=no, location=no, directories=no');
        this.vars.WinPrint.document.open(); 
        this.vars.WinPrint.document.write('<html><head><title>');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.PrivacyPolicy.text.privacyTitleMsg);
        this.vars.WinPrint.document.write('</title><link href="../Stylesheets/MasterBase.css" type="text/css" rel="stylesheet" /></head>');
        this.vars.WinPrint.document.write('<body id="privacyPolicyPrint">');
        this.vars.WinPrint.document.write('<img id="Logo" src="../Images/corbis-logo_sm.gif" align="absmiddle" alt="');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.PrivacyPolicy.text.altTextMsg + '" />');
        this.vars.WinPrint.document.write(' <h1>');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.PrivacyPolicy.text.privacrPolicyTitle);
        this.vars.WinPrint.document.write('</h1>');
        if (this.vars.g_firefox) {
            this.vars.WinPrint.document.write(this.vars.printContent.innerHTML
            .replace('<img src="../Images/en-US/clickseal.gif" style="border-width: 0px;">', "")
            .replace(/<a [^>]*>([^<]*)<\/a>/gi, "<u>$1</u>"));
        }
        else {
            this.vars.WinPrint.document.write(this.vars.printContent.innerHTML

            .replace('<IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" src="../Images/en-US/clickseal.gif">', "")
            .replace(/<a [^>]*>([^<]*)<\/a>/gi, "<u>$1</u>"));
        }
        this.vars.WinPrint.document.write('<p id="copyright">');
        this.vars.WinPrint.document.write(CorbisUI.GlobalVars.PrivacyPolicy.text.copyrightMsg);
        this.vars.WinPrint.document.write('</p></body></html>');
        this.vars.WinPrint.document.close();
        this.vars.WinPrint.focus();
        this.vars.WinPrint.print();
        //this.vars.WinPrint.close();
    }
}
//End: /Scripts/CorbisUI.Legal.js
//Begin: /Scripts/CorbisUI.EnlargementTimerSearch.js

/****************************************************
    Corbis UI Enlargement Timer Search
***************************************************/

CorbisUI.EnlargementTimerSearch = {
    vars: {
        secs: null,
        timerID: null,
        timerRunning: null,
        delay: null,
        qs: null,
        args: null,
        pair: null,
        name: null
    },

    initialize: function() {
        this.vars.timerRunning = false;
        this.vars.timerID = null;
        this.vars.delay = 1000;
    },

    DecodeQuerystring: function() {
        try {
            this.vars.qs = window.location.search.substring(1);
            this.vars.args = this.vars.qs.split('&');
            if (this.vars.args[2] != "undefined" && this.vars.args[2] != null) {
                this.vars.pair = this.vars.args[2].split("=");
                this.vars.name = decodeURIComponent(this.vars.pair[0]);
                if (this.vars.name == "options") {
                    CorbisUI.ExtendedSearch.OpenOptionsAppliedModal();
                    this.InitializeTimer();
                }
            }
        }
        catch (e) {
        }
    },

    InitializeTimer: function() {
        this.vars.secs = 10;
        this.StopTheClock();
        this.StartTheTimer();
    },

    StopTheClock: function() {
        this.initialize();

        if (this.vars.timerRunning) {
            clearTimeout(this.vars.timerID);
        }
        this.vars.timerRunning = false;
    },

    StartTheTimer: function() {
        this.initialize();

        if (this.vars.secs == 0) {
            this.StopTheClock();
            this.HideAppliedOptionsWindow();
        }
        else {
            this.vars.secs = this.vars.secs - 1;
            this.vars.timerRunning = true;
            this.vars.timerID = setTimeout("CorbisUI.EnlargementTimerSearch.StartTheTimer()", this.vars.delay);
            if (CorbisUI.GlobalVars.Search.sb_KeywordSearch.value == CorbisUI.GlobalVars.Search.sb_SearchImages) {
                $('Search').getElement('.Optional').setStyle('background-color', '#ffffcc');
            }
        }
    },

    HideAppliedOptionsWindow: function() {
        try { $('optionsAppliedModalWindow').setStyle('display', 'none'); } catch (er) { }
    }
}
//End: /Scripts/CorbisUI.EnlargementTimerSearch.js
//Begin: /Scripts/CorbisUI.MSOSearch.js

/****************************************************
    Corbis UI MSO Search
    (More Search Options)
***************************************************/

CorbisUI.MSOSearch = {
    vars: {
        imageBase: null,
        imageNumberText: null,
        searchBuddyBase: null,
        noPeopleCheckBox: null,
        numberOfPeopleSelect: null,
        numberOfPeopleValue: null,
        dateContainer: null,
        betweenBtn: null,
        startDate: null,
        endDate: null,
        radioBetweenBase: null,
        radioBetweenButton: null,
        radioDaysBase: null,
        radioDaysTextBox: null
    },

    initialize: function() {
        // No bColumn, MSO is not enabled
        if ($('bColumn')) {
            this.vars.imageBase = $('bColumn');
            this.vars.imageNumberText = this.vars.imageBase.getElement('.imageNumbers');
            this.vars.numberOfPeopleSelect = this.vars.imageBase.getElement('div.numberOfPeople').getElement('select');

            this.vars.searchBuddyBase = $('SearchBuddy');
            if (this.vars.searchBuddyBase != null) {
                if (this.vars.searchBuddyBase.getElement('.NoPeople') != null) {
                    this.vars.noPeopleCheckBox = this.vars.searchBuddyBase.getElement('.NoPeople').getElement('.imageCheckbox');
                }
            }

            this.vars.dateContainer = $('betweenDataContainer');
            this.vars.betweenBtn = this.vars.dateContainer.getElement('input');
            this.vars.startDate = this.vars.dateContainer.getElement('.beginDate').value;
            this.vars.endDate = this.vars.dateContainer.getElement('.endDate').value;
            this.vars.radioBetweenBase = $('radioBetweenDiv');
            this.vars.radioBetweenButton = this.vars.radioBetweenBase.getElement('input[type=radio]'); ;
            this.vars.radioDaysBase = $('radioDaysDiv');
            this.vars.radioDaysTextBox = this.vars.radioDaysBase.getNext('input[type=text]');
        }
    },

    clearText: function() {
        this.initialize();
        if (this.vars.imageNumberText) {
            if (this.vars.imageNumberText.value == CorbisUI.ExtendedSearch.vars.ImageNumbersText) {
                this.vars.imageNumberText.value = "";
            }
        }
    },

    resetText: function() {
        this.initialize();
        if (this.vars.imageNumberText) {
            if (this.vars.imageNumberText.value == "") {
                this.vars.imageNumberText.value = CorbisUI.ExtendedSearch.vars.ImageNumbersText;
            }
        }
    },

    // Called when a selection is made in the MSO Number Of People filter.
    // If the No People checkbox is checked, then uncheck it
    verifyNoPeopleChecked: function() {
        this.initialize();

        this.vars.numberOfPeopleValue = this.vars.numberOfPeopleSelect.value;
        if (this.vars.noPeopleCheckBox != null) {
            CorbisUI.ImageCb.getImageCbObject(this.vars.noPeopleCheckBox).setCheckState(false, true);
        }
    },

    // Called to initialize the MSO Number Of People filter when it loads the first time
    setNumberOfPeopleControlValue: function() {
        this.initialize();
        
        if (this.vars.numberOfPeopleSelect && this.vars.numberOfPeopleValue) {
            if (this.vars.numberOfPeopleValue != 5 &&
                CorbisUI.ExtendedSearch.vars.HiddenMSOValue.value == "Opening" && 
                $(CorbisUI.GlobalVars.Search.showOptionsAppliedStyle).value == "True") {
                this.vars.numberOfPeopleSelect[this.vars.numberOfPeopleValue].selected = true;
            }
            else {
                this.vars.numberOfPeopleSelect[0].selected = true;
            }
        }
    },

    // Called when the No People filter is checked. Sets the MSO Number
    // of People filter to 'Any'.
    verifyNumberOfPeopleChecked: function() {
        this.initialize();

        // Set global var to the 'Any' value 
        this.vars.numberOfPeopleValue = "5";

        if (this.vars.noPeopleCheckBox) {
            if (CorbisUI.ImageCb.getImageCbObject(this.vars.noPeopleCheckBox).getCheckedState()) {
                if (this.vars.numberOfPeopleSelect.selectedIndex > 0) {
                    this.vars.numberOfPeopleSelect[0].selected = true;
                }
            }
        }
    },

    isDate: function(dateString) {
        try {
            var dateParts = CorbisUI.ExtendedSearch.vars.DateTimeFormat.split(CorbisUI.ExtendedSearch.vars.DateSeparator);
            var dateValues = dateString.split(CorbisUI.ExtendedSearch.vars.DateSeparator);
            var mm, dd, yyyy;
            for (var i = 0; i < dateParts.length; i++) {
                if (dateParts[i].indexOf('M') > -1) {
                    mm = dateValues[i];
                }
                if (dateParts[i].indexOf('y') > -1) {
                    yyyy = dateValues[i];
                }
                if (dateParts[i].indexOf('d') > -1) {
                    dd = dateValues[i];
                }
            }
            var d = new Date(mm + "/" + dd + "/" + yyyy);
            return d.getMonth() + 1 == mm && d.getDate() == dd && d.getFullYear() == yyyy;
        } catch (ex) {
            return false;
        }
    },

    getLocalDate: function(dateString) {
        var dateParts = CorbisUI.ExtendedSearch.vars.DateTimeFormat.split(CorbisUI.ExtendedSearch.vars.DateSeparator);
        var dateValues = dateString.split(CorbisUI.ExtendedSearch.vars.DateSeparator);
        var mm, dd, yyyy;
        for (var i = 0; i < dateParts.length; i++) {
            if (dateParts[i].indexOf('M') > -1) {
                mm = dateValues[i];
            }
            if (dateParts[i].indexOf('y') > -1) {
                yyyy = dateValues[i];
            }
            if (dateParts[i].indexOf('d') > -1) {
                dd = dateValues[i];
            }
        }
        var d = new Date(mm + "/" + dd + "/" + yyyy);
        return d;
    },

    checkDateValues: function() {
        this.initialize();
        if (this.vars.betweenBtn) {
            if (this.vars.betweenBtn.checked) {
                if (!this.isDate(this.vars.startDate) || !this.isDate(this.vars.endDate)) {
                    alert(this.vars.notDateErr);
                    return false;
                }
                else if (this.isDate(this.vars.startDate) && this.isDate(this.vars.endDate)) {
                    var date1 = this.getLocalDate(this.vars.startDate);
                    var date2 = this.getLocalDate(this.vars.endDate);
                    if (Date.parse(date1) > Date.parse(date2)) {
                        alert(this.vars.AlertDateText);
                        return false;
                    } else {
                        CorbisUI.ExtendedSearch.vars.noSearchMsg = false;
                    }
                } else {
                    alert(this.vars.AlertDateText);
                    return false;
                }
            }
        }
        return true;
    },

    clearRadioDaysText: function() {
        this.initialize();
        if (this.vars.radioBetweenButton.checked) {
            this.vars.radioDaysTextBox.value = '';
        }
    }

}

//End: /Scripts/CorbisUI.MSOSearch.js
//Begin: /Scripts/CorbisUI.Watermark.js

/****************************************************
    Corbis UI Watermark
***************************************************/

CorbisUI.Watermark = {
    initialize: function() {
        $$('.Watermarked').each(function(el) {
            if (el.value.trim() == "") {
                el.value = el.title;
                el.setProperty('class', el.getProperty('class') + " " + el.getProperty('watermarkcss'));
            }
            el.addEvent("click", function() {
                if (this.value == this.title) {
                    this.value = "";
                    this.setProperty('class', this.getProperty('class').replace(this.getProperty('watermarkcss'), ""));
                }
            });
            el.addEvent("focus", function() {
                if (this.value == this.title) {
                    this.value = "";
                    this.setProperty('class', this.getProperty('class').replace(this.getProperty('watermarkcss'), ""));
                }
            });
            el.addEvent("blur", function() {
                if (this.value.trim() == "") {
                    this.value = this.title;
                    this.setProperty('class', this.getProperty('class') + " " + this.getProperty('watermarkcss'));
                }
            });
        });
    },

    ChangeValue: function(el) {
        try {
            if (el.value.trim() == "") {
                el.value = el.title;
                el.setProperty('class', el.getProperty('class') + " " + el.getProperty('watermarkcss'));
            } else {
                el.setProperty('class', el.getProperty('class').replace(el.getProperty('watermarkcss'), ""));
            }
        } catch (exception) {

        }
    }
};
//End: /Scripts/CorbisUI.Watermark.js
//Begin: /Scripts/CorbisUI.CustomerService.js

/****************************************************
    Corbis UI Customer Service
***************************************************/

CorbisUI.CustomerService = new Class({

    vars: {
        popupAnchor: null
    },

    init: function() {
    this.vars.popupAnchor = $('getThankYouWindow');   
    },

setFooterHeight:function() {
$('FooterContent').setStyle('margin-top', '30px');
},

    clearGetInTouchForm: function() {
        var control = $('formTable').getElements('input');

        // Clear out text inputs
        control.each(function(el) {
            if (el.type == "text") {
                el.value = '';
            }
        }, this);

        // Clear select boxes - set index to 0
        control = $('formTable').getElements('select');
        control.each(function(el) {
            el.selectedIndex = 0;
        }, this);

        // Set textarea to default text
        control = $('formTable').getElements('textarea');
        control.each(function(el) {
            el.value = '';
        }, this);
    },
    OpenThankYouPopup: function() {
        new CorbisUI.Popup('getThankYou', {
            showModalBackground: false,
            closeOnLoseFocus: true,
            positionVert: 'middle',
            positionHoriz: 'bottom'
        });
        this.init();
        this.vars.popupAnchor.setStyles({
            top: 650,
            left: 660
        });
        this.vars.popupAnchor.getElement('.FormButtons').setStyle('margin-top', 5);
        this.vars.popupAnchor.getElement('div .GlassButton').setStyles({
            marginTop: 8,
            marginRight: -10
        });
    }
});
CorbisUI.CustomerService = new CorbisUI.CustomerService();

//End: /Scripts/CorbisUI.CustomerService.js
//Begin: /Scripts/CorbisUI.MyProfile.js

/****************************************************
    Corbis UI MyProfile
****************************************************/


//  CorbisUI.MyProfile Class
//  Contains IModals, Popups, Tooltip
//  and Pane functionality for the Accordion.
//  Also Password for the MyAccounts pages because it
//  is a secure area and different from the SignIn password. 
//  Auth: Travis O. & Rob B.

CorbisUI.MyProfile = new Class({

    vars: {
        source: null,
        sourceEditPayment: null,
        sourceBusiness: null,
        sourceMailingAddress: null,
        popupAnchor: null,
        base: null,
        g_firefox: null,
        g_IE: null,
        ThumbTips: null,
        sourceShippingAddress: null,
        updateBusinessInfoPaneButton: null,
        updatePersonalInfoPaneButton: null,
        updatePreferencesPaneButton: null,
        updatePaymentPaneButton: null,
        hiddenPanesGroupA: null,
        hiddenPanesGroupB: null,
        hiddenPanesGroupC: null,
        hiddenPanesGroupD: null,
        refreshOnce: false
    },

    init: function() {
        this.vars.source = '/Accounts/ChangePersonalInformation.aspx';
        this.vars.sourceEditPayment = '/Checkout/EditPaymentInformation.aspx';
        this.vars.sourceBusiness = '/Accounts/EditBusinessInformation.aspx';
        this.vars.sourceMailingAddress = '/Accounts/EditMailingAddress.aspx';
        this.vars.sourceShippingAddress = '/Accounts/EditShippingAddress.aspx';
        this.vars.popupAnchor = $('getThankYouWindow');
        this.vars.base = $('getExpressCheckout');
        this.vars.g_firefox = document.getElementById && !document.all;
        this.vars.g_IE = Browser.Engine.trident;
        this.vars.hiddenPanesGroupA = [$('businessInfoPaneDiv'), $('paymentPaneDiv'), $('preferencesPaneDiv')];
        this.vars.hiddenPanesGroupA_v2 = [$('businessInfoPaneDiv'), $('preferencesPaneDiv')];
        this.vars.hiddenPanesGroupB = [$('personalInfoPaneDiv'), $('paymentPaneDiv'), $('preferencesPaneDiv')];
        this.vars.hiddenPanesGroupB_v2 = [$('personalInfoPaneDiv'), $('preferencesPaneDiv')];
        this.vars.hiddenPanesGroupC = [$('personalInfoPaneDiv'), $('businessInfoPaneDiv'), $('preferencesPaneDiv')];
        this.vars.hiddenPanesGroupD = [$('personalInfoPaneDiv'), $('businessInfoPaneDiv'), $('paymentPaneDiv')];
        this.vars.hiddenPanesGroupD_v2 = [$('personalInfoPaneDiv'), $('businessInfoPaneDiv')];
    },

    OpenMyPersonalInformation: function() {
        this.init();
        OpenNewIModal(this.vars.source, 360, 540, 'personalInfoModalPopup');
    },

    OpenEditPaymentInformation: function(guid, mode) {
        this.init();
        var ht;
        var source = this.vars.sourceEditPayment;
        source = source + "?parentpage=myprofile";
        if (guid) {
            source = source + "&selectedSubscriptionId=" + guid;
        }
        if (mode) {
            source = source + "&mode=" + mode;
        }
        if (this.vars.g_firefox) {
            ht = 250;
        } else {
            ht = 280;
        }
        if (mode == "delete") {
            ht = 115;
        }
        OpenNewIModal(source, 700, ht, 'editPaymentInfoModalPopup');
    },

    OpenEditBusinessInformation: function() {
        if (this.vars.g_firefox) {
            this.init();
            OpenNewIModal(this.vars.sourceBusiness, 350, 440, 'editBusinessInformation');
        } else {
            this.init();
            OpenNewIModal(this.vars.sourceBusiness, 350, 500, 'editBusinessInformation');
        }
    },

    OpenEditMailingAddress: function() {
        if (this.vars.g_firefox) {
            this.init();
            OpenNewIModal(this.vars.sourceMailingAddress, 350, 300, 'editMailingAddress');
        } else {
            this.init();
            OpenNewIModal(this.vars.sourceMailingAddress, 350, 360, 'editMailingAddress');
        }
    },

    OpenSuccessPopup: function() {
        new CorbisUI.Popup('getSuccess', {
            showModalBackground: false,
            closeOnLoseFocus: true,
            positionVert: 'middle',
            positionHoriz: 'bottom'
        });
    },

    OpenSuccessPopup_andReload: function(reloadURL) {
        new CorbisUI.Popup('getSuccess', {
            showModalBackground: false,
            closeOnLoseFocus: true,
            positionVert: 'middle',
            positionHoriz: 'bottom',
            onHide: CorbisUI.MyProfile.OpenSuccessPopup_andReload_action.pass(reloadURL)
        });

        var win = $('getSuccessWindow');
        var xClose = win.getElement('input.Close');
        var btnClose = win.getElement('div.GlassButton input[id$=GlassButton]');
        btnClose.addEvent('click', CorbisUI.MyProfile.OpenSuccessPopup_andReload_action.pass(reloadURL));
        xClose.addEvent('click', CorbisUI.MyProfile.OpenSuccessPopup_andReload_action.pass(reloadURL));
    },

    OpenSuccessPopup_andReload_action: function(URL) {
        //alert(URL); 
        window.location = URL;
    },

    OpenSuccessChinaPopup: function() {
        new CorbisUI.Popup('registerSuccessDiffCountry', {
            showModalBackground: false,
            closeOnLoseFocus: true,
            positionVert: 'middle',
            positionHoriz: 'bottom'
        });
    },

    registerTooltips: function(isFirstTime) {
        $('aspnetForm').getAllNext('.TIP-license-details').destroy();
        var tipShowDelay = 500;
        var tipHideDelay = 100;
        var tipShowMethod = "in";
        var tipHideMethod = "out";
        if (Browser.Engine.trident) {
            tipShowDelay = 0;
            tipHideDelay = 0;
            tipShowMethod = "show";
            tipHideMethod = "hide";
        }
        this.vars.ThumbTips = new Tips('.thumbWrap', {
            showDelay: tipShowDelay,
            hideDelay: tipHideDelay,
            offsets: { x: 0, y: -130 },
            className: 'TIP-license-details mochaContent lineHeight',
            onHide: function(tip) {
                tip.fade(tipHideMethod);
            },
            onShow: function(tip) {
                tip.fade(tipShowMethod);
            }
        });
    },

    refreshPersonalInfoPane: function() {
        this.vars.updatePersonalInfoPaneButton.click();
    },

    refreshBusinessInfoPane: function() {
        this.vars.updateBusinessInfoPaneButton.click();
    },

    refreshPreferencesPane: function() {
        this.vars.updatePreferencesPaneButton.click();
    },

    refreshPaymentPane: function() {
        if (this.vars.updatePaymentPaneButton != null) {
            this.vars.updatePaymentPaneButton.click();
        }
    },

    ResizePaymentInfo: function() {
        if (this.vars.refreshOnce) {
            this.vars.refreshOnce = false;
        } else {
            var divPay = $$('.paymentPaneDiv .PaneContent')[0];
            var divPayContent = $$('.paymentPaneDiv .PaneContent div')[0];
            divPay.setStyle('height', '66px');
            divPay.setStyle('height', divPayContent.getSize().y + 8);
            // Whenever we update payment, we need to refresh preferences too
            this.vars.refreshOnce = true;
            this.refreshPreferencesPane();
        }
    },

    ResizeBusinessInfo: function() {
        var divPay = $('businessInfoPaneContent');
        divPay.setStyle('height', divPay.getScrollSize().y);
    },

    ResizePersonalInfo: function() {
        var divPay = $('personalInfoPaneContent');
        divPay.setStyle('height', divPay.getScrollSize().y);
    },

    ResizePreferences: function() {
        if (this.vars.refreshOnce) {
            this.vars.refreshOnce = false;
        } else {
            this.vars.refreshOnce = true;
            this.refreshPaymentPane();
        }
        this.registerTooltips(false);
    },

    doChangePasswordSuccess: function() {
        MochaUI.CloseModal('changePassword');
        OpenModal('passwordSuccessDiv');
    },

    changePassword: function() {
        OpenNewIModal('/Accounts/ChangePassword.aspx', 350, 200, 'changePassword');
        var iframeCP = $(document.body).getElement('iframe');
        iframeCP.setProperty('scrolling', 'no');
        iframeCP.setStyle('overflow', 'hidden');
    },

    GetPane: function() {
        var pane = '';
        var setPane = 0;
        $('personalInfoPaneDiv').setStyle('overflow', 'visible');
        var querystring = window.location.search.substring(1);
        var querystringArray = querystring.split("&");
        for (i = 0; i < querystringArray.length; i++) {
            var querystringKeyValue = querystringArray[i].split("=");
            if (querystringKeyValue[0] == 'Pane') {
                pane = querystringKeyValue[1];
            }
        }
        switch (pane) {
            case 'personalInfoPane':
                setPane = 0;
                $('personalInfoPaneDiv').setStyle('overflow', 'visible');
                break;
            case 'businessInfoPane':
                setPane = 1;
                $('businessInfoPaneDiv').setStyle('overflow', 'visible');
                break;
            case 'paymentPane':
                setPane = 2;
                $('paymentPaneDiv').setStyle('overflow', 'visible');
                break;
            //            case 'shippingPane':                            
            //                setPane = 3;                            
            //                break;                            
            case 'preferencesPane':
                setPane = 3;
                $('preferencesPaneDiv').setStyle('overflow', 'visible');
                break;
        }
        return setPane;
    },

    getPaneDiv: function(div) {

        this.init();

        switch (div) {
            case 0:
                $('personalInfoPaneDiv').setStyle('overflow', 'visible');
                if ($('paymentPaneDiv') != null) {
                    this.vars.hiddenPanesGroupA.each(function(item) { item.setStyle('overflow', 'hidden') });
                    $('AccountsContent').removeClass('AccountsContentExpanded');
                } else {
                    this.vars.hiddenPanesGroupA_v2.each(function(item) { item.setStyle('overflow', 'hidden') });
                    $('AccountsContent').removeClass('AccountsContentExpanded_noPaymentPane');
                }

                $('preferencesPaneDiv').removeClass('MB_10');
                break;
            case 1:
                $('businessInfoPaneDiv').setStyle('overflow', 'visible');
                if ($('paymentPaneDiv') != null) {
                    this.vars.hiddenPanesGroupB.each(function(item) { item.setStyle('overflow', 'hidden') });
                    $('AccountsContent').removeClass('AccountsContentExpanded');
                } else {
                    this.vars.hiddenPanesGroupB_v2.each(function(item) { item.setStyle('overflow', 'hidden') });
                    $('AccountsContent').removeClass('AccountsContentExpanded_noPaymentPane');
                }

                $('preferencesPaneDiv').removeClass('MB_10');
                break;
            case 2:
                $('paymentPaneDiv').setStyle('overflow', 'visible');
                this.vars.hiddenPanesGroupC.each(function(item) { item.setStyle('overflow', 'hidden') });
                $('AccountsContent').removeClass('AccountsContentExpanded');
                $('preferencesPaneDiv').removeClass('MB_10');
                break;
            case 3:
                $('preferencesPaneDiv').setStyle('overflow', 'visible').addClass('MB_10');
                if ($('paymentPaneDiv') != null) {
                    this.vars.hiddenPanesGroupD.each(function(item) { item.setStyle('overflow', 'hidden') });
                    $('AccountsContent').addClass('AccountsContentExpanded');
                } else {
                    this.vars.hiddenPanesGroupD_v2.each(function(item) { item.setStyle('overflow', 'hidden') });
                    $('AccountsContent').addClass('AccountsContentExpanded_noPaymentPane');
                }

                break;
        }
    }

});
CorbisUI.MyProfile = new CorbisUI.MyProfile();
//End: /Scripts/CorbisUI.MyProfile.js
//Begin: /Scripts/CorbisUI.Pricing.js

/****************************************************
    Corbis UI Pricing
****************************************************/

CorbisUI.Pricing = {
    RequestPrice: {
        countryList: null,
        domReady: function(countryListId) {
            this.countryList = $(countryListId);
            this.toggleStateAsterisk();
            this.countryList.addEvent('change', this.toggleStateAsterisk.bind(this));
        },
        toggleStateAsterisk: function() {
            var selected = this.countryList.getSelected()[0].value;

            if (selected === 'US' || selected === 'CA' || selected === 'AU' || selected === 'GB') {
                $('stateAsterisk').setStyle('visibility', 'visible');
            }
            else {
                $('stateAsterisk').setStyle('visibility', 'hidden');
            }
        }
    },
    IsAuthenticated: function(controlId) {
        if (CorbisUI.Auth.GetSignInLevel() < CorbisUI.Auth.SignInLevels.AutoLoggedIn) {
            CorbisUI.Auth.Check(CorbisUI.Auth.SignInLevels.AutoLoggedIn, CorbisUI.Auth.ActionTypes.Execute, "$('" + controlId + "').click()");
            return false;
        } else {
            return true;
        }
    },
    ContactUs: {
        vars: {
            source: null,
            corbisid: null,
            lightboxid: null,
            container: null,
            optionselected: null,
            popupAnchor: null
        },
        init: function() {
            this.vars.source = '/Pricing/RequestPrice.aspx';
            this.vars.popupAnchor = $('getThankYouWindow');
        },
        OpenRequestForm: function(corbisid, lightboxid, selectedoption, containername) {
            this.init();
            this.vars.source = this.vars.source + '?corbisid=' + corbisid + '&lightboxid=' + lightboxid + '&optionselected=' + selectedoption + '&container=' + containername;
            OpenNewIModal(this.vars.source, 500, 600, 'requestPriceModalPopup');
        },
        HideRequestForm: function() {
            if (parent && parent.MochaUI) {
                parent.MochaUI.CloseModal('requestPriceModalPopup');
            } else if (parent && parent.CorbisUI.CTip) {
                parent.CorbisUI.CTip.IFrameModal.hide();
            }
        },
        OpenContactCorbis: function(corbisid, lightboxid, selectedoption, containername) {
            parent.CorbisUI.Pricing.ContactUs.OpenRequestForm(corbisid, null, 1, containername);
        },
        clearGetInTouchForm: function(openThankYou) {
            var g_firefox = document.getElementById && !document.all;
            if (g_firefox) {
                var control = $('formTable').getElements('input');
            }
            else {
                var control = $('aspnetForm').getElements('input');
            }
            control.each(function(el) {
                if (el.type == "text") {
                    el.value = '';
                }
            }, this);
            control = $('formTable').getElements('select');
            control.each(function(el) {
                el.selectedIndex = 0;
            }, this);
            control = $('formTable').getElements('textarea');
            control.each(function(el) {
                el.value = '';
            }, this);
            if (openThankYou) CorbisUI.QueueManager.thankyou.run();
        },
        setupThankYouQueue: function() {
            CorbisUI.QueueManager.addQueue('thankyou');
            CorbisUI.QueueManager.thankyou.addItem('openThankYou', function() { CorbisUI.Pricing.ContactUs.OpenThankYouPopup(); });
        },
        OpenThankYouPopup: function() {
            (function() {
                new CorbisUI.Popup('getThankYou', {
                    showModalBackground: false,
                    closeOnLoseFocus: true,
                    positionVert: 'middle',
                    positionHoriz: 'bottom'
                });
            }).delay(200);
        }
    },
    RM: {
        vars: {
            SaveFavoriteUsageButtonID: null
        },
        RegisterToolTips: function() {
            var usageButton = $(CorbisUI.Pricing.RM.vars.SaveFavoriteUsageButtonID);
            if (usageButton == null) {
                return;
            }
            if (usageButton.hasClass('DisabledGlassButton')) {
                return;
            }
            $('aspnetForm').getAllNext('.TIP-license-details').destroy();
            var tipShowDelay = 500;
            var tipHideDelay = 100;
            var tipShowMethod = "in";
            var tipHideMethod = "out";
            if (Browser.Engine.trident) {
                tipShowDelay = 0;
                tipHideDelay = 0;
                tipShowMethod = "show";
                tipHideMethod = "hide";
            }
            new Tips('#' + usageButton.getProperty('id'), {
                showDelay: tipShowDelay,
                hideDelay: tipHideDelay,
                offsets: { x: 20, y: 20 },
                className: 'TIP-license-details mochaContent',
                onHide: function(tip) {
                    tip.fade(tipHideMethod);
                },
                onShow: function(tip) {
                    tip.fade(tipShowMethod);
                }
            });
        }
    },
    RF: {
        vars: {
            priceLabel: null,
            localizedValue: null,
            priceCode: null,
            hidAttributeUID: null,
            hidAttributeValueUID: null,
            delay: 0,
            myPricingList: null,
            cartButton: null,
            lightboxButton: null,
            dataChanged: false
        },
        highlightSelectedRow: function() {
            if (CorbisUI.Pricing.RF.vars.hidAttributeValueUID.value != null && CorbisUI.Pricing.RF.vars.hidAttributeValueUID.value != "") {
                var rowFlag = CorbisUI.Pricing.RF.vars.hidAttributeValueUID.value;
                (function() {
                    var selectedItem = $('srf_middlecontent').getElement("input[value=" + rowFlag + "]");
                    if (selectedItem) {
                        var parent = selectedItem.getNext('ul');
                        CorbisUI.Pricing.RF.vars.myPricingList.pricingListClick(parent);
                        CorbisUI.Pricing.RF.dataChanged = false;
                    }

                }).delay(CorbisUI.Pricing.RF.vars.delay);
            }
        },
        getLocalizedPayment: function() {
            CorbisUI.Pricing.RF.vars.priceLabel.innerHTML = CorbisUI.Pricing.RF.vars.localizedValue;
        },
        setLabelValue: function(value) {
            CorbisUI.Pricing.RF.vars.priceLabel.innerHTML = value.localeFormat('C');
        },
        setPriceLabel: function(amount) {
            CorbisUI.Pricing.RF.vars.priceLabel.innerHTML = amount;
        },
        doRFClick: function(el) {
            var inputs = el.getParent().getChildren("input");
            CorbisUI.Pricing.RF.vars.hidAttributeUID.value = inputs[0].value;
            CorbisUI.Pricing.RF.vars.hidAttributeValueUID.value = inputs[1].value;
            $$('div .imageContainer').setStyle('display', 'none');
            $$('div .licenseAlertDiv').setStyle('display', 'none');
            this.vars.dataChanged = true;
            CorbisUI.Pricing.RF.vars.localizedValue = inputs[3].value;
            this.setPriceLabel(inputs[3].value);
            $('srf_selectedPriceText').value = inputs[2].value + ' ' + CorbisUI.Pricing.RF.vars.priceCode.get('text').replace('(', '').replace(')', '');
        },
        DomReady: function() {
            if (Browser.Engine.trident) {
                CorbisUI.Pricing.RF.vars.delay = 400;
            }
            CorbisUI.Pricing.RF.highlightSelectedRow();
        },
        Resize: function() {
            if(parent && parent.ResizeIModal) {
                parent.ResizeIModal('pricing', GetDocumentHeight());
            }
        },
        OpenRestrictions: function(element) {
            new CorbisUI.Popup('restrictionsPopup', {
                showModalBackground: false,
                centerOverElement: element,
                closeOnLoseFocus: true,
                positionVert: 'top',
                positionHoriz: 'right'
            });
        },
        OpenCustomPriceExpired: function(element) {
            new CorbisUI.Popup('customPriceExpired');
        },
        updatedPricingDataCheck: function(link) {
            PricingModalPopupExit();
            return false;
        },
        checkTab: function(el) {
            if ((document.all) && (9 == event.keyCode)) {
                $('OuterContainer').focus();
            }
        },
        ShowAddToLightboxModal: function(offeringUid) {
            if (CorbisUI.Auth.GetSignInLevel() < 1) {
                var fnName = "CorbisUI.Pricing.RF.ShowAddToLightboxModal_AfterLogIn('" + offeringUid + "');";
                CorbisUI.Auth.Check(1, 'execute', fnName);
            }
            else {
                DoAddToLightboxModal(offeringUid, null, false);
            }
        },
        ShowAddToLightboxModal_AfterLogIn: function(offeringUid) {
            CorbisUI.CookieEvents.addCookieEvent_altPath('/Pricing', function() {
                CorbisUI.Pricing.RF.vars.hidAttributeValueUID.value = this.vars.AV;
                CorbisUI.Pricing.RF.highlightSelectedRow();
                DoAddToLightboxModal(this.vars.OID, null, false);
            }, { OID: offeringUid, AV: this.vars.hidAttributeValueUID.value });
            var temp = JSON.decode("{\"tempFunc\":function(){OpenIModal('" + window.location + "', 640, 480);  }}");
            window.parent.CorbisUI.CookieEvents.addCookieEvent(temp.tempFunc);
            window.parent.location.reload();
        },
        checkoutNow: function(url, isEnlargement) {
            var parentWindow = parent.window;
            var closeParent = false;
            if (isEnlargement) {
                parentWindow = parentWindow.enlargementOpener;
                if (parentWindow) {
                    closeParent = true;
                }
            }
            if (isEnlargement && (!closeParent || parentWindow.closed)) {
                window.open(url);
            }
            else {
                parentWindow.location = url;
            }
            PricingModalPopupExit();
            if (closeParent) {
                parent.window.close();
            }
        },
        PricingList: new Class({
            initialize: function(elements, options) {
                this.setupListEvents();
            },
            setupListEvents: function() {
                $$('div.RFPricingRepeater ul').each(function(el) {
                    el.addEvents({
                        'click': function() {
                            this.pricingListClick(el);
                        } .bind(this)
                    });
                }, this);
            },
            pricingListClick: function(el) {
                el.getElement('.srf_licenseRB').checked = true;
                CorbisUI.Pricing.RF.doRFClick(el);
            }
        }),
        clearAE: function() {
            CorbisUI.Pricing.RF.vars.pricedByAE = false;
            $(this.vars.aeHeaderCID).addClass("hdn");
            $(this.vars.aeDataCID).addClass("hdn");
            $(this.vars.normalHeaderCID).removeClass("hdn");
            $(this.vars.normalDataCID).removeClass("hdn");
            this.Resize();
        },
        rfInit: function() {
            this.vars.myPricingList = new this.PricingList();
            window.addEvent('domready', this.DomReady);
            window.addEvent('load', this.Resize);
            window.addEvent('load', function() { var PPA_items = $$('.PPAToolTip'); if (PPA_items) { PPA_Tooltip = new CorbisUI.Tooltip(PPA_items); } });
        },
        setIsSavedUsage: function() {
            isSavedUsage = true;
        },
        ParentPageRedirect: function() {
            try {
                self.parent.frames.location.reload();
                parent.CloseModal('pricing');
            }
            catch (Exception) { }
        },
        disableCartAndLightBoxButtons: function() {
            this.vars.cartButton.addClass('DisabledGlassButton');
            $(this.vars.cartButton.id + '_GlassButton').setProperty('disabled', 'disabled');
            this.vars.checkoutNowButton.addClass('DisabledGlassButton');
            $(this.vars.checkoutNowButton.id + '_GlassButton').setProperty('disabled', 'disabled');
        },
        enableCartAndLightBoxButtons: function() {
            if (!isSavedUsage) {
                if (this.vars.hidUpdatingCart.value != 'True') {
                    this.vars.cartButton.removeClass('DisabledGlassButton');
                    $(this.vars.cartButton.id + '_GlassButton').removeProperty('disabled');
                    this.vars.checkoutNowButton.removeClass('DisabledGlassButton');
                    $(this.vars.checkoutNowButton.id + '_GlassButton').removeProperty('disabled');
                }
            }
            else {
                this.vars.cartButton.removeClass('DisabledGlassButton');
                $(this.vars.cartButton.id + '_GlassButton').removeProperty('disabled');
                this.vars.checkoutNowButton.removeClass('DisabledGlassButton');
                $(this.vars.checkoutNowButton.id + '_GlassButton').removeProperty('disabled');
            }
        },
        ValidateCheckoutNow: function(buttonEl) {
            if (CorbisUI.Pricing.RF.vars.pricedByAE ||
            (CorbisUI.Pricing.RF.vars.hidAttributeValueUID.value != null &&
            CorbisUI.Pricing.RF.vars.hidAttributeValueUID.value != "")) {
                return true;
            }
            new CorbisUI.Popup('checkoutNowErrorPopup', {
                showModalBackground: false,
                centerOverElement: $(buttonEl.id),
                closeOnLoseFocus: true,
                positionVert: 'top',
                positionHoriz: 'left',
                offsetVert: 22,
                offsetHoriz: 10,
                resizeBeforePosition: true
            });
            return false;
        }
    }
};


//End: /Scripts/CorbisUI.Pricing.js
//Begin: /Scripts/CorbisUI.FormUtilities.js

/****************************************************
    Corbis UI Form Utilities
****************************************************/

CorbisUI.FormUtilities = {};

// This class binds a country dropdown to its dependant province dropdown.
// To maintain the form state on the server, the province hidden fields are
// used to pass values back to the server. Everything but the disabledOptionText is required
// Author: Ron Gilchrist
CorbisUI.FormUtilities.ProvinceBehavior = new Class({
    Implements: [Options],
    options: {
        countriesDropdownId: false,
        provinceDropdownId: false,
        provinceNameHdnId: false,
        provinceCodeHdnId: false,
        ajaxUrl: false,
        validationClass: $empty,
        disabledOptionText: ' - - -'
    },
    countryEl: $empty,
    provinceEl: $empty,
    hdnNameEl: $empty,
    hdnCodeEl: $empty,
    initialize: function(options) {
        this.setOptions(options);
        this.countryEl = $(this.options.countriesDropdownId);
        this.provinceEl = $(this.options.provinceDropdownId);
        this.hdnNameEl = $(this.options.provinceNameHdnId);
        this.hdnCodeEl = $(this.options.provinceCodeHdnId);
        var countryChange = function(e) {
            var req = new Request.HTML({
                method: 'post',
                url: this.options.ajaxUrl,
                data: { country: this.countryEl.value },
                onRequest: function() { },
                onComplete: function(responseTree, responseElements, responseHtml) {
                    this.provinceEl.empty();
                    var Data = parseXMLDoc(responseHtml);
                    if (Data && Data.getElementsByTagName('ContentItem').length > 0) {

                        var ContentItemArray = Data.getElementsByTagName('ContentItem');
                        var ContentItemObject;
                        var KeyObject;
                        var ValueObject;

                        this.provinceEl.removeProperty('disabled');
                        for (var i = 0; i < ContentItemArray.length; i++) {
                            ContentItemObject = ContentItemArray[i];
                            KeyObject = ContentItemObject.getElementsByTagName('Key')[0].childNodes[0].nodeValue;
                            ValueObject = ContentItemObject.getElementsByTagName('ContentValue')[0].childNodes[0].nodeValue;
                            var opt = new Element('option', { value: KeyObject });
                            opt.set('text', ValueObject);
                            opt.inject(this.provinceEl);
                        }



                        if (Data.getElementsByTagName('ContentItem').length == 1) {
                            this.provinceEl.setProperty('disabled', 'disabled');
                            this.hdnNameEl.value = '';
                            this.hdnCodeEl.value = '';
                        }
                    }

                } .bind(this),
                onFailure: function() { }
            }).send();
        }
        var countryChangeHandler = countryChange.bindWithEvent(this);
        var stateChange = function(e) {
            var opt = this.provinceEl.getElements('option')[this.provinceEl.selectedIndex];
            var isEmpty = this.provinceEl.getElements('option').length == 1;
            this.hdnNameEl.value = isEmpty ? '' : opt.get('text');
            this.hdnCodeEl.value = isEmpty ? '' : this.provinceEl.value;
        }
        var stateChangeHandler = stateChange.bindWithEvent(this);
        this.countryEl.addEvent('change', countryChangeHandler);
        this.provinceEl.addEvent('change', stateChangeHandler);
    },
    validateProvince: function(doHilite) {
        var expression = this.provinceEl.getElements('option').length == 1 || this.provinceEl.selectedIndex > 0;
        if (doHilite) this.options.validationClass.highlightRow(!expression, this.provinceEl);
        return expression;
    },
    validateCountry: function(doHilite) {
        var expression = this.countryEl.selectedIndex != 0;
        if (doHilite) this.options.validationClass.highlightRow(!expression, this.countryEl);
        return expression;
    }
});
//End: /Scripts/CorbisUI.FormUtilities.js
//Begin: /Scripts/CorbisUI.Events.js

/****************************
    NAMESPACE CHECK
****************************/
if (typeof (CorbisUI) == 'undefined') {
    CorbisUI = {};
}

/****************************
    EVENTS WATCHER
****************************/

CorbisUI.Events = {

    // simple class for watching key events
    KeyWatch: new Class({
        Implements: [Options],
        options: {
            toDo: 'preventDefault', // preventDefault, stop, stopPropagation, custom or hash
            event: 'keydown', // keydown should be used mostly for KeyWatch. Although keypress and keyup may work
            custom: false // placeholder for SINGLE custom function
        },

        obj: null, // reference to object to watch
        keys: [], // keys to watch [ NOTE: not the key code. the actual key. You may need to play around with mootools events to see what types of values get passed. ]
        eventItem: null, // placeholder for event function


        initialize: function(keys, options) {
            if (options) this.setOptions(options);

            switch ($type(keys)) {
                case "string":
                case "array":
                    $each(keys, function(item) {
                        this.keys.include(item);
                    }, this);
                    break;
                case "hash":
                case "object":
                    if (this.options.toDo != "hash") this.options.toDo = "hash";
                    this.keys = ($type(keys) == "hash") ? keys : new Hash(keys);
                    break;
            }
            this.obj = (Browser.Engine.trident) ? $(document.body) : $(window) ;

            return this;
        },

        start: function() {
            this.eventItem = this.manager.bind(this);
            this.obj.addEvent(this.options.event, this.eventItem);
        },

        stop: function() {
            this.obj.removeEvent(this.options.event, this.eventItem);
        },

        manager: function(event) {
            //console.log('EVENTS: Manager');
            var method = ($type(this.keys) == "hash") ? "has" : "contains";

            var keyCheck = (this.isSpecialKey(event)) ? this.isSpecialKey(event) : event.key;
            //console.log(keyCheck);

            if (this.keys[method](keyCheck)) {
                switch (this.options.toDo) {
                    case "preventDefault":
                    case "stop":
                    case "stopPropagation":
                        event[this.options.toDo]();
                        break;
                    case "custom":
                        this.options.custom.pass(event).bind(this).run();
                        break;
                    case "hash":
                        this.keys.get(keyCheck).pass(event).bind(this).run();
                        break;
                }
            }
        },

        isSpecialKey: function(e) {
            //console.log(e);
            // NOTE: some of these keys are not detectable in all browsers (like IE)
            var keyHash = new Hash({
                16: "shift",
                17: "ctl",
                18: "alt",
                19: "pause",
                20: "caps",
                144: "numlock",
                145: "scrolllock"

            });
            //alert(e.code);
            var key = (keyHash.has(e.code)) ? keyHash.get(e.code) : false;
            return key;
        }

    })
};

var keyWatch;
window.addEvent('domready', function() {
    keyWatch = new CorbisUI.Events.KeyWatch(['space', 'esc'], { toDo: "stop" });
    keyWatch.start();
});
function stopKeyWatch() {
    if(keyWatch) {
        keyWatch.stop();
    }
    else {
        setTimeout(stopKeyWatch, 2000);
    }
}
window.addEvent('load', function() {
    stopKeyWatch();
});

/*
if (Browser.Engine.gecko) {
    var easterEgg = new CorbisUI.Events.KeyWatch({
        "esc": function(e) {
            alert('numlock');
            if (e.alt && e.control && e.shift && !Browser.isHttps()) {
                var where_to = confirm("Do you like Easter?");
                if (where_to == true) {
                    var port = (Browser.getPort()) ? ":" + Browser.getPort() : "";
                    window.location = "http://" + Browser.getHost() + port + "/Search/SearchResults.aspx?q=easter+egg";
                }
                else {
                    alert('no easter egg for you then!');
                }

            }
        }
    });
    easterEgg.start();
}
*/






//End: /Scripts/CorbisUI.Events.js
//Begin: /Scripts/CorbisUI.Tooltip.js

/*
    generic function to setup tooltips.
    
    items (string or collection): the things you want to attach tooltips to
    options (object) : uses basic tips options pluse some custom options
    
    ** Custom Options **
        * showMethod - (string) How you want the tip fade in to be. Defaults to 'in'
        * hideMethod - (string) How you want the tip fade out to be. Defaults to 'out',
        * IEOverride - (boolean) If you set to true, it will override the options showMethod, hideMethod, showDelay, hideDelay. 
                                 Useful if your tip uses PNG images, because IE doesn't like fading in and out PNG images. Defaults to true.
    
    ** Basic Tips Class Options **
        // these are added in options already
        * onShow - (function: defaults to function(tip) { tip.fade(this.options.showMethod); }) The default function for the show event.
        * onHide - (function: defaults to function(tip) { tip.fade(this.options.hideMethod); }) The default function for the hide event.
        * showDelay - (number: defaults to 500) The delay the show event is fired.
        * hideDelay - (number: defaults to 100) The delay the hide hide is fired.
        * className - (string: defaults to null) the className your tooltip container will get. Useful for extreme styling.
              o The tooltip element inside the tooltip container above will have 'tip' as classname.
              o The title will have as classname: tip-title
              o The text will have as classname: tip-text
              
        // these CAN be added - but not necessary       
        * title - (string|function: defaults to title) The property of the element to be used for the tip-title. If this option is a function it will execute it on every element with it passed as the first argument. It uses the return value of this function as the tip-title
        * text - (string|function) Behaves the same as the title option but for tip-title. By default it either uses the rel or the href attribute as tip-title.
        * offset - (object: defaults to {'x': 16, 'y': 16}) The distance of your tooltip from the mouse.
        * fixed - (boolean: defaults to false) If set to true, the toolTip will not follow the mouse.

*/
CorbisUI.Tooltip = new Class({

    Implements: [Options],

    options: {
        onShow: function(tip) {
            tip.fade(this.options.showMethod);
        },

        onHide: function(tip) {
            tip.fade(this.options.hideMethod);
        },

        className: '.TIP-generic-block',

        showDelay: 500,
        hideDelay: 100,

        // CUSTOM OPTIONS
        showMethod: "in",
        hideMethod: "out",
        IEOverride: true
    },

    tipObject: null,

    attach: null,
    detach: null,

    initialize: function(items, options) {
    
        if (options) {
            if (options.className) {
                options.className = (options.className.substring(0, 1) != '.') ? '.' + options.className : options.className;
            }

            this.setOptions(options);
        }

        if (!this.options.skipRemoveAll) {
            $('aspnetForm').getAllNext(this.options.className).destroy();
        }
        
        // new Tips() takes class names without .
        
        this.options.className = this.options.className.substring(1, this.options.className.length);

        //this.tipCollection = ($type(items) == "array") ? items : $$(items);

        // sorry IE, have to dumb you down
        if (this.options.IEOverride && Browser.Engine.trident) {
            this.options.showDelay = 0;
            this.options.hideDelay = 0;
            this.options.showMethod = "show";
            this.options.hideMethod = "hide";
        }
        
        this.tipObject = new Tips(items, this.options);

        // lets alias some things
        this.attach = this.tipObject.attach.bind(this.tipObject);
        this.detach = this.tipObject.detach.bind(this.tipObject);

    },

    hideTip: function() {
        this.tipObject.tip.fade(this.options.hideMethod);
    }



});

//End: /Scripts/CorbisUI.Tooltip.js
//Begin: /Scripts/mocha-debug.js

/* 

Script: Core.js
	MUI - A Web Applications User Interface Framework.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.

License:
	MIT-style license.

Contributors:
	- Scott F. Frederick
	- Joel Lindau

Note:
	This documentation is taken directly from the javascript source files. It is built using Natural Docs.

*/

var MUI = MochaUI = new Hash({
	
	version: '0.9.6 development',

	options: new Hash({
		theme: 'default',				
		advancedEffects: false, // Effects that require fast browsers and are cpu intensive.
		standardEffects: true   // Basic effects that tend to run smoothly.
	}),

	path: {			
		source:  'scripts/source/', // Path to MochaUI source JavaScript
		themes:  'themes/',         // Path to MochaUI Themes
		plugins: 'plugins/'         // Path to Plugins
	},
	
	// Returns the path to the current theme directory
	themePath: function(){
		return MUI.path.themes + MUI.options.theme + '/'; 
	},
	
	files: new Hash()
	
});

//alert ('MOCHA: '+MochaUI.get('version'));

MUI.files[MUI.path.source + 'Core/Core.js'] = 'loaded';

MUI.extend({
	
	Windows: {
		instances: new Hash()
	},

	ieSupport: 'excanvas',  // Makes it easier to switch between Excanvas and Moocanvas for testing	
	
	/*
	
	Function: updateContent
		Replace the content of a window or panel.
		
	Arguments:
		updateOptions - (object)
	
	updateOptions:
		element - The parent window or panel.
		childElement - The child element of the window or panel recieving the content.
		method - ('get', or 'post') The way data is transmitted.
		data - (hash) Data to be transmitted
		title - (string) Change this if you want to change the title of the window or panel.
		content - (string or element) An html loadMethod option.
		loadMethod - ('html', 'xhr', or 'iframe')
		url - Used if loadMethod is set to 'xhr' or 'iframe'.
		scrollbars - (boolean)		
		padding - (object)
		onContentLoaded - (function)

	*/	
	updateContent: function(options){

		var options = $extend({
			element:      null,
			childElement: null,
			method:       null,
			data:         null,
			title:        null,
			content:      null,
			loadMethod:   null,
			url:          null,
			scrollbars:   null,			
			padding:      null,
			require:      {},
			onContentLoaded: $empty
		}, options);		
	
		options.require = $extend({
			css: [], images: [], js: [], onload: null
		}, options.require);		
		
		var args = {};
				
		if (!options.element) return;
		var element = options.element;		

		if (MUI.Windows.instances.get(element.id)){
			args.recipient = 'window';		
		}
		else {
			args.recipient = 'panel';		
		}

		var instance = element.retrieve('instance');
		if (options.title) instance.titleEl.set('html', options.title);			

		var contentEl = instance.contentEl;
		args.contentContainer = options.childElement != null ? options.childElement : instance.contentEl;		
		var contentWrapperEl = instance.contentWrapperEl;

		if (!options.loadMethod){
			if (!instance.options.loadMethod){
				if (!options.url){
					options.loadMethod = 'html';
				}
				else {
					options.loadMethod = 'xhr';
				}
			}
			else {	
				options.loadMethod = instance.options.loadMethod;
			}
		}	
				
		// Set scrollbars if loading content in main content container.
		// Always use 'hidden' for iframe windows
		var scrollbars = options.scrollbars || instance.options.scrollbars;
		if (args.contentContainer == instance.contentEl) {
			contentWrapperEl.setStyles({
				'overflow': scrollbars != false && options.loadMethod != 'iframe' ? 'auto' : 'hidden'
			});
		}		

		if (options.padding != null) {
			contentEl.setStyles({
				'padding-top': options.padding.top,
				'padding-bottom': options.padding.bottom,
				'padding-left': options.padding.left,
				'padding-right': options.padding.right
			});
		}

		// Remove old content.
		if (args.contentContainer == contentEl) {
			contentEl.empty().show();			
			// Panels are not loaded into the padding div, so we remove them separately.
			contentEl.getAllNext('.column').destroy();
			contentEl.getAllNext('.columnHandle').destroy();
		}
		
		args.onContentLoaded = function(){
			
			if (options.require.js.length || typeof options.require.onload == 'function'){
				new MUI.Require({
					js: options.require.js,
					onload: function(){
						if (Browser.Engine.presto){
							options.require.onload.delay(100);
						}
						else {
							options.require.onload();
						}
						options.onContentLoaded ? options.onContentLoaded() : instance.fireEvent('onContentLoaded', element);
					}.bind(this)		
				});
			}		
			else {
				options.onContentLoaded ? options.onContentLoaded() : instance.fireEvent('onContentLoaded', element);
			}			
		
		};
		
		if (options.require.css.length || options.require.images.length){
			new MUI.Require({
				css: options.require.css,
				images: options.require.images,
				onload: function(){
					this.loadSelect(instance, options, args);
				}.bind(this)		
			});
		}		
		else {
			this.loadSelect(instance, options, args);
		}
	},
	
	loadSelect: function(instance, options, args){					
				
		// Load new content.
		switch(options.loadMethod){
			case 'xhr':			
				this.updateContentXHR(instance, options, args);
				break;
			case 'iframe':
				this.updateContentIframe(instance, options, args);				
				break;
			case 'html':
			default:
				this.updateContentHTML(instance, options, args);
				break;
		}

	},
	
	updateContentXHR: function(instance, options, args){
		var contentEl = instance.contentEl;
		var contentContainer = args.contentContainer;
		var onContentLoaded = args.onContentLoaded;
		new Request.HTML({
			url: options.url,
			update: contentContainer,
			method: options.method != null ? options.method : 'get',
			data: options.data != null ? new Hash(options.data).toQueryString() : '', 
			evalScripts: instance.options.evalScripts,
			evalResponse: instance.options.evalResponse,				
			onRequest: function(){
				if (args.recipient == 'window' && contentContainer == contentEl){
					instance.showSpinner();
				}
				else if (args.recipient == 'panel' && contentContainer == contentEl && $('spinner')){
					$('spinner').show();	
				}
			}.bind(this),
			onFailure: function(response){
				if (contentContainer == contentEl){
					var getTitle = new RegExp("<title>[\n\r\s]*(.*)[\n\r\s]*</title>", "gmi");
					var error = getTitle.exec(response.responseText);
					if (!error) error = 'Unknown';							 
					contentContainer.set('html', '<h3>Error: ' + error[1] + '</h3>');
					if (args.recipient == 'window'){
						instance.hideSpinner();
					}							
					else if (args.recipient == 'panel' && $('spinner')){
						$('spinner').hide();
					}						
				}
			}.bind(this),
			onSuccess: function(){
				if (contentContainer == contentEl){
					if (args.recipient == 'window') instance.hideSpinner();							
					else if (args.recipient == 'panel' && $('spinner')) $('spinner').hide();							
				}
				Browser.Engine.trident4 ? onContentLoaded.delay(750) : onContentLoaded();
			}.bind(this),
			onComplete: function(){}.bind(this)
		}).send();
	},
	
	updateContentIframe: function(instance, options, args){
		var contentEl = instance.contentEl;
		var contentContainer = args.contentContainer;
		var contentWrapperEl = instance.contentWrapperEl;
		var onContentLoaded = args.onContentLoaded;			
		if ( instance.options.contentURL == '' || contentContainer != contentEl) {
			return;
		}
		instance.iframeEl = new Element('iframe', {
			'id': instance.options.id + '_iframe',
			'name': instance.options.id + '_iframe',
			'class': 'mochaIframe',
			'src': options.url,
			'marginwidth': 0,
			'marginheight': 0,
			'frameBorder': 0,
			'scrolling': 'no',
			'styles': {
				'height': contentWrapperEl.offsetHeight - contentWrapperEl.getStyle('border-top').toInt() - contentWrapperEl.getStyle('border-bottom').toInt(),
				'width': instance.panelEl ? contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt() : '100%'	
			}
		}).injectInside(contentEl);

		// Add onload event to iframe so we can hide the spinner and run onContentLoaded()
		instance.iframeEl.addEvent('load', function(e) {
			if (args.recipient == 'window') instance.hideSpinner();					
			else if (args.recipient == 'panel' && contentContainer == contentEl && $('spinner')) $('spinner').hide();
			Browser.Engine.trident4 ? onContentLoaded.delay(50) : onContentLoaded();
		}.bind(this));
		if (args.recipient == 'window') instance.showSpinner();				
		else if (args.recipient == 'panel' && contentContainer == contentEl && $('spinner')) $('spinner').show();
	},
	
	updateContentHTML: function(instance, options, args){
		var contentEl = instance.contentEl;
		var contentContainer = args.contentContainer;
		var onContentLoaded = args.onContentLoaded;			
		var elementTypes = new Array('element', 'textnode', 'whitespace', 'collection');
				
		if (elementTypes.contains($type(options.content))){
			options.content.inject(contentContainer);
		} else {
			contentContainer.set('html', options.content);
		}				
		if (contentContainer == contentEl){
			if (args.recipient == 'window') instance.hideSpinner();					
			else if (args.recipient == 'panel' && $('spinner')) $('spinner').hide();									
		}
		Browser.Engine.trident4 ? onContentLoaded.delay(50) : onContentLoaded();
	},
	
	/*
	
	Function: reloadIframe
		Reload an iframe. Fixes an issue in Firefox when trying to use location.reload on an iframe that has been destroyed and recreated.

	Arguments:
		iframe - This should be both the name and the id of the iframe.

	Syntax:
		(start code)
		MUI.reloadIframe(element);
		(end)

	Example:
		To reload an iframe from within another iframe:
		(start code)
		parent.MUI.reloadIframe('myIframeName');
		(end)

	*/
	reloadIframe: function(iframe){
		Browser.Engine.gecko ? $(iframe).src = $(iframe).src : top.frames[iframe].location.reload(true);		
	},
	
	roundedRect: function(ctx, x, y, width, height, radius, rgb, a){
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.beginPath();
		ctx.moveTo(x, y + radius);
		ctx.lineTo(x, y + height - radius);
		ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
		ctx.lineTo(x + width - radius, y + height);
		ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
		ctx.lineTo(x + width, y + radius);
		ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
		ctx.lineTo(x + radius, y);
		ctx.quadraticCurveTo(x, y, x, y + radius);
		ctx.fill(); 
	},
	
	triangle: function(ctx, x, y, width, height, rgb, a){
		ctx.beginPath();
		ctx.moveTo(x + width, y);
		ctx.lineTo(x, y + height);
		ctx.lineTo(x + width, y + height);
		ctx.closePath();
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
	},
	
	circle: function(ctx, x, y, diameter, rgb, a){
		ctx.beginPath();
		ctx.arc(x, y, diameter, 0, Math.PI*2, true);
		ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
		ctx.fill();
	},
	
	notification: function(message){
			new MUI.Window({
				loadMethod: 'html',
				closeAfter: 1500,
				type: 'notification',
				addClass: 'notification',
				content: message,
				width: 220,
				height: 40,
				y: 53,
				padding:  { top: 10, right: 12, bottom: 10, left: 12 },
				shadowBlur: 5	
			});
	},
	
	/*
	  	
	Function: toggleEffects
		Turn effects on and off

	*/
	toggleAdvancedEffects: function(link){
		if (MUI.options.advancedEffects == false) {
			MUI.options.advancedEffects = true;
			if (link){
				this.toggleAdvancedEffectsLink = new Element('div', {
					'class': 'check',
					'id': 'toggleAdvancedEffects_check'
				}).inject(link);
			}			
		}
		else {
			MUI.options.advancedEffects = false;
			if (this.toggleAdvancedEffectsLink) {
				this.toggleAdvancedEffectsLink.destroy();
			}		
		}
	},
	/*
	  	
	Function: toggleStandardEffects
		Turn standard effects on and off

	*/
	toggleStandardEffects: function(link){
		if (MUI.options.standardEffects == false) {
			MUI.options.standardEffects = true;
			if (link){
				this.toggleStandardEffectsLink = new Element('div', {
					'class': 'check',
					'id': 'toggleStandardEffects_check'
				}).inject(link);
			}			
		}
		else {
			MUI.options.standardEffects = false;
			if (this.toggleStandardEffectsLink) {
				this.toggleStandardEffectsLink.destroy();
			}		
		}
	},			
	
	/*
	
	The underlay is inserted directly under windows when they are being dragged or resized
	so that the cursor is not captured by iframes or other plugins (such as Flash)
	underneath the window.
	
	*/
	underlayInitialize: function(){
		var windowUnderlay = new Element('div', {
			'id': 'windowUnderlay',
			'styles': {
				'height': window.getCoordinates().height,
				'opacity': .01,
				'display': 'none'
			}
		}).inject(document.body);
	},
	setUnderlaySize: function(){
		$('windowUnderlay').setStyle('height', window.getCoordinates().height);
	}
});

/* 

function: fixPNG
	Bob Osola's PngFix for IE6.

example:
	(begin code)
	<img src="xyz.png" alt="foo" width="10" height="20" onload="fixPNG(this)">
	(end)

note:
	You must have the image height and width attributes specified in the markup.

*/

function fixPNG(myImage){
	if (Browser.Engine.trident4 && document.body.filters){
		var imgID = (myImage.id) ? "id='" + myImage.id + "' " : "";
		var imgClass = (myImage.className) ? "class='" + myImage.className + "' " : "";
		var imgTitle = (myImage.title) ? "title='" + myImage.title  + "' " : "title='" + myImage.alt + "' ";
		var imgStyle = "display:inline-block;" + myImage.style.cssText;
		var strNewHTML = "<span " + imgID + imgClass + imgTitle
			+ " style=\"" + "width:" + myImage.width
			+ "px; height:" + myImage.height
			+ "px;" + imgStyle + ";"
			+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
			+ "(src=\'" + myImage.src + "\', sizingMethod='scale');\"></span>";
		myImage.outerHTML = strNewHTML;		
	}
}

// Blur all windows if user clicks anywhere else on the page
//document.addEvent('mousedown', function(event){
//	MUI.blurAll.delay(50);
//});

//window.addEvent('domready', function(){
//	MUI.underlayInitialize();
//});

//window.addEvent('resize', function(){
//	if ($('windowUnderlay')) {
//		MUI.setUnderlaySize();
//	}
//	else {
//		MUI.underlayInitialize();
//	}
//});

Element.implement({
	hide: function(){
		this.setStyle('display', 'none');
		return this;
	},
	show: function(){
		this.setStyle('display', 'block');
		return this;
	}	
});	

/*

Shake effect by Uvumi Tools
http://tools.uvumi.com/element-shake.html

Function: shake

Example:
	Shake a window.
	(start code)
	$('parametrics').shake()
	(end)
  
*/

Element.implement({
	shake: function(radius,duration){
		radius = radius || 3;
		duration = duration || 500;
		duration = (duration/50).toInt() - 1;
		var parent = this.getParent();
		if(parent != $(document.body) && parent.getStyle('position') == 'static'){
			parent.setStyle('position','relative');
		}
		var position = this.getStyle('position');
		if(position == 'static'){
			this.setStyle('position','relative');
			position = 'relative';
		}
		if(Browser.Engine.trident){
			parent.setStyle('height',parent.getStyle('height'));
		}
		var coords = this.getPosition(parent);
		if(position == 'relative' && !Browser.Engine.presto){
			coords.x -= parent.getStyle('paddingLeft').toInt();
			coords.y -= parent.getStyle('paddingTop').toInt();
		}
		var morph = this.retrieve('morph');
		if (morph){
			morph.cancel();
			var oldOptions = morph.options;
		}
		var morph = this.get('morph',{
			duration:50,
			link:'chain'
		});
		for(var i=0 ; i < duration ; i++){
			morph.start({
				top:coords.y+$random(-radius,radius),
				left:coords.x+$random(-radius,radius)
			});
		}
		morph.start({
			top:coords.y,
			left:coords.x
		}).chain(function(){
			if(oldOptions){
				this.set('morph',oldOptions);
			}
		}.bind(this));
		return this;
	}
});

String.implement({
 
	parseQueryString: function() {
		var vars = this.split(/[&;]/);
		var rs = {};
		if (vars.length) vars.each(function(val) {
			var keys = val.split('=');
			if (keys.length && keys.length == 2) rs[decodeURIComponent(keys[0])] = decodeURIComponent(keys[1]);
		});
		return rs;
	}
 
});

// Mootools Patch: Fixes issues in Safari, Chrome, and Internet Explorer caused by processing text as XML. 
Request.HTML.implement({
 
	processHTML: function(text){
		var match = text.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
		text = (match) ? match[1] : text;           
		var container = new Element('div');           
		return container.set('html', text);
	}
   
});

/*

	Examples:
		(start code)	
		getCSSRule('.myRule');
		getCSSRule('#myRule');
		(end)
  
*/
MUI.getCSSRule = function(selector) {
	for (var ii = 0; ii < document.styleSheets.length; ii++) {
		var mysheet = document.styleSheets[ii];
		var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
		for (i = 0; i < myrules.length; i++){
			if (myrules[i].selectorText == selector){
				return myrules[i];
			}
		}
	}		  
	return false;
}

// This makes it so Request will work to some degree locally
if (location.protocol == "file:"){

	Request.implement({
		isSuccess : function(status){
			return (status == 0 || (status >= 200) && (status < 300));
		}
	});

	Browser.Request = function(){
		return $try(function(){
			return new ActiveXObject('MSXML2.XMLHTTP');
		}, function(){
			return new XMLHttpRequest();
		});
	};
	
}

MUI.Require = new Class({

	Implements: [Options],

	options: {
		css: [],
		images: [],
		js: [],		
		onload: $empty
	},
	
	initialize: function(options){
		this.setOptions(options);
		var options = this.options;		
		
		this.assetsToLoad = options.css.length + options.images.length + options.js.length;		
		this.assetsLoaded = 0;
		
		var cssLoaded = 0;
		
		// Load CSS before images and JavaScript	
				
		if (options.css.length){
			options.css.each( function(sheet){
				
				this.getAsset(sheet, function(){
					if (cssLoaded == options.css.length - 1){
						
						if (this.assetsLoaded == this.assetsToLoad - 1){
							this.requireOnload();
						}
						else {
							// Add a little delay since we are relying on cached CSS from XHR request.
							this.assetsLoaded++;	 					
							this.requireContinue.delay(50, this);
						}				
					}
					else {
						cssLoaded++;
						this.assetsLoaded++;						
					}
				}.bind(this));
			}.bind(this));
		}
		else if (!options.js.length && !options.images.length){
			this.options.onload();
			return true;
		}
		else {
			this.requireContinue.delay(50, this); // Delay is for Safari
		}		
		
	},
	
	requireOnload: function(){
		this.assetsLoaded++;
		if (this.assetsLoaded == this.assetsToLoad){
			this.options.onload();
			return true;				
		}

	},	
	
	requireContinue: function(){

		var options = this.options;
		if (options.images.length){
			options.images.each( function(image){
				this.getAsset(image, this.requireOnload.bind(this));
			}.bind(this));
		}
	
		if (options.js.length){
			options.js.each( function(script){
				this.getAsset(script, this.requireOnload.bind(this));			
			}.bind(this));
		}
	
	},
	
	getAsset: function(source, onload){

		// If the asset is loaded, fire the onload function.
		if ( MUI.files[source] == 'loaded' ){
			if (typeof onload == 'function'){
				onload();
			}
			return true;	
		}
	
		// If the asset is loading, wait until it is loaded and then fire the onload function.
		// If asset doesn't load by a number of tries, fire onload anyway.
		else if ( MUI.files[source] == 'loading' ){
			var tries = 0;
			var checker = (function(){
				tries++;
				if (MUI.files[source] == 'loading' && tries < '100') return;
				$clear(checker);
				if (typeof onload == 'function'){
					onload();
				}
			}).periodical(50);
		}
	
		// If the asset is not yet loaded or loading, start loading the asset.
		else {
			MUI.files[source] = 'loading';	
	
			properties = {
				'onload': onload != 'undefined' ? onload : $empty	
			};	
	
			// Add to the onload function
			var oldonload = properties.onload;
			properties.onload = function() {
				MUI.files[source] = 'loaded';
				if (oldonload) {
						oldonload();
				}	
			}.bind(this);			
	
			switch ( source.match(/\.\w+$/)[0] ) {
				case '.js': return Asset.javascript(source, properties);
				case '.css': return Asset.css(source, properties);
				case '.jpg':
				case '.png':
				case '.gif': return Asset.image(source, properties);
			}
	
			alert('The required file "' + source + '" could not be loaded');
		}
	}			
		
});

Asset.extend({

	/* Fix an Opera bug in Mootools 1.2 */
	javascript: function(source, properties){
		properties = $extend({
			onload: $empty,
			document: document,
			check: $lambda(true)
		}, properties);
		
		if ($(properties.id)) {
			properties.onload();
			return $(properties.id);
		}				
		
		var script = new Element('script', {'src': source, 'type': 'text/javascript'});
		
		var load = properties.onload.bind(script), check = properties.check, doc = properties.document;
		delete properties.onload; delete properties.check; delete properties.document;
		
		if (!Browser.Engine.webkit419 && !Browser.Engine.presto){
			script.addEvents({
				load: load,
				readystatechange: function(){
					if (Browser.Engine.trident && ['loaded', 'complete'].contains(this.readyState)) 
						load();
				}
			}).setProperties(properties);
		}
		else {
			var checker = (function(){
				if (!$try(check)) return;
				$clear(checker);
				// Opera has difficulty with multiple scripts being injected into the head simultaneously. We need to give it time to catch up.
				Browser.Engine.presto ? load.delay(500) : load();
			}).periodical(50);
		}	
		return script.inject(doc.head);
	},
	
	// Get the CSS with XHR before appending it to document.head so that we can have an onload callback.
	css: function(source, properties){
		
		properties = $extend({
			id: null,
			media: 'screen',
			onload: $empty
		}, properties);		
		
		new Request({
			method: 'get',
			url: source,
			onComplete: function(response) { 
				var newSheet = new Element('link', {
					'id': properties.id,
					'rel': 'stylesheet',
					'media': properties.media,
					'type': 'text/css',
					'href': source
				}).inject(document.head);						
				properties.onload();										
			}.bind(this),
			onFailure: function(response){						
			},					
			onSuccess: function(){						 
			}.bind(this)
		}).send();		
	}	
	
});

/*

REGISTER PLUGINS

	Register Components and Plugins for Lazy Loading

	How this works may take a moment to grasp. Take a look at MUI.Window below.
	If we try to create a new Window and Window.js has not been loaded then the function
	below will run. It will load the CSS required by the MUI.Window Class and then
	then it will load Window.js. Here is the interesting part. When Window.js loads,
	it will overwrite the function below, and new MUI.Window(arg) will be ran
	again. This time it will create a new MUI.Window instance, and any future calls
	to new MUI.Window(arg) will immediately create new windows since the assets
	have already been loaded and our temporary function below has been overwritten.	
	
	Example:
	
	MyPlugins.extend({

		MyGadget: function(arg){
			new MUI.Require({
				css: [MUI.path.plugins + 'myGadget/css/style.css'],
				images: [MUI.path.plugins + 'myGadget/images/background.gif']
				js: [MUI.path.plugins + 'myGadget/scripts/myGadget.js'],
				onload: function(){
					new MyPlguins.MyGadget(arg);
				}		
			});
		}
	
	});	
	
-------------------------------------------------------------------- */

MUI.extend({

	newWindowsFromJSON: function(arg){
		new MUI.Require({
			js: [MUI.path.source + 'Window/Windows-from-json.js'],
			onload: function(){
				new MUI.newWindowsFromJSON(arg);
			}		
		});
	},	
	
	arrangeCascade: function(){
		new MUI.Require({
			js: [MUI.path.source + 'Window/Arrange-cascade.js'],
			onload: function(){
				new MUI.arrangeCascade();
			}		
		});		
	},
	
	arrangeTile: function(){
		new MUI.Require({
			js: [MUI.path.source + 'Window/Arrange-tile.js'],
			onload: function(){
				new MUI.arrangeTile();
			}		
		});		
	},
	
	saveWorkspace: function(){
		new MUI.Require({
			js: [MUI.path.source + 'Layout/Workspaces.js'],
			onload: function(){
				new MUI.saveWorkspace();
			}		
		});		
	},
	
	loadWorkspace: function(){
		new MUI.Require({
			js: [MUI.path.source + 'Layout/Workspaces.js'],
			onload: function(){
				new MUI.loadWorkspace();
			}		
		});			
	},

	Themes: {
		init: function(arg){			
			new MUI.Require({
				js: [MUI.path.source + 'Utilities/Themes.js'],
				onload: function(){
					MUI.Themes.init(arg);
				}		
			});			
		}
	}
	
});
/*

Script: Themes.js
	Allows for switching themes dynamically.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

License:
	MIT-style license.

Requires:
	Core.js
	
Notes:
	Themes are new and experimental.	
	
Syntax:
	(start code)
	new MUI.Themes.init(newTheme);
	(end)
	
Example:
	(start code)
	new MUI.Themes.init('charcoal');
	(end)		

Arguments:
	newTheme - (string) The theme name	

*/

MUI.files[MUI.path.source + 'Utilities/Themes.js'] = 1;
	
MUI.Themes = {

	/*
	
	Function: themeInit
		Initialize a theme. This is experimental and not fully implemented yet.
		
	*/	
	init: function(newTheme){
		this.newTheme = newTheme.toLowerCase();
		if (!this.newTheme || this.newTheme == null || this.newTheme == MUI.options.theme.toLowerCase()) return;

		if ($('spinner')) $('spinner').show();
		
		this.oldURIs = [];
		this.oldSheets = [];
		
		$$('link').each( function(link){			
				var href = link.get('href');
				if (href.contains(MUI.path.themes + MUI.options.theme)){
					this.oldURIs.push(href);
					this.oldSheets.push(link);
				}
		}.bind(this));		
		
		/*
		MUI.files.each( function(value, key, hash){			
			if (key.contains(MUI.path.themes + MUI.options.theme)){
				this.oldURIs.push(key);
			}
		}.bind(this));
		*/		
		
		this.newSheetURLs = this.oldURIs.map(function(item, index){
    		return item.replace("/" + MUI.options.theme + "/", "/" + MUI.Themes.newTheme + "/");
		}.bind(this));
			
		this.sheetsToLoad = this.oldURIs.length;
		this.sheetsLoaded = 0;
		
		// Download new stylesheets and add them to an array
		this.newSheets = [];
		this.newSheetURLs.each( function(link){
			var href = link;
								
				//var id = link.id;
				
				var cssRequest = new Request({
					method: 'get',
					url: href,
					onComplete: function(response) { 
						var newSheet = new Element('link', {
							//'id': id,
							'rel': 'stylesheet',
							'media': 'screen',
							'type': 'text/css',
							'href': href
						});
						this.newSheets.push(newSheet);										
					}.bind(this),
					onFailure: function(response){
						this.themeLoadSuccess = false;
						if ($('spinner')) $('spinner').hide();						
						MUI.notification('Stylesheets did not load.');						
					},					
					onSuccess: function(){						
						this.sheetsLoaded++;
						if (this.sheetsLoaded == this.sheetsToLoad) {
							this.updateThemeStylesheets();
							this.themeLoadSuccess = true;
						}  
					}.bind(this)
				});
				cssRequest.send();				

		}.bind(this));
								
	},
	updateThemeStylesheets: function(){

		this.oldSheets.each( function(sheet){
			sheet.destroy();
		});		

		this.newSheets.each( function(sheet){
			MUI.files[sheet.get('href')] = 1;
			sheet.inject(document.head);
		});		

		// Delay gives the stylesheets time to take effect. IE6 needs more delay.	
		if (Browser.Engine.trident){
			this.redraw.delay(1250, this);
		}
		else {
			this.redraw.delay(250, this);
		}	
	
	},	
	redraw: function(){

		$$('.replaced').removeClass('replaced');

		// Redraw open windows		
		$$('.mocha').each( function(element){			
			var instance = element.retrieve('instance');
			
			// Convert CSS colors to Canvas colors.
			instance.setColors();							
			instance.drawWindow();			
		});
		
		if (MUI.Dock){
			if (MUI.Dock.options.useControls){
				MUI.Dock.setDockColors();
				MUI.Dock.renderDockControls();
			}
		}

		// Reformat layout
		if (MUI.Desktop.desktop){
			var checker = (function(){
				// Make sure the style sheets are really ready.				
				if (MUI.Desktop.desktop.getStyle('overflow') != 'hidden'){					
					return;
				}
				$clear(checker);								
				MUI.Desktop.setDesktopSize();				
			}).periodical(50);
		}
		
		if ($('spinner')) $('spinner').hide();		
		MUI.options.theme = this.newTheme;
		
		/*		
		this.cookie = new Hash.Cookie('mochaUIthemeCookie', {duration: 3600});
		this.cookie.empty();
		this.cookie.set('theme', MUI.options.theme);
		this.cookie.save();
		*/			
						
	}
};

window.addEvent('load', function(){
	/*
	// Load theme the user was last using. This needs work.
	var cookie = new Hash.Cookie('mochaUIthemeCookie', {duration: 3600});
	var themeCookie = cookie.load();
	if(cookie.getKeys().length){	
		if (themeCookie.get('theme') != MUI.Themes.options.theme){
			MUI.Themes.init.delay(1000, MUI.Themes, themeCookie.get('theme'));
		}
	}
	*/
		
	if ($('themeControl')){
		$('themeControl').getElements('option').setProperty('selected', 'false');
		if ($('chooseTheme')){
			$('chooseTheme').setProperty('selected', 'true');
		}
	}
});
/*

Script: Window.js
	Build windows.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.

License:
	MIT-style license.	

Requires:
	Core.js

*/

MUI.files[MUI.path.source + 'Window/Window.js'] = 'loading';
//$require(MUI.themePath() + '/css/Dock.css');

/*
Class: Window
	Creates a single MochaUI window.
	
Syntax:
	(start code)
	new MUI.Window(options);
	(end)	

Arguments:
	options

Options:
	id - The ID of the window. If not defined, it will be set to 'win' + windowIDCount.
	title - The title of the window.
	icon - Place an icon in the window's titlebar. This is either set to false or to the url of the icon. It is set up for icons that are 16 x 16px.
	type - ('window', 'modal', 'modal2', or 'notification') Defaults to 'window'. Modals should be created with new MUI.Modal(options).
	loadMethod - ('html', 'xhr', or 'iframe') Defaults to 'html' if there is no contentURL. Defaults to 'xhr' if there is a contentURL. You only really need to set this if using the 'iframe' method.
	contentURL - Used if loadMethod is set to 'xhr' or 'iframe'.
	closeAfter - Either false or time in milliseconds. Closes the window after a certain period of time in milliseconds. This is particularly useful for notifications.
	evalScripts - (boolean) An xhr loadMethod option. Defaults to true.
	evalResponse - (boolean) An xhr loadMethod option. Defaults to false.
	content - (string or element) An html loadMethod option.
	toolbar - (boolean) Create window toolbar. Defaults to false. This can be used for tabs, media controls, and so forth.
	toolbarPosition - ('top' or 'bottom') Defaults to top.
	toolbarHeight - (number)
	toolbarURL - (url) Defaults to 'pages/lipsum.html'.
	toolbarContent - (string)
	toolbarOnload - (function)
	toolbar2 - (boolean) Create window toolbar. Defaults to false. This can be used for tabs, media controls, and so forth.
	toolbar2Position - ('top' or 'bottom') Defaults to top.
	toolbar2Height - (number)
	toolbar2URL - (url) Defaults to 'pages/lipsum.html'.
	toolbar2Content - (string)
	toolbar2Onload - (function)	
	container - (element ID) Element the window is injected in. The container defaults to 'desktop'. If no desktop then to document.body. Use 'pageWrapper' if you don't want the windows to overlap the toolbars.
	restrict - (boolean) Restrict window to container when dragging.
	shape - ('box' or 'gauge') Shape of window. Defaults to 'box'.
	collapsible - (boolean) Defaults to true.
	minimizable - (boolean) Requires MUI.Desktop and MUI.Dock. Defaults to true if dependenices are met. 
	maximizable - (boolean) Requires MUI.Desktop. Defaults to true if dependenices are met.
	closable - (boolean) Defaults to true.
	storeOnClose - (boolean) Hides a window and it's dock tab rather than destroying them on close. If you try to create the window again it will unhide the window and dock tab.
	modalOverlayClose - (boolean) Whether or not you can close a modal by clicking on the modal overlay. Defaults to true.
	draggable - (boolean) Defaults to false for modals; otherwise true.
	draggableGrid - (false or number) Distance in pixels for snap-to-grid dragging. Defaults to false. 
	draggableLimit - (false or number) An object with x and y properties used to limit the movement of the Window. Defaults to false.
	draggableSnap - (boolean) The distance to drag before the Window starts to respond to the drag. Defaults to false.
	resizable - (boolean) Defaults to false for modals, notifications and gauges; otherwise true.
	resizeLimit - (object) Minimum and maximum width and height of window when resized.
	addClass - (string) Add a class to the window for more control over styling.	
	width - (number) Width of content area.	
	height - (number) Height of content area.
	headerHeight - (number) Height of window titlebar.
	footerHeight - (number) Height of window footer.
	cornerRadius - (number)	
	x - (number) If x and y are left undefined the window is centered on the page.
	y - (number)
	scrollbars - (boolean)
	padding - (object)
	shadowBlur - (number) Width of shadows.
	shadowOffset - Should be positive and not be greater than the ShadowBlur.
	controlsOffset - Change this if you want to reposition the window controls.
	useCanvas - (boolean) Set this to false if you don't want a canvas body.
	useCanvasControls - (boolean) Set this to false if you wish to use images for the buttons.
	useSpinner - (boolean) Toggles whether or not the ajax spinners are displayed in window footers. Defaults to true.
	headerStartColor - ([r,g,b,]) Titlebar gradient's top color
	headerStopColor - ([r,g,b,]) Titlebar gradient's bottom color
	bodyBgColor - ([r,g,b,]) Background color of the main canvas shape
	minimizeBgColor - ([r,g,b,]) Minimize button background color
	minimizeColor - ([r,g,b,]) Minimize button color
	maximizeBgColor - ([r,g,b,]) Maximize button background color
	maximizeColor - ([r,g,b,]) Maximize button color
	closeBgColor - ([r,g,b,]) Close button background color
	closeColor - ([r,g,b,]) Close button color
	resizableColor - ([r,g,b,]) Resizable icon color
	onBeforeBuild - (function) Fired just before the window is built.
	onContentLoaded - (function) Fired when content is successfully loaded via XHR or Iframe.
	onFocus - (function)  Fired when the window is focused.
	onBlur - (function) Fired when window loses focus.
	onResize - (function) Fired when the window is resized.
	onMinimize - (function) Fired when the window is minimized.
	onMaximize - (function) Fired when the window is maximized.
	onRestore - (function) Fired when a window is restored from minimized or maximized.
	onClose - (function) Fired just before the window is closed.
	onCloseComplete - (function) Fired after the window is closed.

Returns:
	Window object.

Example:
	Define a window. It is suggested you name the function the same as your window ID + "Window".
	(start code)
	var mywindowWindow = function(){
		new MUI.Window({
			id: 'mywindow',
			title: 'My Window',
			loadMethod: 'xhr',
			contentURL: 'pages/lipsum.html',
			width: 340,
			height: 150
		});
	}
	(end)

Example:
	Create window onDomReady.
	(start code)	
	window.addEvent('domready', function(){
		mywindow();
	});
	(end)

Example:
	Add link events to build future windows. It is suggested you give your anchor the same ID as your window + "WindowLink" or + "WindowLinkCheck". Use the latter if it is a link in the menu toolbar.

	If you wish to add links in windows that open other windows remember to add events to those links when the windows are created.

	(start code)
	// Javascript:
	if ($('mywindowLink')){
		$('mywindowLink').addEvent('click', function(e) {
			new Event(e).stop();
			mywindow();
		});
	}

	// HTML:
	<a id="mywindowLink" href="pages/lipsum.html">My Window</a>	
	(end)


	Loading Content with an XMLHttpRequest(xhr):
		For content to load via xhr all the files must be online and in the same domain. If you need to load content from another domain or wish to have it work offline, load the content in an iframe instead of using the xhr option.
	
	Iframes:
		If you use the iframe loadMethod your iframe will automatically be resized when the window it is in is resized. If you want this same functionality when using one of the other load options simply add class="mochaIframe" to those iframes and they will be resized for you as well.

*/

// Having these options outside of the Class allows us to add, change, and remove
// individual options without rewriting all of them.

MUI.extend({
	Windows: {	  
		instances:      new Hash(),
		indexLevel:     100,          // Used for window z-Index
		windowIDCount:  0,            // Used for windows without an ID defined by the user
		windowsVisible: true,         // Ctrl-Alt-Q to toggle window visibility
		focusingWindow: false		
	}	
});	

MUI.Windows.windowOptions = {
	id:                null,
	//title:             'New Window',
	icon:              false,
	type:              'window',
	require:           {
		css:           [],
		images:        [],
		js:            [],
		onload:        null
	},
	loadMethod:        null,
	method:	           'get',
	contentURL:        null,
	data:              null,

	closeAfter:        false,

	// xhr options
	evalScripts:       true,
	evalResponse:      false,

	// html options
	content:           'Window content',

	// Toolbar
	toolbar:           false,
	toolbarPosition:   'top',
	toolbarHeight:     29,
	toolbarURL:        'pages/lipsum.html',
	toolbarData:	   null,
	toolbarContent:    '',
	toolbarOnload:     $empty,

	// Toolbar
	toolbar2:           false,
	toolbar2Position:   'bottom',
	toolbar2Height:     29,
	toolbar2URL:        'pages/lipsum.html',
	toolbar2Data:	    null,
	toolbar2Content:    '',
	toolbar2Onload:     $empty,	

	// Container options
	container:         null,
	restrict:          true,
	shape:             'box',

	// Window Controls
	collapsible:       true,
	minimizable:       true,
	maximizable:       true,
	closable:          true,
	
	// Close options	
	storeOnClose:       false, 

	// Modal options	
	modalOverlayClose: true,

	// Draggable
	draggable:         null,
	draggableGrid:     false,
	draggableLimit:    false,
	draggableSnap:     false,

	// Resizable
	resizable:         null,
	resizeLimit:       {'x': [250, 2500], 'y': [125, 2000]},
	
	// Style options:
	addClass:          '',
	width:             300,
	height:            125,
	headerHeight:      25,
	footerHeight:      25,
	cornerRadius:      8,	
	x:                 null,
	y:                 null,
	scrollbars:        true,
	padding:   		   { top: 10, right: 12, bottom: 10, left: 12 },
	shadowBlur:        5,
	shadowOffset:      {'x': 0, 'y': 1},
	controlsOffset:    {'right': 6, 'top': 6},
	useCanvas:         true,
	useCanvasControls: true,
	useSpinner:        true,

	// Color options:
	headerStartColor:  [250, 250, 250],
	headerStopColor:   [232, 232, 232],
	bodyBgColor:       [232, 232, 232],
	minimizeBgColor:   [255, 255, 255],
	minimizeColor:     [0, 0, 0],
	maximizeBgColor:   [255, 255, 255],
	maximizeColor:     [0, 0, 0],
	closeBgColor:      [255, 255, 255],
	closeColor:        [0, 0, 0],
	resizableColor:    [254, 254, 254],

	// Events
	onBeforeBuild:     $empty,
	onContentLoaded:   $empty,
	onFocus:           $empty,
	onBlur:            $empty,
	onResize:          $empty,
	onMinimize:        $empty,
	onMaximize:        $empty,
	onRestore:         $empty,
	onClose:           $empty,
	onCloseComplete:   $empty
};

MUI.Windows.windowOptionsOriginal = $merge(MUI.Windows.windowOptions);

MUI.Window = new Class({

    Implements: [Events, Options],

    options: MUI.Windows.windowOptions,

    initialize: function(options) {
        this.setOptions(options);

        // Shorten object chain
        var options = this.options;

        $extend(this, {
            mochaControlsWidth: 0,
            minimizebuttonX: 0,  // Minimize button horizontal position
            maximizebuttonX: 0,  // Maximize button horizontal position
            closebuttonX: 0,  // Close button horizontal position
            headerFooterShadow: options.headerHeight + options.footerHeight + (options.shadowBlur * 2),
            oldTop: 0,
            oldLeft: 0,
            isMaximized: false,
            isMinimized: false,
            isCollapsed: false,
            timestamp: $time()
        });

        if (options.type != 'window') {
            options.container = document.body;
            options.minimizable = false;
        }
        if (!options.container) {
            options.container = MUI.Desktop && MUI.Desktop.desktop ? MUI.Desktop.desktop : document.body;
        }

        // Set this.options.resizable to default if it was not defined
        if (options.resizable == null) {
            if (options.type != 'window' || options.shape == 'gauge') {
                options.resizable = false;
            }
            else {
                options.resizable = true;
            }
        }

        // Set this.options.draggable if it was not defined
        if (options.draggable == null) {
            options.draggable = options.type != 'window' ? false : true;
        }

        // Gauges are not maximizable or resizable
        if (options.shape == 'gauge' || options.type == 'notification') {
            options.collapsible = false;
            options.maximizable = false;
            options.contentBgColor = 'transparent';
            options.scrollbars = false;
            options.footerHeight = 0;
        }
        if (options.type == 'notification') {
            options.closable = false;
            options.headerHeight = 0;
        }

        // Minimizable, dock is required and window cannot be modal
        if (MUI.Dock && $(MUI.options.dock)) {
            if (MUI.Dock.dock && options.type != 'modal' && options.type != 'modal2') {
                options.minimizable = options.minimizable;
            }
        }
        else {
            options.minimizable = false;
        }

        // Maximizable, desktop is required
        options.maximizable = MUI.Desktop && MUI.Desktop.desktop && options.maximizable && options.type != 'modal' && options.type != 'modal2';

        if (this.options.type == 'modal2') {
            this.options.shadowBlur = 0;
            this.options.shadowOffset = { 'x': 0, 'y': 0 };
            this.options.useSpinner = false;
            this.options.useCanvas = false;
            this.options.footerHeight = 0;
            this.options.headerHeight = 0;
        }

        // If window has no ID, give it one.		
        options.id = options.id || 'win' + (++MUI.Windows.windowIDCount);

        this.windowEl = $(options.id);

        if (options.require.css.length || options.require.images.length) {
            new MUI.Require({
                css: options.require.css,
                images: options.require.images,
                onload: function() {
                    //this.newWindow();
                } .bind(this)
            });
        }
        else {
            this.newWindow();
        }

        // Return window object
        return this;
    },
    saveValues: function() {
        var coordinates = this.windowEl.getCoordinates();
        this.options.x = coordinates.left.toInt();
        this.options.y = coordinates.top.toInt();
    },

    /*

	Internal Function: newWindow
	
	Arguments: 
    properties

	*/
    newWindow: function(properties) { // options is not doing anything
        //alert('new window');
        //console.log(arguments.caller);
        // Shorten object chain
        var instances = MUI.Windows.instances;
        var instanceID = MUI.Windows.instances.get(this.options.id);
        var options = this.options;

        // Here we check to see if there is already a class instance for this window
        if (instanceID) var instance = instanceID;

        // Check if window already exists and is not in progress of closing
        if (this.windowEl && !this.isClosing) {
            //alert('window exists');
            // Restore if minimized
            if (instance.isMinimized) {
                MUI.Dock.restoreMinimized(this.windowEl);
            }
            // Expand and focus if collapsed
            else if (instance.isCollapsed) {
                MUI.collapseToggle(this.windowEl);
                setTimeout(MUI.focusWindow.pass(this.windowEl, this), 10);
            }
            else if (this.windowEl.hasClass('windowClosed')) {

                if (instance.check) instance.check.show();

                this.windowEl.removeClass('windowClosed');
                this.windowEl.setStyle('opacity', 0);
                this.windowEl.addClass('mocha');

                if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') {
                    var currentButton = $(instance.options.id + '_dockTab');
                    if (currentButton != null) {
                        currentButton.show();
                    }
                    MUI.Desktop.setDesktopSize();
                }

                instance.displayNewWindow();

            }
            // Else focus
            else {
                var coordinates = document.getCoordinates();
                if (this.windowEl.getStyle('left').toInt() > coordinates.width || this.windowEl.getStyle('top').toInt() > coordinates.height) {
                    MUI.centerWindow(this.windowEl);
                }
                setTimeout(MUI.focusWindow.pass(this.windowEl, this), 10);
                if (MUI.options.standardEffects == true) {
                    this.windowEl.shake();
                }
            }
            return;
        }
        else {
            //alert('hewwo');
            instances.set(options.id, this);
        }

        this.isClosing = false;
        this.fireEvent('onBeforeBuild');

        // Create window div
        MUI.Windows.indexLevel++;
        this.windowEl = new Element('div', {
            'class': 'mocha',
            'id': options.id,
            'styles': {
                'position': 'absolute',
                'width': options.width,
                'height': options.height,
                'display': 'block',
                'opacity': 0,
                'zIndex': MUI.Windows.indexLevel += 2
            }
        });

        this.windowEl.store('instance', this);

        this.windowEl.addClass(options.addClass);

        if (options.type == 'modal2') {
            this.windowEl.addClass('modal2');
        }

        // Fix a mouseover issue with gauges in IE7
        if (Browser.Engine.trident && options.shape == 'gauge') {
            this.windowEl.setStyle('backgroundImage', 'url(../images/spacer.gif)');
        }

        if ((this.options.type == 'modal' || options.type == 'modal2') && Browser.Platform.mac && Browser.Engine.gecko) {
            if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {
                var ffversion = new Number(RegExp.$1);
                if (ffversion < 3) {
                    this.windowEl.setStyle('position', 'fixed');
                }
            }
        }

        if (options.loadMethod == 'iframe') {
            options.padding = { top: 0, right: 0, bottom: 0, left: 0 };
        }

        // Insert sub elements inside windowEl
        this.insertWindowElements();

        // Set title
        this.titleEl.set('html', options.title);

        this.contentWrapperEl.setStyle('overflow', 'hidden');

        this.contentEl.setStyles({
            'padding-top': options.padding.top,
            'padding-bottom': options.padding.bottom,
            'padding-left': options.padding.left,
            'padding-right': options.padding.right
        });

        if (options.shape == 'gauge') {
            if (options.useCanvasControls) {
                this.canvasControlsEl.setStyle('visibility', 'hidden');
            }
            else {
                this.controlsEl.setStyle('visibility', 'hidden');
            }
            this.windowEl.addEvent('mouseover', function() {
                this.mouseover = true;
                var showControls = function() {
                    if (this.mouseover != false) {
                        if (options.useCanvasControls) {
                            this.canvasControlsEl.setStyle('visibility', 'visible');
                        }
                        else {
                            this.controlsEl.setStyle('visibility', 'visible');
                        }
                        this.canvasHeaderEl.setStyle('visibility', 'visible');
                        this.titleEl.show();
                    }
                };
                showControls.delay(0, this);

            } .bind(this));
            this.windowEl.addEvent('mouseleave', function() {
                this.mouseover = false;
                if (this.options.useCanvasControls) {
                    this.canvasControlsEl.setStyle('visibility', 'hidden');
                }
                else {
                    this.controlsEl.setStyle('visibility', 'hidden');
                }
                this.canvasHeaderEl.setStyle('visibility', 'hidden');
                this.titleEl.hide();
            } .bind(this));
        }

        // Inject window into DOM
        this.windowEl.inject(options.container);

        // Convert CSS colors to Canvas colors.
        this.setColors();

        if (options.type != 'notification') {
            this.setMochaControlsWidth();
        }

        // Add content to window.
        MUI.updateContent({
            'element': this.windowEl,
            'content': options.content,
            'method': options.method,
            'url': options.contentURL,
            'data': options.data,
            'onContentLoaded': null,
            'require': {
                js: options.require.js,
                onload: options.require.onload
            }
        });

        // Add content to window toolbar.
        if (this.options.toolbar == true) {
            MUI.updateContent({
                'element': this.windowEl,
                'childElement': this.toolbarEl,
                'content': options.toolbarContent,
                'loadMethod': 'xhr',
                'method': options.method,
                'url': options.toolbarURL,
                'data': options.toolbarData,
                'onContentLoaded': options.toolbarOnload
            });
        }

        // Add content to window toolbar.
        if (this.options.toolbar2 == true) {
            MUI.updateContent({
                'element': this.windowEl,
                'childElement': this.toolbar2El,
                'content': options.toolbar2Content,
                'loadMethod': 'xhr',
                'method': options.method,
                'url': options.toolbar2URL,
                'data': options.toolbar2Data,
                'onContentLoaded': options.toolbar2Onload
            });
        }

        this.drawWindow();

        // Attach events to the window
        this.attachDraggable();
        this.attachResizable();
        this.setupEvents();

        if (options.resizable) {
            this.adjustHandles();
        }

        // Position window. If position not specified by user then center the window on the page.
        if (options.container == document.body || options.container == MUI.Desktop.desktop) {
            var dimensions = window.getSize();
        }
        else {
            var dimensions = $(this.options.container).getSize();
        }

        if (!options.y) {
            if (MUI.Desktop && MUI.Desktop.desktop) {
                var y = (dimensions.y * .5) - (this.windowEl.offsetHeight * .5);
                if (y < -options.shadowBlur) y = -options.shadowBlur;
            }
            else {
                var y = window.getScroll().y + (window.getSize().y * .5) - (this.windowEl.offsetHeight * .5);
                if (y < -options.shadowBlur) y = -options.shadowBlur;
            }
        }
        else {
            var y = options.y - options.shadowBlur;
        }

        if (!this.options.x) {
            var x = (dimensions.x * .5) - (this.windowEl.offsetWidth * .5);
            if (x < -options.shadowBlur) x = -options.shadowBlur;
        }
        else {
            var x = options.x - options.shadowBlur;
        }

        this.windowEl.setStyles({
            'top': y,
            'left': x
        });

        // Create opacityMorph

        this.opacityMorph = new Fx.Morph(this.windowEl, {
            'duration': 350,
            transition: Fx.Transitions.Sine.easeInOut,
            onComplete: function() {
                if (Browser.Engine.trident) {
                    this.drawWindow();
                }
            } .bind(this)
        });

        this.displayNewWindow();

        // This is a generic morph that can be reused later by functions like centerWindow()
        // It returns the windowEl element rather than this Class.
        this.morph = new Fx.Morph(this.windowEl, {
            'duration': 200
        });
        this.windowEl.store('morph', this.morph);

        this.resizeMorph = new Fx.Elements([this.contentWrapperEl, this.windowEl], {
            duration: 400,
            transition: Fx.Transitions.Sine.easeInOut,
            onStart: function() {
                this.resizeAnimation = this.drawWindow.periodical(20, this);
            } .bind(this),
            onComplete: function() {
                $clear(this.resizeAnimation);
                this.drawWindow();
                // Show iframe
                if (this.iframeEl) {
                    this.iframeEl.setStyle('visibility', 'visible');
                }
            } .bind(this)
        });
        this.windowEl.store('resizeMorph', this.resizeMorph);

        // Add check mark to menu if link exists in menu
        // Need to make sure the check mark is not added to links not in menu	
        if ($(this.windowEl.id + 'LinkCheck')) {
            this.check = new Element('div', {
                'class': 'check',
                'id': this.options.id + '_check'
            }).inject(this.windowEl.id + 'LinkCheck');
        }

        if (this.options.closeAfter != false) {
            MUI.closeWindow.delay(this.options.closeAfter, this, this.windowEl);
        }

        if (MUI.Dock && $(MUI.options.dock) && this.options.type == 'window') {
            MUI.Dock.createDockTab(this.windowEl);
        }

    },
    displayNewWindow: function() {

        options = this.options;
        if (options.type == 'modal' || options.type == 'modal2') {
            MUI.currentModal = this.windowEl;
            if (Browser.Engine.trident4) {
                $('modalFix').show();
            }
            $('modalOverlay').show();
            if (MUI.options.advancedEffects == false) {
                //$('modalOverlay').setStyle('opacity', .6);
                this.windowEl.setStyles({
                    'zIndex': 11000,
                    'opacity': 1
                });
            }
            else {
                MUI.Modal.modalOverlayCloseMorph.cancel();
                //				MUI.Modal.modalOverlayOpenMorph.start({
                //					'opacity': .6
                //				});
                this.windowEl.setStyles({
                    'zIndex': 11000
                });
                this.opacityMorph.start({
                    'opacity': 1
                });
            }

            $$('.dockTab').removeClass('activeDockTab');
            $$('.mocha').removeClass('isFocused');
            this.windowEl.addClass('isFocused');

        }
        else if (MUI.options.advancedEffects == false) {
            this.windowEl.setStyle('opacity', 1);
            setTimeout(MUI.focusWindow.pass(this.windowEl, this), 10);
        }
        else {
            // IE cannot handle both element opacity and VML alpha at the same time.
            if (Browser.Engine.trident) {
                this.drawWindow(false);
            }
            this.opacityMorph.start({
                'opacity': 1
            });
            setTimeout(MUI.focusWindow.pass(this.windowEl, this), 10);
        }

    },
    setupEvents: function() {
        var windowEl = this.windowEl;
        // Set events
        // Note: if a button does not exist, its due to properties passed to newWindow() stating otherwice
        if (this.closeButtonEl) {
            this.closeButtonEl.addEvent('click', function(e) {
                new Event(e).stop();
                MUI.closeWindow(windowEl);
            } .bind(this));
        }

        if (this.options.type == 'window') {
            windowEl.addEvent('mousedown', function(e) {
                if (Browser.Engine.trident) {
                    new Event(e).stop();
                }
                MUI.focusWindow(windowEl);
                if (windowEl.getStyle('top').toInt() < -this.options.shadowBlur) {
                    windowEl.setStyle('top', -this.options.shadowBlur);
                }
            } .bind(this));
        }

        if (this.minimizeButtonEl) {
            this.minimizeButtonEl.addEvent('click', function(e) {
                new Event(e).stop();
                MUI.Dock.minimizeWindow(windowEl);
            } .bind(this));
        }

        if (this.maximizeButtonEl) {
            this.maximizeButtonEl.addEvent('click', function(e) {
                new Event(e).stop();
                if (this.isMaximized) {
                    MUI.Desktop.restoreWindow(windowEl);
                } else {
                    MUI.Desktop.maximizeWindow(windowEl);
                }
            } .bind(this));
        }

        if (this.options.collapsible == true) {
            // Keep titlebar text from being selected on double click in Safari.
            this.titleEl.addEvent('selectstart', function(e) {
                e = new Event(e).stop();
            } .bind(this));

            if (Browser.Engine.trident) {
                this.titleBarEl.addEvent('mousedown', function(e) {
                    this.titleEl.setCapture();
                } .bind(this));
                this.titleBarEl.addEvent('mouseup', function(e) {
                    this.titleEl.releaseCapture();
                } .bind(this));
            }

            this.titleBarEl.addEvent('dblclick', function(e) {
                e = new Event(e).stop();
                MUI.collapseToggle(this.windowEl);
            } .bind(this));
        }

    },
    /*

	Internal Function: attachDraggable()
    Make window draggable.
		
	*/
    attachDraggable: function() {
        var windowEl = this.windowEl;
        if (!this.options.draggable) return;
        this.windowDrag = new Drag.Move(windowEl, {
            handle: this.titleBarEl,
            container: this.options.restrict == true ? $(this.options.container) : false,
            grid: this.options.draggableGrid,
            limit: this.options.draggableLimit,
            snap: this.options.draggableSnap,
            onStart: function() {
                if (this.options.type != 'modal' && this.options.type != 'modal2') {
                    MUI.focusWindow(windowEl);
                    $('windowUnderlay').show();
                }
                if (this.iframeEl) {
                    if (!Browser.Engine.trident) {
                        this.iframeEl.setStyle('visibility', 'hidden');
                    }
                    else {
                        this.iframeEl.hide();
                    }
                }
            } .bind(this),
            onComplete: function() {
                if (this.options.type != 'modal' && this.options.type != 'modal2') {
                    $('windowUnderlay').hide();
                }
                if (this.iframeEl) {
                    if (!Browser.Engine.trident) {
                        this.iframeEl.setStyle('visibility', 'visible');
                    }
                    else {
                        this.iframeEl.show();
                    }
                }
                // Store new position in options.
                this.saveValues();
            } .bind(this)
        });
    },
    /*

	Internal Function: attachResizable
    Make window resizable.

	*/
    attachResizable: function() {
        var windowEl = this.windowEl;
        if (!this.options.resizable) return;
        this.resizable1 = this.windowEl.makeResizable({
            handle: [this.n, this.ne, this.nw],
            limit: {
                y: [
					function() {
					    return this.windowEl.getStyle('top').toInt() + this.windowEl.getStyle('height').toInt() - this.options.resizeLimit.y[1];
					} .bind(this),
					function() {
					    return this.windowEl.getStyle('top').toInt() + this.windowEl.getStyle('height').toInt() - this.options.resizeLimit.y[0];
					} .bind(this)
				]
            },
            modifiers: { x: false, y: 'top' },
            onStart: function() {
                this.resizeOnStart();
                this.coords = this.contentWrapperEl.getCoordinates();
                this.y2 = this.coords.top.toInt() + this.contentWrapperEl.offsetHeight;
            } .bind(this),
            onDrag: function() {
                this.coords = this.contentWrapperEl.getCoordinates();
                this.contentWrapperEl.setStyle('height', this.y2 - this.coords.top.toInt());
                this.resizeOnDrag();
            } .bind(this),
            onComplete: function() {
                this.resizeOnComplete();
            } .bind(this)
        });

        this.resizable2 = this.contentWrapperEl.makeResizable({
            handle: [this.e, this.ne],
            limit: {
                x: [this.options.resizeLimit.x[0] - (this.options.shadowBlur * 2), this.options.resizeLimit.x[1] - (this.options.shadowBlur * 2)]
            },
            modifiers: { x: 'width', y: false },
            onStart: function() {
                this.resizeOnStart();
            } .bind(this),
            onDrag: function() {
                this.resizeOnDrag();
            } .bind(this),
            onComplete: function() {
                this.resizeOnComplete();
            } .bind(this)
        });

        this.resizable3 = this.contentWrapperEl.makeResizable({
            container: this.options.restrict == true ? $(this.options.container) : false,
            handle: this.se,
            limit: {
                x: [this.options.resizeLimit.x[0] - (this.options.shadowBlur * 2), this.options.resizeLimit.x[1] - (this.options.shadowBlur * 2)],
                y: [this.options.resizeLimit.y[0] - this.headerFooterShadow, this.options.resizeLimit.y[1] - this.headerFooterShadow]
            },
            modifiers: { x: 'width', y: 'height' },
            onStart: function() {
                this.resizeOnStart();
            } .bind(this),
            onDrag: function() {
                this.resizeOnDrag();
            } .bind(this),
            onComplete: function() {
                this.resizeOnComplete();
            } .bind(this)
        });

        this.resizable4 = this.contentWrapperEl.makeResizable({
            handle: [this.s, this.sw],
            limit: {
                y: [this.options.resizeLimit.y[0] - this.headerFooterShadow, this.options.resizeLimit.y[1] - this.headerFooterShadow]
            },
            modifiers: { x: false, y: 'height' },
            onStart: function() {
                this.resizeOnStart();
            } .bind(this),
            onDrag: function() {
                this.resizeOnDrag();
            } .bind(this),
            onComplete: function() {
                this.resizeOnComplete();
            } .bind(this)
        });

        this.resizable5 = this.windowEl.makeResizable({
            handle: [this.w, this.sw, this.nw],
            limit: {
                x: [
					function() {
					    return this.windowEl.getStyle('left').toInt() + this.windowEl.getStyle('width').toInt() - this.options.resizeLimit.x[1];
					} .bind(this),
				   function() {
				       return this.windowEl.getStyle('left').toInt() + this.windowEl.getStyle('width').toInt() - this.options.resizeLimit.x[0];
				   } .bind(this)
				]
            },
            modifiers: { x: 'left', y: false },
            onStart: function() {
                this.resizeOnStart();
                this.coords = this.contentWrapperEl.getCoordinates();
                this.x2 = this.coords.left.toInt() + this.contentWrapperEl.offsetWidth;
            } .bind(this),
            onDrag: function() {
                this.coords = this.contentWrapperEl.getCoordinates();
                this.contentWrapperEl.setStyle('width', this.x2 - this.coords.left.toInt());
                this.resizeOnDrag();
            } .bind(this),
            onComplete: function() {
                this.resizeOnComplete();
            } .bind(this)
        });

    },
    resizeOnStart: function() {
        $('windowUnderlay').show();
        if (this.iframeEl) {
            if (!Browser.Engine.trident) {
                this.iframeEl.setStyle('visibility', 'hidden');
            }
            else {
                this.iframeEl.hide();
            }
        }
    },
    resizeOnDrag: function() {
        // Fix for a rendering glitch in FF when resizing a window with panels in it
        if (Browser.Engine.gecko) {
            this.windowEl.getElements('.panel').each(function(panel) {
                panel.store('oldOverflow', panel.getStyle('overflow'));
                panel.setStyle('overflow', 'visible');
            });
        }
        this.drawWindow();
        this.adjustHandles();
        if (Browser.Engine.gecko) {
            this.windowEl.getElements('.panel').each(function(panel) {
                panel.setStyle('overflow', panel.retrieve('oldOverflow')); // Fix for a rendering bug in FF
            });
        }
    },
    resizeOnComplete: function() {
        $('windowUnderlay').hide();
        if (this.iframeEl) {
            if (!Browser.Engine.trident) {
                this.iframeEl.setStyle('visibility', 'visible');
            }
            else {
                this.iframeEl.show();
                // The following hack is to get IE8 RC1 IE8 Standards Mode to properly resize an iframe
                // when only the vertical dimension is changed.
                this.iframeEl.setStyle('width', '99%');
                this.iframeEl.setStyle('height', this.contentWrapperEl.offsetHeight);
                this.iframeEl.setStyle('width', '100%');
                this.iframeEl.setStyle('height', this.contentWrapperEl.offsetHeight);
            }
        }

        // Resize panels if there are any
        if (this.contentWrapperEl.getChildren('.column') != null) {
            MUI.rWidth(this.contentWrapperEl);
            this.contentWrapperEl.getChildren('.column').each(function(column) {
                MUI.panelHeight(column);
            });
        }

        this.fireEvent('onResize', this.windowEl);
    },
    adjustHandles: function() {

        var shadowBlur = this.options.shadowBlur;
        var shadowBlur2x = shadowBlur * 2;
        var shadowOffset = this.options.shadowOffset;
        var top = shadowBlur - shadowOffset.y - 1;
        var right = shadowBlur + shadowOffset.x - 1;
        var bottom = shadowBlur + shadowOffset.y - 1;
        var left = shadowBlur - shadowOffset.x - 1;

        var coordinates = this.windowEl.getCoordinates();
        var width = coordinates.width - shadowBlur2x + 2;
        var height = coordinates.height - shadowBlur2x + 2;

        this.n.setStyles({
            'top': top,
            'left': left + 10,
            'width': width - 20
        });
        this.e.setStyles({
            'top': top + 10,
            'right': right,
            'height': height - 30
        });
        this.s.setStyles({
            'bottom': bottom,
            'left': left + 10,
            'width': width - 30
        });
        this.w.setStyles({
            'top': top + 10,
            'left': left,
            'height': height - 20
        });
        this.ne.setStyles({
            'top': top,
            'right': right
        });
        this.se.setStyles({
            'bottom': bottom,
            'right': right
        });
        this.sw.setStyles({
            'bottom': bottom,
            'left': left
        });
        this.nw.setStyles({
            'top': top,
            'left': left
        });
    },
    detachResizable: function() {
        this.resizable1.detach();
        this.resizable2.detach();
        this.resizable3.detach();
        this.resizable4.detach();
        this.resizable5.detach();
        this.windowEl.getElements('.handle').hide();
    },
    reattachResizable: function() {
        this.resizable1.attach();
        this.resizable2.attach();
        this.resizable3.attach();
        this.resizable4.attach();
        this.resizable5.attach();
        this.windowEl.getElements('.handle').show();
    },
    /*

	Internal Function: insertWindowElements

	Arguments:
    windowEl

	*/
    insertWindowElements: function() {

        var options = this.options;
        var height = options.height;
        var width = options.width;
        var id = options.id;

        var cache = {};

        if (Browser.Engine.trident4) {
            cache.zIndexFixEl = new Element('iframe', {
                'id': id + '_zIndexFix',
                'class': 'zIndexFix',
                'scrolling': 'no',
                'marginWidth': 0,
                'marginHeight': 0,
                'src': '',
                'styles': {
                    'position': 'absolute' // This is set here to make theme transitions smoother
                }
            }).inject(this.windowEl);
        }

        cache.overlayEl = new Element('div', {
            'id': id + '_overlay',
            'class': 'mochaOverlay',
            'styles': {
                'position': 'absolute', // This is set here to make theme transitions smoother
                'top': 0,
                'left': 0
            }
        }).inject(this.windowEl);

        cache.titleBarEl = new Element('div', {
            'id': id + '_titleBar',
            'class': 'mochaTitlebar',
            'styles': {
                'cursor': options.draggable ? 'move' : 'default'
            }
        }).inject(cache.overlayEl, 'top');

        cache.titleEl = new Element('h3', {
            'id': id + '_title',
            'class': 'mochaTitle'
        }).inject(cache.titleBarEl);

        if (options.icon != false) {
            cache.titleEl.setStyles({
                'padding-left': 28,
                'background': 'url(' + options.icon + ') 5px 4px no-repeat'
            });
        }

        cache.contentBorderEl = new Element('div', {
            'id': id + '_contentBorder',
            'class': 'mochaContentBorder'
        }).inject(cache.overlayEl);

        if (options.toolbar) {
            cache.toolbarWrapperEl = new Element('div', {
                'id': id + '_toolbarWrapper',
                'class': 'mochaToolbarWrapper',
                'styles': { 'height': options.toolbarHeight }
            }).inject(cache.contentBorderEl, options.toolbarPosition == 'bottom' ? 'after' : 'before');

            if (options.toolbarPosition == 'bottom') {
                cache.toolbarWrapperEl.addClass('bottom');
            }
            cache.toolbarEl = new Element('div', {
                'id': id + '_toolbar',
                'class': 'mochaToolbar',
                'styles': { 'height': options.toolbarHeight }
            }).inject(cache.toolbarWrapperEl);
        }

        if (options.toolbar2) {
            cache.toolbar2WrapperEl = new Element('div', {
                'id': id + '_toolbar2Wrapper',
                'class': 'mochaToolbarWrapper',
                'styles': { 'height': options.toolbar2Height }
            }).inject(cache.contentBorderEl, options.toolbar2Position == 'bottom' ? 'after' : 'before');

            if (options.toolbar2Position == 'bottom') {
                cache.toolbar2WrapperEl.addClass('bottom');
            }
            cache.toolbar2El = new Element('div', {
                'id': id + '_toolbar2',
                'class': 'mochaToolbar',
                'styles': { 'height': options.toolbar2Height }
            }).inject(cache.toolbar2WrapperEl);
        }

        cache.contentWrapperEl = new Element('div', {
            'id': id + '_contentWrapper',
            'class': 'mochaContentWrapper',
            'styles': {
                'width': width + 'px',
                'height': height + 'px'
            }
        }).inject(cache.contentBorderEl);

        if (this.options.shape == 'gauge') {
            cache.contentBorderEl.setStyle('borderWidth', 0);
        }

        cache.contentEl = new Element('div', {
            'id': id + '_content',
            'class': 'mochaContent'
        }).inject(cache.contentWrapperEl);

        if (this.options.useCanvas == true && Browser.Engine.trident != true) {
            cache.canvasEl = new Element('canvas', {
                'id': id + '_canvas',
                'class': 'mochaCanvas',
                'width': 10,
                'height': 10
            }).inject(this.windowEl);
        }

        if (this.options.useCanvas == true && Browser.Engine.trident) {
            cache.canvasEl = new Element('canvas', {
                'id': id + '_canvas',
                'class': 'mochaCanvas',
                'width': 50000, // IE8 excanvas requires these large numbers
                'height': 20000,
                'styles': {
                    'position': 'absolute',
                    'top': 0,
                    'left': 0
                }
            }).inject(this.windowEl);

            if (MUI.ieSupport == 'excanvas') {
                G_vmlCanvasManager.initElement(cache.canvasEl);
                cache.canvasEl = this.windowEl.getElement('.mochaCanvas');
            }
        }

        cache.controlsEl = new Element('div', {
            'id': id + '_controls',
            'class': 'mochaControls'
        }).inject(cache.overlayEl, 'after');

        if (options.useCanvasControls == true) {
            cache.canvasControlsEl = new Element('canvas', {
                'id': id + '_canvasControls',
                'class': 'mochaCanvasControls',
                'width': 14,
                'height': 14
            }).inject(this.windowEl);

            if (Browser.Engine.trident && MUI.ieSupport == 'excanvas') {
                G_vmlCanvasManager.initElement(cache.canvasControlsEl);
                cache.canvasControlsEl = this.windowEl.getElement('.mochaCanvasControls');
            }
        }

        if (options.closable) {
            cache.closeButtonEl = new Element('div', {
                'id': id + '_closeButton',
                'class': 'mochaCloseButton mochaWindowButton',
                'title': 'Close'
            }).inject(cache.controlsEl);
        }

        if (options.maximizable) {
            cache.maximizeButtonEl = new Element('div', {
                'id': id + '_maximizeButton',
                'class': 'mochaMaximizeButton mochaWindowButton',
                'title': 'Maximize'
            }).inject(cache.controlsEl);
        }

        if (options.minimizable) {
            cache.minimizeButtonEl = new Element('div', {
                'id': id + '_minimizeButton',
                'class': 'mochaMinimizeButton mochaWindowButton',
                'title': 'Minimize'
            }).inject(cache.controlsEl);
        }

        if (options.useSpinner == true && options.shape != 'gauge' && options.type != 'notification') {
            cache.spinnerEl = new Element('div', {
                'id': id + '_spinner',
                'class': 'mochaSpinner',
                'width': 16,
                'height': 16
            }).inject(this.windowEl, 'bottom');
        }

        if (this.options.shape == 'gauge') {
            cache.canvasHeaderEl = new Element('canvas', {
                'id': id + '_canvasHeader',
                'class': 'mochaCanvasHeader',
                'width': this.options.width,
                'height': 26
            }).inject(this.windowEl, 'bottom');

            if (Browser.Engine.trident && MUI.ieSupport == 'excanvas') {
                G_vmlCanvasManager.initElement(cache.canvasHeaderEl);
                cache.canvasHeaderEl = this.windowEl.getElement('.mochaCanvasHeader');
            }
        }

        if (Browser.Engine.trident) {
            cache.overlayEl.setStyle('zIndex', 2);
        }

        // For Mac Firefox 2 to help reduce scrollbar bugs in that browser
        if (Browser.Platform.mac && Browser.Engine.gecko) {
            if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {
                var ffversion = new Number(RegExp.$1);
                if (ffversion < 3) {
                    cache.overlayEl.setStyle('overflow', 'auto');
                }
            }
        }

        if (options.resizable) {
            cache.n = new Element('div', {
                'id': id + '_resizeHandle_n',
                'class': 'handle',
                'styles': {
                    'top': 0,
                    'left': 10,
                    'cursor': 'n-resize'
                }
            }).inject(cache.overlayEl, 'after');

            cache.ne = new Element('div', {
                'id': id + '_resizeHandle_ne',
                'class': 'handle corner',
                'styles': {
                    'top': 0,
                    'right': 0,
                    'cursor': 'ne-resize'
                }
            }).inject(cache.overlayEl, 'after');

            cache.e = new Element('div', {
                'id': id + '_resizeHandle_e',
                'class': 'handle',
                'styles': {
                    'top': 10,
                    'right': 0,
                    'cursor': 'e-resize'
                }
            }).inject(cache.overlayEl, 'after');

            cache.se = new Element('div', {
                'id': id + '_resizeHandle_se',
                'class': 'handle cornerSE',
                'styles': {
                    'bottom': 0,
                    'right': 0,
                    'cursor': 'se-resize'
                }
            }).inject(cache.overlayEl, 'after');

            cache.s = new Element('div', {
                'id': id + '_resizeHandle_s',
                'class': 'handle',
                'styles': {
                    'bottom': 0,
                    'left': 10,
                    'cursor': 's-resize'
                }
            }).inject(cache.overlayEl, 'after');

            cache.sw = new Element('div', {
                'id': id + '_resizeHandle_sw',
                'class': 'handle corner',
                'styles': {
                    'bottom': 0,
                    'left': 0,
                    'cursor': 'sw-resize'
                }
            }).inject(cache.overlayEl, 'after');

            cache.w = new Element('div', {
                'id': id + '_resizeHandle_w',
                'class': 'handle',
                'styles': {
                    'top': 10,
                    'left': 0,
                    'cursor': 'w-resize'
                }
            }).inject(cache.overlayEl, 'after');

            cache.nw = new Element('div', {
                'id': id + '_resizeHandle_nw',
                'class': 'handle corner',
                'styles': {
                    'top': 0,
                    'left': 0,
                    'cursor': 'nw-resize'
                }
            }).inject(cache.overlayEl, 'after');
        }
        $extend(this, cache);

    },
    /*
	
	Convert CSS colors to Canvas colors. 
	  
    */
    setColors: function() {

        if (this.options.useCanvas == true) {

            // Set TitlebarColor
            var pattern = /\?(.*?)\)/;
            if (this.titleBarEl.getStyle('backgroundImage') != 'none') {
                var gradient = this.titleBarEl.getStyle('backgroundImage');
                gradient = gradient.match(pattern)[1];
                gradient = gradient.parseQueryString();
                var gradientFrom = gradient.from;
                var gradientTo = gradient.to.replace(/\"/, ''); // IE7 was adding a quotation mark in. No idea why.						

                this.options.headerStartColor = new Color(gradientFrom);
                this.options.headerStopColor = new Color(gradientTo);
                this.titleBarEl.addClass('replaced');
            }
            else if (this.titleBarEl.getStyle('background-color') !== '' && this.titleBarEl.getStyle('background-color') !== 'transparent') {
                this.options.headerStartColor = new Color(this.titleBarEl.getStyle('background-color')).mix('#fff', 20);
                this.options.headerStopColor = new Color(this.titleBarEl.getStyle('background-color')).mix('#000', 20);
                this.titleBarEl.addClass('replaced');
            }

            // Set BodyBGColor
            if (this.windowEl.getStyle('background-color') !== '' && this.windowEl.getStyle('background-color') !== 'transparent') {
                this.options.bodyBgColor = new Color(this.windowEl.getStyle('background-color'));
                this.windowEl.addClass('replaced');
            }

            // Set resizableColor, the color of the SE corner resize handle			
            if (this.options.resizable && this.se.getStyle('background-color') !== '' && this.se.getStyle('background-color') !== 'transparent') {
                this.options.resizableColor = new Color(this.se.getStyle('background-color'));
                this.se.addClass('replaced');
            }

        }

        if (this.options.useCanvasControls == true) {

            if (this.minimizeButtonEl) {

                // Set Minimize Button Foreground Color
                if (this.minimizeButtonEl.getStyle('color') !== '' && this.minimizeButtonEl.getStyle('color') !== 'transparent') {
                    this.options.minimizeColor = new Color(this.minimizeButtonEl.getStyle('color'));
                }

                // Set Minimize Button Background Color
                if (this.minimizeButtonEl.getStyle('background-color') !== '' && this.minimizeButtonEl.getStyle('background-color') !== 'transparent') {
                    this.options.minimizeBgColor = new Color(this.minimizeButtonEl.getStyle('background-color'));
                    this.minimizeButtonEl.addClass('replaced');
                }

            }

            if (this.maximizeButtonEl) {

                // Set Maximize Button Foreground Color
                if (this.maximizeButtonEl.getStyle('color') !== '' && this.maximizeButtonEl.getStyle('color') !== 'transparent') {
                    this.options.maximizeColor = new Color(this.maximizeButtonEl.getStyle('color'));
                }

                // Set Maximize Button Background Color
                if (this.maximizeButtonEl.getStyle('background-color') !== '' && this.maximizeButtonEl.getStyle('background-color') !== 'transparent') {
                    this.options.maximizeBgColor = new Color(this.maximizeButtonEl.getStyle('background-color'));
                    this.maximizeButtonEl.addClass('replaced');
                }

            }

            if (this.closeButtonEl) {

                // Set Close Button Foreground Color
                if (this.closeButtonEl.getStyle('color') !== '' && this.closeButtonEl.getStyle('color') !== 'transparent') {
                    this.options.closeColor = new Color(this.closeButtonEl.getStyle('color'));
                }

                // Set Close Button Background Color
                if (this.closeButtonEl.getStyle('background-color') !== '' && this.closeButtonEl.getStyle('background-color') !== 'transparent') {
                    this.options.closeBgColor = new Color(this.closeButtonEl.getStyle('background-color'));
                    this.closeButtonEl.addClass('replaced');
                }

            }
        }
    },
    /*

	Internal function: drawWindow
    This is where we create the canvas GUI	

	Arguments: 
    windowEl: the $(window)
    shadows: (boolean) false will draw a window without shadows

	*/
    drawWindow: function(shadows) {

        if (this.drawingWindow == true) return;
        this.drawingWindow = true;

        if (this.isCollapsed) {
            this.drawWindowCollapsed(shadows);
            return;
        }

        var windowEl = this.windowEl;

        var options = this.options;
        var shadowBlur = options.shadowBlur;
        var shadowBlur2x = shadowBlur * 2;
        var shadowOffset = this.options.shadowOffset;

        this.overlayEl.setStyles({
            'width': this.contentWrapperEl.offsetWidth
        });

        // Resize iframe when window is resized
        if (this.iframeEl) {
            this.iframeEl.setStyle('height', this.contentWrapperEl.offsetHeight);
        }

        var borderHeight = this.contentBorderEl.getStyle('border-top').toInt() + this.contentBorderEl.getStyle('border-bottom').toInt();
        var toolbarHeight = this.toolbarWrapperEl ? this.toolbarWrapperEl.getStyle('height').toInt() + this.toolbarWrapperEl.getStyle('border-top').toInt() : 0;
        var toolbar2Height = this.toolbar2WrapperEl ? this.toolbar2WrapperEl.getStyle('height').toInt() + this.toolbar2WrapperEl.getStyle('border-top').toInt() : 0;

        this.headerFooterShadow = options.headerHeight + options.footerHeight + shadowBlur2x;
        var height = this.contentWrapperEl.getStyle('height').toInt() + this.headerFooterShadow + toolbarHeight + toolbar2Height + borderHeight;
        var width = this.contentWrapperEl.getStyle('width').toInt() + shadowBlur2x;
        this.windowEl.setStyles({
            'height': height,
            'width': width
        });

        this.overlayEl.setStyles({
            'height': height,
            'top': shadowBlur - shadowOffset.y,
            'left': shadowBlur - shadowOffset.x
        });

        if (this.options.useCanvas == true) {
            if (Browser.Engine.trident) {
                this.canvasEl.height = 20000;
                this.canvasEl.width = 50000;
            }
            this.canvasEl.height = height;
            this.canvasEl.width = width;
        }

        // Part of the fix for IE6 select z-index bug
        if (Browser.Engine.trident4) {
            this.zIndexFixEl.setStyles({
                'width': width,
                'height': height
            })
        }

        this.titleBarEl.setStyles({
            'width': width - shadowBlur2x,
            'height': options.headerHeight
        });

        // Make sure loading icon is placed correctly.
        if (options.useSpinner == true && options.shape != 'gauge' && options.type != 'notification') {
            this.spinnerEl.setStyles({
                'left': shadowBlur - shadowOffset.x + 3,
                'bottom': shadowBlur + shadowOffset.y + 4
            });
        }

        if (this.options.useCanvas != false) {

            // Draw Window
            var ctx = this.canvasEl.getContext('2d');
            ctx.clearRect(0, 0, width, height);

            switch (options.shape) {
                case 'box':
                    this.drawBox(ctx, width, height, shadowBlur, shadowOffset, shadows);
                    break;
                case 'gauge':
                    this.drawGauge(ctx, width, height, shadowBlur, shadowOffset, shadows);
                    break;
            }

            if (options.resizable) {
                MUI.triangle(
					ctx,
					width - (shadowBlur + shadowOffset.x + 17),
					height - (shadowBlur + shadowOffset.y + 18),
					11,
					11,
					options.resizableColor,
					1.0
				);
            }

            // Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7
            if (Browser.Engine.trident) {
                MUI.triangle(ctx, 0, 0, 10, 10, options.resizableColor, 0);
            }
        }

        if (options.type != 'notification' && options.useCanvasControls == true) {
            this.drawControls(width, height, shadows);
        }

        // Resize panels if there are any
        if (MUI.Desktop && this.contentWrapperEl.getChildren('.column').length != 0) {
            MUI.rWidth(this.contentWrapperEl);
            this.contentWrapperEl.getChildren('.column').each(function(column) {
                MUI.panelHeight(column);
            });
        }

        this.drawingWindow = false;
        return this;

    },
    drawWindowCollapsed: function(shadows) {

        var windowEl = this.windowEl;

        var options = this.options;
        var shadowBlur = options.shadowBlur;
        var shadowBlur2x = shadowBlur * 2;
        var shadowOffset = options.shadowOffset;

        var headerShadow = options.headerHeight + shadowBlur2x + 2;
        var height = headerShadow;
        var width = this.contentWrapperEl.getStyle('width').toInt() + shadowBlur2x;
        this.windowEl.setStyle('height', height);

        this.overlayEl.setStyles({
            'height': height,
            'top': shadowBlur - shadowOffset.y,
            'left': shadowBlur - shadowOffset.x
        });

        // Part of the fix for IE6 select z-index bug
        if (Browser.Engine.trident4) {
            this.zIndexFixEl.setStyles({
                'width': width,
                'height': height
            });
        }

        // Set width
        this.windowEl.setStyle('width', width);
        this.overlayEl.setStyle('width', width);
        this.titleBarEl.setStyles({
            'width': width - shadowBlur2x,
            'height': options.headerHeight
        });

        // Draw Window
        if (this.options.useCanvas != false) {
            this.canvasEl.height = height;
            this.canvasEl.width = width;

            var ctx = this.canvasEl.getContext('2d');
            ctx.clearRect(0, 0, width, height);

            this.drawBoxCollapsed(ctx, width, height, shadowBlur, shadowOffset, shadows);
            if (options.useCanvasControls == true) {
                this.drawControls(width, height, shadows);
            }

            // Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7
            if (Browser.Engine.trident) {
                MUI.triangle(ctx, 0, 0, 10, 10, options.resizableColor, 0);
            }
        }

        this.drawingWindow = false;
        return this;

    },
    drawControls: function(width, height, shadows) {
        var options = this.options;
        var shadowBlur = options.shadowBlur;
        var shadowOffset = options.shadowOffset;
        var controlsOffset = options.controlsOffset;

        // Make sure controls are placed correctly.
        this.controlsEl.setStyles({
            'right': shadowBlur + shadowOffset.x + controlsOffset.right,
            'top': shadowBlur - shadowOffset.y + controlsOffset.top
        });

        this.canvasControlsEl.setStyles({
            'right': shadowBlur + shadowOffset.x + controlsOffset.right,
            'top': shadowBlur - shadowOffset.y + controlsOffset.top
        });

        // Calculate X position for controlbuttons
        //var mochaControlsWidth = 52;
        this.closebuttonX = options.closable ? this.mochaControlsWidth - 7 : this.mochaControlsWidth + 12;
        this.maximizebuttonX = this.closebuttonX - (options.maximizable ? 19 : 0);
        this.minimizebuttonX = this.maximizebuttonX - (options.minimizable ? 19 : 0);

        var ctx2 = this.canvasControlsEl.getContext('2d');
        ctx2.clearRect(0, 0, 100, 100);

        if (this.options.closable) {
            this.closebutton(
				ctx2,
				this.closebuttonX,
				7,
				options.closeBgColor,
				1.0,
				options.closeColor,
				1.0
			);
        }
        if (this.options.maximizable) {
            this.maximizebutton(
				ctx2,
				this.maximizebuttonX,
				7,
				options.maximizeBgColor,
				1.0,
				options.maximizeColor,
				1.0
			);
        }
        if (this.options.minimizable) {
            this.minimizebutton(
				ctx2,
				this.minimizebuttonX,
				7,
				options.minimizeBgColor,
				1.0,
				options.minimizeColor,
				1.0
			);
        }
        // Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7
        if (Browser.Engine.trident) {
            MUI.circle(ctx2, 0, 0, 3, this.options.resizableColor, 0);
        }

    },
    drawBox: function(ctx, width, height, shadowBlur, shadowOffset, shadows) {

        var options = this.options;
        var shadowBlur2x = shadowBlur * 2;
        var cornerRadius = this.options.cornerRadius;

        // This is the drop shadow. It is created onion style.
        if (shadows != false) {
            for (var x = 0; x <= shadowBlur; x++) {
                MUI.roundedRect(
					ctx,
					shadowOffset.x + x,
					shadowOffset.y + x,
					width - (x * 2) - shadowOffset.x,
					height - (x * 2) - shadowOffset.y,
					cornerRadius + (shadowBlur - x),
					[0, 0, 0],
					x == shadowBlur ? .29 : .065 + (x * .01)
				);
            }
        }
        // Window body.
        this.bodyRoundedRect(
			ctx,                          // context
			shadowBlur - shadowOffset.x,  // x
			shadowBlur - shadowOffset.y,  // y
			width - shadowBlur2x,         // width
			height - shadowBlur2x,        // height
			cornerRadius,                 // corner radius
			options.bodyBgColor      // Footer color
		);

        if (this.options.type != 'notification') {
            // Window header.
            this.topRoundedRect(
				ctx,                          // context
				shadowBlur - shadowOffset.x,  // x
				shadowBlur - shadowOffset.y,  // y
				width - shadowBlur2x,         // width
				options.headerHeight,         // height
				cornerRadius,                 // corner radius
				options.headerStartColor,     // Header gradient's top color
				options.headerStopColor       // Header gradient's bottom color
			);
        }
    },
    drawBoxCollapsed: function(ctx, width, height, shadowBlur, shadowOffset, shadows) {

        var options = this.options;
        var shadowBlur2x = shadowBlur * 2;
        var cornerRadius = options.cornerRadius;

        // This is the drop shadow. It is created onion style.
        if (shadows != false) {
            for (var x = 0; x <= shadowBlur; x++) {
                MUI.roundedRect(
					ctx,
					shadowOffset.x + x,
					shadowOffset.y + x,
					width - (x * 2) - shadowOffset.x,
					height - (x * 2) - shadowOffset.y,
					cornerRadius + (shadowBlur - x),
					[0, 0, 0],
					x == shadowBlur ? .3 : .06 + (x * .01)
				);
            }
        }

        // Window header
        this.topRoundedRect2(
			ctx,                          // context
			shadowBlur - shadowOffset.x,  // x
			shadowBlur - shadowOffset.y,  // y
			width - shadowBlur2x,         // width
			options.headerHeight + 2,     // height
			cornerRadius,                 // corner radius
			options.headerStartColor,     // Header gradient's top color
			options.headerStopColor       // Header gradient's bottom color
		);

    },
    drawGauge: function(ctx, width, height, shadowBlur, shadowOffset, shadows) {
        var options = this.options;
        var radius = (width * .5) - (shadowBlur) + 16;
        if (shadows != false) {
            for (var x = 0; x <= shadowBlur; x++) {
                MUI.circle(
					ctx,
					width * .5 + shadowOffset.x,
					(height + options.headerHeight) * .5 + shadowOffset.x,
					(width * .5) - (x * 2) - shadowOffset.x,
					[0, 0, 0],
					x == shadowBlur ? .75 : .075 + (x * .04)
				);
            }
        }
        MUI.circle(
			ctx,
			width * .5 - shadowOffset.x,
			(height + options.headerHeight) * .5 - shadowOffset.y,
			(width * .5) - shadowBlur,
			options.bodyBgColor,
			1
		);

        // Draw gauge header
        this.canvasHeaderEl.setStyles({
            'top': shadowBlur - shadowOffset.y,
            'left': shadowBlur - shadowOffset.x
        });
        var ctx = this.canvasHeaderEl.getContext('2d');
        ctx.clearRect(0, 0, width, 100);
        ctx.beginPath();
        ctx.lineWidth = 24;
        ctx.lineCap = 'round';
        ctx.moveTo(13, 13);
        ctx.lineTo(width - (shadowBlur * 2) - 13, 13);
        ctx.strokeStyle = 'rgba(0, 0, 0, .65)';
        ctx.stroke();
    },
    bodyRoundedRect: function(ctx, x, y, width, height, radius, rgb) {
        ctx.fillStyle = 'rgba(' + rgb.join(',') + ', 1)';
        ctx.beginPath();
        ctx.moveTo(x, y + radius);
        ctx.lineTo(x, y + height - radius);
        ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
        ctx.lineTo(x + width - radius, y + height);
        ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
        ctx.lineTo(x + width, y + radius);
        ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
        ctx.lineTo(x + radius, y);
        ctx.quadraticCurveTo(x, y, x, y + radius);
        ctx.fill();

    },
    topRoundedRect: function(ctx, x, y, width, height, radius, headerStartColor, headerStopColor) {
        var lingrad = ctx.createLinearGradient(0, 0, 0, height);
        lingrad.addColorStop(0, 'rgb(' + headerStartColor.join(',') + ')');
        lingrad.addColorStop(1, 'rgb(' + headerStopColor.join(',') + ')');
        ctx.fillStyle = lingrad;
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x, y + height);
        ctx.lineTo(x + width, y + height);
        ctx.lineTo(x + width, y + radius);
        ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
        ctx.lineTo(x + radius, y);
        ctx.quadraticCurveTo(x, y, x, y + radius);
        ctx.fill();

    },
    topRoundedRect2: function(ctx, x, y, width, height, radius, headerStartColor, headerStopColor) {
        // Chrome is having trouble rendering the LinearGradient in this particular case
        if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
            ctx.fillStyle = 'rgba(' + headerStopColor.join(',') + ', 1)';
        }
        else {
            var lingrad = ctx.createLinearGradient(0, this.options.shadowBlur - 1, 0, height + this.options.shadowBlur + 3);
            lingrad.addColorStop(0, 'rgb(' + headerStartColor.join(',') + ')');
            lingrad.addColorStop(1, 'rgb(' + headerStopColor.join(',') + ')');
            ctx.fillStyle = lingrad;
        }
        ctx.beginPath();
        ctx.moveTo(x, y + radius);
        ctx.lineTo(x, y + height - radius);
        ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
        ctx.lineTo(x + width - radius, y + height);
        ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
        ctx.lineTo(x + width, y + radius);
        ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
        ctx.lineTo(x + radius, y);
        ctx.quadraticCurveTo(x, y, x, y + radius);
        ctx.fill();
    },
    maximizebutton: function(ctx, x, y, rgbBg, aBg, rgb, a) {
        // Circle
        ctx.beginPath();
        ctx.arc(x, y, 7, 0, Math.PI * 2, true);
        ctx.fillStyle = 'rgba(' + rgbBg.join(',') + ',' + aBg + ')';
        ctx.fill();
        // X sign
        ctx.strokeStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(x, y - 3.5);
        ctx.lineTo(x, y + 3.5);
        ctx.moveTo(x - 3.5, y);
        ctx.lineTo(x + 3.5, y);
        ctx.stroke();
    },
    closebutton: function(ctx, x, y, rgbBg, aBg, rgb, a) {
        // Circle
        ctx.beginPath();
        ctx.arc(x, y, 7, 0, Math.PI * 2, true);
        ctx.fillStyle = 'rgba(' + rgbBg.join(',') + ',' + aBg + ')';
        ctx.fill();
        // Plus sign
        ctx.strokeStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(x - 3, y - 3);
        ctx.lineTo(x + 3, y + 3);
        ctx.moveTo(x + 3, y - 3);
        ctx.lineTo(x - 3, y + 3);
        ctx.stroke();
    },
    minimizebutton: function(ctx, x, y, rgbBg, aBg, rgb, a) {
        // Circle
        ctx.beginPath();
        ctx.arc(x, y, 7, 0, Math.PI * 2, true);
        ctx.fillStyle = 'rgba(' + rgbBg.join(',') + ',' + aBg + ')';
        ctx.fill();
        // Minus sign
        ctx.strokeStyle = 'rgba(' + rgb.join(',') + ',' + a + ')';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(x - 3.5, y);
        ctx.lineTo(x + 3.5, y);
        ctx.stroke();
    },
    setMochaControlsWidth: function() {
        this.mochaControlsWidth = 0;
        var options = this.options;
        if (options.minimizable) {
            this.mochaControlsWidth += (this.minimizeButtonEl.getStyle('margin-left').toInt() + this.minimizeButtonEl.getStyle('width').toInt());
        }
        if (options.maximizable) {
            this.mochaControlsWidth += (this.maximizeButtonEl.getStyle('margin-left').toInt() + this.maximizeButtonEl.getStyle('width').toInt());
        }
        if (options.closable) {
            this.mochaControlsWidth += (this.closeButtonEl.getStyle('margin-left').toInt() + this.closeButtonEl.getStyle('width').toInt());
        }
        this.controlsEl.setStyle('width', this.mochaControlsWidth);
        if (options.useCanvasControls == true) {
            this.canvasControlsEl.setProperty('width', this.mochaControlsWidth);
        }
    },
    /*

	Function: hideSpinner
    Hides the spinner.
		
	Example:	
    (start code)
    $('myWindow').retrieve('instance').hideSpinner();
    (end)		
		
	*/
    hideSpinner: function() {
        if (this.spinnerEl) this.spinnerEl.hide();
        return this;
    },
    /*

	Function: showSpinner
    Shows the spinner.
		
	Example:	
    (start code)
    $('myWindow').retrieve('instance').showSpinner();
    (end)		
	
	*/
    showSpinner: function() {
        if (this.spinnerEl) this.spinnerEl.show();
        return this;
    },
    /* 

	Function: close
    Closes the window. This is an alternative to using MUI.Core.closeWindow().
		
	Example:	
    (start code)
    $('myWindow').retrieve('instance').close();
    (end)		
		
	 */
    close: function() {
        if (!this.isClosing) MUI.closeWindow(this.windowEl);
        return this;
    },
    /*

	Function: minimize
    Minimizes the window.
		
	Example:	
    (start code)
    $('myWindow').retrieve('instance').minimize();
    (end)		

	 */
    minimize: function() {
        MUI.Dock.minimizeWindow(this.windowEl);
        return this;
    },
    /*

	Function: maximize
    Maximizes the window.
		
	Example:	
    (start code)
    $('myWindow').retrieve('instance').maximize();
    (end)		

	 */
    maximize: function() {
        if (this.isMinimized) {
            MUI.Dock.restoreMinimized(this.windowEl);
        }
        MUI.Desktop.maximizeWindow(this.windowEl);
        return this;
    },
    /*

	Function: restore
    Restores a minimized/maximized window to its original size.
		
	Example:	
    (start code)
    $('myWindow').retrieve('instance').restore();
    (end)		

	 */
    restore: function() {
        if (this.isMinimized)
            MUI.Dock.restoreMinimized(this.windowEl);
        else if (this.isMaximized)
            MUI.Desktop.restoreWindow(this.windowEl);
        return this;
    },
    /*

	Function: resize
    Resize a window.
		
	Notes:
    If Advanced Effects are on the resize is animated. If centered is set to true the window remains centered as it resizes.	
			
    Example:	
    (start code)
    $('myWindow').retrieve('instance').resize({width:500,height:300,centered:true});
    (end)		

	 */
    resize: function(options) {
        MUI.resizeWindow(this.windowEl, options);
        return this;
    },
    /*

	Function: center
    Center a window.
			
    Example:	
    (start code)
    $('myWindow').retrieve('instance').center();
    (end)		

	 */
    center: function() {
        MUI.centerWindow(this.windowEl);
        return this;
    },

    hide: function() {
        this.windowEl.setStyle('display', 'none');
        return this;
    },

    show: function() {
        this.windowEl.setStyle('display', 'block');
        return this;
    }

});

MUI.extend({
	/*

	Function: closeWindow
		Closes a window.

	Syntax:
	(start code)
		MUI.closeWindow();
	(end)

	Arguments: 
		windowEl - the ID of the window to be closed

	Returns:
		true - the window was closed
		false - the window was not closed

	*/
	closeWindow: function(windowEl){		

		var instance = windowEl.retrieve('instance');
		
		// Does window exist and is not already in process of closing ?
		if (windowEl != $(windowEl) || instance.isClosing) return;
			
		instance.isClosing = true;
		instance.fireEvent('onClose', windowEl);
		
		if (instance.options.storeOnClose){
			this.storeOnClose(instance, windowEl);
			return;
		}
		if (instance.check) instance.check.destroy();

		if ((instance.options.type == 'modal' || instance.options.type == 'modal2') && Browser.Engine.trident4){
			$('modalFix').hide();
		}
		
		if (MUI.options.advancedEffects == false){			
			if (instance.options.type == 'modal' || instance.options.type == 'modal2'){
				$('modalOverlay').setStyle('opacity', 0);
			}			
			MUI.closingJobs(windowEl);			
			return true;	
		}
		else {
			// Redraws IE windows without shadows since IE messes up canvas alpha when you change element opacity
			if (Browser.Engine.trident) instance.drawWindow(false);
			if (instance.options.type == 'modal' || instance.options.type == 'modal2'){
				MUI.Modal.modalOverlayCloseMorph.start({
					'opacity': 0
				});
			}
			var closeMorph = new Fx.Morph(windowEl, {
				duration: 120,
				onComplete: function(){
					MUI.closingJobs(windowEl);
					return true;
				}.bind(this)
			});
			closeMorph.start({
				'opacity': .4
			});
		}

	},
	closingJobs: function(windowEl){

		var instances = MUI.Windows.instances;
		var instance = instances.get(windowEl.id);		
		windowEl.setStyle('visibility', 'hidden');
		// Destroy throws an error in IE8
		if (Browser.Engine.trident) {
			windowEl.dispose();
		}
		else {
			windowEl.destroy();
		}
		instance.fireEvent('onCloseComplete');		
		
		if (instance.options.type != 'notification'){
			var newFocus = this.getWindowWithHighestZindex();
			this.focusWindow(newFocus);
		}

		instances.erase(instance.options.id);
		if (this.loadingWorkspace == true) {
			this.windowUnload();
		}

		if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') {
			var currentButton = $(instance.options.id + '_dockTab');
			if (currentButton != null) {
				MUI.Dock.dockSortables.removeItems(currentButton).destroy();
			}
			// Need to resize everything in case the dock becomes smaller when a tab is removed
			MUI.Desktop.setDesktopSize();
		}
	},
	storeOnClose: function(instance, windowEl){
	
		if (instance.check) instance.check.hide();

		windowEl.setStyles({
			zIndex: -1
		});
		windowEl.addClass('windowClosed');
		windowEl.removeClass('mocha');		

		if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') {
			var currentButton = $(instance.options.id + '_dockTab');
			if (currentButton != null) {
				currentButton.hide();
			}
			MUI.Desktop.setDesktopSize();
		}
		
		instance.fireEvent('onCloseComplete');		
		
		if (instance.options.type != 'notification'){
			var newFocus = this.getWindowWithHighestZindex();
			this.focusWindow(newFocus);
		}
		
		instance.isClosing = false;		
		
	},
	/*
	
	Function: closeAll	
		Close all open windows.

	*/
	closeAll: function() {		
		$$('.mocha').each(function(windowEl){
			this.closeWindow(windowEl);
		}.bind(this));
	},
	/*
	  	
	Function: collapseToggle
		Collapses an expanded window. Expands a collapsed window.

	*/
	collapseToggle: function(windowEl){
		var instance = windowEl.retrieve('instance');
		var handles = windowEl.getElements('.handle');
		if (instance.isMaximized == true) return;		
		if (instance.isCollapsed == false) {
			instance.isCollapsed = true;
			handles.hide();
			if ( instance.iframeEl ) {
				instance.iframeEl.setStyle('visibility', 'hidden');
			}
			instance.contentBorderEl.setStyles({
				visibility: 'hidden',
				position: 'absolute',
				top: -10000,
				left: -10000
			});
			if(instance.toolbarWrapperEl){
				instance.toolbarWrapperEl.setStyles({
					visibility: 'hidden',
					position: 'absolute',
					top: -10000,
					left: -10000
				});
			}
			instance.drawWindowCollapsed();
		}
		else {
			instance.isCollapsed = false;
			instance.drawWindow();
			instance.contentBorderEl.setStyles({
				visibility: 'visible',
				position: null,
				top: null,
				left: null
			});
			if(instance.toolbarWrapperEl){
				instance.toolbarWrapperEl.setStyles({
					visibility: 'visible',
					position: null,
					top: null,
					left: null
				});
			}
			if ( instance.iframeEl ) {
				instance.iframeEl.setStyle('visibility', 'visible');
			}
			handles.show();
		}
	},	
	/*

	Function: toggleWindowVisibility
		Toggle window visibility with Ctrl-Alt-Q.

	*/	
	toggleWindowVisibility: function(){
		MUI.Windows.instances.each(function(instance){
			if (instance.options.type == 'modal' || instance.options.type == 'modal2' || instance.isMinimized == true) return;									
			var id = $(instance.options.id);
			if (id.getStyle('visibility') == 'visible'){
				if (instance.iframe){
					instance.iframeEl.setStyle('visibility', 'hidden');
				}
				if (instance.toolbarEl){
					instance.toolbarWrapperEl.setStyle('visibility', 'hidden');
				}
				instance.contentBorderEl.setStyle('visibility', 'hidden');
				id.setStyle('visibility', 'hidden');
				MUI.Windows.windowsVisible = false;
			}
			else {
				id.setStyle('visibility', 'visible');
				instance.contentBorderEl.setStyle('visibility', 'visible');
				if (instance.iframe){
					instance.iframeEl.setStyle('visibility', 'visible');
				}
				if (instance.toolbarEl){
					instance.toolbarWrapperEl.setStyle('visibility', 'visible');
				}
				MUI.Windows.windowsVisible = true;
			}
		}.bind(this));

	},
	focusWindow: function(windowEl, fireEvent){

		// This is used with blurAll
		MUI.Windows.focusingWindow = true;
		var windowClicked = function(){
			MUI.Windows.focusingWindow = false;
		};
		windowClicked.delay(170, this);
		
		// Only focus when needed
		if ($$('.mocha').length == 0) return;
		if (windowEl != $(windowEl) || windowEl.hasClass('isFocused')) return;

		var instances =  MUI.Windows.instances;
		var instance = instances.get(windowEl.id);
	
		if (instance.options.type == 'notification'){
			windowEl.setStyle('zIndex', 11001);
			return;
		};

		MUI.Windows.indexLevel += 2;
		windowEl.setStyle('zIndex', MUI.Windows.indexLevel);

		// Used when dragging and resizing windows
		$('windowUnderlay').setStyle('zIndex', MUI.Windows.indexLevel - 1).inject($(windowEl),'after');

		// Fire onBlur for the window that lost focus.
		instances.each(function(instance){
			if (instance.windowEl.hasClass('isFocused')){
				instance.fireEvent('onBlur', instance.windowEl);
			}
			instance.windowEl.removeClass('isFocused');
		});

		if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') {
			MUI.Dock.makeActiveTab();
		}
		windowEl.addClass('isFocused');

		if (fireEvent != false){
			instance.fireEvent('onFocus', windowEl);
		}

	},
	getWindowWithHighestZindex: function(){
		this.highestZindex = 0;
		$$('.mocha').each(function(element){
			this.zIndex = element.getStyle('zIndex');
			if (this.zIndex >= this.highestZindex) {
				this.highestZindex = this.zIndex;
			}	
		}.bind(this));
		$$('.mocha').each(function(element){
			if (element.getStyle('zIndex') == this.highestZindex) {
				this.windowWithHighestZindex = element;
			}
		}.bind(this));
		return this.windowWithHighestZindex;
	},
	blurAll: function(){		
		if (MUI.Windows.focusingWindow == false) {
			$$('.mocha').each(function(windowEl){
				var instance = windowEl.retrieve('instance');
				if (instance.options.type != 'modal' && instance.options.type != 'modal2'){
					windowEl.removeClass('isFocused');
				}
			});
			$$('.dockTab').removeClass('activeDockTab');
		}
	},
	centerWindow: function(windowEl){
		
		if(!windowEl){
			MUI.Windows.instances.each(function(instance){
				if (instance.windowEl.hasClass('isFocused')){
					windowEl = instance.windowEl;
				}
			});
		}

		var instance = windowEl.retrieve('instance');
		var options = instance.options;
		var dimensions = options.container.getCoordinates();
				
		var windowPosTop = window.getScroll().y + (window.getSize().y * .5) - (windowEl.offsetHeight * .5);
		if (windowPosTop < -instance.options.shadowBlur){
			windowPosTop = -instance.options.shadowBlur;
		}
		var windowPosLeft =	(dimensions.width * .5) - (windowEl.offsetWidth * .5);
		if (windowPosLeft < -instance.options.shadowBlur){
			windowPosLeft = -instance.options.shadowBlur;
		}
		if (MUI.options.advancedEffects == true){
			instance.morph.start({
				'top': windowPosTop,
				'left': windowPosLeft
			});
		}
		else {
			windowEl.setStyles({
				'top': windowPosTop,
				'left': windowPosLeft
			});
		}
	},
	resizeWindow: function(windowEl, options){
		var instance = windowEl.retrieve('instance');
		
		$extend({
			width: null,
			height: null,
			top: null,
			left: null,
			centered: true
		}, options);
				
		var oldWidth = windowEl.getStyle('width').toInt();
		var oldHeight = windowEl.getStyle('height').toInt();
		var oldTop = windowEl.getStyle('top').toInt();
		var oldLeft = windowEl.getStyle('left').toInt();
		
		if (options.centered){
			var top = options.top || oldTop - ((options.height - oldHeight) * .5);
			var left = options.left || oldLeft - ((options.width - oldWidth) * .5);
		}
		else {
			var top =  options.top || oldTop;
			var left = options.left || oldLeft;
		}				
		
		if (MUI.options.advancedEffects == false){
			windowEl.setStyles({
				'top': top,
				'left': left
			});
			instance.contentWrapperEl.setStyles({
				'height': options.height,
				'width':  options.width
			});
			instance.drawWindow();
			// Show iframe
			if (instance.iframeEl){
				if (!Browser.Engine.trident) {
					instance.iframeEl.setStyle('visibility', 'visible');
				}
				else {
					instance.iframeEl.show();
				}
			}
		}
		else {
			windowEl.retrieve('resizeMorph').start({
				'0': {	'height': options.height,
						'width':  options.width
				},
				'1': {	'top': top,
						'left': left 
				}
			});		
		}
		return instance;
	},
	/*

	Internal Function: dynamicResize
		Use with a timer to resize a window as the window's content size changes, such as with an accordian.

	*/
	dynamicResize: function(windowEl, maxHeight){
		var instance = windowEl.retrieve('instance');
		var contentWrapperEl = instance.contentWrapperEl;
		var contentEl = instance.contentEl.childNodes[0];
		var heightToBe = contentEl.offsetHeight;
		var modalPopupContent = contentWrapperEl.getElement(".ModalPopupContent");
		
		//reset the modal and calculate height
		if(maxHeight && modalPopupContent) {
            modalPopupContent.setStyles({
                height: 'auto',
                overflow: 'visible'
            });
            heightToBe = contentEl.offsetHeight > maxHeight ? maxHeight : contentEl.offsetHeight
	    }
		
		contentWrapperEl.setStyles({
			'height': heightToBe,
			'width': contentEl.offsetWidth
		});
		
		if(maxHeight && contentEl.offsetHeight > maxHeight) {
		    if(modalPopupContent) {
		        modalPopupContent.setStyles({
		            height: maxHeight - 31,
		            'overflow-y': 'auto',
		            'overflow-x': 'hidden'
		        });
		        if(Browser.Engine.trident) {
                    modalPopupContent.setStyles({
		                'float': 'none'
		            });
		        }
		    }
		}
		instance.drawWindow();
	}
});

// Toggle window visibility with Ctrl-Alt-Q
document.addEvent('keydown', function(event){
	if (event.key == 'q' && event.control && event.alt) {
		MUI.toggleWindowVisibility();
	}
});
/*

Script: Modal.js
	Create modal dialog windows.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

License:
	MIT-style license.	

Requires:
	Core.js, Window.js

See Also:
	<Window>	
	
*/

MUI.files[MUI.path.source + 'Window/Modal.js'] = 'loaded';

MUI.Modal = new Class({

	Extends: MUI.Window,
	
	options: {
		type: 'modal'
	},	
	
	initialize: function(options,justInit){
		
		if (!$('modalOverlay')){
			this.modalInitialize();
		
			window.addEvent('resize', function(){
				this.setModalSize();
			}.bind(this));
        }
        // if we aren't just setting up the modal overlay, then create a new window.
        // otherwise, we don't call the parent to setup window.	
		// -- CHRIS	
		if(!justInit) this.parent(options);

	},
	modalInitialize: function(){
		var modalOverlay = new Element('div', {
			'id': 'modalOverlay',
			'styles': {
				'height': document.getCoordinates().height,				
				'opacity': .6
			}
		}).inject(document.body);
		
		modalOverlay.setStyles({
				'position': Browser.Engine.trident4 ? 'absolute' : 'fixed'
		});
		
//		modalOverlay.addEvent('click', function(e){
//			var instance = MUI.Windows.instances.get(MUI.currentModal.id);
//			if (instance.options.modalOverlayClose == true) {
//				MUI.closeWindow(MUI.currentModal);
//			}
//		});
		
		if (Browser.Engine.trident4){
			var modalFix = new Element('iframe', {
				'id': 'modalFix',
				'scrolling': 'no',
				'marginWidth': 0,
				'marginHeight': 0,
				'src': '',
				'styles': {
					'height': document.getCoordinates().height
				}
			}).inject(document.body);
		}

		this.modalOverlayOpenMorph = new Fx.Morph($('modalOverlay'), {
			'duration': 150
		});
		this.modalOverlayCloseMorph = new Fx.Morph($('modalOverlay'), {
			'duration': 150,
			onComplete: function(){
				$('modalOverlay').hide();
				if (Browser.Engine.trident4){
					$('modalFix').hide();
				}
			}.bind(this)
		});
	},
	setModalSize: function(){
		$('modalOverlay').setStyle('height', document.getCoordinates().height);
		if (Browser.Engine.trident4){
			$('modalFix').setStyle('height', document.getCoordinates().height);
		}
	}

});
/*

Script: Windows-from-html.js
	Create windows from html markup in page.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

License:
	MIT-style license.	

Requires:
	Core.js, Window.js

Example:
	HTML markup.
	(start code)
<div class="mocha" id="mywindow" style="width:300px;height:255px;top:50px;left:350px">
	<h3 class="mochaTitle">My Window</h3>
	<p>My Window Content</p>
</div>	
	(end)

See Also:
	<Window>

*/

MUI.files[MUI.path.source + 'Window/Windows-from-html.js'] = 'loaded';

MUI.extend({
	NewWindowsFromHTML: function(){
		$$('.mocha').each(function(el) {
			// Get the window title and destroy that element, so it does not end up in window content
			if ( Browser.Engine.presto || Browser.Engine.trident5 ){
				el.hide(); // Required by Opera, and probably IE7
			}
			var title = el.getElement('h3.mochaTitle');
			
			if(Browser.Engine.presto) el.show();
			
			var elDimensions = el.getStyles('height', 'width');
			var properties = {
				id: el.getProperty('id'),
				height: elDimensions.height.toInt(),
				width: elDimensions.width.toInt(),
				x: el.getStyle('left').toInt(),
				y: el.getStyle('top').toInt()
			};
			// If there is a title element, set title and destroy the element so it does not end up in window content
			if ( title ) {
				properties.title = title.innerHTML;
				title.destroy();
			}
		
			// Get content and destroy the element
			properties.content = el.innerHTML;
			el.destroy();
			
			// Create window
			new MUI.Window(properties, true);
		}.bind(this));
	}
});
/*

Script: Windows-from-json.js
	Create one or more windows from JSON data. You can define all the same properties as you can for new MUI.Window(). Undefined properties are set to their defaults.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

License:
	MIT-style license.	

Syntax:
	(start code)
	MUI.newWindowsFromJSON(properties);
	(end)

Example:
	(start code)
	MUI.jsonWindows = function(){
		var url = 'data/json-windows-data.js';
		var request = new Request.JSON({
			url: url,
			method: 'get',
			onComplete: function(properties) {
				MUI.newWindowsFromJSON(properties.windows);
			}
		}).send();
	}
	(end)

Note: 
	Windows created from JSON are not compatible with the current cookie based version
	of Save and Load Workspace.  	

See Also:
	<Window>

*/

MUI.files[MUI.path.source + 'Window/Windows-from-json.js'] = 'loaded';

MUI.extend({	
	newWindowsFromJSON: function(newWindows){
		newWindows.each(function(options) {
			var temp = new Hash(options);
			temp.each( function(value, key, hash) {
				if ($type(value) != 'string') return;
				if (value.substring(0,8) == 'function'){
					eval("options." + key + " = " + value);
				}
			});			
			new MUI.Window(options);
		});
	}
});
/*

Script: Arrange-cascade.js
	Cascade windows.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

License:
	MIT-style license.	

Requires:
	Core.js, Window.js

Syntax:
	(start code)
	MUI.arrangeCascade();
	(end)

*/

MUI.files[MUI.path.source + 'Window/Arrange-cascade.js'] = 'loaded';

MUI.extend({   
	arrangeCascade: function(){

		var	viewportTopOffset = 30;    // Use a negative number if neccessary to place first window where you want it
	var viewportLeftOffset = 20;
	var windowTopOffset = 50;    // Initial vertical spacing of each window
	var windowLeftOffset = 40; 

		// See how much space we have to work with
		var coordinates = document.getCoordinates();
		
		var openWindows = 0;
		MUI.Windows.instances.each(function(instance){
			if (!instance.isMinimized && instance.options.draggable) openWindows ++; 
		});
		
		if ((windowTopOffset * (openWindows + 1)) >= (coordinates.height - viewportTopOffset)) {
			var topOffset = (coordinates.height - viewportTopOffset) / (openWindows + 1);
		}
		else {
			var topOffset = windowTopOffset;
		}
		
		if ((windowLeftOffset * (openWindows + 1)) >= (coordinates.width - viewportLeftOffset - 20)) {
			var leftOffset = (coordinates.width - viewportLeftOffset - 20) / (openWindows + 1);
		}
		else {
			var leftOffset = windowLeftOffset;
		}

		var x = viewportLeftOffset;
		var y = viewportTopOffset;
		$$('.mocha').each(function(windowEl){
			var instance = windowEl.retrieve('instance');
			if (!instance.isMinimized && !instance.isMaximized && instance.options.draggable){
				id = windowEl.id;
				MUI.focusWindow(windowEl);
				x += leftOffset;
				y += topOffset;

				if (MUI.options.advancedEffects == false){
					windowEl.setStyles({
						'top': y,
						'left': x
					});
				}
				else {
					var cascadeMorph = new Fx.Morph(windowEl, {
						'duration': 550
					});
					cascadeMorph.start({
						'top': y,
						'left': x
					});
				}
			}
		}.bind(this));
	}
});
/*

Script: Arrange-tile.js
	Cascade windows.
	
Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

Authors:
	Harry Roberts and Greg Houston

License:
	MIT-style license.	

Requires:
	Core.js, Window.js

Syntax:
	(start code)
	MUI.arrangeTile();
	(end)

*/

MUI.files[MUI.path.source + 'Window/Arrange-tile.js'] = 'loaded';
 
MUI.extend({
	arrangeTile: function(){

		var	viewportTopOffset = 30;    // Use a negative number if neccessary to place first window where you want it
		var viewportLeftOffset = 20;

		var x = 10;
		var y = 80;
	
		var instances =  MUI.Windows.instances;

		var windowsNum = 0;

		instances.each(function(instance){
			if (!instance.isMinimized && !instance.isMaximized){
				windowsNum++;
			}
		});

		var cols = 3;
		var rows = Math.ceil(windowsNum / cols);
		
		var coordinates = document.getCoordinates();
	
		var col_width = ((coordinates.width - viewportLeftOffset) / cols);
		var col_height = ((coordinates.height - viewportTopOffset) / rows);
		
		var row = 0;
		var col = 0;
		
		instances.each(function(instance){
			if (!instance.isMinimized && !instance.isMaximized && instance.options.draggable ){
				
				var content = instance.contentWrapperEl;
				var content_coords = content.getCoordinates();
				var window_coords = instance.windowEl.getCoordinates();
				
				// Calculate the amount of padding around the content window
				var padding_top = content_coords.top - window_coords.top;
				var padding_bottom = window_coords.height - content_coords.height - padding_top;
				var padding_left = content_coords.left - window_coords.left;
				var padding_right = window_coords.width - content_coords.width - padding_left;

				/*

				// This resizes the windows
				if (instance.options.shape != 'gauge' && instance.options.resizable == true){
					var width = (col_width - 3 - padding_left - padding_right);
					var height = (col_height - 3 - padding_top - padding_bottom);

					if (width > instance.options.resizeLimit.x[0] && width < instance.options.resizeLimit.x[1]){
						content.setStyle('width', width);
					}
					if (height > instance.options.resizeLimit.y[0] && height < instance.options.resizeLimit.y[1]){
						content.setStyle('height', height);
					}

				}*/

				var left = (x + (col * col_width));
				var top = (y + (row * col_height));

				instance.drawWindow();
				
				MUI.focusWindow(instance.windowEl);
				
				if (MUI.options.advancedEffects == false){
					instance.windowEl.setStyles({
						'top': top,
						'left': left
					});
				}
				else {
					var tileMorph = new Fx.Morph(instance.windowEl, {
						'duration': 550
					});
					tileMorph.start({
						'top': top,
						'left': left
					});
				}				

				if (++col === cols) {
					row++;
					col = 0;
				}
			}
		}.bind(this));
	}
});
/*

Script: Tabs.js
	Functionality for window tabs.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

License:
	MIT-style license.

Requires:
	Core.js, Window.js (for tabbed windows) or Layout.js (for tabbed panels)

*/

MUI.files[MUI.path.source + 'Components/Tabs.js'] = 'loaded';

MUI.extend({
	/*

	Function: initializeTabs
		Add click event to each list item that fires the selected function.

	*/
	initializeTabs: function(el){
		$(el).setStyle('list-style', 'none'); // This is to fix a glitch that occurs in IE8 RC1 when dynamically switching themes
		$(el).getElements('li').each(function(listitem){
			listitem.addEvent('click', function(e){
				MUI.selected(this, el);
			});
		});
	},
	/*

	Function: selected
		Add "selected" class to current list item and remove it from sibling list items.

	Syntax:
		(start code)
			selected(el, parent);
		(end)

Arguments:
	el - the list item
	parent - the ul

	*/
	selected: function(el, parent){
		$(parent).getChildren().each(function(listitem){
			listitem.removeClass('selected');
		});
		el.addClass('selected');
	}
});

/*

Script: Layout.js
	Create web application layouts. Enables window maximize.
	
Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.

License:
	MIT-style license.	

Requires:
	Core.js
	
*/

MUI.files[MUI.path.source + 'Layout/Layout.js'] = 'loaded';

MUI.extend({
	Columns: {
		instances: new Hash(),
		columnIDCount: 0 // Used for columns without an ID defined by the user
	},
	Panels: {
		instances: new Hash(),
		panelIDCount: 0 // Used for panels without an ID defined by the user
	}
});

MUI.Desktop = {
	
	options: {
		// Naming options:
		// If you change the IDs of the MochaUI Desktop containers in your HTML, you need to change them here as well.
		desktop:             'desktop',
		desktopHeader:       'desktopHeader',
		desktopFooter:       'desktopFooter',
		desktopNavBar:       'desktopNavbar',
		pageWrapper:         'pageWrapper',
		page:                'page',
		desktopFooter:       'desktopFooterWrapper'
	},	
	initialize: function(){

		this.desktop         = $(this.options.desktop);
		this.desktopHeader   = $(this.options.desktopHeader);
		this.desktopNavBar   = $(this.options.desktopNavBar);
		this.pageWrapper     = $(this.options.pageWrapper);
		this.page            = $(this.options.page);
		this.desktopFooter   = $(this.options.desktopFooter);
		
		if (this.desktop) {
			($$('body')).setStyles({
				overflow: 'hidden',
				height: '100%',
				margin: 0
			});
			($$('html')).setStyles({
				overflow: 'hidden',
				height: '100%'
			});			
		}		
	
		// This is run on dock initialize so no need to do it twice.
		if (!MUI.Dock){
			this.setDesktopSize();
		}
		this.menuInitialize();		

		// Resize desktop, page wrapper, modal overlay, and maximized windows when browser window is resized
		window.addEvent('resize', function(e){
			this.onBrowserResize();
		}.bind(this));
		
		if (MUI.myChain){
			MUI.myChain.callChain();
		}
		
	},
	menuInitialize: function(){
		// Fix for dropdown menus in IE6
		if (Browser.Engine.trident4 && this.desktopNavBar){
			this.desktopNavBar.getElements('li').each(function(element) {
				element.addEvent('mouseenter', function(){
					this.addClass('ieHover');
				});
				element.addEvent('mouseleave', function(){
					this.removeClass('ieHover');
				});
			});
		};
	},
	onBrowserResize: function(){
		this.setDesktopSize();
		// Resize maximized windows to fit new browser window size
		setTimeout( function(){
			MUI.Windows.instances.each(function(instance){
				if (instance.isMaximized){

					// Hide iframe while resize for better performance
					if ( instance.iframeEl ){
						instance.iframeEl.setStyle('visibility', 'hidden');
					}

					var coordinates = document.getCoordinates();
					var borderHeight = instance.contentBorderEl.getStyle('border-top').toInt() + instance.contentBorderEl.getStyle('border-bottom').toInt();
					var toolbarHeight = instance.toolbarWrapperEl ? instance.toolbarWrapperEl.getStyle('height').toInt() + instance.toolbarWrapperEl.getStyle('border-top').toInt() : 0;
					instance.contentWrapperEl.setStyles({
						'height': coordinates.height - instance.options.headerHeight - instance.options.footerHeight - borderHeight - toolbarHeight,
						'width': coordinates.width
					});

					instance.drawWindow();
					if ( instance.iframeEl ){
						instance.iframeEl.setStyles({
							'height': instance.contentWrapperEl.getStyle('height')
						});
						instance.iframeEl.setStyle('visibility', 'visible');
					}

				}
			}.bind(this));
		}.bind(this), 100);
	},
	setDesktopSize: function(){
		var windowDimensions = window.getCoordinates();

		// var dock = $(MUI.options.dock);
		var dockWrapper = $(MUI.options.dockWrapper);
		
		// Setting the desktop height may only be needed by IE7
		if (this.desktop){
			this.desktop.setStyle('height', windowDimensions.height);
		}

		// Set pageWrapper height so the dock doesn't cover the pageWrapper scrollbars.
		if (this.pageWrapper) {
			var dockOffset = MUI.dockVisible ? dockWrapper.offsetHeight : 0;
			var pageWrapperHeight = windowDimensions.height;
			pageWrapperHeight -= this.pageWrapper.getStyle('border-top').toInt();
			pageWrapperHeight -= this.pageWrapper.getStyle('border-bottom').toInt();
			if (this.desktopHeader){ pageWrapperHeight -= this.desktopHeader.offsetHeight; }
			if (this.desktopFooter){ pageWrapperHeight -= this.desktopFooter.offsetHeight; }
			pageWrapperHeight -= dockOffset;

			if (pageWrapperHeight < 0){
				pageWrapperHeight = 0;
			}
			this.pageWrapper.setStyle('height', pageWrapperHeight);
		}

		if (MUI.Columns.instances.getKeys().length > 0){ // Conditional is a fix for a bug in IE6 in the no toolbars demo.
			MUI.Desktop.resizePanels();
		}		
	},
	resizePanels: function(){
		MUI.panelHeight();
		MUI.rWidth();	
	},	
	/*
	
	Function: maximizeWindow
		Maximize a window.
	
	Syntax:
		(start code)
		MUI.Desktop.maximizeWindow(windowEl);
		(end)	

	*/	
	maximizeWindow: function(windowEl){

		var instance = MUI.Windows.instances.get(windowEl.id);
		var options = instance.options;
		var windowDrag = instance.windowDrag;

		// If window no longer exists or is maximized, stop
		if (windowEl != $(windowEl) || instance.isMaximized ) return;
		
		if (instance.isCollapsed){
			MUI.collapseToggle(windowEl);	
		}

		instance.isMaximized = true;
		
		// If window is restricted to a container, it should not be draggable when maximized.
		if (instance.options.restrict){
			windowDrag.detach();
			if (options.resizable) {
				instance.detachResizable();
			}
			instance.titleBarEl.setStyle('cursor', 'default');
		}	

		// If the window has a container that is not the desktop
		// temporarily move the window to the desktop while it is minimized.
		if (options.container != this.desktop){
			this.desktop.grab(windowEl);
			if (this.options.restrict){
			windowDrag.container = this.desktop;
			}
		}		

		// Save original position
		instance.oldTop = windowEl.getStyle('top');
		instance.oldLeft = windowEl.getStyle('left');

		var contentWrapperEl = instance.contentWrapperEl;

		// Save original dimensions
		contentWrapperEl.oldWidth = contentWrapperEl.getStyle('width');
		contentWrapperEl.oldHeight = contentWrapperEl.getStyle('height');

		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( instance.iframeEl ) {
			if (!Browser.Engine.trident) {
				instance.iframeEl.setStyle('visibility', 'hidden');
			}
			else {
				instance.iframeEl.hide();
			}
		}
		
		var windowDimensions = document.getCoordinates();
		var options = instance.options;
		var shadowBlur = options.shadowBlur;
		var shadowOffset = options.shadowOffset;
		var newHeight = windowDimensions.height - options.headerHeight - options.footerHeight;
		newHeight -= instance.contentBorderEl.getStyle('border-top').toInt();
		newHeight -= instance.contentBorderEl.getStyle('border-bottom').toInt();
		newHeight -= (instance.toolbarWrapperEl ? instance.toolbarWrapperEl.getStyle('height').toInt() + instance.toolbarWrapperEl.getStyle('border-top').toInt() : 0);
		
		MUI.resizeWindow(windowEl, {
			width: windowDimensions.width,
			height: newHeight,
			top: shadowOffset.y - shadowBlur,
			left: shadowOffset.x - shadowBlur
		});
		instance.fireEvent('onMaximize', windowEl);
		
		if (instance.maximizeButtonEl) {
			instance.maximizeButtonEl.setProperty('title', 'Restore');
		}
		MUI.focusWindow(windowEl);

	},
	/*

	Function: restoreWindow
		Restore a maximized window.

	Syntax:
		(start code)
		MUI.Desktop.restoreWindow(windowEl);
		(end)	

	*/	
	restoreWindow: function(windowEl){	
	
		var instance = windowEl.retrieve('instance');
		
		// Window exists and is maximized ?
		if (windowEl != $(windowEl) || !instance.isMaximized) return;
			
		var options = instance.options;
		instance.isMaximized = false;
		
		if (options.restrict){
			instance.windowDrag.attach();
			if (options.resizable){
				instance.reattachResizable();
			}			
			instance.titleBarEl.setStyle('cursor', 'move');
		}		
		
		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( instance.iframeEl ) {
			if (!Browser.Engine.trident) {
				instance.iframeEl.setStyle('visibility', 'hidden');
			}
			else {
				instance.iframeEl.hide();
			}
		}
		
		var contentWrapperEl = instance.contentWrapperEl;	
		
		MUI.resizeWindow(windowEl,{
			width: contentWrapperEl.oldWidth,
			height: contentWrapperEl.oldHeight,
			top: instance.oldTop,
			left: instance.oldLeft
		});
		instance.fireEvent('onRestore', windowEl);
				
		if (instance.maximizeButtonEl){		
			instance.maximizeButtonEl.setProperty('title', 'Maximize');
		}
	}
};

/*

Class: Column
	Create a column. Columns should be created from left to right.

Syntax:
(start code)
	MUI.Column();
(end)

Arguments:
	options

Options:
	id - The ID of the column. This must be set when creating the column.
	container - Defaults to MUI.Desktop.pageWrapper. 	
	placement - Can be 'right', 'main', or 'left'. There must be at least one column with the 'main' option.
	width - 'main' column is fluid and should not be given a width.
	resizeLimit - resizelimit of a 'right' or 'left' column.
	sortable - (boolean) Whether the panels can be reordered via drag and drop.
	onResize - (function) Fired when the column is resized.
	onCollapse - (function) Fired when the column is collapsed.
	onExpand - (function) Fired when the column is expanded.
		
*/
MUI.Column = new Class({

	Implements: [Events, Options],

	options: {
		id:            null,
		container:     null,
		placement:     null, 
		width:         null,
		resizeLimit:   [],
		sortable:      true,

		// Events
		onResize:     $empty, 
		onCollapse:   $empty,
		onExpand:     $empty

	},
	
	initialize: function(options){
		this.setOptions(options);
		
		$extend(this, {
			timestamp: $time(),
			isCollapsed: false,
			oldWidth: 0
		});
		
		// If column has no ID, give it one.
		if (this.options.id == null){
			this.options.id = 'column' + (++MUI.Columns.columnIDCount);
		}		

		// Shorten object chain
		var options = this.options;
		var instances = MUI.Columns.instances;
		var instanceID = instances.get(options.id);

		if (options.container == null) {
			options.container = MUI.Desktop.pageWrapper
		}
		else {
			$(options.container).setStyle('overflow', 'hidden');
		}

		if (typeof this.options.container == 'string'){
			this.options.container = $(this.options.container);
		}

		// Check to see if there is already a class instance for this Column
		if (instanceID){
			var instance = instanceID;
		}

		// Check if column already exists
		if ( this.columnEl ){
			return;
		}
		else {			
			instances.set(options.id, this);
		}		
		
		// If loading columns into a panel, hide the regular content container.
		if ($(options.container).getElement('.pad') != null) {
			$(options.container).getElement('.pad').hide();
		}
		
		// If loading columns into a window, hide the regular content container.
		if ($(options.container).getElement('.mochaContent') != null) {
			$(options.container).getElement('.mochaContent').hide();
		}
		
		this.columnEl = new Element('div', {
			'id': this.options.id,
			'class': 'column expanded',
			'styles': {
				'width': options.placement == 'main' ? null : options.width
			}
		}).inject($(options.container));
		
		this.columnEl.store('instance', this);
		
		var parent = this.columnEl.getParent();
		var columnHeight = parent.getStyle('height').toInt();
		this.columnEl.setStyle('height', columnHeight);		
		
		if (this.options.sortable){
			if (!this.options.container.retrieve('sortables')){
				var sortables = new Sortables(this.columnEl, {
					opacity: 1,
					handle: '.panel-header',		
					constrain: false,
					revert: false,				
					onSort: function(){
						$$('.column').each(function(column){
							column.getChildren('.panelWrapper').each(function(panelWrapper){
								panelWrapper.getElement('.panel').removeClass('bottomPanel');
							});
							if (column.getChildren('.panelWrapper').getLast()){
								column.getChildren('.panelWrapper').getLast().getElement('.panel').addClass('bottomPanel');
							}
							MUI.panelHeight();
						}.bind(this));
					}.bind(this)
				});
				this.options.container.store('sortables', sortables);			
			}
			else {
				this.options.container.retrieve('sortables').addLists(this.columnEl);
			}
		}		
		
		if (options.placement == 'main'){
			this.columnEl.addClass('rWidth');
		}

		switch (this.options.placement) {
			case 'left':
				this.handleEl = new Element('div', {
					'id': this.options.id + '_handle',
					'class': 'columnHandle'
				}).inject(this.columnEl, 'after');

				this.handleIconEl = new Element('div', {
					'id': options.id + '_handle_icon',
					'class': 'handleIcon'
				}).inject(this.handleEl);

				addResizeRight(this.columnEl, options.resizeLimit[0], options.resizeLimit[1]);
				break;
			case 'right':
				this.handleEl = new Element('div', {
					'id': this.options.id + '_handle',
					'class': 'columnHandle'
				}).inject(this.columnEl, 'before');

				this.handleIconEl = new Element('div', {
					'id': options.id + '_handle_icon',
					'class': 'handleIcon'
				}).inject(this.handleEl);
				addResizeLeft(this.columnEl, options.resizeLimit[0], options.resizeLimit[1]);
				break;
		}

		if (this.handleEl != null){
			this.handleEl.addEvent('dblclick', function(){
				this.columnToggle();
			}.bind(this));
		}

		MUI.rWidth();

	},
	columnToggle: function(){
		var column = this.columnEl;
		
		// Collapse
		if (this.isCollapsed == false){
			this.oldWidth = column.getStyle('width').toInt();

			this.resize.detach();
			this.handleEl.removeEvents('dblclick');
			this.handleEl.addEvent('click', function(){
				this.columnToggle();
			}.bind(this));
			this.handleEl.setStyle('cursor', 'pointer').addClass('detached');
			
			column.setStyle('width', 0);
			this.isCollapsed = true;
			column.addClass('collapsed');
			column.removeClass('expanded');
			MUI.rWidth();		
			this.fireEvent('onCollapse');
		}
		// Expand
		else {
			column.setStyle('width', this.oldWidth);
			this.isCollapsed = false;
			column.addClass('expanded');
			column.removeClass('collapsed');

			this.handleEl.removeEvents('click');
			this.handleEl.addEvent('dblclick', function(){
				this.columnToggle();
			}.bind(this));
			this.resize.attach();
			this.handleEl.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize').addClass('attached');

			MUI.rWidth();
			this.fireEvent('onExpand');
		}
	}
});
MUI.Column.implement(new Options, new Events);

/*

Class: Panel
	Create a panel. Panels go one on top of another in columns. Create your columns first and then add your panels. Panels should be created from top to bottom, left to right.

Syntax:
(start code)
	MUI.Panel();
(end)

Arguments:
	options

Options:
	id - The ID of the panel. This must be set when creating the panel.
	column - Where to inject the panel. This must be set when creating the panel.
	loadMethod - ('html', 'xhr', or 'iframe') Defaults to 'html' if there is no contentURL. Defaults to 'xhr' if there is a contentURL. You only really need to set this if using the 'iframe' method. May create a 'panel' loadMethod in the future.
	contentURL - Used if loadMethod is set to 'xhr' or 'iframe'.
	method - ('get', or 'post') The method used to get the data. Defaults to 'get'.
	data - (hash) Data to send with the URL. Defaults to null.
	evalScripts - (boolean) An xhr loadMethod option. Defaults to true.
	evalResponse - (boolean) An xhr loadMethod option. Defaults to false.
	content - (string or element) An html loadMethod option.
	tabsURL - (url)	
	tabsData - (hash) Data to send with the URL. Defaults to null.
	tabsOnload - (function)
	header - (boolean) Display the panel header or not
	headerToolbox: (boolean)
	headerToolboxURL: (url)
	headerToolboxOnload: (function)	
	footer - (boolean) Add a panel footer or not
	footerURL - (url)
	footerData - (hash) Data to send with the URL. Defaults to null.
	footerOnload - (function)
	height - (number) Height of content area.
	addClass - (string) Add a class to the panel.
	scrollbars - (boolean)
	padding - (object)
	collapsible - (boolean)
	onBeforeBuild - (function) Fired before the panel is created.
	onContentLoaded - (function) Fired after the panel's conten is loaded.
	onResize - (function) Fired when the panel is resized.
	onCollapse - (function) Fired when the panel is collapsed.
	onExpand - (function) Fired when the panel is expanded.
		
*/
MUI.Panel = new Class({
							
	Implements: [Events, Options],
	
	options: {
		id:                 null,
		title:              'New Panel',
		column:             null,
		require:            {
			css:            [],
			images:         [],
			js:             [],
			onload:         null
		},		
		loadMethod:         null,
		contentURL:         null,
	
		// xhr options
		method:             'get',
		data:               null,
		evalScripts:        true,
		evalResponse:       false,
	
		// html options
		content:            'Panel content',
		
		// Tabs
		tabsURL:            null,
		tabsData:           null,
		tabsOnload:         $empty,

		header:             true,		
		headerToolbox:      false,
		headerToolboxURL:   'pages/lipsum.html',
		headerToolboxOnload: $empty,		

		footer:             false,
		footerURL:          'pages/lipsum.html',
		footerData:         null,
		footerOnload:       $empty,
		
		// Style options:
		height:             125,
		addClass:           '',
		scrollbars:         true,
		padding:   		    { top: 8, right: 8, bottom: 8, left: 8 },
		
		// Other:
		collapsible:	    true,

		// Events
		onBeforeBuild:       $empty,
		onContentLoaded:     $empty,
		onResize:            $empty,
		onCollapse:          $empty,
		onExpand:            $empty

	},	
	initialize: function(options){
		this.setOptions(options);

		$extend(this, {
			timestamp: $time(),
			isCollapsed: false, // This is probably redundant since we can check for the class
			oldHeight: 0,
			partner: null
		});

		// If panel has no ID, give it one.
		if (this.options.id == null){
			this.options.id = 'panel' + (++MUI.Panels.panelIDCount);
		}

		// Shorten object chain
		var instances = MUI.Panels.instances;
		var instanceID = instances.get(this.options.id);
		var options = this.options;
	
		// Check to see if there is already a class instance for this panel
		if (instanceID){
			var instance = instanceID;
		}

		// Check if panel already exists
		if ( this.panelEl ){
			return;
		}
		else {			
			instances.set(this.options.id, this);
		}

		this.fireEvent('onBeforeBuild');		
		
		if (options.loadMethod == 'iframe') {
			// Iframes have their own padding.
			options.padding = { top: 0, right: 0, bottom: 0, left: 0 };
		}

		this.showHandle = true;
		if ($(options.column).getChildren().length == 0) {
			this.showHandle = false;
		}
		
		this.panelWrapperEl = new Element('div', {
			'id': this.options.id + '_wrapper',
			'class': 'panelWrapper expanded'	
		}).inject($(options.column));		
				
		this.panelEl = new Element('div', {
			'id': this.options.id,
			'class': 'panel expanded',
			'styles': {
				'height': options.height
			}
		}).inject(this.panelWrapperEl);
		
		this.panelEl.store('instance', this);
		
		this.panelEl.addClass(options.addClass);
		
		this.contentEl = new Element('div', {
			'id': options.id + '_pad',
			'class': 'pad'
		}).inject(this.panelEl);
		
		if (options.footer) {
			this.footerWrapperEl = new Element('div', {
				'id': options.id + '_panelFooterWrapper',
				'class': 'panel-footerWrapper'
			}).inject(this.panelEl);
			
			this.footerEl = new Element('div', {
				'id': options.id + '_panelFooter',
				'class': 'panel-footer'
			}).inject(this.footerWrapperEl);			
		}

		// This is in order to use the same variable as the windows do in updateContent.
		// May rethink this.
		this.contentWrapperEl = this.panelEl;
		
		this.contentEl.setStyles({
			'padding-top': options.padding.top,
			'padding-bottom': options.padding.bottom,
			'padding-left': options.padding.left,
			'padding-right': options.padding.right
		});
		
		this.panelHeaderEl = new Element('div', {
			'id': this.options.id + '_header',
			'class': 'panel-header',
			'styles': {
				'display': options.header ? 'block' : 'none'
			}
		}).inject(this.panelEl, 'before');
		
		var columnInstances = MUI.Columns.instances;
		var columnInstance = columnInstances.get(this.options.column);
		
		if (columnInstance.options.sortable){
			this.panelHeaderEl.setStyle('cursor', 'move');		
			columnInstance.options.container.retrieve('sortables').addItems(this.panelWrapperEl);		
		}
		
		if (this.options.collapsible) {
			this.collapseToggleInit();
		}
		
		if (this.options.headerToolbox) {
			this.panelHeaderToolboxEl = new Element('div', {
				'id': options.id + '_headerToolbox',
				'class': 'panel-header-toolbox'
			}).inject(this.panelHeaderEl);
		}
		
		this.panelHeaderContentEl = new Element('div', {
			'id': options.id + '_headerContent',
			'class': 'panel-headerContent'
		}).inject(this.panelHeaderEl);
		
		this.titleEl = new Element('h2', {
			'id': options.id + '_title'
		}).inject(this.panelHeaderContentEl);
		
		this.handleEl = new Element('div', {
			'id': options.id + '_handle',
			'class': 'horizontalHandle',
			'styles': {
				'display': this.showHandle == true ? 'block' : 'none'
			}
		}).inject(this.panelEl, 'after');
		
		this.handleIconEl = new Element('div', {
			'id': options.id + '_handle_icon',
			'class': 'handleIcon'
		}).inject(this.handleEl);		
		
		addResizeBottom(options.id);
		
		if (options.require.css.length || options.require.images.length){
			new MUI.Require({
				css: options.require.css,
				images: options.require.images,
				onload: function(){
					this.newPanel();
				}.bind(this)		
			});
		}		
		else {
			this.newPanel();
		}
	},
	newPanel: function(){
		
		options = this.options;
		
		if (options.footer) {			
			MUI.updateContent({
				'element': this.panelEl,
				'childElement': this.footerEl,
				'loadMethod': 'xhr',
				'data': options.footerData,
				'url': options.footerURL,
				'onContentLoaded': options.footerOnload
			});			
		}				
		
		if (this.options.headerToolbox) {			
			MUI.updateContent({
				'element': this.panelEl,
				'childElement': this.panelHeaderToolboxEl,
				'loadMethod': 'xhr',
				'url': options.headerToolboxURL,
				'onContentLoaded': options.headerToolboxOnload
			});
		}		
		
		if (options.tabsURL == null) {
			this.titleEl.set('html', options.title);
		} else {
			this.panelHeaderContentEl.addClass('tabs');
			MUI.updateContent({
				'element': this.panelEl,
				'childElement': this.panelHeaderContentEl,
				'loadMethod': 'xhr',
				'url': options.tabsURL,
				'data': options.tabsData,
				'onContentLoaded': options.tabsOnload
			});
		}		
		
		// Add content to panel.
		MUI.updateContent({
			'element': this.panelEl,
			'content': options.content,
			'method': options.method,
			'data': options.data,
			'url': options.contentURL,
			'onContentLoaded': null,
			'require': {
				js: options.require.js,
				onload: options.require.onload
			}			
		});
		
		// Do this when creating and removing panels
		$(options.column).getChildren('.panelWrapper').each(function(panelWrapper){
			panelWrapper.getElement('.panel').removeClass('bottomPanel');
		});
		$(options.column).getChildren('.panelWrapper').getLast().getElement('.panel').addClass('bottomPanel');
		
		MUI.panelHeight(options.column, this.panelEl, 'new');

	},
	collapseToggleInit: function(options){

		var options = this.options;

		this.panelHeaderCollapseBoxEl = new Element('div', {
			'id': options.id + '_headerCollapseBox',
			'class': 'toolbox'
		}).inject(this.panelHeaderEl);

		if (options.headerToolbox) {
			this.panelHeaderCollapseBoxEl.addClass('divider');
		}

		this.collapseToggleEl = new Element('div', {
			'id': options.id + '_collapseToggle',
			'class': 'panel-collapse icon16',
			'styles': {
				'width': 16,
				'height': 16
			},
			'title': 'Collapse Panel'
		}).inject(this.panelHeaderCollapseBoxEl);

		this.collapseToggleEl.addEvent('click', function(event){
			var panel = this.panelEl;
			var panelWrapper = this.panelWrapperEl
			
			// Get siblings and make sure they are not all collapsed.
			// If they are all collapsed and the current panel is collapsing
			// Then collapse the column.
			var instances = MUI.Panels.instances;
			var expandedSiblings = [];
			
			panelWrapper.getAllPrevious('.panelWrapper').each(function(sibling){
				var instance = instances.get(sibling.getElement('.panel').id);
				if (instance.isCollapsed == false){
					expandedSiblings.push(sibling.getElement('.panel').id);
				}
			});
			
			panelWrapper.getAllNext('.panelWrapper').each(function(sibling){
				var instance = instances.get(sibling.getElement('.panel').id);
				if (instance.isCollapsed == false){
					expandedSiblings.push(sibling.getElement('.panel').id);
				}
			});

			// Collapse Panel
			if (this.isCollapsed == false) {
				var currentColumn = MUI.Columns.instances.get($(options.column).id);

				if (expandedSiblings.length == 0 && currentColumn.options.placement != 'main'){
					var currentColumn = MUI.Columns.instances.get($(options.column).id);
					currentColumn.columnToggle();
					return;
				}
				else if (expandedSiblings.length == 0 && currentColumn.options.placement == 'main'){
					return;
				}
				this.oldHeight = panel.getStyle('height').toInt();
				if (this.oldHeight < 10) this.oldHeight = 20;
				this.contentEl.setStyle('position', 'absolute'); // This is so IE6 and IE7 will collapse the panel all the way		
				panel.setStyle('height', 0);								
				this.isCollapsed = true;				
				panelWrapper.addClass('collapsed');
				panelWrapper.removeClass('expanded');				
				MUI.panelHeight(options.column, panel, 'collapsing');
				MUI.panelHeight(); // Run this a second time for panels within panels
				this.collapseToggleEl.removeClass('panel-collapsed');
				this.collapseToggleEl.addClass('panel-expand');
				this.collapseToggleEl.setProperty('title','Expand Panel');
				this.fireEvent('onCollapse');				
			}
			
			// Expand Panel
			else {
				this.contentEl.setStyle('position', null); // This is so IE6 and IE7 will collapse the panel all the way				
				panel.setStyle('height', this.oldHeight);
				this.isCollapsed = false;				
				panelWrapper.addClass('expanded');
				panelWrapper.removeClass('collapsed');
				MUI.panelHeight(this.options.column, panel, 'expanding');
				MUI.panelHeight(); // Run this a second time for panels within panels
				this.collapseToggleEl.removeClass('panel-expand');
				this.collapseToggleEl.addClass('panel-collapsed');
				this.collapseToggleEl.setProperty('title','Collapse Panel');
				this.fireEvent('onExpand');
			}
		}.bind(this));	
	}	
});
MUI.Panel.implement(new Options, new Events);

/*
  	arguments:
		column - The column to resize the panels in
		changing -  The panel that is collapsing, expanding, or new
  		action - collapsing, expanding, or new
  
*/

MUI.extend({
	// Panel Height	
	panelHeight: function(column, changing, action){
		if (column != null) {
			MUI.panelHeight2($(column), changing, action);
		}
		else {
			$$('.column').each(function(column){
				MUI.panelHeight2(column);
			}.bind(this));
		}
	},
	/*

	actions can be new, collapsing or expanding.

	*/
	panelHeight2: function(column, changing, action){

		var instances = MUI.Panels.instances;
		
		var parent = column.getParent();
		var columnHeight = parent.getStyle('height').toInt();
		if (Browser.Engine.trident4 && parent == MUI.Desktop.pageWrapper) {
			columnHeight -= 1;
		}
		column.setStyle('height', columnHeight);
		
		// Get column panels
		var panels = [];
		column.getChildren('.panelWrapper').each( function(panelWrapper){
			panels.push(panelWrapper.getElement('.panel'));
		}.bind(this));
		
		// Get expanded column panels
		var panelsExpanded = [];
		column.getChildren('.expanded').each( function(panelWrapper){
			panelsExpanded.push(panelWrapper.getElement('.panel'));
		}.bind(this));				
		
		 // All the panels in the column whose height will be effected.
		var panelsToResize = [];
		
		// The panel with the greatest height. Remainders will be added to this panel
		var tallestPanel; 
		var tallestPanelHeight = 0;
		
		this.panelsTotalHeight = 0; // Height of all the panels in the column	
		this.height = 0; // Height of all the elements in the column
			
		// Set panel resize partners
		panels.each(function(panel){
			instance = instances.get(panel.id);
			if (panel.getParent().hasClass('expanded') && panel.getParent().getNext('.expanded')) {
				instance.partner = panel.getParent().getNext('.expanded').getElement('.panel');
				instance.resize.attach();
				instance.handleEl.setStyles({
					'display': 'block',
					'cursor': Browser.Engine.webkit ? 'row-resize' : 'n-resize'
				}).removeClass('detached');
			} else {
				instance.resize.detach();
				instance.handleEl.setStyles({
					'display': 'none',
					'cursor': null
				}).addClass('detached');
			}
			if (panel.getParent().getNext('.panelWrapper') == null) {
				instance.handleEl.hide();
			}
		}.bind(this));
			
		// Add panels to panelsToResize
		// Get the total height of all the resizable panels
		// Get the total height of all the column's children
		column.getChildren().each(function(panelWrapper){
		
		panelWrapper.getChildren().each(function(el){

			if (el.hasClass('panel')){
				var instance = instances.get(el.id);

				// Are any next siblings Expanded?
				anyNextSiblingsExpanded = function(el){
					var test;
					el.getParent().getAllNext('.panelWrapper').each(function(sibling){
						var siblingInstance = instances.get(sibling.getElement('.panel').id);
						if (siblingInstance.isCollapsed == false){
							test = true;
						}
					}.bind(this));
					return test;
				}.bind(this);

				// If a next sibling is expanding, are any of the nexts siblings of the expanding sibling Expanded?
				anyExpandingNextSiblingsExpanded = function(el){
					var test;
					changing.getParent().getAllNext('.panelWrapper').each(function(sibling){
						var siblingInstance = instances.get(sibling.getElement('.panel').id);
						if (siblingInstance.isCollapsed == false){
							test = true;
						}
					}.bind(this));
					return test;
				}.bind(this);
				
				// Is the panel that is collapsing, expanding, or new located after this panel?
				anyNextContainsChanging = function(el){					
					var allNext = [];
					el.getParent().getAllNext('.panelWrapper').each(function(panelWrapper){
						allNext.push(panelWrapper.getElement('.panel'));							
					}.bind(this));					
					var test = allNext.contains(changing);			
					return test;					
				}.bind(this);
				
				nextExpandedChanging = function(el){
					var test;
					if (el.getParent().getNext('.expanded')){
						if (el.getParent().getNext('.expanded').getElement('.panel') == changing) test = true;
					}
					return test;
				}
				
				// NEW PANEL	
				// Resize panels that are "new" or not collapsed
				if (action == 'new') {
					if (!instance.isCollapsed && el != changing) {
						panelsToResize.push(el);
						this.panelsTotalHeight += el.offsetHeight.toInt();
					}
				}
				
				// COLLAPSING PANELS and CURRENTLY EXPANDED PANELS
				// Resize panels that are not collapsed. 
				// If a panel is collapsing resize any expanded panels below.
				// If there are no expanded panels below it, resize the expanded panels above it.
				else if (action == null || action == 'collapsing' ){
					if (!instance.isCollapsed && (!anyNextContainsChanging(el) || !anyNextSiblingsExpanded(el))){
						panelsToResize.push(el);
						this.panelsTotalHeight += el.offsetHeight.toInt();
					}
				}
				
				// EXPANDING PANEL
				// Resize panels that are not collapsed and are not expanding.
				// Resize any expanded panels below the expanding panel.
				// If there are no expanded panels below the expanding panel, resize the first expanded panel above it.
				else if (action == 'expanding' && !instance.isCollapsed  && el != changing){
					if (!anyNextContainsChanging(el) || (!anyExpandingNextSiblingsExpanded(el) && nextExpandedChanging(el))){
						panelsToResize.push(el);
						this.panelsTotalHeight += el.offsetHeight.toInt();
					}					   					
				}

				if (el.style.height){
					this.height += el.getStyle('height').toInt();
				}
			}
			else {
				this.height += el.offsetHeight.toInt();
			}
		}.bind(this));
		
		}.bind(this));

		// Get the remaining height
		var remainingHeight = column.offsetHeight.toInt() - this.height;
		
		this.height = 0;

		// Get height of all the column's children
		column.getChildren().each(function(el){
			this.height += el.offsetHeight.toInt();
		}.bind(this));
				
		var remainingHeight = column.offsetHeight.toInt() - this.height;

		panelsToResize.each(function(panel){
			var ratio = this.panelsTotalHeight / panel.offsetHeight.toInt();
			var newPanelHeight = panel.getStyle('height').toInt() + (remainingHeight / ratio);
			if (newPanelHeight < 1){
				newPanelHeight = 0;
			}
			panel.setStyle('height', newPanelHeight);
		}.bind(this));	

		// Make sure the remaining height is 0. If not add/subtract the
		// remaining height to the tallest panel. This makes up for browser resizing,
		// off ratios, and users trying to give panels too much height.
			
		// Get height of all the column's children
		this.height = 0;
		column.getChildren().each(function(panelWrapper){
			panelWrapper.getChildren().each(function(el){
				this.height += el.offsetHeight.toInt();
				if (el.hasClass('panel') && el.getStyle('height').toInt() > tallestPanelHeight){
					tallestPanel = el;
					tallestPanelHeight = el.getStyle('height').toInt();
				}
			}.bind(this));
		}.bind(this));

		var remainingHeight = column.offsetHeight.toInt() - this.height;

		if (remainingHeight != 0 && tallestPanelHeight > 0){
			tallestPanel.setStyle('height', tallestPanel.getStyle('height').toInt() + remainingHeight );
			if (tallestPanel.getStyle('height') < 1){
				tallestPanel.setStyle('height', 0 );
			}
		}

		parent.getChildren('.columnHandle').each(function(handle){
			var parent = handle.getParent();
			if (parent.getStyle('height').toInt() < 1) return; // Keeps IE7 and 8 from throwing an error when collapsing a panel within a panel
			var handleHeight = parent.getStyle('height').toInt() - handle.getStyle('border-top').toInt() - handle.getStyle('border-bottom').toInt();
			if (Browser.Engine.trident4 && parent == MUI.Desktop.pageWrapper){
				handleHeight -= 1;
			}
			handle.setStyle('height', handleHeight);
		});
			
		panelsExpanded.each(function(panel){
			MUI.resizeChildren(panel);
		}.bind(this));			
			
	},
	// May rename this resizeIframeEl()
	resizeChildren: function(panel){
		var instances = MUI.Panels.instances;
		var instance = instances.get(panel.id);
		var contentWrapperEl = instance.contentWrapperEl;

		if (instance.iframeEl) {
			if (!Browser.Engine.trident) {
				instance.iframeEl.setStyles({
					'height': contentWrapperEl.getStyle('height'),
					'width': contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt()
				});
			}
			else {
				// The following hack is to get IE8 RC1 IE8 Standards Mode to properly resize an iframe
				// when only the vertical dimension is changed.
				instance.iframeEl.setStyles({
					'height': contentWrapperEl.getStyle('height'),
					'width': contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt() - 1
				});
				instance.iframeEl.setStyles({
					'width': contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt()
				});			
			}			
		}				
		
	},
	// Remaining Width
	rWidth: function(container){
		if (container == null) {
			var container = MUI.Desktop.desktop;
		}
		container.getElements('.rWidth').each(function(column){
			var currentWidth = column.offsetWidth.toInt();
			currentWidth -= column.getStyle('border-left').toInt();
			currentWidth -= column.getStyle('border-right').toInt();
			
			var parent = column.getParent();
			this.width = 0;
			
			// Get the total width of all the parent element's children
			parent.getChildren().each(function(el){
				if (el.hasClass('mocha') != true) {
					this.width += el.offsetWidth.toInt();
				}
			}.bind(this));
			
			// Add the remaining width to the current element
			var remainingWidth = parent.offsetWidth.toInt() - this.width;
			var newWidth = currentWidth + remainingWidth;
			if (newWidth < 1) newWidth = 0;
			column.setStyle('width', newWidth);
			column.getChildren('.panel').each(function(panel){
				panel.setStyle('width', newWidth - panel.getStyle('border-left').toInt() - panel.getStyle('border-right').toInt());
				MUI.resizeChildren(panel);
			}.bind(this));
			
		});
	}

});

function addResizeRight(element, min, max){
	if (!$(element)) return;
	element = $(element);
	
	var instances = MUI.Columns.instances;
	var instance = instances.get(element.id);
	
	var handle = element.getNext('.columnHandle');
	handle.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize');
	if (!min) min = 50;
	if (!max) max = 250;
	if (Browser.Engine.trident) {
		handle.addEvents({
			'mousedown': function(){
				handle.setCapture();
			},
			'mouseup': function(){
				handle.releaseCapture();
			}
		});
	}
	instance.resize = element.makeResizable({
		handle: handle,
		modifiers: {
			x: 'width',
			y: false
		},
		limit: {
			x: [min, max]
		},
		onStart: function(){
			element.getElements('iframe').setStyle('visibility', 'hidden');
			element.getNext('.column').getElements('iframe').setStyle('visibility', 'hidden');
		}.bind(this),
		onDrag: function(){
			if (Browser.Engine.gecko) {
				$$('.panel').each(function(panel){
					if (panel.getElements('.mochaIframe').length == 0) {
						panel.hide(); // Fix for a rendering bug in FF
					}
				});
			}
			MUI.rWidth(element.getParent());
			if (Browser.Engine.gecko) {
				$$('.panel').show(); // Fix for a rendering bug in FF			
			}
			if (Browser.Engine.trident4) {
				element.getChildren().each(function(el){
					var width = $(element).getStyle('width').toInt();
					width -= el.getStyle('border-right').toInt();
					width -= el.getStyle('border-left').toInt();
					width -= el.getStyle('padding-right').toInt();
					width -= el.getStyle('padding-left').toInt();
					el.setStyle('width', width);
				}.bind(this));
			}
		}.bind(this),
		onComplete: function(){
			MUI.rWidth(element.getParent());
			element.getElements('iframe').setStyle('visibility', 'visible');
			element.getNext('.column').getElements('iframe').setStyle('visibility', 'visible');
			instance.fireEvent('onResize');
		}.bind(this)
	});
}

function addResizeLeft(element, min, max){
	if (!$(element)) return;
	element = $(element);

	var instances = MUI.Columns.instances;
	var instance = instances.get(element.id);

	var handle = element.getPrevious('.columnHandle');
	handle.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize');
	var partner = element.getPrevious('.column');
	if (!min) min = 50;
	if (!max) max = 250;
	if (Browser.Engine.trident){	
		handle.addEvents({
			'mousedown': function(){
				handle.setCapture();
			},	
			'mouseup': function(){
				handle.releaseCapture();
			}
		});
	}
	instance.resize = element.makeResizable({
		handle: handle,
		modifiers: {x: 'width' , y: false},
		invert: true,
		limit: { x: [min, max] },
		onStart: function(){
			$(element).getElements('iframe').setStyle('visibility','hidden');
			partner.getElements('iframe').setStyle('visibility','hidden');
		}.bind(this),
		onDrag: function(){
			MUI.rWidth(element.getParent());
		}.bind(this),
		onComplete: function(){
			MUI.rWidth(element.getParent());
			$(element).getElements('iframe').setStyle('visibility','visible');
			partner.getElements('iframe').setStyle('visibility','visible');
			instance.fireEvent('onResize');			
		}.bind(this)
	});
}

function addResizeBottom(element){
	if (!$(element)) return;
	var element = $(element);
	
	var instances = MUI.Panels.instances;
	var instance = instances.get(element.id);
	var handle = instance.handleEl;
	handle.setStyle('cursor', Browser.Engine.webkit ? 'row-resize' : 'n-resize');
	partner = instance.partner;
	min = 0;
	max = function(){
		return element.getStyle('height').toInt() + partner.getStyle('height').toInt();
	}.bind(this);
	
	if (Browser.Engine.trident) {
		handle.addEvents({
			'mousedown': function(){
				handle.setCapture();
			},
			'mouseup': function(){
				handle.releaseCapture();
			}
		});
	}
	instance.resize = element.makeResizable({
		handle: handle,
		modifiers: {x: false, y: 'height'},
		limit: { y: [min, max] },
		invert: false,
		onBeforeStart: function(){
			partner = instance.partner;
			this.originalHeight = element.getStyle('height').toInt();
			this.partnerOriginalHeight = partner.getStyle('height').toInt();
		}.bind(this),
		onStart: function(){
			if (instance.iframeEl) {
				if (!Browser.Engine.trident) {
					instance.iframeEl.setStyle('visibility', 'hidden');
					partner.getElements('iframe').setStyle('visibility','hidden');
				}
				else {
					instance.iframeEl.hide();
					partner.getElements('iframe').hide();
				}
			}
			
		}.bind(this),
		onDrag: function(){
			partnerHeight = partnerOriginalHeight;
			partnerHeight += (this.originalHeight - element.getStyle('height').toInt());
			partner.setStyle('height', partnerHeight);
			MUI.resizeChildren(element, element.getStyle('height').toInt());
			MUI.resizeChildren(partner, partnerHeight);
			element.getChildren('.column').each( function(column){
				MUI.panelHeight(column);
			});
			partner.getChildren('.column').each( function(column){
				MUI.panelHeight(column);
			});						
		}.bind(this),
		onComplete: function(){
			partnerHeight = partnerOriginalHeight;
			partnerHeight += (this.originalHeight - element.getStyle('height').toInt());
			partner.setStyle('height', partnerHeight);
			MUI.resizeChildren(element, element.getStyle('height').toInt());
			MUI.resizeChildren(partner, partnerHeight);
			element.getChildren('.column').each( function(column){
				MUI.panelHeight(column);
			});
			partner.getChildren('.column').each( function(column){
				MUI.panelHeight(column);
			});			
			if (instance.iframeEl) {
				if (!Browser.Engine.trident) {
					instance.iframeEl.setStyle('visibility', 'visible');
					partner.getElements('iframe').setStyle('visibility','visible');
				}
				else {
					instance.iframeEl.show();
					partner.getElements('iframe').show();
					// The following hack is to get IE8 Standards Mode to properly resize an iframe
					// when only the vertical dimension is changed.
					var width = instance.iframeEl.getStyle('width').toInt();
					instance.iframeEl.setStyle('width', width - 1);
					MUI.rWidth();
					instance.iframeEl.setStyle('width', width);									
				}
			}		
			instance.fireEvent('onResize');
		}.bind(this)
	});
}

MUI.extend({
	/*

	Function: closeColumn
		Destroys/removes a column.

	Syntax:
	(start code)
		MUI.closeColumn();
	(end)

	Arguments: 
		columnEl - the ID of the column to be closed

	Returns:
		true - the column was closed
		false - the column was not closed

	*/	
	closeColumn: function(columnEl){
		var instances = MUI.Columns.instances;
		var instance = instances.get(columnEl.id);
		if (columnEl != $(columnEl) || instance.isClosing) return;
			
		instance.isClosing = true;
		
		if (instance.options.sortable){
			instance.container.retrieve('sortables').removeLists(this.columnEl);
		}	
		
		// Destroy all the panels in the column.
		var panels = columnEl.getChildren('.panel');		
		panels.each(function(panel){
			MUI.closePanel($(panel.id));
		}.bind(this));				
		
		if (Browser.Engine.trident) {
			columnEl.dispose();
			if (instance.handleEl != null) {
				instance.handleEl.dispose();
			}			
		}
		else {
			columnEl.destroy();
			if (instance.handleEl != null) {
				instance.handleEl.destroy();
			}			
		}
		if (MUI.Desktop) {
			MUI.Desktop.resizePanels();
		}	
		instances.erase(instance.options.id);
		return true;		
	},
	/*

	Function: closePanel
		Destroys/removes a panel.

	Syntax:
	(start code)
		MUI.closePanel();
	(end)

	Arguments: 
		panelEl - the ID of the panel to be closed

	Returns:
		true - the panel was closed
		false - the panel was not closed

	*/	
	closePanel: function(panelEl){
		var instances = MUI.Panels.instances;
		var instance = instances.get(panelEl.id);
		if (panelEl != $(panelEl) || instance.isClosing) return;
		
		var column = instance.options.column;
		
		instance.isClosing = true;
		
		var columnInstances = MUI.Columns.instances;
		var columnInstance = columnInstances.get(column);
		
		if (columnInstance.options.sortable){
			columnInstance.options.container.retrieve('sortables').removeItems(instance.panelWrapperEl);
		}	

		instance.panelWrapperEl.destroy();

		if (MUI.Desktop) {
			MUI.Desktop.resizePanels();
		}
		
		// Do this when creating and removing panels
		$(column).getChildren('.panelWrapper').each(function(panelWrapper){
			panelWrapper.getElement('.panel').removeClass('bottomPanel');
		});
		$(column).getChildren('.panelWrapper').getLast().getElement('.panel').addClass('bottomPanel');
		
		instances.erase(instance.options.id);
		return true;
		
	}
});
/*

Script: Dock.js
	Implements the dock/taskbar. Enables window minimize.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.	

License:
	MIT-style license.

Requires:
	Core.js, Window.js, Layout.js	

Todo:
	- Make it so the dock requires no initial html markup.

*/

MUI.files[MUI.path.source + 'Layout/Dock.js'] = 'loaded';

MUI.options.extend({
	// Naming options:
	// If you change the IDs of the Mocha Desktop containers in your HTML, you need to change them here as well.
	dockWrapper: 'dockWrapper',
	dock:        'dock'
});

MUI.extend({
	/*

	Function: minimizeAll
		Minimize all windows that are minimizable.

	*/	
	minimizeAll: function() {
		$$('.mocha').each(function(windowEl){
			var instance = windowEl.retrieve('instance');
			if (!instance.isMinimized && instance.options.minimizable == true){
				MUI.Dock.minimizeWindow(windowEl);
			}
		}.bind(this));
	}
});

MUI.Dock = {

	options: {
		useControls:          true,      // Toggles autohide and dock placement controls.
		dockPosition:         'bottom',  // Position the dock starts in, top or bottom.
		// Style options
		trueButtonColor:      [70, 245, 70],     // Color for autohide on
		enabledButtonColor:   [115, 153, 191], 
		disabledButtonColor:  [170, 170, 170]
	},
	
	initialize: function(options){
		// Stops if MUI.Desktop is not implemented
		if (!MUI.Desktop) return;
		
		MUI.dockVisible = true;
		this.dockWrapper   = $(MUI.options.dockWrapper);
		this.dock          = $(MUI.options.dock);
		this.autoHideEvent = null;		
		this.dockAutoHide  = false;  // True when dock autohide is set to on, false if set to off

		if (!this.dockWrapper) return;

		if (!this.options.useControls){
			if($('dockPlacement')){
				$('dockPlacement').setStyle('cursor', 'default');
			}
			if($('dockAutoHide')){
				$('dockAutoHide').setStyle('cursor', 'default');
			}
		}

		this.dockWrapper.setStyles({
			'display':  'block',
			'position': 'absolute',
			'top':      null,
			'bottom':   MUI.Desktop.desktopFooter ? MUI.Desktop.desktopFooter.offsetHeight : 0,
			'left':     0
		});
		
		if (this.options.useControls){
			this.initializeDockControls();
		}

		// Add check mark to menu if link exists in menu
		if ($('dockLinkCheck')){
			this.sidebarCheck = new Element('div', {
				'class': 'check',
				'id': 'dock_check'
			}).inject($('dockLinkCheck'));
		}

		this.dockSortables = new Sortables('#dockSort', {
			opacity: 1,
			constrain: true,
			clone: false,
			revert: false
		});

		MUI.Desktop.setDesktopSize();
		
		if (MUI.myChain){
			MUI.myChain.callChain();
		}
		
	},
	
	initializeDockControls: function(){
		
		// Convert CSS colors to Canvas colors.
		this.setDockColors();
		
		if (this.options.useControls){
			// Insert canvas
			var canvas = new Element('canvas', {
				'id':     'dockCanvas',
				'width':  '15',
				'height': '18'
			}).inject(this.dock);

			// Dynamically initialize canvas using excanvas. This is only required by IE
			if (Browser.Engine.trident && MUI.ieSupport == 'excanvas'){
				G_vmlCanvasManager.initElement(canvas);
			}
		}
		
		var dockPlacement = $('dockPlacement');
		var dockAutoHide = $('dockAutoHide');

		// Position top or bottom selector
		dockPlacement.setProperty('title','Position Dock Top');

		// Attach event
		dockPlacement.addEvent('click', function(){
			this.moveDock();
		}.bind(this));

		// Auto Hide toggle switch
		dockAutoHide.setProperty('title','Turn Auto Hide On');
		
		// Attach event Auto Hide 
		dockAutoHide.addEvent('click', function(event){
			if ( this.dockWrapper.getProperty('dockPosition') == 'top' )
				return false;

			var ctx = $('dockCanvas').getContext('2d');
			this.dockAutoHide = !this.dockAutoHide;	// Toggle
			if (this.dockAutoHide){
				$('dockAutoHide').setProperty('title', 'Turn Auto Hide Off');
				//ctx.clearRect(0, 11, 100, 100);
				MUI.circle(ctx, 5 , 14, 3, this.options.trueButtonColor, 1.0);

				// Define event
				this.autoHideEvent = function(event) {
					if (!this.dockAutoHide)
						return;
					if (!MUI.Desktop.desktopFooter) {
						var dockHotspotHeight = this.dockWrapper.offsetHeight;
						if (dockHotspotHeight < 25) dockHotspotHeight = 25;
					}
					else if (MUI.Desktop.desktopFooter) {
						var dockHotspotHeight = this.dockWrapper.offsetHeight + MUI.Desktop.desktopFooter.offsetHeight;
						if (dockHotspotHeight < 25) dockHotspotHeight = 25;
					}						
					if (!MUI.Desktop.desktopFooter && event.client.y > (document.getCoordinates().height - dockHotspotHeight)){
						if (!MUI.dockVisible){
							this.dockWrapper.show();
							MUI.dockVisible = true;
							MUI.Desktop.setDesktopSize();
						}
					}
					else if (MUI.Desktop.desktopFooter && event.client.y > (document.getCoordinates().height - dockHotspotHeight)){
						if (!MUI.dockVisible){
							this.dockWrapper.show();
							MUI.dockVisible = true;
							MUI.Desktop.setDesktopSize();
						}
					}
					else if (MUI.dockVisible){
						this.dockWrapper.hide();
						MUI.dockVisible = false;
						MUI.Desktop.setDesktopSize();
						
					}
				}.bind(this);

				// Add event
				document.addEvent('mousemove', this.autoHideEvent);

			} else {
				$('dockAutoHide').setProperty('title', 'Turn Auto Hide On');
				//ctx.clearRect(0, 11, 100, 100);
				MUI.circle(ctx, 5 , 14, 3, this.options.enabledButtonColor, 1.0);
				// Remove event
				document.removeEvent('mousemove', this.autoHideEvent);
			}

		}.bind(this));

		this.renderDockControls();
		
		if (this.options.dockPosition == 'top'){
			this.moveDock();
		}

	},
	
	setDockColors: function(){	
		var dockButtonEnabled = MUI.getCSSRule('.dockButtonEnabled');
		if (dockButtonEnabled && dockButtonEnabled.style.backgroundColor){ 	
			this.options.enabledButtonColor = new Color(dockButtonEnabled.style.backgroundColor);
		}
		
		var dockButtonDisabled = MUI.getCSSRule('.dockButtonDisabled');
		if (dockButtonDisabled && dockButtonDisabled.style.backgroundColor){ 	
			this.options.disabledButtonColor = new Color(dockButtonDisabled.style.backgroundColor);
		}
		
		var trueButtonColor = MUI.getCSSRule('.dockButtonTrue');
		if (trueButtonColor && trueButtonColor.style.backgroundColor){ 	
			this.options.trueButtonColor = new Color(trueButtonColor.style.backgroundColor);
		}									
	},
		
	renderDockControls: function(){
		// Draw dock controls
		var ctx = $('dockCanvas').getContext('2d');
		ctx.clearRect(0, 0, 100, 100);
		MUI.circle(ctx, 5 , 4, 3, this.options.enabledButtonColor, 1.0);
		
		if( this.dockWrapper.getProperty('dockPosition') == 'top'){
			MUI.circle(ctx, 5 , 14, 3, this.options.disabledButtonColor, 1.0)
		}
		else if (this.dockAutoHide){
			MUI.circle(ctx, 5 , 14, 3, this.options.trueButtonColor, 1.0);
		}
		else {
			MUI.circle(ctx, 5 , 14, 3, this.options.enabledButtonColor, 1.0);
		}
	},
	
	moveDock: function(){
			var ctx = $('dockCanvas').getContext('2d');
			// Move dock to top position
			if (this.dockWrapper.getStyle('position') != 'relative'){
				this.dockWrapper.setStyles({
					'position': 'relative',
					'bottom':   null
				});
				this.dockWrapper.addClass('top');
				MUI.Desktop.setDesktopSize();
				this.dockWrapper.setProperty('dockPosition','top');
				ctx.clearRect(0, 0, 100, 100);
				MUI.circle(ctx, 5, 4, 3, this.options.enabledButtonColor, 1.0);
				MUI.circle(ctx, 5, 14, 3, this.options.disabledButtonColor, 1.0);
				$('dockPlacement').setProperty('title', 'Position Dock Bottom');
				$('dockAutoHide').setProperty('title', 'Auto Hide Disabled in Top Dock Position');
				this.dockAutoHide = false;
			}
			// Move dock to bottom position
			else {
				this.dockWrapper.setStyles({
					'position':      'absolute',
					'bottom':        MUI.Desktop.desktopFooter ? MUI.Desktop.desktopFooter.offsetHeight : 0
				});
				this.dockWrapper.removeClass('top');
				MUI.Desktop.setDesktopSize();
				this.dockWrapper.setProperty('dockPosition', 'bottom');
				ctx.clearRect(0, 0, 100, 100);
				MUI.circle(ctx, 5, 4, 3, this.options.enabledButtonColor, 1.0);
				MUI.circle(ctx, 5 , 14, 3, this.options.enabledButtonColor, 1.0);
				$('dockPlacement').setProperty('title', 'Position Dock Top');
				$('dockAutoHide').setProperty('title', 'Turn Auto Hide On');
			}
	},
	
	createDockTab: function(windowEl){

		var instance = windowEl.retrieve('instance');

		var dockTab = new Element('div', {
			'id': instance.options.id + '_dockTab',
			'class': 'dockTab',
			'title': titleText
		}).inject($('dockClear'), 'before');
		
		dockTab.addEvent('mousedown', function(e){
			new Event(e).stop();
			this.timeDown = $time();
		});
		
		dockTab.addEvent('mouseup', function(e){
			this.timeUp = $time();
			if ((this.timeUp - this.timeDown) < 275){
				// If the visibility of the windows on the page are toggled off, toggle visibility on.
				if (MUI.Windows.windowsVisible == false) {
					MUI.toggleWindowVisibility();
					if (instance.isMinimized == true) {
						MUI.Dock.restoreMinimized.delay(25, MUI.Dock, windowEl);
					}
					else {
						MUI.focusWindow(windowEl);
					}
					return;
				}
				// If window is minimized, restore window.
				if (instance.isMinimized == true) {
					MUI.Dock.restoreMinimized.delay(25, MUI.Dock, windowEl);
				}
				else{
					// If window is not minimized and is focused, minimize window.
					if (instance.windowEl.hasClass('isFocused') && instance.options.minimizable == true){
						MUI.Dock.minimizeWindow(windowEl)
					}
					// If window is not minimized and is not focused, focus window.	
					else{
						MUI.focusWindow(windowEl);
					}
					// if the window is not minimized and is outside the viewport, center it in the viewport.
					var coordinates = document.getCoordinates();
					if (windowEl.getStyle('left').toInt() > coordinates.width || windowEl.getStyle('top').toInt() > coordinates.height){
						MUI.centerWindow(windowEl);	
					}
				}
			}
		});

		this.dockSortables.addItems(dockTab);

		var titleText = instance.titleEl.innerHTML;

		var dockTabText = new Element('div', {
			'id': instance.options.id + '_dockTabText',
			'class': 'dockText'
		}).set('html', titleText.substring(0,19) + (titleText.length > 19 ? '...' : '')).inject($(dockTab));

		// If I implement this again, will need to also adjust the titleText truncate and the tab's
		// left padding.
		if (instance.options.icon != false){
			// dockTabText.setStyle('background', 'url(' + instance.options.icon + ') 4px 4px no-repeat');
		}
		
		// Need to resize everything in case the dock wraps when a new tab is added
		MUI.Desktop.setDesktopSize();

	},
	
	makeActiveTab: function(){

		// getWindowWith HighestZindex is used in case the currently focused window
		// is closed.		
		var windowEl = MUI.getWindowWithHighestZindex();
		var instance = windowEl.retrieve('instance');
		
		$$('.dockTab').removeClass('activeDockTab');
		if (instance.isMinimized != true) {
			
			instance.windowEl.addClass('isFocused');

			var currentButton = $(instance.options.id + '_dockTab');
			if (currentButton != null) {
				currentButton.addClass('activeDockTab');
			}
		}
		else {
			instance.windowEl.removeClass('isFocused');
		}	
	},
		
	minimizeWindow: function(windowEl){
		if (windowEl != $(windowEl)) return;
		
		var instance = windowEl.retrieve('instance');
		instance.isMinimized = true;

		// Hide iframe
		// Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues
		if ( instance.iframeEl ) {
			// Some elements are still visible in IE8 in the iframe when the iframe's visibility is set to hidden.
			if (!Browser.Engine.trident) {
				instance.iframeEl.setStyle('visibility', 'hidden');
			}
			else {
				instance.iframeEl.hide();
			}
		}

		// Hide window and add to dock	
		instance.contentBorderEl.setStyle('visibility', 'hidden');
		if(instance.toolbarWrapperEl){		
			instance.toolbarWrapperEl.hide();
		}
		windowEl.setStyle('visibility', 'hidden');

		 // Fixes a scrollbar issue in Mac FF2
		if (Browser.Platform.mac && Browser.Engine.gecko){
			if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){
				var ffversion = new Number(RegExp.$1);
				if (ffversion < 3) {
					instance.contentWrapperEl.setStyle('overflow', 'hidden');
				}
			}
		}
	
		MUI.Desktop.setDesktopSize();

		// Have to use timeout because window gets focused when you click on the minimize button
		setTimeout(function(){
			windowEl.setStyle('zIndex', 1);
			windowEl.removeClass('isFocused');
			this.makeActiveTab();	
		}.bind(this),100);	

		instance.fireEvent('onMinimize', windowEl);
	},
	
	restoreMinimized: function(windowEl) {

		var instance = windowEl.retrieve('instance');

		if (instance.isMinimized == false) return;

		if (MUI.Windows.windowsVisible == false){
			MUI.toggleWindowVisibility();
		}

		MUI.Desktop.setDesktopSize();

		 // Part of Mac FF2 scrollbar fix
		if (instance.options.scrollbars == true && !instance.iframeEl){ 
			instance.contentWrapperEl.setStyle('overflow', 'auto');
		}

		if (instance.isCollapsed) {
			MUI.collapseToggle(windowEl);
		}

		windowEl.setStyle('visibility', 'visible');
		instance.contentBorderEl.setStyle('visibility', 'visible');
		if(instance.toolbarWrapperEl){
			instance.toolbarWrapperEl.show();
		}

		// Show iframe
		if (instance.iframeEl){
			if (!Browser.Engine.trident){
				instance.iframeEl.setStyle('visibility', 'visible');
			}
			else {
				instance.iframeEl.show();
			}
		}

		instance.isMinimized = false;
		MUI.focusWindow(windowEl);
		instance.fireEvent('onRestore', windowEl);

	}
};
/*

Script: Workspaces.js
	Save and load workspaces. The Workspaces emulate Adobe Illustrator functionality remembering what windows are open and where they are positioned.

Copyright:
	Copyright (c) 2007-2009 Greg Houston, <http://greghoustondesign.com/>.

License:
	MIT-style license.

Requires:
	Core.js, Window.js

To do:
	- Move to Window

*/

MUI.files[MUI.path.source + 'Layout/Workspaces.js'] = 'loaded';

MUI.extend({			   
	/*
	
	Function: saveWorkspace
		Save the current workspace.
	
	Syntax:
	(start code)
		MUI.saveWorkspace();
	(end)
	
	Notes:
		This version saves the ID of each open window to a cookie, and reloads those windows using the functions in mocha-init.js. This requires that each window have a function in mocha-init.js used to open them. Functions must be named the windowID + "Window". So if your window is called mywindow, it needs a function called mywindowWindow in mocha-init.js.
	
	*/
	saveWorkspace: function(){
		this.cookie = new Hash.Cookie('mochaUIworkspaceCookie', {duration: 3600});
		this.cookie.empty();
		MUI.Windows.instances.each(function(instance) {
			instance.saveValues();
			this.cookie.set(instance.options.id, {
				'id': instance.options.id,
				'top': instance.options.y,
				'left': instance.options.x,
				'width': instance.contentWrapperEl.getStyle('width').toInt(),
				'height': instance.contentWrapperEl.getStyle('height').toInt()
			});
		}.bind(this));
		this.cookie.save();

		new MUI.Window({
			loadMethod: 'html',
			type: 'notification',
			addClass: 'notification',
			content: 'Workspace saved.',
			closeAfter: '1400',
			width: 200,
			height: 40,
			y: 53,
			padding:  { top: 10, right: 12, bottom: 10, left: 12 },
			shadowBlur: 5,
			bodyBgColor: [255, 255, 255]
		});
		
	},
	windowUnload: function(){
		if ($$('.mocha').length == 0 && this.myChain){
			this.myChain.callChain();
		}		
	},
	loadWorkspace2: function(workspaceWindows){		
		workspaceWindows.each(function(workspaceWindow){				
			windowFunction = eval('MUI.' + workspaceWindow.id + 'Window');
			if (windowFunction){
				eval('MUI.' + workspaceWindow.id + 'Window({width:'+ workspaceWindow.width +',height:' + workspaceWindow.height + '});');
				var windowEl = $(workspaceWindow.id);
				windowEl.setStyles({
					'top': workspaceWindow.top,
					'left': workspaceWindow.left
				});
				var instance = windowEl.retrieve('instance');
				instance.contentWrapperEl.setStyles({
					'width': workspaceWindow.width,
					'height': workspaceWindow.height
				});
				instance.drawWindow();
			}
		}.bind(this));
		this.loadingWorkspace = false;
	},
	/*

	Function: loadWorkspace
		Load the saved workspace.

	Syntax:
	(start code)
		MUI.loadWorkspace();
	(end)

	*/
	loadWorkspace: function(){
		cookie = new Hash.Cookie('mochaUIworkspaceCookie', {duration: 3600});
		workspaceWindows = cookie.load();

		if(!cookie.getKeys().length){
			new MUI.Window({
				loadMethod: 'html',
				type: 'notification',
				addClass: 'notification',
				content: 'You have no saved workspace.',
				closeAfter: '1400',
				width: 220,
				height: 40,
				y: 25,
				padding:  { top: 10, right: 12, bottom: 10, left: 12 },
				shadowBlur: 5,
				bodyBgColor: [255, 255, 255]
			});
			return;
		}

		if ($$('.mocha').length != 0){
			this.loadingWorkspace = true;
			this.myChain = new Chain();
			this.myChain.chain(
				function(){
					$$('.mocha').each(function(el) {
						this.closeWindow(el);
					}.bind(this));
				}.bind(this),
				function(){
					this.loadWorkspace2(workspaceWindows);
				}.bind(this)
			);
			this.myChain.callChain();
		}
		else {
			this.loadWorkspace2(workspaceWindows);
		}

	}
});

//End: /Scripts/mocha-debug.js
//Begin: /Scripts/fValidator-debug.js

/* ************************************************************************************* *\
 * The MIT License
 * Copyright (c) 2007 Fabio Zendhi Nagao - http://zend.lojcomm.com.br
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this
 * software and associated documentation files (the "Software"), to deal in the Software
 * without restriction, including without limitation the rights to use, copy, modify,
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies
 * or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
\* ************************************************************************************* */

var fValidator = new Class({
	options: {
		msgContainerTag: "div",
		msgClass: "fValidator-msg",

		styleNeutral: {"background-color": "#ffc", "border-color": "#cc0"},
		styleInvalid: {"background-color": "#fcc", "border-color": "#c00"},
		styleValid: {"background-color": "#cfc", "border-color": "#0c0"},

		required: {type: "required", re: /[^.*]/, msg: "This field is required."},
		alpha: {type: "alpha", re: /^[a-z ._-]+$/i, msg: "This field accepts alphabetic characters only."},
		alphanum: {type: "alphanum", re: /^[a-z0-9 ._-]+$/i, msg: "This field accepts alphanumeric characters only."},
		integer: {type: "integer", re: /^[-+]?\d+$/, msg: "Please enter a valid integer."},
		real: {type: "real", re: /^[-+]?\d*\.?\d+$/, msg: "Please enter a valid number."},
		date: {type: "date", re: /^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$/, msg: "Please enter a valid date (mm/dd/yyyy)."},
		email: {type: "email", re: /^[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i, msg: "Please enter a valid email."},
		phone: {type: "phone", re: /^[\d\s ().-]+$/, msg: "Please enter a valid phone."},
		url: {type: "url", re: /^(http|https|ftp)\:\/\/[a-z0-9\-\.]+\.[a-z]{2,3}(:[a-z0-9]*)?\/?([a-z0-9\-\._\?\,\'\/\\\+&amp;%\$#\=~])*$/i, msg: "Please enter a valid url."},
		confirm: {type: "confirm", msg: "Confirm Password does not match original Password."},

		onValid: Class.empty,
		onInvalid: Class.empty
	},

	initialize: function(form, options) {
		this.form = $(form);
		this.setOptions(options);

		this.fields = this.form.getElements("*[class^=fValidate]");
		this.validations = [];

		this.fields.each(function(element) {
			if(!this._isChildType(element)) element.setStyles(this.options.styleNeutral);
			element.cbErr = 0;
			var classes = element.getProperty("class").split(' ');
			classes.each(function(klass) {
				if(klass.match(/^fValidate(\[.+\])$/)) {
					var aFilters = eval(klass.match(/^fValidate(\[.+\])$/)[1]);
					for(var i = 0; i < aFilters.length; i++) {
						if(this.options[aFilters[i]]) this.register(element, this.options[aFilters[i]]);
						if(aFilters[i].charAt(0) == '=') this.register(element, $extend(this.options.confirm, {idField: aFilters[i].substr(1)}));
					}
				}
			}.bind(this));
		}.bind(this));

		this.form.addEvents({
			"submit": this._onSubmit.bind(this),
			"reset": this._onReset.bind(this)
		});
	},

	register: function(field, options) {
		field = $(field);
		this.validations.push([field, options]);
		field.addEvent("blur", function() {
			this._validate(field, options);
		}.bind(this));
	},

	_isChildType: function(el) {
		var elType = el.type.toLowerCase();
		if((elType == "radio") || (elType == "checkbox")) return true;
		return false;
	},

	_validate: function(field, options) {
		switch(options.type) {
			case "confirm":
				if($(options.idField).getValue() == field.getValue()) this._msgRemove(field, options);
				else this._msgInject(field, options);
				break;
			default:
				if(options.re.test(field.getValue())) this._msgRemove(field, options);
				else this._msgInject(field, options);
		}
	},

	_validateChild: function(child, options) {
		var nlButtonGroup = this.form[child.getProperty("name")];
		var cbCheckeds = 0;
		var isValid = true;
 		for(var i = 0; i < nlButtonGroup.length; i++) {
			if(nlButtonGroup[i].checked) {
				cbCheckeds++;
				if(!options.re.test(nlButtonGroup[i].getValue())) {
					isValid = false;
					break;
				}
			}
		}
		if(cbCheckeds == 0 && options.type == "required") isValid = false;
		if(isValid) this._msgRemove(child, options);
		else this._msgInject(child, options);
	},

	_msgInject: function(owner, options) {
		if(!$(owner.getProperty("id") + options.type +"_msg")) {
			var msgContainer = new Element(this.options.msgContainerTag, {"id": owner.getProperty("id") + options.type +"_msg", "class": this.options.msgClass})
				.setHTML(options.msg)
				.setStyle("opacity", 0)
				.injectAfter(owner)
				.effect("opacity", {
					duration: 500,
					transition: Fx.Transitions.linear
				}).start(0, 1);
			owner.cbErr++;
			this._chkStatus(owner, options);
		}
	},

	_msgRemove: function(owner, options, isReset) {
		isReset = isReset || false;
		if($(owner.getProperty("id") + options.type +"_msg")) {
			var el = $(owner.getProperty("id") + options.type +"_msg");
			el.effect("opacity", {
				duration: 500,
				transition: Fx.Transitions.linear,
				onComplete: function() {el.remove()}
			}).start(1, 0);
			if(!isReset) {
				owner.cbErr--;
				this._chkStatus(owner, options);
			}
		}
	},

	_chkStatus: function(field, options) {
		if(field.cbErr == 0) {
			field.effects({duration: 500, transition: Fx.Transitions.linear}).start(this.options.styleValid);
			this.fireEvent("onValid", [field, options], 50);
		} else {
			field.effects({duration: 500, transition: Fx.Transitions.linear}).start(this.options.styleInvalid);
			this.fireEvent("onInvalid", [field, options], 50);
		}
	},

	_onSubmit: function(event) {
		event = new Event(event);
		var isValid = true;

		this.validations.each(function(array) {
			if(this._isChildType(array[0])) this._validateChild(array[0], array[1]);
			else this._validate(array[0], array[1]);
			if(array[0].cbErr > 0) isValid = false;
		}.bind(this));

		if(!isValid) event.stop();
		return isValid;
	},

	_onReset: function() {
		this.validations.each(function(array) {
			if(!this._isChildType(array[0])) array[0].setStyles(this.options.styleNeutral);
			array[0].cbErr = 0;
			this._msgRemove(array[0], array[1], true);
		}.bind(this));
	}
});
fValidator.implement(new Events); // Implements addEvent(type, fn), fireEvent(type, [args], delay) and removeEvent(type, fn)
fValidator.implement(new Options);// Implements setOptions(defaults, options)
//End: /Scripts/fValidator-debug.js
//Begin: /Scripts/mocha-extensions.js

// NEW WINDOW FROM DIV
MochaUI.extend({
    NewWindowFromDiv: function(el, props) {
        //console.log('CALLING: NewWindowFromDiv');
        if (!$('windowUnderlay')) {
            MochaUI.underlayInitialize();
        }
        // Create window
        new MochaUI.Window(props);
        el.injectInside($(el.getProperty('id') + "Window_content"));
        $(el.getProperty('id') + "Window").injectInside(document.forms[0]);
    },

    NewWindowFromDivHTML: function(el) {
        //console.log('CALLING: NewWindowFromDivHTML');
        var title = el.getElement('h3.mochaTitle');
        var properties = {
            collapsible: false,
            minimizable: false,
            contentBgColor: '#E8E8E8',
            useCanvasControls: false,
            headerStartColor: [219, 219, 219],
            headerStopColor: [219, 219, 219],
            footerStartColor: [219, 219, 219],
            footerStopColor: [219, 219, 219],
            cornerRadius: 5,
            headerHeight: 8,
            footerHeight: 5,
            padding: 0,
            scrollbars: false,
            closable: true,
            type: 'window',
            id: el.getProperty('id') + "Window"

        };

        var elInnerHTML = el.innerHTML;

        if (arguments.length > 1) {
            for (var i = 1; i < arguments.length; i++) {
                var regex = new RegExp('\\{' + (i - 1) + '\\}', 'g');
                elInnerHTML = elInnerHTML.replace(regex, arguments[i]);
            }
        }

        properties.content = elInnerHTML;

        if (title) {
            properties.title = title.innerHTML;
        }

        // Create window
        new MochaUI.Window(properties);
        MochaUI.dynamicResize($(el.getProperty('id') + "Window"));
    },

    // NEW MODAL FROM DIV

    NewModalFromDiv: function(el, options) {
        //console.log('CALLING: NewModalFromDiv');
        el.setStyle('position', 'absolute');
        el.setStyle('top', '-1000px');
        el.setStyle('display', 'block');
        var title = el.getElement('h3.mochaTitle');
        var elDimensions = el.getSize();
        var properties = {
            title: '',
            collapsible: false,
            minimizable: false,
            contentBgColor: '#E8E8E8',
            useEffects: false,
            useCanvasControls: false,
            headerStartColor: [219, 219, 219],
            headerStopColor: [219, 219, 219],
            footerStartColor: [219, 219, 219],
            footerStopColor: [219, 219, 219],
            cornerRadius: 5,
            headerHeight: 8,
            footerHeight: 5,
            padding: 0,
            scrollbars: false,
            closable: false,
            type: 'modal',
            id: el.getProperty('id') + "Window",
            height: elDimensions.y,
            width: elDimensions.x,
            content: ''
        };

        if (options) properties = $merge(properties, options);
        // Create window
        new MochaUI.Window(properties);
        el.setStyle('top', '');
        el.injectInside($(el.getProperty('id') + "Window_content"));
        $(el.getProperty('id') + "Window").injectInside(document.forms[0]);
    },

    HideModal: function(el) {
        //console.log('CALLING: HideModal');
        if ($(el + "Window")) {
            $(el + "Window").setStyle('display', 'none');
            /*if (OpenModalCount == 0) {
            $('modalOverlay').setStyle('opacity', 0);
            if (Browser.Engine.trident4) {
            $('modalFix').setStyle('display', 'none');
            }
            }*/

            /* 
            NEW - Chris
            better way to detect if we should hide
            the modalOverlay, although slightly slower
            */
            var items = $$('div.mochaOverlay');
            var modalCount = 0;
            items.each(function(el) {
                var parent = el.getParent('div.mocha');
                // Z-index set to 11000 for modals
                if (parent.getStyle('display') != 'none' && parent.getStyle('z-index') == '11000') {
                    modalCount++;
                }
            });
            if (modalCount == 0) {
                if ($('modalOverlay')) {
                    $('modalOverlay').setStyle('opacity', 0);
                }

                if (Browser.Engine.trident4) {
                    $('modalFix').setStyle('display', 'none');
                }
            }

        }
    },

    ModalExists: function(el) {
        //console.log('CALLING: ModalExists');
        if ($(el + "Window")) {
            return true;
        } else {
            return false;
        }
    },

    ShowModal: function(el) {
        //console.log('CALLING: ShowModal');
        if ($(el + "Window")) {
            $(el + "Window").setStyle('display', 'block');
            if (!$('modalOverlay')) {
                MochaUI.Modal = new MochaUI.Modal({},true);
            }
            $('modalOverlay').setStyle('opacity', 0.4);
            if (Browser.Engine.trident4) {
                $('modalFix').setStyle('display', 'block');
            }
        }
    },

    CloseModal: function(el) {
        //console.log('CALLING: CloseModal');
        var windowEl = $(el + 'Window')
        if (windowEl) {
            // Only hide the modal layer if this is the last window
            var items = $$('div.mochaOverlay');
            var modalCount = 0;
            items.each(function(el) {
                var parent = el.getParent('div.mocha');
                // Z-index set to 11000 for modals
                if (parent.getStyle('display') != 'none' && parent.getStyle('z-index') == '11000') {
                    modalCount++;
                }
            });
            if (modalCount <= 1) {
                if ($('modalOverlay')) {
                    $('modalOverlay').setStyle('opacity', 0);
                }

                if (Browser.Engine.trident4) {
                    if ($('modalFix')) {
                    $('modalFix').setStyle('display', 'none');
                }
                }
            }

            var instances = MochaUI.Windows.instances;
            var currentInstance = instances.get(windowEl.id);
            if (windowEl != $(windowEl) || currentInstance.isClosing) return;
            currentInstance.isClosing = true;
            currentInstance.fireEvent('onClose', windowEl);
            if (currentInstance.check) currentInstance.check.destroy();
            windowEl.removeEvents();
            windowEl.setStyle('visibility', 'hidden');

            //work around for IE issue where all textboxes gets locked up when user open modal in a modal
            if (Browser.Engine.trident) {
                try {
                    var newTextBox = new Element('input', {
                        'id': 'dummyInput',
                        'styles': {
                            'position': 'absolute',
                            'top': parent.window.document.documentElement.scrollTop
                        }
                    });
                    newTextBox.inject($(parent.document).getElement('body')).focus();
                    $(parent.document).getElement('body').focus();
                    newTextBox.dispose();
                }
                catch (e) { };
            }

            // Why set timeout?  Because MS.AJAX has something connected to the iframe that breaks in IE
            setTimeout("$('" + windowEl.id + "').destroy()", 20);
        }
    },

    // NEW MODAL FROM DIV HTML

    NewModalFromDivHTML: function(el) {
        //console.log('CALLING: NewModalFromDivHTML');
        var title = el.getElement('h3.mochaTitle');
        var properties = {
            collapsible: false,
            minimizable: false,
            contentBgColor: '#E8E8E8',
            useCanvasControls: false,
            headerStartColor: [219, 219, 219],
            headerStopColor: [219, 219, 219],
            footerStartColor: [219, 219, 219],
            footerStopColor: [219, 219, 219],
            cornerRadius: 5,
            headerHeight: 8,
            footerHeight: 5,
            padding: 0,
            scrollbars: false,
            closable: true,
            type: 'modal',
            id: el.getProperty('id') + "Window"

        };
        var elInnerHTML = el.innerHTML;
        var width = el.getStyle('width');
        if (!isNaN(parseInt(width, 10))) {
            properties.width = parseInt(width, 10);
        }

        if (arguments.length > 1) {
            var replaceText = arguments[1];
            for (var i = 0; i < replaceText.length; i++) {
                var regex = new RegExp('\\{' + (i) + '\\}', 'g');
                elInnerHTML = elInnerHTML.replace(regex, replaceText[i]);
            }
        }

        properties.content = elInnerHTML;

        if (title) {
            properties.title = title.innerHTML;
        }

        // Create window
        new MochaUI.Window(properties);
        ResizeModal(el.getProperty('id'));
    },

    // RECENTER A MOCHA UI WINDOW

    recenterWindow: function(windowEl) {
        //console.log('CALLING: recenterWindow');

        if (!windowEl) {
            MochaUI.Windows.instances.each(function(instance) {
                if (instance.isFocused == true) {
                    windowEl = instance.windowEl;
                }
            });
        }

        var currentInstance = MochaUI.Windows.instances.get(windowEl.id);
        var options = currentInstance.options;
        var dimensions = options.container.getCoordinates();
        var scrollPos = document.getScroll();
        var windowPosTop = (dimensions.height * .5) - ((options.height + currentInstance.headerFooterShadow) * .5) + scrollPos.y;
        var windowPosLeft = (dimensions.width * .5) - (options.width * .5);

        if (MochaUI.options.useEffects == true) {
            currentInstance.morph.start({
                'top': windowPosTop,
                'left': windowPosLeft
            });
        }
        else {
            windowEl.setStyles({
                'top': windowPosTop,
                'left': windowPosLeft
            });
        }
    }
});

if (typeof(CorbisUI) == 'undefined') {
    CorbisUI = {};
}
CorbisUI.Popup = new Class({

    Implements: [Options],

    //options  
    options: {
        showModalBackground: true,
        centerOverElement: null,
        positionVert: 'top',
        positionHoriz: 'middle',
        offsetVert: 0,
        offsetHoriz: 0,
        closeOnLoseFocus: false,
        onHide: null,
        createFromHTML: false,
        replaceText: [],
        titleText: null,
        //mike:this is for popup on another popup
        backgroundElement: null,
        resizeBeforePosition: false,
        maxHeight: null,
        maxLeft: null,
        maxTop: null
    },

    setCloseOnLoseFocus: function(elementId) {
        if (this.options.closeOnLoseFocus) {
            if (this.options.onHide) {
                $('modalOverlay').addEvent('click', this.options.onHide);
            }
            if (this.options.createFromHTML) {
                $('modalOverlay').addEvent('click', function() { MochaUI.CloseModal(elementId); });
            } else {
                $('modalOverlay').addEvent('click', function() { MochaUI.HideModal(elementId); });
            }
        }
    },

    setPosition: function(elementId) {
        var el = $(elementId + "Window");
        var scrollPos = document.getScroll();

        var backgroundEle = $(this.options.backgroundElement);
        if (backgroundEle) {
            el.setStyle("zIndex", backgroundEle.getStyle("zIndex") + 2);
        }
        
        if(this.options.resizeBeforePosition || this.options.maxHeight) {
            ResizeModal(elementId,  this.options.maxHeight);
        }

        if (this.options.centerOverElement != null) {
            var openerElement = $(this.options.centerOverElement);
            if (openerElement) {
                var openerPos = openerElement.getCoordinates();
                el.setStyle("position", "absolute");
                
                var positionVert = 0;
                switch (this.options.positionVert) {
                    case "top":
                        positionVert = openerPos.top - el.getCoordinates().height + 5;
                        break;
                    case "middle":
                        positionVert = openerPos.top + (openerPos.height / 2) - (el.getCoordinates().height / 2);
                        break;
                    case "bottom":
                        positionVert = openerPos.top;
                        break;
                    default:
                        if (!isNaN(parseInt(this.options.positionVert, 10))) {
                            positionVert = openerPos.top + parseInt(this.options.positionVert, 10);
                        }
                        break;
                }
                if(this.options.maxTop && positionVert > this.options.maxTop) {
                    positionVert = this.options.maxTop;
                }
                positionVert += this.options.offsetVert;
                if(positionVert) {
                    el.setStyle("top", positionVert);
                }

                var positionHoriz = 0;
                switch (this.options.positionHoriz) {
                    case "left":
                        positionHoriz = openerPos.left + openerPos.width - el.getCoordinates().width;
                        break;
                    case "middle":
                        positionHoriz = openerPos.left + (openerPos.width / 2) - (el.getCoordinates().width / 2);
                        break;
                    case "right":
                        positionHoriz = openerPos.left;
                        break;
                    default:
                        if (!isNaN(parseInt(this.options.positionHoriz, 10))) {
                            positionHoriz = openerPos.left + parseInt(this.options.positionHoriz, 10);
                        }
                        break;
                }
                if(this.options.maxLeft && positionHoriz > this.options.maxLeft) {
                    positionHoriz = this.options.maxLeft;
                }
                positionHoriz += this.options.offsetHoriz;
                if(positionHoriz) {
                    el.setStyle("left", positionHoriz);
                }

            }
        } else {
            var styleTop = scrollPos.y + (window.getSize().y / 2) - (el.getCoordinates().height / 2);
            var styleLeft = (window.getSize().x / 2) - (el.getCoordinates().width / 2);
            if (styleTop < 10) { styleTop = 10; }
            el.setStyle("top", styleTop);
            el.setStyle("left", styleLeft);
        }

    },

    initialize: function(elementId, options) {
        //console.log('CALLING: new CorbisUI.Popup:initialize');
        this.setOptions(options);

        if (!$('modalOverlay')) {
            MochaUI.Modal = new MochaUI.Modal({},true);
        }
        if (!$('windowUnderlay')) {
            MochaUI.underlayInitialize();
        }

        this.setCloseOnLoseFocus(elementId);
        
        // If there's a titleText, set the modal's title to it
        
        if (this.options.titleText) {
            var modal = $(elementId);
            var titleElement = modal.getElement('.Title');
            var closeButton = titleElement.getElement('input');
            titleElement.innerHTML = '';
            closeButton.inject(titleElement);
            new Element('span', {
                text: this.options.titleText
            }).inject(titleElement);
        }

        if (!this.options.createFromHTML) {
            if ($(elementId + "Window")) {
                $(elementId + "Window").setStyle('display', 'block');
                if (Browser.Engine.trident4) {
                    $('modalFix').setStyle('display', 'block');
                }
            } else {
                MochaUI.NewModalFromDiv($(elementId), options);
            }
        } else {
            MochaUI.NewModalFromDivHTML($(elementId), this.options.replaceText);
        }

        this.setPosition(elementId);

        $('modalOverlay').setStyle('display', 'block');
        if (!this.options.showModalBackground) {
            $('modalOverlay').setStyle('opacity', .01);
        } else {
            $('modalOverlay').setStyle('opacity', .4);
        }
    }
});    
//End: /Scripts/mocha-extensions.js
//Begin: /Scripts/ModalPopup.js

if (typeof (CorbisUI) == 'undefined') {
    CorbisUI = {};
}

function OpenModal(divId) {
    //console.log('CALLING: OpenModal');
    /// <summary> Mike: be careful with this one. Try to use OpenModal2.
    ///  this OpenModal will be depricated later.
    /// It is not compatible with UpdatePanel, because "createFromHTML= true"
    /// </summary>
    new CorbisUI.Popup(divId, { 
        showModalBackground: true,
        closeOnLoseFocus: false });
}
function OpenModal2(divId, backgroundDivId) {
    //console.log('CALLING: OpenModal2');
    /// <summary> this is to open a popup on another popup </summary>
    /// <param name="divId"> this is the div id of current popup</param>
    /// <param name="backgroundDivId"> this is the background div id </param>
    /// <returns> none </returns>
    if (MochaUI.ModalExists(divId)) {
        MochaUI.ShowModal(divId);
    } else {
        new CorbisUI.Popup(divId, {
            showModalBackground: true,
            closeOnLoseFocus: false,
            createFromHTML: false,
            backgroundElement: backgroundDivId
        });
    }
    
    ResizeModal(divId);
}

function OpenCloseWarning(divId, opener) {
    //console.log('CALLING: OpenCloseWarning');
    new CorbisUI.Popup(divId, { showModalBackground: false, closeOnLoseFocus: true, centerOverElement: opener, positionVert: 'bottom', positionHoriz: 'left'  } );
}

function HideModal(divId) {
    //console.log('CALLING: HideModal');
    MochaUI.HideModal(divId);
}

function CloseModal(divId) {
    //console.log('CALLING: CloseIModal');
    MochaUI.CloseModal(divId);
}

function ResizeModal(divId, maxHeight) {
    //console.log('CALLING: ResizeModal');
    if ($(divId + "Window")) {
        MochaUI.dynamicResize($(divId + "Window"), maxHeight);
    }
}
function ResizeIModalXY(divId, w, h) {
    //console.log('CALLING: ResizeIModalXY');
    if ($(divId + 'Window')) {
        $(divId + 'Window').setStyle('width', w + 'px');
        if ($(divId + 'Window_iframe') != null) {
            $(divId + 'Window_iframe').setStyle('width', w + 'px');
            $(divId + 'Window_iframe').setStyle('height', h + 'px');
        }
        $(divId + 'Window_contentWrapper').setStyle('width', w + 'px');
        $(divId + 'Window').setStyle('height', (h + 23) + 'px');
        $(divId + 'Window_contentWrapper').setStyle('height', h + 'px');
        ResizeModal(divId);
    }
}

function ResizeIModal(divId, height) {
    //console.log('CALLING: ResizeIModal');
    if ($(divId + 'Window')) {
        $(divId + 'Window').setStyle('height', (height + 23) + 'px');
        $(divId + 'Window_iframe').setStyle('height', height + 'px');
        $(divId + 'Window_contentWrapper').setStyle('height', height + 'px');
        var currentInstance = MochaUI.Windows.instances.get($(divId + 'Window').id);
        var contentWrapperEl = currentInstance.contentWrapperEl;
        var contentEl = currentInstance.contentEl.childNodes[0];
        contentWrapperEl.setStyle('height', contentEl.offsetHeight);
        currentInstance.drawWindow($(divId + 'Window'));
    }
}

function OpenIModal(source, modalWidth, modalHeight) {
    //console.log('CALLING: OpenIModal');
    OpenNewIModal(source, modalWidth, modalHeight, 'pricing');
}

function OpenNewIModal(source, modalWidth, modalHeight, windowID) {
    //console.log('CALLING: OpenNewIModal');
    windowID = windowID + 'Window';
    // If the windowID object is there, don't open again.
    if ($(windowID) != null) {
        ////console.log('window exists');
        return;
    }
    if (!$('modalOverlay')) {
        MochaUI.Modal = new MochaUI.Modal({},true);
    }
    /* DELAY TIME IS FOR BUG 19890 / 20058
    IE 6 needs a delay for the express checkout to come up ok */
    var delayTime = (Browser.Engine.trident4) ? 50 : 0;

    (function() {
        new MochaUI.Window({
            id: windowID,
            title: '',
            loadMethod: 'iframe',
            contentBgColor: '#dbdbdb',
            useCanvasControls: false,
            headerStartColor: [219, 219, 219],
            headerStopColor: [219, 219, 219],
            footerStartColor: [219, 219, 219],
            footerStopColor: [219, 219, 219],
            bodyBgColor: [219, 219, 219],
            cornerRadius: 5,
            headerHeight: 8,
            footerHeight: 5,
            padding: 0,
            collapsible: false,
            minimizable: false,
            scrollbars: false,
            closable: false,
            contentURL: source,
            type: 'modal',
            width: modalWidth,
            height: modalHeight,
            onContentLoaded: function(id, source) {
                var instance = MochaUI.Windows.instances.get(id);
                //MochaUI.focusWindow($(id), true);
                ////console.log('on CONTENT LOADED');
                //alert('on CONTENT LOADED');
                ////console.log(instance.options.contentURL);
                //alert(instance.options.contentURL);
                if (!Browser.Engine.trident) {
                    // set automagically the focus event
                    if (!instance.iframeEl.hasEvent('focusMe')) {
                        // add custom event to be fired when opened
                        instance.iframeEl.addEvent('focusMe', iFrame_windowFocus.bind(instance));
                        // hijack attempts to click away from iframe
                        // if user clicks off iframe, this will fire and refocus on first element again
                        //if(!Browser.Engine.trident)instance.iframeEl.addEvent('blur', iFrame_windowFocus.bind(instance));
                    }
                    // fire focus event on non-https pages.
                    //
                    // NOTE: for https pages you will need to
                    // put a focus event on page load
                    // (see bottom of ExpressCheckout.js)
                    if (!Browser.isHttps(instance.options.contentURL)) instance.iframeEl.fireEvent('focusMe');
                }
            } .pass(windowID, source).bind(window)/*,
        onBeforeBuild: function(id, source) {
            //console.log('on BEFORE BUILD');
        } .pass(windowID, source).bind(this),
        onFocus: function() {
            //console.log('on FOCUS');
        } .pass(windowID, source).bind(this),
        onBlur: function() {
            //console.log('on BLUR');
        } .pass(windowID, source).bind(this),
        onResize: function() {
            //console.log('on RESIZE');
        } .pass(windowID, source).bind(this),
        onMinimize: function() {
            //console.log('on MINIMIZE');
        } .pass(windowID, source).bind(this),
        onMaximize: function() {
            //console.log('on MAXIMIZE');
        } .pass(windowID, source).bind(this),
        onRestore: function() {
            //console.log('on RESTORE');
        } .pass(windowID, source).bind(this),
        onClose: function(id, source) {
            //console.log('on CLOSE');
        } .pass(windowID, source).bind(this),
        onCloseComplete: function() {
            //console.log('on CLOSE COMPLETE');
        } .pass(windowID, source).bind(this)*/
        });
        //alert('humbug');

        $('modalOverlay').setStyle('opacity', 0.4);
        var scrollPos = document.getScroll();
        var styleTop = scrollPos.y + (window.getSize().y / 2) - ($(windowID).getCoordinates().height / 2);
        if (styleTop < 10) { styleTop = 10; }
        $(windowID).setStyle('top', styleTop);
    }).delay(delayTime);
}
//  **********************************************************
//  TODO: We have rolled back the changes on bug #18338. If we
//  decide to use this function for Enlargement centering of the Pricing Module
//  it is here
//  **********************************************************
//function OpenPricingIModal(source, modalWidth, modalHeight) {
//    OpenNewPricingIModal(source, modalWidth, modalHeight, 'pricing');
//}

//function OpenNewPricingIModal(source, modalWidth, modalHeight, windowID) {
//    windowID = windowID + 'Window';
//    // If the windowID object is there, don't open again.
//    if ($(windowID) != null) {
//        //console.log('window exists');
//        return;
//    }
//    if (!$('modalOverlay')) {
//        MochaUI.Modal = new MochaUI.Modal();
//    }
//    new MochaUI.Window({
//        id: windowID,
//        title: '',
//        loadMethod: 'iframe',
//        contentBgColor: '#dbdbdb',
//        useCanvasControls: false,
//        headerStartColor: [219, 219, 219],
//        headerStopColor: [219, 219, 219],
//        footerStartColor: [219, 219, 219],
//        footerStopColor: [219, 219, 219],
//        bodyBgColor: [219, 219, 219],
//        cornerRadius: 5,
//        headerHeight: 8,
//        footerHeight: 5,
//        padding: 0,
//        collapsible: false,
//        minimizable: false,
//        scrollbars: false,
//        closable: false,
//        contentURL: source,
//        type: 'modal',
//        x: 145,
//        y: 30,
//        width: modalWidth,
//        height: modalHeight
//        ,
//        onContentLoaded: function(id, source) {
//            var instance = MochaUI.Windows.instances.get(id);
//            //console.log('on CONTENT LOADED');
//            //console.log(instance.options.contentURL);
//            if (!instance.iframeEl.hasEvent('focusMe')) {
//                instance.iframeEl.addEvent('focusMe', iFrame_windowFocus.bind(instance));
//            }
//            if (!Browser.isHttps(instance.options.contentURL)) instance.iframeEl.fireEvent('focusMe');
//        } .pass(windowID, source).bind(window)
//    });
//    $('modalOverlay').setStyle('opacity', 0.4);
//    $(windowID).setStyles({
//        'position': 'absolute',
//        'left': 145,
//        'top': 30
//    });
//}
// MAGIC FOCUSER FOR IFRAMES
function iFrame_windowFocus(e) {
    //alert('CALLING: iFrame_windowFocus');
    try {
        var item;
        if (window.frames.length > 1) {
            $each(window.frames, function(el, idx) {
                if (el.frameElement.name == this.iframeEl.name) {
                    item = $(el.document);
                }
                ////console.log(el);
            }, this);
        } else {
            item = $(window.frames[0].document);
        }
        //if(item == null) item = $(window.window[this.name].document);
        //    try {
        var form = $(item.forms[0]);
        var Body = $(window.frames[0].document.body);
        //        var tempInput = window.frames[0].CorbisUI.createDummyInput().inject(Body);
        //        tempInput.focus();
        //        form.focus();
        //        tempInput.destroy();
        //    } catch (e) { }
        var formDoc = $try(
            function() {
                //alert('option 1');
                // testing for pricing iframe modals
                return form.getElement('input[id$=cartButton_GlassButton]');
            },
            function() {
                //alert('option 2');
                // other standard iframe modals like credit card
                return form.getElement('div.titleWrapper').getNext('div').getElement('select');
            },
            function() {
                //alert('option 3');
                // other standard iframe modals like credit card
                return form.getElement('div.titleWrapper').getNext('div').getElement('input[type != hidden]');
            },
            function() {
                //alert('option 4');
                // other standard iframe modals like credit card
                return form.getElement('div.titleWrapper').getNext('div').getElement('div.GlassButton input');
            },
            function() {
                // uh oh...nothing could be found
                //alert('crap. Its false');
                return false;
            }
        );
        if (formDoc) {
            var item = formDoc;
            //        .getNext('div')
            //        .getElement('input[type!=hidden]');
            //        alert(item);
            item.focus();
        }
    } catch (e) {}
}


// Pop Up Window for Enlarge Image from Search Page
function EnlargeImagePopUp(URL)
{
	popupHeight = 618;
	popupWidth = 986;

	popupLeft = Math.floor((parent.window.screen.width/2) - (popupWidth/2));
	popupTop = Math.floor((parent.window.screen.height/2) - (popupHeight/2));

	var caller = $pick(URL.match(new RegExp('(caller=)([^?&]*)', 'i')), new Array('', '', ''))[2];
	var corbisId = $pick(URL.match(new RegExp('(id=)([^?&]*)', 'i')), new Array('', '', ''))[2];
    var pager = $('Pager');
    var imageList;
    var totalItems;
    var pageSize;
    var pageNo;
    var searchQuery;
    var imageIndex;
    var lightboxId;

    switch (caller) {
        case 'search':
        case 'imagegroups':
            //set up parameters that's needed
            var pager = $('Pager');

            if (pager) {
                //set up parameters that's needed
                totalItems = $('Pager').getElement('input.totalItems').value;
                imageList = $('ProductResults').getElements('span.ProductBlock').map(function(el, index) {
                    return el.getProperty('corbisID');
                });

                pageSize = $('Pager').getElement('input.pageSize').value;
                pageNo = $('Pager').getElement('input.origPageNumber').value;
            }
            if (caller == "imagegroups") {
                // id in ImageGroup Page refers to Rfcd-Id, which is represented by  imagegroupid in Enlargement Page     
                searchQuery = window.location.href.substring(window.location.href.indexOf('?')).replace("?id=", "?imagegroupid=").replace("&id=", "&imagegroupid=").substring(1);
            }
            else  // caller=="search"
            {
                searchQuery = window.location.href.substring(window.location.href.indexOf('?') + 1);
            }
            break;
        case 'lightbox':
            //setting up from lightbox buddy of search page, image groups or media search
            if (window.location.href.test('searchresults.aspx', 'i') ||
                window.location.href.test('imagegroups.aspx', 'i') ||
                window.location.href.test('mediasetsearch.aspx', 'i')) {
                var lightboxContainer = $('LBXContainer');

                //Getting total count from attribute rather than length because we can't gaurantee the lightbox is completely loaded.
                totalItems = lightboxContainer.getProperty('imageCount');

                var currentIndex = lightboxContainer.getElements('div.lightboxBlock').map(function(el, index) {
                    return el.getProperty('corbisid');
                }).indexOf(corbisId);

                //lightbox buddy images are reverse ordered.
                imageIndex = totalItems - currentIndex;

                //Will default page size to 50 and since we do not know if page completely loaded, set image list to null to load servers-side.
                lightboxId = $('SearchBuddy').getElement('select.lightboxList').value;
            }
            //setting up lightbox page
            else if (window.location.href.test('MyLightboxes.aspx', 'i') || window.location.href.test('emailLightboxview.aspx', 'i')) {
                totalItems = $('Pager').getElement('input.totalItems').value;
                imageList = $('LightboxProducts').getElements('span.ProductBlock').map(function(el, index) {
                    return el.getProperty('corbisID');
                });

                pageSize = $('Pager').getElement('input.pageSize').value;
                pageNo = $('Pager').getElement('input.origPageNumber').value;

                if (window.location.href.test('emailLightboxview.aspx', 'i')) {
                    lightboxId = $(CorbisUI.GlobalVars.Lightbox.lightboxId).value;
                }
                else {
                    lightboxId = $('Tree').getElement('div.Active').id;
                }
            }

            break;
        case 'mediaset':
            var mediaSetId = $pick(URL.match(new RegExp('(mediasetid=)([^?&]*)', 'i')), new Array('', '', ''))[2];
            var mediaSet = $('relatedImageGroups').getElement('ul[mediasetid=' + mediaSetId + ']');
            
            //Assert that the image id is not blank, to avoid blank media set items for unauthenticated users (due to spacer.gif)
            var mediaSetItems = mediaSet.getElements('img[id!=]'); 
            
            totalItems = mediaSetItems.length;
            imageList = mediaSetItems.map(function(el, index) {
                return el.getProperty('title');
            });

            pageSize = totalItems;
            pageNo = 1;

            break;
        case 'quickpic':
            lightboxItems = $('quickPicsContainer').getElements('div.quickPicBlock');
            totalItems = lightboxItems.length;
            imageList = lightboxItems.map(function(el, index) {
                return el.getProperty('corbisid');
            });

            pageSize = totalItems;
            pageNo = 1;

            break;
        default:
            break;
    }
    
    //window.open should have unique id for each window.
    var windowId = (new Date()).getTime().toString();
    var form = $('enlargementPostForm');
    if (!form) {
        form = new Element('form');
        form.setProperty('id', 'enlargementPostForm');
        form.setProperty('name', 'enlargementPostForm');
        form.setProperty('method', 'post');
        form.inject($(window.document.body));
       
    }

    form.setProperty('target', windowId);
    form.setProperty('action', URL);

    GetHiddenControl('totalItems', form).value = totalItems;
    GetHiddenControl('imageList', form).value = imageList;
    GetHiddenControl('pageSize', form).value = pageSize;
    GetHiddenControl('pageNo', form).value = pageNo;
    GetHiddenControl('imageIndex', form).value = imageIndex;
    GetHiddenControl('lightboxId', form).value = lightboxId;
    GetHiddenControl('searchQuery', form).value = searchQuery;

    //Open form just before we submit
    var winOptions = 'titlebar=0, toolbar=0, scrollbars=1, location=0, status=0, menubar=0 , resizable=1, height={winHeight}, width={winWidth}, left={winLeft}, top={winTop}';
    var winReplace = { winHeight: popupHeight, winWidth: popupWidth, winLeft: popupLeft, winTop: popupTop };
    winOptions = winOptions.substitute(winReplace);

    win = window.open(URL, windowId, winOptions);

    // IE6 gives access denied when submitting form.
    if (Browser.Engine.trident4) {
        var enlargeWin = setInterval(function() {
            try {
                if (win.document) {
                    // submit when document is ready
                    form.submit();
                    clearInterval(enlargeWin);
                }
            }
            catch (e) {
                // No need to log this exception
            }
        }, 250)
    }
    else {
        try {
            form.submit();
        } catch (e) {
        //No need to log this exception
        }
    }
}

function GetHiddenControl(controlId, parent) {
    var controlToGet = parent.getElement('#' + controlId);
    if (!controlToGet) {
        controlToGet = new Element('input', {
            'type': 'hidden',
            'id': controlId,
            'name': controlId
        });
        controlToGet.inject(parent);
    }

    return controlToGet;
}

function OpenHtmlModal(windowId, html, options)
{
	windowId += 'Window';
	
	var properties = {
		title: '',
		collapsible: false,
		minimizable: false,
		contentBgColor: '#E8E8E8',
		useEffects: false,
		useCanvasControls: false,
		headerStartColor: [219, 219, 219],
		headerStopColor: [219, 219, 219],
		footerStartColor: [219, 219, 219],
		footerStopColor: [219, 219, 219],
		cornerRadius: 5,
		headerHeight: 8,
		footerHeight: 5,
		padding: 0,
		scrollbars: false,
		closable: false,
		type: 'modal',
		id: windowId,
		showModalBackground: false,
		closeOnLoseFocus: true, 
		loadMethod: 'html',
		content: html
	};	
	
	if (options) properties =  $merge(properties, options);

	new MochaUI.Window(properties);
	
	var scrollPos = document.getScroll();
	var styleTop = scrollPos.y + (window.getSize().y/2) - ($(windowId).getCoordinates().height/2);
	if (styleTop < 10) { styleTop = 10; }
	$(windowId).setStyle('top', styleTop);
}

var EnlargementManager = new Class(
{
    hash: null,

    initialize: function() {
        this.hash = new Hash({});
    },

    addWindow: function(childWin) {
        this.hash.set(childWin.location.href, childWin);
    },

    removeWindow: function(childWin) {
        if (this.hash.has(childWin.location.href)) this.hash.erase(childWin.location.href);
    },

    minimizeAll: function() {
        // IE
        if (Browser.Engine.trident) {
            this.hash.each(function(value, key) {
                if (value && !value.closed) {
                    value.IsJsMinimized = 'Y';
                    value.resizeTo(value.MinimumWidth, value.MinimumHeight);
                    value.moveTo(screen.width, screen.height);
                }
            });
        }
        else {
            // NON IE
            this.hash.each(function(value, key) {
                if (value && !value.closed) {
                    value.IsJsMinimized = 'Y';
                    value.resizeTo(value.MinimumWidth, value.MinimumHeight);
                    value.moveTo(screen.width, screen.height);
                }
            });
        }
    },

    closeAll: function() {
        this.hash.each(function(value, key) {
            value.close();
            this.hash.erase(key);
        }, this);
    }

});

CorbisUI.QueueManager.afterDomReady.addItem('windowManagerSetup', function() {
    EnlargementManager = new EnlargementManager();
});

CorbisUI.ContactCorbis = {
    contactCorbisOption: null,

    ShowContactCorbisModal: function(elementToCenterOver) {
        Corbis.Web.UI.CustomerService.CustomerServiceWebService.GetContactCorbisOffice(CorbisUI.ContactCorbis.GetContactCorbisOfficeSucceeded, CorbisUI.ContactCorbis.GetContactCorbisOfficeFailed, elementToCenterOver);
    },

    GetContactCorbisOfficeSucceeded: function(result, context) {
        //add the required stylesheet.
        var windowDocument = $(document);
        if (!windowDocument.getElement('head').getElement('link[id=contactCorbisCss]')) {
            var css = new Element('link', {
                id: 'contactCorbisCss',
                rel: 'stylesheet',
                type: 'text/css',
                href: '../StyleSheets/ContactCorbis.css'
            });

            css.inject(windowDocument.getElement('head'));
        }

        //Fill in the contact info
        var contactInfo = $('contactInfo');
        if (result.UseDefaultOfficeInfo) {
            if (!contactInfo.hasClass('defaultOffice')) contactInfo.addClass('defaultOffice');
            contactInfo.set('html', result.DefaultOfficeInfo);
        }
        else {
            contactInfo.removeClass('defaultOffice');
            var addressTemplate = $('contactAddressTemplate').get('html');
            contactInfo.set('html', String.format(addressTemplate, result.ContactName, result.OfficeAddress, result.OfficePhoneNumber, result.OfficeFaxNumber, result.EmailAddress));
            //attribute values get escaped, {4} becomes %7B4%7D so we set the href here instead.
            contactInfo.getElement('a').set('href', 'mailto:' + result.EmailAddress);
            if (!result.ContactName || result.ContactName == '') {
                contactInfo.getElement('tr').addClass('hdn');
            }
        }

        var options = {
            showModalBackground: false,
            closeOnLoseFocus: true,
            createFromHTML: false,
            centerOverElement: $(context),
            bodyBgColor: [219, 219, 219]
        };
        var linkOptions = null;
        if(context) {
            switch (context.id) {
                case 'enlargementContactLink':
                    //setting position after modal is visible as we need to center it to the parent modal after the modal is resized.
                    break;
                case 'rmPricingContactLink':
                case 'cartFooter':
                case 'accountMultipleError':
                case 'accountSingleError':
                case 'promoCodeError':
                    linkOptions = { positionVert: 'top', positionHoriz: 'left' };
                    break;
                case 'filesizeContactLink':
                    linkOptions = { positionVert: 'top', positionHoriz: -200 };
                    //adding this event because modal overlay is already attached to FileSize modal.
                    $('fileSizeModalWindow').addEvent('click', function() { HideModal('contactCorbisModal'); });
                    break;
                case 'rfPricingContactLink':
                case 'rsPricingContactLink':
                case 'learnMoreContactLink':
                    linkOptions = { positionVert: 'top', positionHoriz: 'right' };
                    break;
                case 'quickPicContactLink':
                    linkOptions = { positionVert: 15, positionHoriz: 'right' };
                    break;
                case 'feedbackContactLink':
                    linkOptions = { positionVert: 15, positionHoriz: -133 };
                    //adding this event because modal overlay is already attached to feedbackPopup modal
                    if (context.id == 'feedbackContactLink') {
                        $('feedbackPopupWindow').addEvent('click', function() { HideModal('contactCorbisModal'); });
                    }
                    break;
                case 'quickPicTermsContactLink':
                    linkOptions = { positionVert: 'top', positionHoriz: 'right' };
                    break;
                case 'getInTouchPaneHeader':
                    linkOptions = { positionVert: 35, positionHoriz: 'middle' };
                    break;
                case 'modalOverlay':
                case 'priceZone':
                    linkOptions = { positionVert: 'middle', positionHoriz: 'middle' };
                    break;
                default:
                    linkOptions = { positionVert: 'middle', positionHoriz: 'middle' };

            }
        }

        options = $merge(linkOptions, options);

        CorbisUI.ContactCorbis.contactCorbisOption = options;

        (function() {
            new CorbisUI.Popup('contactCorbisModal', options);
            ResizeModal('contactCorbisModal');

            //For cases in pricing where the modal can ended up behind the learn more modal.
            var contactModalStyles = { 'z-index': 11100 };

            //image feedback is a dialog modal, so need to adjust the background opacity
            if (context && context.id == 'feedbackContactLink') {
                $('modalOverlay').setStyle('opacity', '0.4');
            }

            //Due to postion of contact link differing due to localization and the size of the parent window we are going to center the contact window for this
            //we also have to do this heere because the height of the contact modal is dynamic
            if (context && context.id == 'enlargementContactLink') {
                contactModalStyles = $merge(contactModalStyles, CorbisUI.ContactCorbis.GetCenterPosition($('viewDimensionsModalWindow')));
            }

            $('contactCorbisModalWindow').setStyles(contactModalStyles);
        }).delay(100);
    },

    GetCenterPosition: function(parentWindow) {
        var parentWindowPosition = parentWindow.getCoordinates();
        var contactModalPosition = $('contactCorbisModal').getCoordinates(); ;

        var horizontalposition = parentWindowPosition.left + ((parentWindowPosition.width - contactModalPosition.width) / 2);
        var verticalPosition = parentWindowPosition.top + ((parentWindowPosition.height - contactModalPosition.height) / 2);

        return { top: verticalPosition, left: horizontalposition };
    },

    GetContactCorbisOfficeFailed: function(result, context) {
        //TODO: determine what to do here.
    }
};

//End: /Scripts/ModalPopup.js
//Begin: /Scripts/InstantService.js


// IF AGENTS ARE AVAILABLE:
function agents_available() {
    var divInstantService = document.getElementById('divInstantService');
    if(divInstantService) {
        divInstantService.style.display = "";
    }
    return true;
}
 
// IF AGENTS ARE NOT AVAILABLE:
function agents_not_available() { 
    // Keep div invisible
    
    return true;
}
//End: /Scripts/InstantService.js
//Begin: /Scripts/rounded.js

// Contributors 
// Ilkka Huotari at http://www.editsite.net
// Mathieu 'p01' HENRI at http://www.p01.org/
// http://seky.nahory.net/2005/04/rounded-corners/
// Steven Wittens at http://www.acko.net/anti-aliased-nifty-corners
// Original Nifty Corners by Alessandro Fulciniti at http://pro.html.it/esempio/nifty/
function NiftyCheck() {
  if(!document.getElementById || !document.createElement) {
    return false;
  }
  var b = navigator.userAgent.toLowerCase();
  if (b.indexOf("msie 5") > 0 && b.indexOf("opera") == -1) {
    return false;
  }
  return true;
}

function Rounded(className, sizex, sizey, sizex_b, sizey_b) {
	var bk;
	if (!NiftyCheck()) return;
	if (typeof(sizex_b) == 'undefined')
		sizex_b = sizex;
	if (typeof(sizey_b) == 'undefined')
		sizey_b = sizey;
	var v = $$('.'+className);
	var l = v.length;
	
	for (var i = 0; i < l; i++) {
		    color = get_current_style(v[i],"background-color","transparent");
		    bk = get_current_style(v[i].parentNode,"background-color","transparent");
		    AddRounded(v[i], bk, color, sizex, sizey, true);
		    AddRounded(v[i], bk, color, sizex_b, sizey_b, false);
	}
}

var MooRC = new Class({
    Implements: [Options],
    options: {
        radius: { x: 4, y: 4 }
    },
    initialize: function(items, options) {

        if (options) this.setOptions(options);
        if (!NiftyCheck()) return;

        items.each(function(el) {
            var isInternal = false;
            var isBottomOnly = false;
            var isTopOnly = false;
            var tmp = el;
            if (el.getProperty('internal') == 'true') isInternal = true;
            if (el.getProperty('isBottomOnly') == 'true') isBottomOnly = true;

            var color1;
            var color2;
            var temp;
            if (!isInternal) {
                //temp = el.getParent(); 
                color1 = color2 = getColor(el);
            }
            else {
                //temp = el;
                if (!isBottomOnly)
                    color1 = getChildColor(el, true, true);
                if (!isTopOnly)
                    color2 = getChildColor(el, false, true);
            }

            var bk = get_current_style(el.parentNode, "background-color", "transparent");

            if (!isBottomOnly)
                AddRounded(el, bk, color1, this.options.radius.x, this.options.radius.y, true);
            if (!isTopOnly)
                AddRounded(el, bk, color2, this.options.radius.x, this.options.radius.y, false);

        }, this);
    }
});

function getColor(element)
//Get div color
//if it is transparent, we will try to get it from the parent
{
    element = $(element);
    var color;
    color = foundColor(element);
    if (color != false && element.getStyle('display') != 'none')
        return color;
    getColor(element.getParent());
            
}

function getChildColor(element, isTop, isFirstTime)
// element: this is the main div we want to apply round corner 
// isTop: value: true/false, flag to get the color for top round corner color or for the bottom
{
    // first to find color from the first child
    // go deep if the item is transparent
    element = $(element);
    var color; 
    if (!isFirstTime)
    {
        color = foundColor(element);
        if (color != false && element.getStyle('display') != 'none')
            return color;
    }
    if (element.hasChild)
    {
        var allSubItems = element.getChildren();
        var subItem;
        
        if (isTop == true)
        {
            for (i = 0; i < (allSubItems.length - 1); i++)
            {
                var myColor = getChildColor(allSubItems[i], isTop, false);
                if (myColor != false)
                    return myColor;
            }
        }
        else 
        {
            for (i = (allSubItems.length - 1); i >= 0; i--)
            {
                var myColor = getChildColor(allSubItems[i], isTop, false);
                if (myColor != false)
                    return myColor;
            }
        }
        
    }
    return false;
}

//var myColor = foundColor(myelement, myColor);
//if ( myColor != false)
//{
//    myColor 
//}

function foundColor(el)
// el: this is the div we need to get the color
{
    var color = el.getStyle('background-color') ;
    if (color != null && color != 'transparent')
    {
        return color;
    }
    return false;
}


Math.sqr = function (x) {
  return x*x;
};

function checkColorCodeLength(str) {
    var tmpStr = str;
    if (tmpStr.length <= 4) {
        tmpStr = (str.contains('#')) ? str.replace('#', '') : str;
        tmpStr = tmpStr.split('');
        tmpStr.each(function(item, index) {
            tmpStr[index] = item.toString() + item.toString();
        });
        tmpStr = '#' + tmpStr.join('');
    }
    return tmpStr;
}

function Blend(a, b, alpha) {
   
  if(b && a && alpha){ //Adding check to make sure this function does not fire when there is no value.
  
      a = checkColorCodeLength(a); //Convert to 6 digit code
      b = checkColorCodeLength(b); //Convert to 6 digit code
      var ca = Array(
        parseInt('0x' + a.substring(1, 3)), 
        parseInt('0x' + a.substring(3, 5)), 
        parseInt('0x' + a.substring(5, 7))
      );
      var cb = Array(
        parseInt('0x' + b.substring(1, 3)), 
        parseInt('0x' + b.substring(3, 5)), 
        parseInt('0x' + b.substring(5, 7))
      );
      
      return '#' + ('0'+Math.round(ca[0] + (cb[0] - ca[0])*alpha).toString(16)).slice(-2).toString(16)
                 + ('0'+Math.round(ca[1] + (cb[1] - ca[1])*alpha).toString(16)).slice(-2).toString(16)
                 + ('0'+Math.round(ca[2] + (cb[2] - ca[2])*alpha).toString(16)).slice(-2).toString(16);

  }
}

function GetFirstDiv(element)
{
    //while (element.children
}

function AddRounded(el, bk, color, sizex, sizey, top) {
  if (!sizex && !sizey)
	return;
  var i, j;
  var d = document.createElement("div");
  d.style.backgroundColor = bk;
  var lastarc = 0;
  for (i = 1; i <= sizey; i++) {
    var coverage, arc2, arc3;
    // Find intersection of arc with bottom of pixel row
    arc = Math.sqrt(1.0 - Math.sqr(1.0 - i / sizey)) * sizex;
    // Calculate how many pixels are bg, fg and blended.
    var n_bg = sizex - Math.ceil(arc);
    var n_fg = Math.floor(lastarc);
    var n_aa = sizex - n_bg - n_fg;
    // Create pixel row wrapper
    var x = document.createElement("div");
    var y = d;
    x.style.margin = "0px " + n_bg + "px";
	x.style.height='1px';
	x.style.overflow='hidden';
    // Make a wrapper per anti-aliased pixel (at least one)
    for (j = 1; j <= n_aa; j++) {
      // Calculate coverage per pixel
      // (approximates circle by a line within the pixel)
      if (j == 1) {
        if (j == n_aa) {
          // Single pixel
          coverage = ((arc + lastarc) * .5) - n_fg;
        }
        else {
          // First in a run
          arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
          coverage = (arc2 - (sizey - i)) * (arc - n_fg - n_aa + 1) * .5;
          // Coverage is incorrect. Why?
          coverage = 0;
        }
      }
      else if (j == n_aa) {
        // Last in a run
        arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
        coverage = 1.0 - (1.0 - (arc2 - (sizey - i))) * (1.0 - (lastarc - n_fg)) * .5;
      }
      else {
        // Middle of a run
        arc3 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j) / sizex)) * sizey;
        arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
        coverage = ((arc2 + arc3) * .5) - (sizey - i);
    }
    if (Blend(bk, color, coverage) != "#aNaNaN") {
        x.style.backgroundColor = Blend(bk, color, coverage);
    }
	  if (top)
	      y.appendChild(x);
      else
	      y.insertBefore(x, y.firstChild);
      y = x;
      var x = document.createElement("div");
		x.style.height='1px';
		x.style.overflow='hidden';
      x.style.margin = "0px 1px";
    }
    x.style.backgroundColor = color;
    if (top)
	    y.appendChild(x);
    else
		y.insertBefore(x, y.firstChild);
    lastarc = arc;
  }
  if (top)
	  el.insertBefore(d, el.firstChild);
  else
	  el.appendChild(d);
}

function getElements(className) {
	var elements = [];
	var el = document.getElementsByTagName('DIV');  
	var regexp=new RegExp("\\b"+className+"\\b");
	for (var i = 0; i < el.length; i++) 
	{
		if (regexp.test(el[i].className)) 
			elements.push(el[i]);
	}
	return elements;
}

function get_current_style(element,property,not_accepted)
{
  var ee,i,val,apr;
  try
  {
    var cs=document.defaultView.getComputedStyle(element,'');
    val=cs.getPropertyValue(property);
  }
  catch(ee)
  {
    if(element.currentStyle)
  	{
	    apr=property.split("-");
	    for(i=1;i<apr.length;i++) apr[i]=apr[i].toUpperCase();
	    apr=apr.join("");
	    val=element.currentStyle.getAttribute(apr);
   }
  }
  if((val.indexOf("rgba") > -1 || val==not_accepted) && element.parentNode)
  {
	 if(element.parentNode != document) 
		 val=get_current_style(element.parentNode,property,not_accepted);
	 else
		 val = '#FFFFFF';
  }
  if (val.indexOf("rgb") > -1 && val.indexOf("rgba") == -1)
	  val = rgb2hex(val);
  if (val.length == 4)
	  val = '#'+val.substring(1,1)+val.substring(1,1)+val.substring(2,1)+val.substring(2,1)+val.substring(3,1)+val.substring(3,1);
  return val;
}

function rgb2hex(value)
{
	var x = 255;
	var hex = '';
	var i;
	var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
	var array=regexp.exec(value);
	for(i=1;i<4;i++) hex += ('0'+parseInt(array[i]).toString(16)).slice(-2);
	return '#'+hex;
}

//End: /Scripts/rounded.js
//Begin: /Scripts/DropShadow.js

/**
* Copyright (c) 2008 Michael Grundkoetter, MIT Style License.
* Depends from Mootools Framework v1.11 (mootools.net) by Valerio Proietti
* 
* Creates drop shadows for rectangle-like elements on the underground. (works at least in FF, Opera, IE7 and Safari)
* You have to use it like this:
* 
* new DropShadow('*.dropShadow', 'dropShadowBackground');
* 
* This will create drop shadows for all elements with css class "dropShadow". You have to call it after the dom tree has been created completely.
* You might to call it like this: (see parameter explanation below)
* 
* window.addEvent('domready', function() {new DropShadow('*.dropShadow', 'dropShadowBackground'); });
* 
* Known issues: - allSideShadow seems to work properly in FF only; IE does not display divs containing text correctly
* 				 - dimensions of shadow throwing elements must be set via css, otherwise the shadow is wrong or missing
* 				 - currently dragged item should be on top of the rest
* 
*/

var DropShadow = new Class({
    /**
    * @param String targetElements is an css style selector. It defines on which elements the shadow will be applied (like *.myClass)
    * @param String shadowStyleClass is the css class name which will be applied on the shadow (see rules in css comments)
    * @param Integer xOffset the shadow is moved that many px from left (optional; default is 10)
    * @param Integer yOffset the shadow is moved that many px from top (optional; default is 10)
    * @param Float shadowOpacity Initial shadow opacity (optional; standard is 0.8; 0 < x <= 1)
    * @param Boolean softShadow sets whether the shadow shall fade out until the opacity reaches 0 (optional; default is true)
    * @param Float cycleFallOff sets the amount of opacity of which the initial will be decreased each cycle (optional; default is 0.5; 0 < x < shadowOpacity)
    * @param Boolean allSideShadow sets whether the shadow shall be thrown in all 4 directions (optional; default is false)
    * @param Integer shadowDistance defines the distance from the object to where the shadow is thrown on. The greater the distance is, the bigger the shadow will be.
    * 				  (optional; default is 3; depends from allSideShadow 0 < x < n)
    * @param String allSideClass is the css class name which will be applide on the shadow borders id allSideShadow is active (depends from allSideShadow)
    */
    initialize: function(targetElements, shadowStyleClass, xOffset, yOffset, shadowOpacity, softShadow, cycleFallOff, allSideShadow, shadowDistance, allSideClass) {
        //set default values if no parameters given
        xOffset = $pick(xOffset, 10);
        yOffset = $pick(yOffset, 10);
        shadowOpacity = $pick(shadowOpacity, .8);
        softShadow = $pick(softShadow, true);
        cycleFallOff = $pick(cycleFallOff, .1);
        allSideShadow = $pick(allSideShadow, false);
        shadowDistance = $pick(shadowDistance, 3);

        //get the elements
        $$(targetElements).each(function(current) {
            var container = current.clone().empty().injectBefore(current).adopt(current).setStyle('position', 'relative');
            current.setStyles({
                position: 'absolute',
                top: 0,
                left: 0,
                margin: 0,
                padding: 0
            });
            //first shadow needs to be a solid rectangle
            var shadow = current.clone().empty().injectBefore(current).addClass(shadowStyleClass).setOpacity(shadowOpacity);
            if (allSideShadow) {
                shadow.setStyles({
                    top: (current.getStyle('top').toInt() + yOffset - shadowDistance) + 'px',
                    left: (current.getStyle('left').toInt() + xOffset - shadowDistance) + 'px',
                    width: (shadow.getStyle('width').toInt() + shadowDistance * 2 + xOffset) + 'px',
                    height: (shadow.getStyle('height').toInt() + shadowDistance * 2 + yOffset) + 'px'
                })
            } else {
                shadow.setStyles({
                    top: (current.getStyle('top').toInt() + yOffset) + 'px',
                    left: (current.getStyle('left').toInt() + xOffset) + 'px'
                })
            }

            //additional shadow layers only need to be 1px in size to not overlap the big shadow
            var counter = 0;
            var tempOpacity = shadowOpacity;
            while (softShadow && (tempOpacity - cycleFallOff).round(2) > 0) {
                tempOpacity = (tempOpacity - cycleFallOff).round(2);

                if (allSideShadow) {
                    //shadow on every side
                    var shadowFrame = shadow.clone().removeClass(shadowStyleClass).addClass(allSideClass).setOpacity(tempOpacity).injectBefore(current).setStyles({
                        height: (shadow.getStyle('height').toInt() + counter * 2) + 'px',
                        width: (shadow.getStyle('width').toInt() + counter * 2) + 'px',
                        top: (shadow.getStyle('top').toInt() - counter - 1) + 'px',
                        left: (shadow.getStyle('left').toInt() - counter - 1) + 'px',
                        'background-color': 'transparent'
                    });
                } else {
                    //shadow only right and bottom
                    //vertical shadow
                    var vShadow = shadow.clone().setOpacity(tempOpacity).injectBefore(current).setStyles({
                        top: (shadow.getStyle('top').toInt() + counter + 1) + 'px',
                        left: (shadow.getStyle('left').toInt() + shadow.getStyle('width').toInt() + counter) + 'px',
                        height: (shadow.getStyle('height').toInt() - 1) + 'px',
                        width: '1px'
                    });
                    //horizontal shadow
                    var hShadow = shadow.clone().setOpacity(tempOpacity).injectBefore(current).setStyles({
                        top: (shadow.getStyle('top').toInt() + shadow.getStyle('height').toInt() + counter) + 'px',
                        left: (shadow.getStyle('left').toInt() + counter + 1) + 'px',
                        width: (shadow.getStyle('width').toInt() - 1) + 'px',
                        height: '1px'
                    });
                    //corner shadow
                    if ((tempOpacity - cycleFallOff).round(2) > 0) {
                        var cShadow = hShadow.clone().setOpacity((tempOpacity - cycleFallOff).round(2)).injectBefore(current).setStyles({
                            left: (hShadow.getStyle('left').toInt() + hShadow.getStyle('width').toInt()) + 'px',
                            width: '1px'
                        });
                    }
                }
                counter++;
            }
        });
    }
});
//End: /Scripts/DropShadow.js
//Begin: /Scripts/Common.js

/***************************
    NAMESPACES
****************************/
if (typeof(CorbisUI) == 'undefined') {
    CorbisUI = {}; 
}

var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1];
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 16 : 0; //extra height in px to add to iframe in FireFox 1.0+ browsers

//Disable asp.net default button when a button has focus on hitting the enter key (ie a Cancel Button)

function DisableDefaultButtonForButtons()
{
    if (typeof(WebForm_FireDefaultButton) != 'undefined' ) 
    {
      var originalFireDefaultButton = WebForm_FireDefaultButton; 
    }

    WebForm_FireDefaultButton = function(event, target) 
    { 
      if (event.keyCode == 13)
      { 
        var src = event.srcElement || event.target; 
        // Don't call original function if focus is on a button 
        if (src && (src.tagName.toLowerCase() == "input") && (src.type.toLowerCase() == "submit" || src.type.toLowerCase() == "button")) 
	    { 
          return true; 
        } 
      } 

      return originalFireDefaultButton(event, target); 
    }
}


/* OMNITURE START ----------------------------------------------------------------------------------------- */

Omniture = {

    event: {
        // Keep this in numerical order, with non-numerical events at the top
        addedToCart:       "scAdd",
        addedToLightbox:   "event12",
        addedToQuickPic:   "event15",
        viewRelatedImages: "event28",
        addedToPicplan:    "event45"
    },

    log: function(event) {
        LogOmnitureEvent(event);
    }

};

/**
 * Log Omniture Variables
 * IE: s.prop1 = "test"; s.eVar2 = "what";
 */
function LogOmniture(key, value) {
    try
    {   
        s=s_gi(s_account);
        s.linkTrackVars=key;
        
        s[key] = value;

        s.tl(this,'o','My Link Name');
    }
    catch(e){}
}

function LogOmnitureEvent(eventName)
{
    try
    {
        s=s_gi(s_account);
        s.linkTrackVars="events";
        s.linkTrackEvents=eventName;
        s.events=eventName;
        s.tl(this,'o','My Link Name');
    }
    catch(e){}
}

/**
 * Legacy Function, left to perserve existing functionality
 * Use LogOmniture(key, value) instead
 */
function LogOmnitureProperty(propertyName, propertyValue)
{
    LogOmniture(propertyName, propertyValue);
}

/**
 * Legacy Function, left to perserve existing functionality
 * Use LogOmniture(key, value) instead
 */
function LogOmnitureVariable(variableName, variableValue)
{
    LogOmniture(variableName, variableValue);
}

/* OMNITURE END ------------------------------------------------------------------------------------------- */

function PrintWindow()
{
  window.print();
}

function NewWindow(url,width,height,resizable)
{
    if(Browser.Engine.trident){
        resizable = (resizable == "True" ) ? "yes" : "no";
    }
    var windowName = "Corbis";
	(window.open(url, windowName, 'width=' + width + ',height=' + height + '' + ',resizable=' + resizable)).focus();
}

function PricingModalPopupExit()
{
    if (parent && parent.MochaUI) {
        parent.MochaUI.CloseModal('pricing');
    } else if (parent && parent.CorbisUI.CTip) {
        parent.CorbisUI.CTip.IFrameModal.hide();
    }
}

function UpdateCartCount(numItems)
{
    var cartCounter = CorbisUI.DomCache.get('cartCount');
    if (cartCounter) {
        cartCounter.setProperty('text', numItems);   
        fixIECheckoutWidgetWidth(); 
    }
}

function Click(buttonID)
{
    button = $get(buttonID);
    if (button)
    {
        button.click();
    }
}

function ToggleChecked(inputID)
{
    input = $get(inputID);
    if (input)
    {
        input.checked = !input.checked;
    }
}

function SetImage(imgID, path)
{
    img = $get(imgID);
    if (img)
    {
        img.src = path;
    }
}

function Hide(id)
{
    obj = $get(id);
    if (obj)
    {
        obj.style.display = 'none';
    }
}

function Show(id)
{
    obj = $get(id);
    if (obj)
    {
        obj.style.display = 'block';
    }
}
function NoPasteKey(e)
{
    var keyCode = e.keyCode ? e.keyCode : e.which;
    if ((e.ctrlKey == true && String.fromCharCode(keyCode).toLowerCase() == 'v') ||
        (e.shiftKey == true && keyCode == 45) /* Shift+Insert */
        )
    {
        return false;
    }
    return true;
}

function IE()
{
    if (/MSIE (\d+\.\d+);/.test(navigator.userAgent))
    {
        var index = navigator.userAgent.indexOf('MSIE');
        var version = parseFloat(navigator.userAgent.substring(index + 5));
        return version;
    }
    return null;
}

function FixPng(img)
{
    var version = IE();
    if (version && version < 7)
    {
        img.parentNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img.src + "', sizingMethod='crop')";
        img.className = 'displayNone';
        return;
    }
    img.className = 'block';
}

function DefineAnchorClick(linkId)
{
    link = $get(linkId);
    if (link && typeof(link.click == 'undefined'))
    {
        link.click = function()
        {
            // attached on load, detach after clicked to avoid IE memory leaks
            DetachEvent(link.id, "click", DefineAnchorClick);
            var result = true;
            if (link.onclick)
            {
                result = link.onclick();
            }
            if (typeof(result) == 'undefined' || result)
            {
                eval(link.href);
            }
        }
    }
}

function AttachEvent(objId, eventName, target)
{
    obj = $get(objId);
    if (!obj || !target)
    {
        return;
    }
    if (obj.addEventListener)
    {
        obj.addEventListener(eventName, target, false);
    }
    else if (obj.attachEvent)
    {
        obj.attachEvent("on" + eventName, target);
    }
}

function DetachEvent(objId, eventName, target)
{
    obj = $get(objId);
    if (!obj || !target)
    {
        return;
    }
	if (obj.removeEventListener)
	{
		obj.removeEventListener(eventName, target, false);
	}
	else if (obj.detachEvent)
	{
		obj.detachEvent("on" + eventName, target);
	}
}

function SortCollection(collectionContainer, attribToSortBy, sortDescending)
{
	var nodeCollection = collectionContainer.childNodes;

	var i = 0;
	var j = 0;
	var nodeArray = new Array();

	//only removing the nodes with the appropriate attribute for sort.
	while (i < nodeCollection.length)
	{
		if (nodeCollection.item(i).innerHTML && nodeCollection.item(i).attributes[attribToSortBy])
		{
			nodeArray[j] = collectionContainer.removeChild(nodeCollection.item(i));
			j++;
			i--;
		}
		
		i++;
	}

	//sort nodes
	nodeArray.sort(function(lhs, rhs)
		{
			if (lhs.attributes[attribToSortBy].value == rhs.attributes[attribToSortBy].value) return 0;
			if (sortDescending ^ (lhs.attributes[attribToSortBy].value.toUpperCase() < rhs.attributes[attribToSortBy].value.toUpperCase())) return -1;
			return 1;
		}
	);

	//put it all back in order.
	for(i=0; i<nodeArray.length; i++)
	{
		collectionContainer.appendChild(nodeArray[i]);
	}
}

function fixIECheckoutWidgetWidth(){
    //We had to remove the fixed width from the Checkout widget.
    //which is no problem in Firefox, Safari, Chrome et al.
    //But IE needs a little fixer upper to make sure the top and
    //bottom of the widget are the same width
    if(Browser.Engine.trident){
        var checkoutWidget = $('CheckoutWidget');
        if (checkoutWidget) {
            var checkout_wgt = checkoutWidget.getElement('div.Checkout');
            var cart_wgt = checkoutWidget.getElement('div.Cart');
            
            if(checkout_wgt){
                if(checkout_wgt.getStyle('width') < cart_wgt.getStyle('width'))
                        checkout_wgt.setStyle('width', cart_wgt.getStyle('width') );
                
                if(checkout_wgt.getStyle('width') > cart_wgt.getStyle('width')) 
                        cart_wgt.setStyle('width', checkout_wgt.getStyle('width') );
            }
         }
    }
}

window.addEvent('domready', function() {
    //We want to call this function before 'domready' or 'load'
    //So the user doesn't see the width mismatch
    fixIECheckoutWidgetWidth();
    //Sys.CultureInfo.CurrentCulture.numberFormat.CurrencySymbol = '';
    //new DropShadow('*.dropShadow', 'dropShadowBackground', 0, 0); 
});
window.addEvent('load',function(){
    //  To have 4 rounded corners: use 'rounded' class.
    //  To have top rounded corners only: use 'rounded4' class and 'internal="true"' attribute.
    //  To have bottom rounded corners only: use 'rounded4' class and 'isBottomOnly="true"' attribute.
    var RC4pxRad = $$('div.rounded4');
    if(RC4pxRad) new MooRC(RC4pxRad,{ radius: {x: 4, y: 4} });
    if($$('.rounded').length > 0) { Rounded('rounded', 4, 4); }
    
});

function pageLoad(sender, args) {
    //this has to be stored here, or a place when the whole page is ready, instead of DomReady
    if (Sys != null && Sys.CultureInfo != null) {
        Sys.CultureInfo.CurrentCulture.numberFormat.CurrencySymbol = '';
    }
    // this is just a temporary solution, we need to figure out how to make multiple pageLoad
    // calls to chain together and then move the following code into cart.aspx page instead 
    // of global area. 
    
//settings1 = {
//      tl: { radius: 10 },
//      tr: { radius: 10 },
//      bl: { radius: 10 },
//      br: { radius: 10 },
//      antiAlias: true,
//      autoPad: true
//    }
//settings2 = {
//      tl: { radius: 10 },
//      tr: { radius: 10 },
//      bl: { radius: 10 },
//      br: { radius: 10 },
//      antiAlias: true,
//      autoPad: true
//    }
//    //var divObj1 = $get('unpricedBox');
//    //var divObj2 = $get('pricedBox');
//    //var cornersObj1 = new curvyCorners(settings, divObj1);
//    //var cornersObj2 = new curvyCorners(settings, divObj2);

//    var cornersObj4 = new curvyCorners(settings1, "checkoutStage");
//    var cornersObj3 = new curvyCorners(settings2, "wrap");
//    
//    cornersObj4.applyCornersToAll();
//    //cornersObj1.applyCornersToAll();
//    //cornersObj2.applyCornersToAll();
//    cornersObj3.applyCornersToAll();
}

function CloseModalPopup(modalPopupName)
{
	var modalPopup = $find(modalPopupName); 
	if (modalPopup)
	{
		modalPopup.hide();
	}
}

function findChildByClass(item, className)
{
    // First check all immediate child items
    var child = item.firstChild;
    while( child != null )
    {
        if( child.className == className )
        {
            return child;
        }
        child = child.nextSibling;
    }
    
    // Not found, recursively check all child items
    child = item.firstChild;
    while( child != null )
    {
        var found = this._findChildByClass( child, className );
        if( found != null )
        {
            return found;
        }
        child = child.nextSibling;
    }
}

function ResizeIframe(frameid){
    var currentfr=parent.document.getElementById(frameid);
    if (currentfr && !window.opera){
        currentfr.style.display="block";
        if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) //ns6 syntax
            currentfr.height = currentfr.contentDocument.body.offsetHeight+FFextraHeight;
        else if (currentfr.Document && currentfr.Document.body.scrollHeight) //ie5+ syntax
            currentfr.height = currentfr.Document.body.scrollHeight;
    }
}


//   
//   Begin Script
//   Originally Build By: v-nicks 10/31/08
//   This code vertically centers two HTML elements within a page.
//    

function verticalMiddleGlobal(innerElement, outerElement){
    
        var elementToChange = outerElement;
        var innerElement = $(innerElement).getSize();
        var outerElement = $(outerElement).getSize();
        var deltaHeight = (innerElement.y - outerElement.y)/2;
       // alert(innerElement) 
        $(elementToChange).setStyle('margin-top', deltaHeight);                            
}
//   End Script
//   Originally Build By: Nick Stark 10/31/08
//   This code vertically centers two HTML elements within a page
//

function SetUniqueRadioButton(nameregex, current) {
//this is helper function to handle radio button in a repeater
    re = new RegExp(nameregex);
    radios = $$('input[type=radio]');
    radios.each(function(item) {
        item = $(item);
        if (re.test(item.name)) {
            item.checked = false;
        }
    });
//    for (i = 0; i < document.elements.length; i++) {
//        elm = document.forms[0].elements[i]
//        if (elm.type == 'radio') {
//            if (re.test(elm.name)) {
//                elm.checked = false;
//            }
//        }
//    }
    current.checked = true;
}

function HtmlDecode(s) 
{ 
      var out = ""; 
      if (s==null) return; 

      var l = s.length; 
      for (var i=0; i<l; i++) 
      { 
            var ch = s.charAt(i); 

            if (ch == '&') 
            { 
                var semicolonIndex = s.indexOf(';', i+1); 

                if (semicolonIndex > 0) 
                { 
                    var entity = s.substring(i + 1, semicolonIndex); 

                    if (entity.length > 1 && entity.charAt(0) == '#') 
                    { 
                        if (entity.charAt(1) == 'x' || entity.charAt(1) == 'X') 
                            ch = String.fromCharCode(eval('0'+entity.substring(1))); 
                        else 
                            ch = String.fromCharCode(eval(entity.substring(1))); 
                    } 
                    else 
                    { 
                        switch (entity) 
                        { 
                            case 'quot': ch = String.fromCharCode(0x0022); break; 
                            case 'amp': ch = String.fromCharCode(0x0026); break; 
                            case 'lt': ch = String.fromCharCode(0x003c); break; 
                            case 'gt': ch = String.fromCharCode(0x003e); break; 
                            case 'nbsp': ch = String.fromCharCode(0x00a0); break; 
                            case 'iexcl': ch = String.fromCharCode(0x00a1); break; 
                            case 'cent': ch = String.fromCharCode(0x00a2); break; 
                            case 'pound': ch = String.fromCharCode(0x00a3); break; 
                            case 'curren': ch = String.fromCharCode(0x00a4); break; 
                            case 'yen': ch = String.fromCharCode(0x00a5); break; 
                            case 'brvbar': ch = String.fromCharCode(0x00a6); break; 
                            case 'sect': ch = String.fromCharCode(0x00a7); break; 
                            case 'uml': ch = String.fromCharCode(0x00a8); break; 
                            case 'copy': ch = String.fromCharCode(0x00a9); break; 
                            case 'ordf': ch = String.fromCharCode(0x00aa); break; 
                            case 'laquo': ch = String.fromCharCode(0x00ab); break; 
                            case 'not': ch = String.fromCharCode(0x00ac); break; 
                            case 'shy': ch = String.fromCharCode(0x00ad); break; 
                            case 'reg': ch = String.fromCharCode(0x00ae); break; 
                            case 'macr': ch = String.fromCharCode(0x00af); break; 
                            case 'deg': ch = String.fromCharCode(0x00b0); break; 
                            case 'plusmn': ch = String.fromCharCode(0x00b1); break; 
                            case 'sup2': ch = String.fromCharCode(0x00b2); break; 
                            case 'sup3': ch = String.fromCharCode(0x00b3); break; 
                            case 'acute': ch = String.fromCharCode(0x00b4); break; 
                            case 'micro': ch = String.fromCharCode(0x00b5); break; 
                            case 'para': ch = String.fromCharCode(0x00b6); break; 
                            case 'middot': ch = String.fromCharCode(0x00b7); break; 
                            case 'cedil': ch = String.fromCharCode(0x00b8); break; 
                            case 'sup1': ch = String.fromCharCode(0x00b9); break; 
                            case 'ordm': ch = String.fromCharCode(0x00ba); break; 
                            case 'raquo': ch = String.fromCharCode(0x00bb); break; 
                            case 'frac14': ch = String.fromCharCode(0x00bc); break; 
                            case 'frac12': ch = String.fromCharCode(0x00bd); break; 
                            case 'frac34': ch = String.fromCharCode(0x00be); break; 
                            case 'iquest': ch = String.fromCharCode(0x00bf); break; 
                            case 'Agrave': ch = String.fromCharCode(0x00c0); break; 
                            case 'Aacute': ch = String.fromCharCode(0x00c1); break; 
                            case 'Acirc': ch = String.fromCharCode(0x00c2); break; 
                            case 'Atilde': ch = String.fromCharCode(0x00c3); break; 
                            case 'Auml': ch = String.fromCharCode(0x00c4); break;
                            case 'Aring': ch = String.fromCharCode(0x00c5); break;
                            case 'AElig': ch = String.fromCharCode(0x00c6); break; 
                            case 'Ccedil': ch = String.fromCharCode(0x00c7); break; 
                            case 'Egrave': ch = String.fromCharCode(0x00c8); break; 
                            case 'Eacute': ch = String.fromCharCode(0x00c9); break; 
                            case 'Ecirc': ch = String.fromCharCode(0x00ca); break; 
                            case 'Euml': ch = String.fromCharCode(0x00cb); break; 
                            case 'Igrave': ch = String.fromCharCode(0x00cc); break; 
                            case 'Iacute': ch = String.fromCharCode(0x00cd); break; 
                            case 'Icirc': ch = String.fromCharCode(0x00ce ); break; 
                            case 'Iuml': ch = String.fromCharCode(0x00cf); break; 
                            case 'ETH': ch = String.fromCharCode(0x00d0); break; 
                            case 'Ntilde': ch = String.fromCharCode(0x00d1); break; 
                            case 'Ograve': ch = String.fromCharCode(0x00d2); break; 
                            case 'Oacute': ch = String.fromCharCode(0x00d3); break; 
                            case 'Ocirc': ch = String.fromCharCode(0x00d4); break; 
                            case 'Otilde': ch = String.fromCharCode(0x00d5); break; 
                            case 'Ouml': ch = String.fromCharCode(0x00d6); break; 
                            case 'times': ch = String.fromCharCode(0x00d7); break; 
                            case 'Oslash': ch = String.fromCharCode(0x00d8); break; 
                            case 'Ugrave': ch = String.fromCharCode(0x00d9); break; 
                            case 'Uacute': ch = String.fromCharCode(0x00da); break; 
                            case 'Ucirc': ch = String.fromCharCode(0x00db); break; 
                            case 'Uuml': ch = String.fromCharCode(0x00dc); break; 
                            case 'Yacute': ch = String.fromCharCode(0x00dd); break; 
                            case 'THORN': ch = String.fromCharCode(0x00de); break; 
                            case 'szlig': ch = String.fromCharCode(0x00df); break; 
                            case 'agrave': ch = String.fromCharCode(0x00e0); break; 
                            case 'aacute': ch = String.fromCharCode(0x00e1); break; 
                            case 'acirc': ch = String.fromCharCode(0x00e2); break; 
                            case 'atilde': ch = String.fromCharCode(0x00e3); break; 
                            case 'auml': ch = String.fromCharCode(0x00e4); break; 
                            case 'aring': ch = String.fromCharCode(0x00e5); break; 
                            case 'aelig': ch = String.fromCharCode(0x00e6); break; 
                            case 'ccedil': ch = String.fromCharCode(0x00e7); break; 
                            case 'egrave': ch = String.fromCharCode(0x00e8); break; 
                            case 'eacute': ch = String.fromCharCode(0x00e9); break; 
                            case 'ecirc': ch = String.fromCharCode(0x00ea); break; 
                            case 'euml': ch = String.fromCharCode(0x00eb); break; 
                            case 'igrave': ch = String.fromCharCode(0x00ec); break; 
                            case 'iacute': ch = String.fromCharCode(0x00ed); break; 
                            case 'icirc': ch = String.fromCharCode(0x00ee); break; 
                            case 'iuml': ch = String.fromCharCode(0x00ef); break; 
                            case 'eth': ch = String.fromCharCode(0x00f0); break; 
                            case 'ntilde': ch = String.fromCharCode(0x00f1); break; 
                            case 'ograve': ch = String.fromCharCode(0x00f2); break; 
                            case 'oacute': ch = String.fromCharCode(0x00f3); break; 
                            case 'ocirc': ch = String.fromCharCode(0x00f4); break; 
                            case 'otilde': ch = String.fromCharCode(0x00f5); break; 
                            case 'ouml': ch = String.fromCharCode(0x00f6); break; 
                            case 'divide': ch = String.fromCharCode(0x00f7); break; 
                            case 'oslash': ch = String.fromCharCode(0x00f8); break; 
                            case 'ugrave': ch = String.fromCharCode(0x00f9); break; 
                            case 'uacute': ch = String.fromCharCode(0x00fa); break; 
                            case 'ucirc': ch = String.fromCharCode(0x00fb); break; 
                            case 'uuml': ch = String.fromCharCode(0x00fc); break; 
                            case 'yacute': ch = String.fromCharCode(0x00fd); break; 
                            case 'thorn': ch = String.fromCharCode(0x00fe); break; 
                            case 'yuml': ch = String.fromCharCode(0x00ff); break; 
                            case 'OElig': ch = String.fromCharCode(0x0152); break; 
                            case 'oelig': ch = String.fromCharCode(0x0153); break; 
                            case 'Scaron': ch = String.fromCharCode(0x0160); break; 
                            case 'scaron': ch = String.fromCharCode(0x0161); break; 
                            case 'Yuml': ch = String.fromCharCode(0x0178); break; 
                            case 'fnof': ch = String.fromCharCode(0x0192); break; 
                            case 'circ': ch = String.fromCharCode(0x02c6); break; 
                            case 'tilde': ch = String.fromCharCode(0x02dc); break; 
                            case 'Alpha': ch = String.fromCharCode(0x0391); break; 
                            case 'Beta': ch = String.fromCharCode(0x0392); break; 
                            case 'Gamma': ch = String.fromCharCode(0x0393); break; 
                            case 'Delta': ch = String.fromCharCode(0x0394); break; 
                            case 'Epsilon': ch = String.fromCharCode(0x0395); break; 
                            case 'Zeta': ch = String.fromCharCode(0x0396); break; 
                            case 'Eta': ch = String.fromCharCode(0x0397); break; 
                            case 'Theta': ch = String.fromCharCode(0x0398); break; 
                            case 'Iota': ch = String.fromCharCode(0x0399); break; 
                            case 'Kappa': ch = String.fromCharCode(0x039a); break; 
                            case 'Lambda': ch = String.fromCharCode(0x039b); break; 
                            case 'Mu': ch = String.fromCharCode(0x039c); break; 
                            case 'Nu': ch = String.fromCharCode(0x039d); break; 
                            case 'Xi': ch = String.fromCharCode(0x039e); break; 
                            case 'Omicron': ch = String.fromCharCode(0x039f); break; 
                            case 'Pi': ch = String.fromCharCode(0x03a0); break; 
                            case ' Rho ': ch = String.fromCharCode(0x03a1); break; 
                            case 'Sigma': ch = String.fromCharCode(0x03a3); break; 
                            case 'Tau': ch = String.fromCharCode(0x03a4); break; 
                            case 'Upsilon': ch = String.fromCharCode(0x03a5); break; 
                            case 'Phi': ch = String.fromCharCode(0x03a6); break; 
                            case 'Chi': ch = String.fromCharCode(0x03a7); break; 
                            case 'Psi': ch = String.fromCharCode(0x03a8); break; 
                            case 'Omega': ch = String.fromCharCode(0x03a9); break; 
                            case 'alpha': ch = String.fromCharCode(0x03b1); break; 
                            case 'beta': ch = String.fromCharCode(0x03b2); break; 
                            case 'gamma': ch = String.fromCharCode(0x03b3); break; 
                            case 'delta': ch = String.fromCharCode(0x03b4); break; 
                            case 'epsilon': ch = String.fromCharCode(0x03b5); break; 
                            case 'zeta': ch = String.fromCharCode(0x03b6); break; 
                            case 'eta': ch = String.fromCharCode(0x03b7); break; 
                            case 'theta': ch = String.fromCharCode(0x03b8); break; 
                            case 'iota': ch = String.fromCharCode(0x03b9); break; 
                            case 'kappa': ch = String.fromCharCode(0x03ba); break; 
                            case 'lambda': ch = String.fromCharCode(0x03bb); break; 
                            case 'mu': ch = String.fromCharCode(0x03bc); break; 
                            case 'nu': ch = String.fromCharCode(0x03bd); break; 
                            case 'xi': ch = String.fromCharCode(0x03be); break; 
                            case 'omicron': ch = String.fromCharCode(0x03bf); break; 
                            case 'pi': ch = String.fromCharCode(0x03c0); break; 
                            case 'rho': ch = String.fromCharCode(0x03c1); break; 
                            case 'sigmaf': ch = String.fromCharCode(0x03c2); break; 
                            case 'sigma': ch = String.fromCharCode(0x03c3); break; 
                            case 'tau': ch = String.fromCharCode(0x03c4); break; 
                            case 'upsilon': ch = String.fromCharCode(0x03c5); break; 
                            case 'phi': ch = String.fromCharCode(0x03c6); break; 
                            case 'chi': ch = String.fromCharCode(0x03c7); break; 
                            case 'psi': ch = String.fromCharCode(0x03c8); break; 
                            case 'omega': ch = String.fromCharCode(0x03c9); break; 
                            case 'thetasym': ch = String.fromCharCode(0x03d1); break; 
                            case 'upsih': ch = String.fromCharCode(0x03d2); break; 
                            case 'piv': ch = String.fromCharCode(0x03d6); break; 
                            case 'ensp': ch = String.fromCharCode(0x2002); break; 
                            case 'emsp': ch = String.fromCharCode(0x2003); break; 
                            case 'thinsp': ch = String.fromCharCode(0x2009); break; 
                            case 'zwnj': ch = String.fromCharCode(0x200c); break; 
                            case 'zwj': ch = String.fromCharCode(0x200d); break; 
                            case 'lrm': ch = String.fromCharCode(0x200e); break; 
                            case 'rlm': ch = String.fromCharCode(0x200f); break; 
                            case 'ndash': ch = String.fromCharCode(0x2013); break; 
                            case 'mdash': ch = String.fromCharCode(0x2014); break; 
                            case 'lsquo': ch = String.fromCharCode(0x2018); break; 
                            case 'rsquo': ch = String.fromCharCode(0x2019); break; 
                            case 'sbquo': ch = String.fromCharCode(0x201a); break; 
                            case 'ldquo': ch = String.fromCharCode(0x201c); break; 
                            case 'rdquo': ch = String.fromCharCode(0x201d); break; 
                            case 'bdquo': ch = String.fromCharCode(0x201e); break; 
                            case 'dagger': ch = String.fromCharCode(0x2020); break; 
                            case 'Dagger': ch = String.fromCharCode(0x2021); break; 
                            case 'bull': ch = String.fromCharCode(0x2022); break; 
                            case 'hellip': ch = String.fromCharCode(0x2026); break; 
                            case 'permil': ch = String.fromCharCode(0x2030); break; 
                            case 'prime': ch = String.fromCharCode(0x2032); break; 
                            case 'Prime': ch = String.fromCharCode(0x2033); break; 
                            case 'lsaquo': ch = String.fromCharCode(0x2039); break; 
                            case 'rsaquo': ch = String.fromCharCode(0x203a); break; 
                            case 'oline': ch = String.fromCharCode(0x203e); break; 
                            case 'frasl': ch = String.fromCharCode(0x2044); break; 
                            case 'euro': ch = String.fromCharCode(0x20ac); break; 
                            case 'image': ch = String.fromCharCode(0x2111); break; 
                            case 'weierp': ch = String.fromCharCode(0x2118); break; 
                            case 'real': ch = String.fromCharCode(0x211c); break; 
                            case 'trade': ch = String.fromCharCode(0x2122); break; 
                            case 'alefsym': ch = String.fromCharCode(0x2135); break; 
                            case 'larr': ch = String.fromCharCode(0x2190); break; 
                            case 'uarr': ch = String.fromCharCode(0x2191); break; 
                            case 'rarr': ch = String.fromCharCode(0x2192); break; 
                            case 'darr': ch = String.fromCharCode(0x2193); break; 
                            case 'harr': ch = String.fromCharCode(0x2194); break; 
                            case 'crarr': ch = String.fromCharCode(0x21b5); break; 
                            case 'lArr': ch = String.fromCharCode(0x21d0); break; 
                            case 'uArr': ch = String.fromCharCode(0x21d1); break; 
                            case 'rArr': ch = String.fromCharCode(0x21d2); break; 
                            case 'dArr': ch = String.fromCharCode(0x21d3); break; 
                            case 'hArr': ch = String.fromCharCode(0x21d4); break; 
                            case 'forall': ch = String.fromCharCode(0x2200); break; 
                            case 'part': ch = String.fromCharCode(0x2202); break; 
                            case 'exist': ch = String.fromCharCode(0x2203); break; 
                            case 'empty': ch = String.fromCharCode(0x2205); break; 
                            case 'nabla': ch = String.fromCharCode(0x2207); break; 
                            case 'isin': ch = String.fromCharCode(0x2208); break; 
                            case 'notin': ch = String.fromCharCode(0x2209); break; 
                            case 'ni': ch = String.fromCharCode(0x220b); break; 
                            case 'prod': ch = String.fromCharCode(0x220f); break; 
                            case 'sum': ch = String.fromCharCode(0x2211); break; 
                            case 'minus': ch = String.fromCharCode(0x2212); break; 
                            case 'lowast': ch = String.fromCharCode(0x2217); break; 
                            case 'radic': ch = String.fromCharCode(0x221a); break; 
                            case 'prop': ch = String.fromCharCode(0x221d); break; 
                            case 'infin': ch = String.fromCharCode(0x221e); break; 
                            case 'ang': ch = String.fromCharCode(0x2220); break; 
                            case 'and': ch = String.fromCharCode(0x2227); break; 
                            case 'or': ch = String.fromCharCode(0x2228); break; 
                            case 'cap': ch = String.fromCharCode(0x2229); break; 
                            case 'cup': ch = String.fromCharCode(0x222a); break; 
                            case 'int': ch = String.fromCharCode(0x222b); break; 
                            case 'there4': ch = String.fromCharCode(0x2234); break; 
                            case 'sim': ch = String.fromCharCode(0x223c); break; 
                            case 'cong': ch = String.fromCharCode(0x2245); break; 
                            case 'asymp': ch = String.fromCharCode(0x2248); break; 
                            case 'ne': ch = String.fromCharCode(0x2260); break; 
                            case 'equiv': ch = String.fromCharCode(0x2261); break; 
                            case 'le': ch = String.fromCharCode(0x2264); break; 
                            case 'ge': ch = String.fromCharCode(0x2265); break; 
                            case 'sub': ch = String.fromCharCode(0x2282); break; 
                            case 'sup': ch = String.fromCharCode(0x2283); break; 
                            case 'nsub': ch = String.fromCharCode(0x2284); break; 
                            case 'sube': ch = String.fromCharCode(0x2286); break; 
                            case 'supe': ch = String.fromCharCode(0x2287); break; 
                            case 'oplus': ch = String.fromCharCode(0x2295); break; 
                            case 'otimes': ch = String.fromCharCode(0x2297); break; 
                            case 'perp': ch = String.fromCharCode(0x22a5); break; 
                            case 'sdot': ch = String.fromCharCode(0x22c5); break; 
                            case 'lceil': ch = String.fromCharCode(0x2308); break; 
                            case 'rceil': ch = String.fromCharCode(0x2309); break; 
                            case 'lfloor': ch = String.fromCharCode(0x230a); break; 
                            case 'rfloor': ch = String.fromCharCode(0x230b); break; 
                            case 'lang': ch = String.fromCharCode(0x2329); break; 
                            case 'rang': ch = String.fromCharCode(0x232a); break; 
                            case 'loz': ch = String.fromCharCode(0x25ca); break; 
                            case 'spades': ch = String.fromCharCode(0x2660); break; 
                            case 'clubs': ch = String.fromCharCode(0x2663); break; 
                            case 'hearts': ch = String.fromCharCode(0x2665); break; 
                            case 'diams': ch = String.fromCharCode(0x2666); break; 
                            default: ch = ''; break; 
                    } 
                } 
                i = semicolonIndex; 
            } 
        } 

    out += ch; 
    } 

    return out;
}

function HtmlDecodeTextArea(s)
{
    return HtmlDecode(s).replace(/<br[//]?>/gi, '\n');
}

function HtmlEncode(str) {
	var div = document.createElement('div');
	var text = document.createTextNode(str);
	
	div.appendChild(text);
	//IE7 doesn't encode spaces, encoding here for consistency
	return div.innerHTML.replace(/ /g,'&nbsp;');
}

function HtmlFieldEncode(str) {
	return str.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}

function HtmlEncodeTextArea(str) {
    return HtmlFieldEncode(str).replace(/[\r\n]+/g, '<br/>');
}

function UrlEncode(str) {
    return encodeURIComponent(str.replace(/\s+/g, " ")).replace(/%20/g, "+");
}

//Pricing presenter needs this function as is
function PriceImage(source, modalWidth, modalHeight) {
    if (source.toString().indexOf('RMPricing') > -1) 
    {
        if(CorbisUI.Auth.GetSignInLevel() < 1)
        {
            //var actionArg = "OpenIModal('" + source + "', " + modalWidth + ", " + modalHeight + ")";
            var actionArg = "PriceImage_MAGIC('" + source + "', " + modalWidth + ", " + modalHeight + ")";
            //CorbisUI.Auth.Check(1, CorbisUI.Auth.ActionTypes.Execute, actionArg);
            CorbisUI.Auth.OpenSSLSignIn(CorbisUI.Auth.ActionTypes.Execute, actionArg);
        }
        else
        {
            if (source.toString().indexOf('ParentPage=Search') > -1
            || source.toString().indexOf('ParentPage=Lightbox') > -1
            || source.toString().indexOf('ParentPage=Cart') > -1 )
            {
                LogOmnitureEvent("event16");
            }
            OpenIModal(source, modalWidth, modalHeight);
        }
        
    } 
    else
     {
        OpenIModal(source, modalWidth, modalHeight);
    }
}

function PriceImage_MAGIC(source, modalWidth, modalHeight){
    var temp = JSON.decode("{\"tempFunc\":function(){OpenIModal('" + source + "', " + modalWidth + ", " + modalHeight + ");}}");
    //var cookieItem = temp.tempFunc
    //CorbisUI.CookieEvents.addCookieEvent_altPath('/Search',temp.tempFunc);
    CorbisUI.CookieEvents.addCookieEvent(temp.tempFunc);
    window.location.reload();
}

// Add to lightbox functionality
function showNewLightboxDiv() {
    $(CorbisUI.GlobalVars.AddToLightbox.createLightboxSection).removeClass('displayNone');
    ResizeModal('addToLightboxModalPopup');
}
function ResetNewOrAddDivs() {
    $(CorbisUI.GlobalVars.AddToLightbox.createLightboxSection).addClass('displayNone');
    if ($(CorbisUI.GlobalVars.AddToLightbox.addToLightboxSection)) $(CorbisUI.GlobalVars.AddToLightbox.addToLightboxSection).removeClass('displayNone');
    ResizeModal('addToLightboxModalPopup');
}

function ShowAddAllItemsToLightboxModal(offeringUid, ele, showError,addAll) {
    $(CorbisUI.GlobalVars.AddToLightbox.addAllItemsToLightboxHiddenName).value = addAll;
    
    ShowAddToLightboxModal(offeringUid, ele, showError);
}
function ReloadPageWithQueryParams(paramstr) {
    if(paramstr != null ){
        if(window.location.pathname.contains('RFPricing'))
        {
             window.location = window.location + '&' + paramstr +'&hidattributeValue=' + hidAttributeValueUID.value;
        }else if(window.location.pathname.contains('Enlargement'))
        {
            refreshEnlargementPage('AddToLightbox');
        }else
        {   
           window.location = window.location; 
        }
       
    }
}
function ShowAddToLightboxModal(offeringUid, ele, showError) {
    if (CorbisUI.Auth.GetSignInLevel() < 1) {
        CorbisUI.CookieEvents.addCookieEvent(function() { DoAddToLightboxModal(this.vars.OID, null, this.vars.SE) }, { OID: offeringUid, SE: showError } );
        CorbisUI.Auth.Check(1);
    } else {
        DoAddToLightboxModal(offeringUid, ele, showError);
    }
}

function DoAddToLightboxModal(offeringUid, ele, showError) {
    if (CorbisUI.Auth.GetSignInLevel() < 1) { return; }
    
    
    if(!CorbisUI.GlobalVars.AddToLightbox || !CorbisUI.GlobalVars.AddToLightbox.commandButtonName) {
        setTimeout(function() { DoAddToLightboxModal(offeringUid, ele, showError); }, 100);
        return;
    }
    
    
    $(CorbisUI.GlobalVars.AddToLightbox.commandButtonName).value = "";
    //no button means no lightbox, so only add lightbox option, so we display it.
    if ($(CorbisUI.GlobalVars.AddToLightbox.createLightboxButtonName) && !showError) {
        $(CorbisUI.GlobalVars.AddToLightbox.createLightboxSection).addClass('displayNone');
        $(CorbisUI.GlobalVars.AddToLightbox.lightboxName).value = '';

    }
    else {
        $(CorbisUI.GlobalVars.AddToLightbox.createLightboxSection).removeClass('displayNone');
    }
    $(CorbisUI.GlobalVars.AddToLightbox.offeringUidHiddenName).value = offeringUid;
    $(CorbisUI.GlobalVars.AddToLightbox.addToNewLightboxSummary).removeClass('displayNone');

    if (showError) {
        showNewLightboxDiv();
    } else {
        $(CorbisUI.GlobalVars.AddToLightbox.addToNewLightboxSummary).addClass('displayNone');
        OpenModal('addToLightboxModalPopup');
        ResizeModal('addToLightboxModalPopup');
        /* For repositioning the Lightbox widget on top of the AddToLightBox icon */
        if(ele != null && typeof(ele) != 'boolean' ){
            var position = $(ele).getCoordinates();
            var dimensions = $('addToLightboxModalPopupWindow').getCoordinates();
	        $('addToLightboxModalPopupWindow').setStyles({
	            'top': position.top - (dimensions.height/2 - 15),
                'left': position.left -(dimensions.width/2 + 80)
	        });
	    }
    }
}

function RefreshOpener() {
    try {
        window.opener.location = window.opener.location;
    }
    catch (e) {
    }
}

function RefreshOpener_Reload() {
    try {
        setTimeout("window.opener.location.reload();", 500);
    }
    catch (e) {
    }
}

function RefreshOpenerAndSelf() {
    RefreshOpener();
    window.location = window.location;
}

function GetDocumentHeight() {
    var docHeight;
    if (document.all) {
        docHeight = document.body.scrollHeight + 12;
    } else {
        docHeight = document.body.offsetHeight + 16;  //+ FFextraHeight;
    }
    return docHeight;
}

//Extends windows.location to included method for returning a query string parameter.
//If parameter does not exist return empty string.
var queryString =
{
    queryStringParam: function(param) {
        return $pick(window.location.search.match(new RegExp('(' + param + '=)([^?&]*)', 'i')), new Array('', '', ''))[2];
    }
}

$extend(window.location, queryString);


//double click solution
var currentTimeStamp = 0;
var curenntClickedTarget = '';
var BLOCKPERIOD = 1; //block one second
function allowClickEvent(newTarget) {
    /// newTarget: should be an unique id, such as the element id, product uid, etc
    /// this can be a generic solution for all click event
    if (newTarget != curenntClickedTarget) {
        currentTimeStamp = new Date();
        curenntClickedTarget = newTarget;
        return true;
    }
    newTimeStamp = new Date();
    
    if ((newTimeStamp - currentTimeStamp) / 1000 > BLOCKPERIOD) {
        currentTimeStamp = newTimeStamp;
        curenntClickedTarget = newTarget;
        //console.log('allowed click at ' + newTarget);
        return true;
    }
    //console.log('blocked click at ' + newTarget);
    return false;
}
//end double click solution
 
 function parseXMLDoc(xmlString) {
        var xmlDoc;
        try //Internet Explorer
        {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(xmlString);
        }
        catch (e) {
                try //Firefox, Mozilla, Opera, etc.
                {
                    parser = new DOMParser();
                    xmlDoc = parser.parseFromString(xmlString, "text/xml");
                }
                catch (e) {}
            }
       return xmlDoc;
    }

CorbisUI.Pager = {
	pageNumberChanged: function(element) {
		if (element.value != '' && !isNaN(element.value) && doPost) {
			textChanged = true;
			
			//reset other pager control, otherwise the first changed control would take precedence.
			$$('div[id=Pager]').each(function(el) {
				var pageNumber = el.getElement('input[type=text]');
				if (pageNumber != element) {
					pageNumber.value = el.getElement('input.origPageNumber').value;
				}
			});
			
			setTimeout('__doPostBack(\'' + element.name + '\',\'\')', 0);
		}; 
		doPost = false;
	},

	keyCheck: function(event, element) {
		doPost = false;
        if (textChanged) return false;

        //return key checks
        if (event.keyCode == 13) {

            //bypass cases where we don't want to post, like if value is empty or hasn't changed
            if (element.value == '' || element.value == $('Pager').getElement('input.origPageNumber').value) {
                return false;
            }

            //setting variable so only return key can trigger onchange, and not lost focus events
            doPost = true;
            
            //skip event post for safari, by skipping WebForm_TextBoxKeyHandler, as it does it by default
             if (Browser.Engine.webkit) 
            {
             if(element.id.toString().toLowerCase().indexOf('searchresultpager_pagenumber') < 0
            ||  event.target.ownerDocument.location.toString().toLowerCase().indexOf('mylightboxes.aspx') < 0
            ){            
            return true;            
            }
            }     
        }
        //allow numbers and control characters only for fireefox
        else if (Browser.Engine.gecko) {
			if ((event.charCode < 48 || event.charCode > 57) && (event.keyCode == 0) && !event.ctrlKey && !event.altKey)
					return false;
        }
		//allow numbers and control characters only for others
        else if ((event.keyCode < 48 || event.keyCode > 57) && event.keyCode > 31 && event.keyCode != 127 && !event.ctrlKey && !event.altKey) return false;

        return (WebForm_TextBoxKeyHandler(event));
    }
};


window.addEvent('load',function(){
    try {
        if(typeof(AjaxControlToolkit) != 'undefined' && typeof(AjaxControlToolkit.CalendarBehavior) != 'undefined' && typeof(AjaxControlToolkit.CalendarBehavior.prototype)!='undefined'
            && AjaxControlToolkit && AjaxControlToolkit.CalendarBehavior && AjaxControlToolkit.CalendarBehavior.prototype)
        {           
            AjaxControlToolkit.CalendarBehavior.prototype._performLayout = function() {
                var elt = this.get_element();if (!elt) return;if (!this.get_isInitialized()) return;if (!this._isOpen) return;var dtf = Sys.CultureInfo.CurrentCulture.dateTimeFormat;var selectedDate = this.get_selectedDate();var visibleDate = this._getEffectiveVisibleDate();var todaysDate = this.get_todaysDate();
                switch (this._mode) {
                    case "days":
                        var firstDayOfWeek = this._getFirstDayOfWeek();var daysToBacktrack = visibleDate.getDay() - firstDayOfWeek;if (daysToBacktrack <= 0)
                        daysToBacktrack += 7;var startDate = new Date(visibleDate.getFullYear(), visibleDate.getMonth(), visibleDate.getDate() - daysToBacktrack, this._hourOffsetForDst);var currentDate = startDate;for (var i = 0;i < 7;i++) {
                        var dayCell = this._daysTableHeaderRow.cells[i].firstChild;if (dayCell.firstChild) {
                        dayCell.removeChild(dayCell.firstChild);}
                        dayCell.appendChild(document.createTextNode(dtf.ShortestDayNames[(i + firstDayOfWeek) % 7]));}
                        for (var week = 0;week < 6;week ++) {
                        var weekRow = this._daysBody.rows[week];for (var dayOfWeek = 0;dayOfWeek < 7;dayOfWeek++) {
                        var dayCell = weekRow.cells[dayOfWeek].firstChild;if (dayCell.firstChild) {
                        dayCell.removeChild(dayCell.firstChild);}
                        dayCell.appendChild(document.createTextNode(currentDate.getDate()));dayCell.title = currentDate.localeFormat("D");dayCell.date = currentDate;$common.removeCssClasses(dayCell.parentNode, [ "ajax__calendar_other", "ajax__calendar_active" ]);Sys.UI.DomElement.addCssClass(dayCell.parentNode, this._getCssClass(dayCell.date, 'd'));currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 1, this._hourOffsetForDst);}
                        }
                        this._prevArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() - 1, 1, this._hourOffsetForDst);this._nextArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() + 1, 1, this._hourOffsetForDst);if (this._title.firstChild) {
                        this._title.removeChild(this._title.firstChild);}
                        this._title.appendChild(document.createTextNode(visibleDate.localeFormat("y")));this._title.date = visibleDate;
                        break;

                    case "months":
                        for (var i = 0;i < this._monthsBody.rows.length;i++) {
                        var row = this._monthsBody.rows[i];for (var j = 0;j < row.cells.length;j++) {
                        var cell = row.cells[j].firstChild;cell.date = new Date(visibleDate.getFullYear(), cell.month, 1, this._hourOffsetForDst);cell.title = cell.date.localeFormat("Y");$common.removeCssClasses(cell.parentNode, [ "ajax__calendar_other", "ajax__calendar_active" ]);Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'M'));}
                        }
                        if (this._title.firstChild) {
                        this._title.removeChild(this._title.firstChild);}
                        this._title.appendChild(document.createTextNode(visibleDate.localeFormat("yyyy")));this._title.date = visibleDate;this._prevArrow.date = new Date(visibleDate.getFullYear() - 1, 0, 1, this._hourOffsetForDst);this._nextArrow.date = new Date(visibleDate.getFullYear() + 1, 0, 1, this._hourOffsetForDst);
                        break;

                    case "years":
                        var minYear = (Math.floor(visibleDate.getFullYear() / 10) * 10);
                        for (var i = 0;i < this._yearsBody.rows.length;i++) {
                            var row = this._yearsBody.rows[i];
                            for (var j = 0;j < row.cells.length;j++) {
                                var cell = row.cells[j].firstChild;
                                cell.date = new Date(minYear + cell.year, 0, 1, this._hourOffsetForDst);
                                if (cell.firstChild) {
                                    cell.removeChild(cell.lastChild);
                                }
                                else {
                                    cell.appendChild(document.createElement("br"));
                                }
                                cell.appendChild(document.createTextNode(minYear + cell.year));
                                $common.removeCssClasses(cell.parentNode, [ "ajax__calendar_other", "ajax__calendar_active" ]);
                                Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'y'));
                            }
                        }
                        if (this._title.firstChild) {
                            this._title.removeChild(this._title.firstChild);
                        }
                        this._title.appendChild(document.createTextNode(minYear.toString() + "-" + (minYear + 9).toString()));
                        this._title.date = visibleDate;
                        this._prevArrow.date = new Date(minYear - 10, 0, 1, this._hourOffsetForDst);
                        this._nextArrow.date = new Date(minYear + 10, 0, 1, this._hourOffsetForDst);
                        break;
                }
                if (this._today.firstChild) {
                    this._today.removeChild(this._today.firstChild);
                }
                this._today.appendChild(document.createTextNode(String.format(localizedWordToday+" : {0}", new Date().localeFormat("d"))));
                this._today.date = todaysDate;
            }
        }
    }
    catch(e){}
});

function InitResizeModal(modalName) {
    window.addEvent('load', function() {
        parent.ResizeIModal(modalName, GetDocumentHeight());
	});
}

function redirectToRegister() {
	if(typeof(registerWindowTitle) == 'undefined') {
		self.focus();
		if (window.location.search.test('ReturnUrl')) {
			window.location = registerPageUrl + '?redirect=' + window.location.search.substring(11);
		}
		else {
			window.location = registerPageUrl + '?redirect=' + escape(window.location.pathname) + escape(window.location.hash);
		}
	}
	else {
	    try {
	        if(window.location.pathname == '/Enlargement/Enlargement.aspx'){
                Cookie.write('refreshEnlPage', 'false', CorbisUI.CookieOptions());
                var start = +new Date();
                var intv = setInterval(function(){
                    var val = Cookie.read('refreshEnlPage');
                    if(val == null){
                        clearInterval(intv);
                        refreshEnlargementPage('');
                    }
                    // check for 30 min at max then exit setInterval
                    if(+new Date() - start > 1000*60*30){
                        clearInterval(intv);
                    }
                },2000);
            }
			PricingModalPopupExit();
			if (window.opener != null && typeof (window.opener) != undefined) {
				window.blur();
				window.opener.redirectToRegister();
				return;
			}
		}
		catch (e) {}
		window.open(registerPageUrl, registerWindowTitle);
	}
}

function redirectToCustomerService() {
    window.location = HttpUrl + "/CustomerService/CustomerService.aspx";
}

function GoToCartByFlow(byFlow) {
	if (byFlow) {
		if (flow == coffFlow) {
			window.location = flowRedirect;
			return;
		}
	}
	GoToCart();
}
function GoToCart() {
	if (CorbisUI.Auth.GetSignInLevel() < 1) {
		CorbisUI.Auth.Check(1, CorbisUI.Auth.ActionTypes.Execute, "CorbisUI.GlobalNav.RefreshCartStatus(true)");
	} else {
		if ($('cartCount')) {
			var cartItems = parseInt($('cartCount').innerHTML, 10);
			if (!isNaN(cartItems) && cartItems > 0)
			{
				window.location = cartURL;
			}
			else
			{
				OpenNoItems();
			}
		}
	}
}

function OpenNoItems()
{
	new CorbisUI.Popup('noItems', { showModalBackground: false, closeOnLoseFocus: true, centerOverElement: 'cartCountDiv', positionVert: -15, positionHoriz: -215  } );
}

function InitSearch(data) {
	window.addEvent('domready', function() {
		CorbisUI.GlobalVars.Search = {
			showOptionsAppliedStyle: data.showOptionsAppliedStyleCID,
			sb_KeywordSearch: data.keywordSearch,
			sb_SearchImages: data.searchImages,
			sb_EmptySearchStringAlert: data.emptySearchStringAlert,
			sb_ImageNumbers: data.imageNumbersCID
		};
		CorbisUI.ExtendedSearch.vars.SearchUri = data.searchResultsUrl;
		CorbisUI.ExtendedSearch.vars.HiddenMSOTrigger = data.hiddenMSOTrigger;
		CorbisUI.ExtendedSearch.vars.HiddenMSOValue = data.hiddenMSOValue;
		CorbisUI.ExtendedSearch.vars.HiddenMSOValue.value = "UnOpened";
		CorbisUI.ExtendedSearch.vars.KeywordSearch = data.keywordSearch;
		CorbisUI.ExtendedSearch.vars.LastMSOFilters = data.msoSearchParameters;
		CorbisUI.ExtendedSearch.vars.ImageNumbers = data.imageNumbersCID;
		CorbisUI.ExtendedSearch.vars.SearchImages = data.searchImages;
		CorbisUI.ExtendedSearch.vars.EmptySearchStringAlert = data.emptySearchStringAlert;
		CorbisUI.ExtendedSearch.vars.SubscriptionOnly = data.subscriptionCheckboxCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.creative = data.creativeCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.editorial = data.editorialCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.documentary = data.documentaryCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.fineArt = data.fineArtCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.archival = data.archivalCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.currentEvents = data.currentEventsCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.entertainment = data.entertainmentCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.outline = data.outlineCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.rmLicense = data.rightsManagedCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.subscriptionsOnly = data.subscriptionCheckboxCID;
		CorbisUI.ExtendedSearch.vars.checkBoxIDS.rfLicense = data.royaltyFreeCID;
		CorbisUI.ExtendedSearch.vars.DaysButton = data.daysButtonCID;
		CorbisUI.ExtendedSearch.vars.DaysText = data.daysCID;
		CorbisUI.ExtendedSearch.vars.MSOStartDateExtend = data.msoStartDateExtendBID;
		CorbisUI.ExtendedSearch.vars.MSOEndDateExtend = data.msoEndDateExtendBID;
		CorbisUI.ExtendedSearch.vars.SearchClientId = data.searchCID;
		CorbisUI.ExtendedSearch.vars.DeleteMSO = data.deleteMoreSearchOptionsCID;
		CorbisUI.ExtendedSearch.vars.ImageNumbersText = data.imageNumbersText;
		CorbisUI.ExtendedSearch.vars.DateCreated = data.dateCreatedCID;
		CorbisUI.ExtendedSearch.vars.Location = data.locationCID;
		CorbisUI.ExtendedSearch.vars.Photographer = data.photographerCID;
		CorbisUI.ExtendedSearch.vars.Provider = data.providerCID;
		CorbisUI.ExtendedSearch.vars.Horizontal = data.horizontalCheckboxCID;
		CorbisUI.ExtendedSearch.vars.Vertical = data.verticalCheckboxCID;
		CorbisUI.ExtendedSearch.vars.Panoramic = data.panoramaCheckboxCID;
		CorbisUI.ExtendedSearch.vars.PointOfView = data.pointOfViewCID;
		CorbisUI.ExtendedSearch.vars.NumberOfPeople = data.numberOfPeopleCID;
		CorbisUI.ExtendedSearch.vars.ImmediateAvailablility = data.immediateAvailablilityCID;
		CorbisUI.ExtendedSearch.vars.BetweenButton = data.betweenButtonCID;
		CorbisUI.ExtendedSearch.vars.StartDate = data.beginDateCID;
		CorbisUI.ExtendedSearch.vars.EndDate = data.endDateCID;
		CorbisUI.ExtendedSearch.vars.DefaultStartDate = data.defaultStartDate;
		CorbisUI.ExtendedSearch.vars.DefaultEndDate = data.defaultEndDate;
		CorbisUI.ExtendedSearch.vars.DateTimeFormat = data.shortDatePattern;
		CorbisUI.ExtendedSearch.vars.DateSeparator = data.dateSeparator;
		CorbisUI.ExtendedSearch.vars.IsManualSearch = data.showReturnToPreviousSearch;
		CorbisUI.MSOSearch.vars.AlertDateText = data.alertDateText;
		CorbisUI.MSOSearch.vars.notDateErr = data.notDateErr;
		CorbisUI.MSOSearch.vars.CollectionCountStringFormat = data.collectionCountStringFormat;
		CorbisUI.MSOSearch.vars.numberOfPeopleValue = data.numberOfPeopleText;
		CorbisUI.SearchAutoComplete.vars.languageCode = data.languageCode;
		CorbisUI.SearchAutoComplete.vars.textTurnoffAutoComplete = data.textTurnoffAutoCompleteCID;
		CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete = false;
		CorbisUI.SearchAutoComplete.vars.keyWordSearch = data.keywordSearch;
	
        CorbisUI.EnlargementTimerSearch.DecodeQuerystring();
        // Show Options Applied Style in the Search box
        CorbisUI.ExtendedSearch.showOptionAppliedStyle();
        if(typeof data.callback == "function") {
            data.callback();
        }
    });
}

CorbisUI.CookieOptions = function (){
    var myURI = (window.location.hostname).toString();
    var domain = '';
    domain = (myURI.contains(CookieDomain)) ? CookieDomain : ".corbis.pre";
    return {path: "/", domain: domain, secure: false, duration: 1};
}

//End: /Scripts/Common.js
//Begin: /Scripts/ExtendedSearch.js

if (typeof (CorbisUI) == 'undefined') {
    CorbisUI = {};
}

if (typeof (CorbisUI.SearchAutoComplete) == 'undefined') {
    CorbisUI.SearchAutoComplete = {};
}

CorbisUI.ExtendedSearch = {

    vars: {
        SearchUri: null,
        HiddenMSOTrigger: null,
        HiddenMSOValue: null,
        KeywordSearch: null,
        ImageNumbers: null,
        SearchImages: null,
        EmptySearchStringAlert: null,
        ImageNumbersText: null,
        DaysButton: null,
        BetweenButton: null,
        DaysText: null,
        MSO: null,
        MSOStartDateExtend: null,
        MSOEndDateExtend: null,
        noLicense: false,
        noResults: false,
        noCat: false,
        SearchClientId: null,
        DeleteMSO: null,
        DateCreated: null,
        Location: null,
        Photographer: null,
        Provider: null,
        Horizontal: null,
        Vertical: null,
        Panoramic: null,
        PointOfView: null,
        NumberOfPeople: null,
        ImmediateAvailablility: null,
        StartDate: null,
        EndDate: null,
        DefaultStartDate: null,
        DefaultEndDate: null,
        _isResultsPage: location.pathname.toLowerCase().indexOf('searchresults.aspx') != -1,
        //_anyEditorialChecked: false,
        _isSearching: false,
        _isSearchFlyoutMousedown: false,
        _msoStartDate: null,
        _msoEndDate: new Date(),
        _isAddLightBox: null,
        _isOptionsAppliedWindowMousedown: false,
        _MSOErrorString: null,
        MSODeleted: false,
        noSearchMsg: true,
        currentPage: null,
        totalPages: null,
        MSOParameters: ['dr', 'ma', 'bd', 'lc', 'pg', 'pr', 'in', 'or', 'pv', 'np', 'ia', 'mrc'],
        checkBoxIDS: {
            creative: null,
            editorial: null,
            documentary: null,
            fineArt: null,
            archival: null,
            currentEvents: null,
            entertainment: null,
            outline: null,
            noPeople: null,
            rmLicense: null,
            rfLicense: null,
            photography: null,
            illustration: null,
            color: null,
            blackWhite: null,
            onlyModelReleased: null,
            IsManualSearch: true,
            LastMSOFilters: null,
            subscription: null
        }
    },

    flyoutKeyPress: function() {
        //console.log('CALLING: flyoutKeyPress');
        $('searchFlyout').onkeypress = function(e) {
            if (!e) var e = window.event;
            e = e || window.event;
            var code = e.keyCode || e.which;
            if (code == 13) {
                CorbisUI.ExtendedSearch.combineSearchBuddy();
                e.returnValue = false;
                return false;
            }
        }
    },

    getSearchTipsWindow: function() {
        //console.log('CALLING: getSEarchTipsWindow');
        tipsWindow = window.open("/Creative/SearchTips/Page.aspx", "tipsWindow", "left=0,top=0,width=1009,height=633,toolbar=0,resizable=0,scrollbars=0,menubar=0");
        tipsWindow.moveTo(0, 0);
    },


    testNoSearchResult: function(isFlyoutInvoked) {
        //console.log('CALLING: testNoSearchResults');
        if ($('searchFlyout').getStyle('display') == 'none' && !CorbisUI.ExtendedSearch.vars._isResultsPage) {
            return true;
        }

        //CorbisUI.ExtendedSearch.vars.noLicense = !CorbisUI.ImageCb.getImageCbObject(this.vars.checkBoxIDS.rmLicense).getCheckedState() && !CorbisUI.ImageCb.getImageCbObject(this.vars.checkBoxIDS.rfLicense).getCheckedState();
        //CorbisUI.ExtendedSearch.vars.noCat = !CorbisUI.ImageCb.getImageCbObject(this.vars.checkBoxIDS.editorial).getCheckedState() && !CorbisUI.ImageCb.getImageCbObject(this.vars.checkBoxIDS.creative).getCheckedState();

        CorbisUI.ExtendedSearch.vars.noResults = !CorbisUI.ImageCb.getImageCbObject(this.vars.checkBoxIDS.editorial).getCheckedState() && !CorbisUI.ImageCb.getImageCbObject(this.vars.checkBoxIDS.creative).getCheckedState();

        if (CorbisUI.ExtendedSearch.vars.noResults && !isFlyoutInvoked) {
            if (!$('noSearchResultsWarningWindow')) {
                new CorbisUI.Popup('noSearchResultsWarning', {
                    createFromHTML: true,
                    showModalBackground: false,
                    centerOverElement: 'noSearchResultsWarning',
                    closeOnLoseFocus: true,
                    positionVert: 180,
                    positionHoriz: 212,
                    replaceText: ['']
                });

                setTimeout('CorbisUI.ExtendedSearch.setNoResultsOptions()', 100);
            }


            return false;
        }
        else if (!CorbisUI.ExtendedSearch.vars.noResults) {
            MochaUI.CloseModal('noSearchResultsWarning');
            this.flyoutKeyPress();
            return true;
        }
        return !CorbisUI.ExtendedSearch.vars.noResults;
    },

    MoveToEnd: function() {
        window.addEvent('domready', function() {
            //console.log('CALLING: MoveToEnd');
            var keywordSearchTextbox = CorbisUI.ExtendedSearch.vars.KeywordSearch;
            var keywordSearchValue = keywordSearchTextbox.getProperty('value');

            if (navigator.userAgent.indexOf('MSIE') != -1) {
                keywordSearchTextbox.focus();
                keywordSearchTextbox.select();
                document.selection.clear();
                keywordSearchTextbox.setProperty('value', keywordSearchValue);
            }
            else {
                var keywordSearchValue = keywordSearchTextbox.getProperty('value');
                keywordSearchTextbox.setProperty('value', '');
                keywordSearchTextbox.setProperty('value', keywordSearchValue);
            }
        });
    },

    ShowSearchProgIndicator: function(dimmerOnly) {
        //console.log('CALLING: ShowSearchProgIndicator');
        if ($type($('searchProgIndicator')) == 'element') {
            $('searchProgIndicator').setStyle('display', 'block');

            var progContents = $('searchProgContents');

            if (dimmerOnly) {
                progContents.addClass('hdn');
            } else {
                if (progContents.hasClass('hdn')) progContents.removeClass('hdn');
            }
        }
        //$('searchProgIndicator').setStyle('display', 'block');
        //console.log($('searchProgIndicator'));
    },

    HideSearchProgIndicator: function() {
        //console.log('CALLING: HideSearchProgIndicator');

        if ($type($('searchProgIndicator')) == 'element') {
            $('searchProgIndicator').setStyle('display', 'none');
        }
    },
    OpenSearchTipsPopup: function() {
        //console.log('CALLING: OpenSearchTipsPopup');
        var frog = window.open('/SearchTips/SearchTipsPopup.aspx', 'dummyname', 'location=no,toolbar=no,menubar=no,directories=no,status=no,height=585,width=610', false);
        frog.focus();
    },

    setCheckedState_flyout: function(currentCheckbox) {
        //console.log('CALLING: setCheckedState_flyout');
        if (!currentCheckbox.hasClass('imageCheckbox'))
            currentCheckbox = $(currentCheckbox).getParent('.imageCheckbox');
        var allUnchecked = true;
        var parentCheckbox = currentCheckbox.getParent().getPrevious('.imageCheckbox');
        var checks = currentCheckbox.getParent().getElements('div.imageCheckbox');

        checks.each(function(cb) {
            if (CorbisUI.ImageCb.getImageCbObject(cb).getCheckedState()) {
                allUnchecked = false;
            }
        });
        CorbisUI.ImageCb.getImageCbObject(parentCheckbox).setCheckState(!allUnchecked, false);

        //CorbisUI.ExtendedSearch.vars._anyEditorialChecked = !allUnchecked;
    },

    OpenMoreSearchOptions: function() {
        //console.log('CALLING: OpenMoreSearchOptions');
        CorbisUI.ExtendedSearch.ShowSearchProgIndicator(true); // true to hide the little idicator
        if (CorbisUI.ExtendedSearch.vars.HiddenMSOValue.value == "UnOpened") {
            //            $('columnContainer').setStyle('width', '1000px');
            //            $('columnContainer').setStyle('height', '430px');
            //            ResizeModal('searchFlyout');

            CorbisUI.ExtendedSearch.vars.HiddenMSOValue.value = "Opening";
            CorbisUI.ExtendedSearch.vars.HiddenMSOTrigger.click();
        }
        if (CorbisUI.ExtendedSearch.vars.HiddenMSOValue.value == "Reset") {
            CorbisUI.ExtendedSearch.vars.HiddenMSOValue.value = "Opening";
            CorbisUI.ExtendedSearch.vars.HiddenMSOTrigger.click();
        }
        var noFlyout = false;
        if ($('moreSearchOptionsWindow')) {
            if ($('moreSearchOptionsWindow').getStyle('display') == 'none') {
                $('moreSearchOptionsWindow').setStyle('display', 'block');
            }
            else {
                CorbisUI.ExtendedSearch.hideMSOWindow(true);
                CorbisUI.ExtendedSearch.vars._isSearchFlyoutMousedown = false;
                CorbisUI.ExtendedSearch.hideSearchFlyout();
                noFlyout = true;
            }
        }
        else {
            var el = $('moreSearchOptions');
            el.setStyle('display', 'block');
            var elDimensions = el.getCoordinates();

            // fix for IE6 flyout
            var flyoutY = (Browser.Engine.trident4) ? 205 : 150;

            var properties = {
                title: '',
                collapsible: false,
                minimizable: false,
                contentBgColor: '#363636',
                headerStartColor: [74, 74, 74],
                headerStopColor: [65, 65, 65],
                bodyBgColor: [54, 54, 54],
                useCanvasControls: false,
                cornerRadius: 4,
                headerHeight: 14,
                footerHeight: 4,
                padding: 0,
                scrollbars: false,
                closable: false,
                type: 'window',
                id: el.getProperty('id') + "Window",
                height: elDimensions.height,
                width: elDimensions.width,
                //		        x: elDimensions.left,
                //		        y: elDimensions.top,
                x: 220,
                y: flyoutY,
                content: '',
                draggable: false,
                resizable: false
            };
            MochaUI.NewWindowFromDiv(el, properties);
            CorbisUI.ExtendedSearch.vars._isSearchFlyoutMousedown = false;
            $(document.body).addEvent('mousedown', function() {
                setTimeout("CorbisUI.ExtendedSearch.hideMSOWindow(true);", 10);
            });
        }
        if (CorbisUI.ExtendedSearch.vars._isResultsPage && !noFlyout) {
            //console.log('blah blah blah');
            CorbisUI.ExtendedSearch.ShowSearchProgIndicator(true);
        }
        else if (!noFlyout) {
            //console.log('hewwo silly wabbit');
            CorbisUI.ExtendedSearch.showSearchFlyout();
        }
        return false;
    },

    restoreDefaultMSO: function() {
        //console.log('CALLING: restoreDefaultMSO');
        var control = $('moreSearchOptions').getElements('input');
        control.each(function(el) {
            // Restore checkboxes to checked
            if (el.type == "checkbox") {
                if (!el.checked) {
                    CorbisUI.ImageCb.getImageCbObject(el).toggleCheckbox(true); ;
                }
            }
            // Clear out text inputs
            if (el.type == "text") {
                // DON'T DO ANYTHING TO HIDDEN MSO VALUE
                if (!el.id.contains('hiddenMSOValue')) el.value = '';
            }
        }, this);
        var daysButton = $(CorbisUI.ExtendedSearch.vars.DaysButton);
        if (daysButton) {
            radioClicked(daysButton.getParent().getParent().id);
        }
        if (($(this.vars.StartDate)) != null && ($(this.vars.EndDate) != null)) {
            $(this.vars.StartDate).value = this.vars.DefaultStartDate;
            $(this.vars.EndDate).value = this.vars.DefaultEndDate;
        }

        // Clear select boxes - set index to 0
        control = $('moreSearchOptions').getElements('select');
        control.each(function(el) {
            el.selectedIndex = 0;
        }, this);

        // Set textarea to default text
        control = $('moreSearchOptions').getElements('textarea');
        control.each(function(el) {
            el.value = CorbisUI.ExtendedSearch.vars.ImageNumbersText;
        }, this);

        $('moreSearchOptions').getElements('div.MSO_toggler').each(function(el) {
            var elementId = el.id.toString();
            CorbisUI.ExtendedSearch.vars.MSO.updateStatCounts(elementId);
        });
        this.vars.MSODeleted = true;
    },

    cancelMSOChanges: function() {
        //console.log('CALLING: cancelMSOChanges');
        if (this.vars.MSODeleted) {
            this.restoreDefaultMSO();
        }
        else {
            var control = $('moreSearchOptions').getElements('input');
            control.each(function(el) {
                if (el.type == "checkbox") {
                    if (el.checked != el.defaultChecked) {
                        CorbisUI.ImageCb.getImageCbObject(el).toggleCheckbox(true);
                    }
                }
                else if (el.type == "radio") {
                    if (el.defaultChecked) {
                        radioClicked(el.getParent().getParent().id);
                    }
                }
                else {
                    el.value = el.defaultValue;
                }
            }, this);

            control = $('moreSearchOptions').getElements('select');
            control.each(function(el) {
                el.selectedIndex = 0;
            }, this);

            control = $('moreSearchOptions').getElements('textarea');
            control.each(function(el) {
                el.value = el.defaultValue;
            }, this);

            $('moreSearchOptions').getElements('div.MSO_toggler').each(function(el) {
                var elementId = el.id.toString();
                CorbisUI.ExtendedSearch.vars.MSO.updateStatCounts(elementId);
            });
        }
        CorbisUI.ExtendedSearch.HideSearchProgIndicator();
    },


    deleteSearchOptions: function(callback) {
        //console.log('CALLING: deleteSearchOptions');
        var keywordSearchTextbox = CorbisUI.ExtendedSearch.vars.KeywordSearch;

        if (this.vars.HiddenMSOValue.value == "UnOpened") {
            this.vars.HiddenMSOValue.value = "Reset";
        }
        else {
            // try to clear fields
            this.restoreDefaultMSO();
        }
        $(CorbisUI.GlobalVars.Search.showOptionsAppliedStyle).value = 'false';
        $('optionsAppliedClose').setStyle('display', 'none');
        $('Search').getElement('div[id=Keywords]').removeClass("optionsApplied");
        $("optionsAppliedDiv").removeClass("optionsAppliedDiv").setStyle("display", "none");
        keywordSearchTextbox.setStyle('background-color', '#ffffff');

        if ($('optionsAppliedClose').getStyle('display') == 'none') {
            keywordSearchTextbox.removeClass("optionsAppliedInput");
        }
        var req = new Request({
            method: 'post',
            url: "/searchold/searchscriptservice.asmx/DeleteMoreSearchOptions",
            async: false,
            onSuccess: function() {
                // clearing MSO parameters in cookie
                var searchCookie = CorbisUI.ExtendedSearch.GetSearchCookie();
                if (searchCookie != null && searchCookie != '') {
                    var paramArray = searchCookie.split('&');
                    var nonMSOParameters = "";
                    paramArray.each(function(value) {
                        var flag = false;
                        for (var i = 0; i < CorbisUI.ExtendedSearch.vars.MSOParameters.length; i++) {
                            if (value.contains(CorbisUI.ExtendedSearch.vars.MSOParameters[i] + '=')) {
                                flag = true;
                                break;
                            }
                        }
                        if (!flag) nonMSOParameters += "&" + value;
                    });
                    if (nonMSOParameters != '') {
                        CorbisUI.ExtendedSearch.SetSearchCookie(nonMSOParameters.substr(1));
                    }
                    else {
                        CorbisUI.ExtendedSearch.SetSearchCookie();
                    }
                }
            }
        }).send();

        if (typeof callback == "function") {
            callback();
        }
    },

    hideMSOWindow: function(force) {
        //console.log('CALLING: hideMSOWindow');
        if (CorbisUI.ExtendedSearch.vars._isSearching) {
            return;
        }
        if (force || (!CorbisUI.ExtendedSearch.vars._isSearchFlyoutMousedown && $('moreSearchOptionsWindow') != null)) {
            try {
                $('moreSearchOptionsWindow').setStyle('display', 'none');
            }
            catch (er) { }
        }
        CorbisUI.ExtendedSearch.vars._isSearchFlyoutMousedown = false;
        //if (CorbisUI.ExtendedSearch.vars._isResultsPage && !CorbisUI.ExtendedSearch.vars._isSearching) {
        if (!CorbisUI.ExtendedSearch.vars._isSearching) {
            CorbisUI.ExtendedSearch.HideSearchProgIndicator();
            //$('searchProgContents').setStyle('display', 'block');
        }
    },

    showSearchFlyout: function() {
        //console.log('CALLING: showSearchFlyout');
        if (CorbisUI.ExtendedSearch.vars._isResultsPage) {
            return;
        }
        if ($('searchFlyoutWindow')) {
            //$('columnContainer').setStyle('width', '1100px');
            //$('columnContainer').setStyle('height', '430px');
            $('searchFlyoutWindow').setStyle('display', 'block');
            //ResizeModal('searchFlyout');
        }
        else {
            var el = $('searchFlyout');
            el.setStyle('display', 'block');
            var elDimensions = el.getCoordinates();

            //fix for flyout for IE6
            elDimensions.top = (Browser.Engine.trident4) ? elDimensions.top + 55 : elDimensions.top;


            var properties = {
                title: '',
                indexLevel: 11111,
                collapsible: false,
                minimizable: false,
                contentBgColor: [102, 102, 102],
                headerStartColor: [117, 117, 117],
                headerStopColor: [110, 110, 110],
                bodyBgColor: [102, 102, 102],
                useCanvasControls: false,
                cornerRadius: 4,
                headerHeight: 15,
                footerHeight: 4,
                padding: 10,
                scrollbars: false,
                closable: true,
                type: 'window',
                id: el.getProperty('id') + "Window",
                height: elDimensions.height,
                width: elDimensions.width,
                x: elDimensions.left,
                y: elDimensions.top - 32,
                content: '',
                draggable: false,
                resizable: false
            };


            el.setStyle("left", "0");



            el.setStyle("top", "0");
            MochaUI.NewWindowFromDiv(el, properties);
            $(document.body).addEvent('mousedown', function() {
                setTimeout('CorbisUI.ExtendedSearch.hideSearchFlyout()', 10);
            });
            $('searchFlyoutWindow_titleBar').setStyle('background', 'transparent');
            $('searchFlyoutWindow_contentWrapper').setStyle('background', 'transparent');
            CorbisUI.ExtendedSearch.vars._isSearchFlyoutMousedown = false;
        }
    },

    hideSearchFlyout: function() {
        //console.log('CALLING: hideSearchFlyout');
        if ($('KeywordsAutoComplete_Window')) {
            setTimeout('CorbisUI.SearchAutoComplete.hideWindowAutoComplete()', 300);
        }

        if (CorbisUI.ExtendedSearch.vars._isResultsPage) return;
        if (!CorbisUI.ExtendedSearch.vars._isSearchFlyoutMousedown)
            try { $('searchFlyoutWindow').setStyle('display', 'none'); } catch (er) { }
        CorbisUI.ExtendedSearch.vars._isSearchFlyoutMousedown = false;
        MochaUI.CloseModal('noSearchResultsWarning');
        //CorbisUI.ExtendedSearch.ShowSearchProgIndicator();
    },


    CheckedStateChanged_flyout: function(currentCheckbox) {
        //console.log('CALLING: CheckedStateChanged_flyout');
        currentCheckbox = $(currentCheckbox).getParent('.imageCheckbox');
        var checks = currentCheckbox.getNext('div').getElements('div.imageCheckbox');
        checks.each(function(cb) {
            CorbisUI.ImageCb.getImageCbObject(cb).setCheckState(CorbisUI.ImageCb.getImageCbObject(currentCheckbox).getCheckedState(), false);
        });
        //CorbisUI.ExtendedSearch.vars._anyEditorialChecked = checked;
    },

    setNoResultsOptions: function() {
        //console.log('CALLING: setNoResultsOptions');
        if (CorbisUI.ExtendedSearch.vars._isResultsPage) return;
        var pop = $('noSearchResultsWarningWindow');
        pop.getElement('p[textKey=License]').setStyle('display', 'none');
        pop.getElement('p[textKey=Category]').setStyle('display', 'none');
        //alert(pop.getElement('p[textKey=License]'));

        if (CorbisUI.ExtendedSearch.vars.noResults)
            pop.getElement('p[textKey=NoResults]').setStyle('display', 'block');
        //else if (CorbisUI.ExtendedSearch.vars.noCat)
        //    pop.getElement('p[textKey=Category]').setStyle('display', 'block');

        $('searchFlyoutWindow').setStyle('z-index', '9999');
        $('searchFlyoutWindow').addEvent('mousedown', function() {
            $('searchFlyoutWindow').setStyle('z-index', '9999');
        });
        $('modalOverlay').addEvent('click', function() {
            $('modalOverlay').setStyle('display', 'none');
        });
        if (!$('searchFlyoutWindow') || $('searchFlyoutWindow').getStyle('display', 'none'))
            CorbisUI.ExtendedSearch.showSearchFlyout();
    },

    IMA_disabler: function(e, ele) {
        //console.log('CALLING: IMA_disabler');
        // get the parent wrapper
        var parent = this.getParent('.roundMe');
        // fire the click event
        parent.getElement('input').setProperty('checked', 'true');
    },


    // Calendar controls on MSO pane

    checkStartDate: function(sender, args) {
        //console.log('CALLING: checkStartDate');
        CorbisUI.ExtendedSearch.vars._msoStartDate = sender._selectedDate;
        var dt = new Date();
        if (sender._selectedDate > dt) {
            sender._textbox.set_Value(dt.format(CorbisUI.ExtendedSearch.vars.DateTimeFormat));  //fixed bug 18733 changing format to be like checkendDate
            CorbisUI.ExtendedSearch.vars._msoStartDate = dt;
        }
        if (CorbisUI.ExtendedSearch.vars._msoStartDate > CorbisUI.ExtendedSearch.vars._msoEndDate) {
            sender._textbox.set_Value(CorbisUI.ExtendedSearch.vars._msoEndDate.format(CorbisUI.ExtendedSearch.vars.DateTimeFormat)); //fix bug 18733
            CorbisUI.ExtendedSearch.vars._msoStartDate = CorbisUI.ExtendedSearch.vars._msoEndDate;
        }
    },

    checkEndDate: function(sender, args) {
        //console.log('CALLING: checkEndDate');
        CorbisUI.ExtendedSearch.vars._msoEndDate = sender._selectedDate;
        var dt = new Date();
        if (sender._selectedDate > dt) {
            sender._textbox.set_Value(dt.format(CorbisUI.ExtendedSearch.vars.DateTimeFormat));
        }
        if (CorbisUI.ExtendedSearch.vars._msoStartDate > CorbisUI.ExtendedSearch.vars._msoEndDate) {
            sender._textbox.set_Value(CorbisUI.ExtendedSearch.vars._msoStartDate.format(CorbisUI.ExtendedSearch.vars.DateTimeFormat));
            CorbisUI.ExtendedSearch.vars._msoEndDate = CorbisUI.ExtendedSearch.vars._msoStartDate;
        }
    },

    // *******************************
    // Advanced Search Option
    // *******************************
    OpenOptionsAppliedModal: function() {
        //console.log('CALLING: openOptionsAppliedModal');
        if ($('optionsAppliedModalWindow')) {
            $('optionsAppliedModalWindow').setStyle('display', 'block');
        } else {
            var el = $('optionsAppliedModal');
            el.setStyle('display', 'block');
            var elDimensions = el.getCoordinates();
            var properties = {
                title: '',
                collapsible: false,
                minimizable: false,
                contentBgColor: '#e8e8e8',
                headerStartColor: [219, 219, 219],
                headerStopColor: [219, 219, 219],
                bodyBgColor: [232, 232, 232],
                useCanvasControls: false,
                cornerRadius: 4,
                headerHeight: 42,
                footerHeight: 4,
                padding: 0,
                shadowBlur: 9,
                scrollbars: false,
                closable: false,
                type: 'window',
                id: el.getProperty('id') + "Window",
                height: elDimensions.height,
                width: elDimensions.width,
                //		        x: elDimensions.left,
                //		        y: elDimensions.top,
                x: 340,
                y: 180,
                content: '',
                draggable: false,
                resizable: false
            };
            MochaUI.NewWindowFromDiv(el, properties);

            $(document.body).addEvent('mousedown', CorbisUI.ExtendedSearch.detectOptionsAppliedModalClick.bindWithEvent($('optionsAppliedModalWindow')));
            if (!document.location.href.toString().contains("options=true"))
                $('optionsAppliedModalWindow').getElement('img.close').setStyle('display', 'none');
        }
    },

    hideAppliedOptionsWindow: function(e) {
        //console.log('CALLING: hideAppliedOptionsWindow');
        if ($('optionsAppliedModalWindow')) {
            $('optionsAppliedModalWindow').setStyle('display', 'none');

            CorbisUI.ExtendedSearch.cancelMSOChanges();
            e.cancelBubble = true;
        } else {
            var el = $('optionsAppliedModal');
            el.setStyle('display', 'none');
            CorbisUI.ExtendedSearch.hideMSOWindow(true);
        }
    },

    detectOptionsAppliedModalClick: function(ev) {
        //console.log('CALLING: detectOptionsAppliedClick');
        var coord = this.getCoordinates();
        if (
            ((ev.page.y < coord.top) || (ev.page.y > (coord.top + coord.height)))
            ||
            (ev.page.x < coord.left) || (ev.page.x > (coord.left + coord.width))
        ) {
            (function() { CorbisUI.ExtendedSearch.hideTimerWindow() }).delay(10);
        }
    },

    hideTimerWindow: function() {
        //console.log('CALLING: hideTimerWindow');
        if (!CorbisUI.ExtendedSearch.vars._isOptionsAppliedWindowMousedown)
            try { $('optionsAppliedModalWindow').setStyle('display', 'none'); } catch (e) { }
        CorbisUI.ExtendedSearch.vars._isOptionsAppliedWindowMousedown = false;
    },

    setupMSO: function() {
        //console.log('CALLING: setupMSO');
        // startup accordion for more search options
        CorbisUI.ExtendedSearch.vars.MSO = new MSOaccordion();

        // get the more search options wrap
        var MSOwrap = $('moreSearchOptions');
        //var MSOwrap = $('searchFlyout');

        // get input elements
        var IMA_last_items = MSOwrap.getElement('div.IMA_lastDays').getElements('input[type=text]');
        var IMA_between_items = MSOwrap.getElement('div.IMA_between').getElements('input[type=text]');

        // combine the element arrays
        IMA_between_items.combine(IMA_last_items);

        // loopty do
        IMA_between_items.each(function(item) {
            item.addEvent('focus', CorbisUI.ExtendedSearch.IMA_disabler.bindWithEvent(item))
        });

        if ($('MSOIndicator')) {
            $('MSOIndicator').setStyle('display', 'none');
        }

        MSOwrap.onkeypress = function(e) {
            if (!e) var e = window.event;
            e = e || window.event;
            var target = window.event ? window.event.srcElement : e ? e.target : null;
            var code = e.keyCode || e.which;
            if (target.id != CorbisUI.ExtendedSearch.vars.ImageNumbers) {
                //if (code == 13 && $('searchFlyoutWindow') && $('searchFlyoutWindow').getStyle('display') == 'block') {
                if (code == 13 && $('moreSearchOptionsWindow') && $('moreSearchOptionsWindow').getStyle('display') == 'block') {
                    CorbisUI.ExtendedSearch.validateSearch();
                    e.returnValue = false;
                    return false;
                }
            } else {
                e.returnValue = true;
                return true;
            }
        }
    },

    invokeSearch: function(isFromFilters, resetOptions) {
        //console.log('CALLING: invokeSearch');
        LogOmnitureEvent("event5");
        CorbisUI.ExtendedSearch.hideMSOWindow(true);
        CorbisUI.ExtendedSearch.hideSearchFlyout();
        try {
            var pop = $('noSearchResultsWarningWindow');
            if (pop && pop.getStyle('display') == 'block') {
                if (CorbisUI.ExtendedSearch.vars._isResultsPage)
                    $('searchBuddyMask').setStyle('display', 'none');
                return false;
            }
        } catch (er) { }
        if (isFromFilters) {
            $('processingFilters').setStyle('display', 'block');
        }
        CorbisUI.ExtendedSearch.ShowSearchProgIndicator();
        CorbisUI.ExtendedSearch.vars._isSearching = true;
        this.executeSearchQuery();
    },

    executeSearchQuery: function() {
        //console.log('CALLING: executeSearchQuery');
        this.vars.SearchUri = HttpUrl + "/Search";
        var query = "";
        if ($(this.vars.KeywordSearch).value != this.vars.SearchImages && $(this.vars.KeywordSearch).value != "")
            query += "&q=" + UrlEncode($(this.vars.KeywordSearch).value);
        if (CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete == true) {
            var ac = $(this.vars.KeywordSearch).value;
            if (ac != this.vars.SearchImages && ac != "")
                query += "&ac=" + UrlEncode(ac);   //Setting query parameter for Omniture                   
        }
        if ($("moreSearchOptionsWindow") && $(this.vars.DateCreated)) {

            if ($(this.vars.DateCreated).value)
                query += "&dr=" + UrlEncode($(this.vars.DateCreated).value.trim());

            if ($(this.vars.DaysButton).checked && $(this.vars.DaysText).value.trim())
                query += "&ma=" + UrlEncode($(this.vars.DaysText).value.trim());
            else if ($(this.vars.BetweenButton).checked)
                query += "&bd=" + UrlEncode($(this.vars.StartDate).value.trim()) + "," + UrlEncode($(this.vars.EndDate).value.trim());

            if ($(this.vars.Location).value)
                query += "&lc=" + UrlEncode($(this.vars.Location).value.trim());

            if ($(this.vars.Photographer).value)
                query += "&pg=" + UrlEncode($(this.vars.Photographer).value.trim());

            if ($(this.vars.Provider).value)
                query += "&pr=" + UrlEncode($(this.vars.Provider).value.trim());

            if ($(this.vars.ImageNumbers).value && $(this.vars.ImageNumbers).value != this.vars.ImageNumbersText)
                query += "&in=" + UrlEncode($(this.vars.ImageNumbers).value.trim());

            query += this.getOrientationQuery();

            if ($(this.vars.PointOfView).value && $(this.vars.PointOfView).value != "0")
                query += "&pv=" + $(this.vars.PointOfView).value;

            if ($(this.vars.NumberOfPeople).value && $(this.vars.NumberOfPeople).value != "5")
                query += "&np=" + $(this.vars.NumberOfPeople).value;

            if ($(this.vars.ImmediateAvailablility).value && $(this.vars.ImmediateAvailablility).value != "1")
                query += "&ia=" + $(this.vars.ImmediateAvailablility).value;

            query += this.getMarketingCollectionQuery();
        }

        else if (this.vars.HiddenMSOValue.value != "Reset" && this.vars.LastMSOFilters) {
            // Clear out the 'np' parameter if 'any' is the current Number of people
            if (CorbisUI.MSOSearch.vars.numberOfPeopleValue == "5") {
                var str = this.vars.LastMSOFilters.replace(/&?np\=[0-9]/, "");
                if (str) query += "&" + str;
            }
            else {
                query += "&" + this.vars.LastMSOFilters;
            }
        }
        else {

            var gMSO = this.GetMSOFromSearchCookie();
            if (gMSO != '')
                query += '&' + gMSO;
        }

        query += this.getCategoryQuery();
        query += this.getMediaTypeQuery();
        query += this.getColorFormatQuery();
        query += this.getModelReleaseQuery();
        query += this.getSubscriptionId();

        // Check for "No People" checkbox
        {
            // Returns "&np=6" for "No People" or empty string
            // for not "No People"

            var np = this.getNoPeopleQuery();

            // A check overrides any saved previous MSO search
            // unless the MSO options are open at time of search

            if (np && !$("moreSearchOptionsWindow")) {
                if (query.indexOf("np=") != -1) {
                    query = query.replace(/&?np=[0-9]/, np);
                }
                else {
                    query += np;
                }
            }

            // If there's no check but query has "No People" 
            // from saved previous MSO search, remove it

            else if (!np && query.indexOf("np=6") != -1) {
                query = query.replace(/&?np=6/, "");
            }
        }

        var clarificationQuery = CorbisUI.ExtendedSearch.getClarifactionChecked();
        if (clarificationQuery && clarificationQuery != ',') {
            query += "&cl=" + clarificationQuery;
        }
        if (query.indexOf("el=") < 0) {
            CorbisUI.ExtendedSearch.SetSearchCookie(UrlEncode(query.substring(1)));
            CorbisUI.ExtendedSearch.updateSearchSession('#' + query.substring(1));
        }



        if (query != "") {
            location.href = this.vars.SearchUri + '#' + query.substr(1);

        }
        else {
            location.href = this.vars.SearchUri;
        }
        return false;
    },


    updateSearchSession: function(finalSearchUrl) {
        var req = new Request({
            method: 'post',
            url: "/SearchTools/UpdateOptionsInSession",
            data: { 'searchUrl': finalSearchUrl }
        }).send();
    },


    GetSearchCookie: function() {
        try {
            return decodeURIComponent(Cookie.read('UserSearchOptions'));
        } catch (e) { }
    },

    GetMSOFromSearchCookie: function() {
        //console.log('CALLING: GetMSOFromSearchCookie');
        var strMSO = "";
        if (this.GetSearchCookie() != null && this.GetSearchCookie() != '') {
            var paramArray = this.GetSearchCookie().split('&');
            paramArray.each(function(value) {
                if (value != '') {
                    this.vars.MSOParameters.each(function(MSOs) {
                        if (value.contains(MSOs + '='))
                            strMSO += "&" + value;
                    });
                }
            }, this);
            if (strMSO != '')
                strMSO = strMSO.substr(1);
        }
        return strMSO;
    },

    SetSearchCookie: function(value) {
        //console.log('CALLING: setSearchCookie');
        try {
            var name = "UserSearchOptions";
            var myURI = (location.hostname).toString();
            var domain = '';
            domain = (myURI.contains(CookieDomain)) ? CookieDomain : ".corbis.pre";
            Cookie.write(name, value, {
                secure: false
            });
        } catch (e) { }
    },

    getClarifactionChecked: function(method) {
        //console.log('CALLING: getClarificationChecked');
        var base = $('ambiguousModal');
        if (base) {
            var clarificationGroups = base.getElements('.Clarification');
            var clarificationString = '';

            clarificationGroups.each(function(el) {
                clarificationString += ',';

                var isOneClarificationSelected = false;

                var checkboxWrap = el.getElements('.checkboxWrap');
                for (i = 0; i < checkboxWrap.length; i++) {
                    var cbx = checkboxWrap[i].getElement('input[type=checkbox]');
                    if (cbx.checked) {
                        isOneClarificationSelected = true;
                        break;
                    }
                }

                if (isOneClarificationSelected) {
                    el.getElements('.checkboxWrap').each(function(itemEl) {
                        var cbx = itemEl.getElement('input[type=checkbox]');
                        (cbx.checked) ? cbx.value = 1 : cbx.value = 0;
                        clarificationString += cbx.value;
                    });
                }
            });

            clarificationString = clarificationString.substring(1);
            if (clarificationString.endsWith(",")) {
                clarificationString = clarificationString.substring(0, clarificationString.length - 1);
            }
            var queryFlags = $(CorbisUI.GlobalVars.SearchResults.clarificationQueryFlags);
            queryFlags.value = clarificationString;
            if (method == "cancel") {
                HideModal('ambiguousModal');
            }
            else {
                MochaUI.CloseModal('ambiguousModal');
                return clarificationString;
            }
        }
    },

    getOrientationQuery: function() {
        //console.log('CALLING: getOrientationQuery');
        var horz = CorbisUI.ImageCb.getImageCbObject(this.vars.Horizontal).getCheckedState();
        var vert = CorbisUI.ImageCb.getImageCbObject(this.vars.Vertical).getCheckedState();
        var pano = CorbisUI.ImageCb.getImageCbObject(this.vars.Panoramic).getCheckedState();
        var str = "";
        if (!(horz & vert & pano) && !(!horz & !vert & !pano)) {
            str += "&or=";
            var sep = "";
            if (vert) { str += sep + "1"; sep = ","; }
            if (horz) { str += sep + "2"; sep = ","; }
            if (pano) { str += sep + "3"; sep = ","; }
        }
        return str;
    },

    /* 2009-06-24  WI#20188 - remove creative as a category and add CreativeRM and CreativeRF */
    getCategoryQuery: function() {
        //console.log('CALLING: getCategoryQuery');
        var cats = new Array();
        var cbControls = this.vars.checkBoxIDS;
        var isOutline = $(cbControls.outline) != null;
        var query = "";

        if (this.vars._isResultsPage)
            cbControls = CorbisUI.GlobalVars.SearchResults.checkBoxIDS;

        var cbToCheck = new Array(cbControls.rmLicense,
                                  cbControls.rfLicense,
                                  cbControls.documentary,
                                  cbControls.fineArt,
                                  cbControls.archival,
                                  cbControls.currentEvents,
                                  cbControls.entertainment);

        cbToCheck.each(function(cbControl) {
            if (CorbisUI.ImageCb.getImageCbObject(cbControl).getCheckedState())
                cats.push(CorbisUI.ImageCb.getImageCbObject(cbControl).getCheckboxValue());
        });

        if (isOutline && CorbisUI.ImageCb.getImageCbObject(cbControls.outline).getCheckedState())
            cats.push(CorbisUI.ImageCb.getImageCbObject(cbControls.outline).getCheckboxValue());

        if (((isOutline && cats.length < 8) || (!isOutline && cats.length < 7)) && cats.length > 0) {
            query = "&cat=" + cats.join(',');
        }
        return query;
    },

    getUserSearchOptions: function(optionName) {
        //console.log('CALLING: getUserSearchOptions');
        try {
            var name = "UserSearchOptions";
            var myURI = (location.hostname).toString();
            var domain = '';
            domain = (myURI.contains(CookieDomain)) ? CookieDomain : ".corbis.pre";
            if (document.cookie.length > 0) {
                var c_start = 0;
                while (c_start > -1) {
                    c_start = document.cookie.indexOf(name + "=", c_start);
                    if (c_start != -1) {
                        c_start = c_start + name.length + 1;
                        c_end = document.cookie.indexOf(";", c_start);
                        if (c_end == -1) c_end = document.cookie.length;
                        var cookieValue = unescape(document.cookie.substring(c_start, c_end));
                        if (cookieValue.indexOf(optionName + "=") != -1) {
                            var optionValue;
                            var tempCookieValue = cookieValue.substring(cookieValue.indexOf(optionName));
                            if (tempCookieValue.indexOf("&") == -1) {
                                optionValue = cookieValue.substring(cookieValue.indexOf(optionName));
                                return optionValue;
                            }
                            else {
                                optionValue = tempCookieValue.substring(0, tempCookieValue.indexOf("&"));
                                return optionValue;
                            }
                        }
                    }
                }
            }

        } catch (e) { }
    },
    getNoPeopleQuery: function() {
        //console.log('CALLING: getNoPeopleQuery');
        var query = "";
        if (this.vars._isResultsPage) {
            if (CorbisUI.ImageCb.getImageCbObject(CorbisUI.GlobalVars.SearchResults.checkBoxIDS.noPeople).getCheckedState())
                query = "&np=" + CorbisUI.ImageCb.getImageCbObject(CorbisUI.GlobalVars.SearchResults.checkBoxIDS.noPeople).getCheckboxValue();
        }
        else {
            var tempNoPeopleFilterValue = this.getUserSearchOptions("np");
            if (tempNoPeopleFilterValue) {
                //break down this query further and make sure that np is = 6, otherwise ignore it. 

                if (tempNoPeopleFilterValue == "np=6")
                    query = query + "&" + tempNoPeopleFilterValue;

            }
        }

        return query;
    },

    getSubscriptionId: function() {

        var query = "";
        var cbControls = this.vars.checkBoxIDS;
        var isSubscription = $(cbControls.subscriptionsOnly) != null;
        if (isSubscription) {
            if (!this.vars._isResultsPage) {
                var subscriptionSearchOnlyCheckbox = CorbisUI.ImageCb.getImageCbObject(cbControls.subscriptionsOnly);
                var subscriptionSearchOnly = subscriptionSearchOnlyCheckbox.getCheckedState();
                if (subscriptionSearchOnly) {
                    query += "&sid=" + CorbisUI.ImageCb.getImageCbObject(cbControls.subscriptionsOnly).getCheckboxValue();
                }
            }
            else {
                var controlGroup = CorbisUI.GlobalVars.SearchResults.checkBoxIDS;
                var subscriptionSearchOnlyCheckbox = CorbisUI.ImageCb.getImageCbObject(controlGroup.subscriptionOnly);
                var subscriptionSearchOnly = subscriptionSearchOnlyCheckbox.getCheckedState();
                if (subscriptionSearchOnly) {
                    query += "&sid=" + CorbisUI.ImageCb.getImageCbObject(controlGroup.subscriptionOnly).getCheckboxValue();
                }

            }
        }
        return query;
    },

    getMediaTypeQuery: function() {
        //console.log('CALLING: getMediaTypeQuery');
        var filters = new Array();
        var query = "";
        if (this.vars._isResultsPage) {
            var cbToCheck = new Array(CorbisUI.GlobalVars.SearchResults.checkBoxIDS.photography,
                                      CorbisUI.GlobalVars.SearchResults.checkBoxIDS.illustration);

            cbToCheck.each(function(cbControl) {
                if (CorbisUI.ImageCb.getImageCbObject(cbControl).getCheckedState())
                    filters.push(CorbisUI.ImageCb.getImageCbObject(cbControl).getCheckboxValue());
            });

            if (filters.length == 1)
                query = "&mt=" + filters.join(',');
        }
        else {
            var tempMediaFilterValue = this.getUserSearchOptions("mt");
            if (tempMediaFilterValue)
                query = query + "&" + tempMediaFilterValue;
        }

        return query;
    },

    getColorFormatQuery: function() {
        //console.log('CALLING: getColorFormatQuery');
        var filters = new Array();
        var query = "";
        if (this.vars._isResultsPage) {
            var cbToCheck = new Array(CorbisUI.GlobalVars.SearchResults.checkBoxIDS.color,
                                      CorbisUI.GlobalVars.SearchResults.checkBoxIDS.blackWhite);

            cbToCheck.each(function(cbControl) {
                if (CorbisUI.ImageCb.getImageCbObject(cbControl).getCheckedState())
                    filters.push(CorbisUI.ImageCb.getImageCbObject(cbControl).getCheckboxValue());
            });

            if (filters.length == 1)
                query = "&cf=" + filters.join(',');
        }
        else {
            var tempColorFormatFilterValue = this.getUserSearchOptions("cf");
            if (tempColorFormatFilterValue)
                query = query + "&" + tempColorFormatFilterValue;
        }
        return query;
    },

    getModelReleaseQuery: function() {
        //console.log('CALLING: getModelReleaseQuery');
        var query = "";
        if (this.vars._isResultsPage) {
            if (CorbisUI.ImageCb.getImageCbObject(CorbisUI.GlobalVars.SearchResults.checkBoxIDS.onlyModelReleased).getCheckedState())
                query = "&mr=" + CorbisUI.ImageCb.getImageCbObject(CorbisUI.GlobalVars.SearchResults.checkBoxIDS.onlyModelReleased).getCheckboxValue();
        }
        else {
            var tempModelReleasedFilterValue = this.getUserSearchOptions("mr");
            if (tempModelReleasedFilterValue)
                query = query + "&" + tempModelReleasedFilterValue;
        }
        return query;
    },

    getMarketingCollectionQuery: function() {
        //console.log('CALLING: getMarketingCollectionQuery');
        var str = "";
        var sep = "";
        var isAllChecked = true;
        var items = $('MSO_accordion').getElements('input[type=checkbox]')
        items.each(function(el) {
            if (el.checked) {
                str += sep + el.value;
                sep = ",";
            }
            else {
                isAllChecked = false;
            }
        });
        return (isAllChecked || str == "") ? "" : "&mrc=" + str;
    },

    combineSearchBuddy: function() {
    //console.log('CALLING: combineSearchBuddy');
        CorbisUI.ExtendedSearch.validateInputSearchString();
        if (this.vars._isResultsPage) {
            if (CorbisUI.SearchBuddy.validateCheckBoxes()) {
                if ($("KeywordsAutoComplete_Window")) {
                    $("KeywordsAutoComplete_Window").setStyle('display', 'none');
                }
                CorbisUI.ExtendedSearch.SetCookie('SetProp14', 'true');
                CorbisUI.ExtendedSearch.validateSearch();
            }
        }
        else {
            CorbisUI.ExtendedSearch.validateSearch();
        }
        if (location.toString().contains("q=")) {
            CorbisUI.ExtendedSearch.SetCookie('PreviousSearchLink', location);
        } else {
        CorbisUI.ExtendedSearch.SetCookie('PreviousSearchLink', CorbisUI.ExtendedSearch.vars.SearchUri+ "#q=" + CorbisUI.GlobalVars.Search.sb_KeywordSearch.value);

        }

        return false;
    },

    GetCookie: function(c_name) {
        if (document.cookie.length > 0) {
            c_start = document.cookie.indexOf(c_name + "=");
            if (c_start != -1) {
                c_start = c_start + c_name.length + 1;
                c_end = document.cookie.indexOf(";", c_start);
                if (c_end == -1) c_end = document.cookie.length;
                return unescape(document.cookie.substring(c_start, c_end));
            }
        }
        return "";
    },
    SetCookie: function(name, value) {
        //console.log('CALLING: SetProp14Cookie');
        try {
            var myURI = (location.hostname).toString();
            var domain = '';
            domain = (myURI.contains(CookieDomain)) ? CookieDomain : ".corbis.pre";
            Cookie.write(name, value, {
                path: "/",
                domain: domain,
                secure: false
            });
        } catch (e) { }
    },

    validateInputSearchString: function() {
        //console.log('CALLING: validateInputSearchString');
        var myRegExp = new RegExp("#", "g");
        if (CorbisUI.GlobalVars.Search.sb_KeywordSearch) {
            var strSearch = CorbisUI.GlobalVars.Search.sb_KeywordSearch.value.trim();
            strSearch = strSearch.replace(myRegExp, "");
            CorbisUI.GlobalVars.Search.sb_KeywordSearch.value = strSearch;
        }
    },

    validateSearch: function() {
        //console.log('CALLING: validateSearch');
        if (CorbisUI.ExtendedSearch.vars._isAddLightBox) return;

        this.validateSearchString();
        if (CorbisUI.ExtendedSearch.validateMSO()) {
            if (this.vars._isResultsPage || this.testNoSearchResult()) {

                CorbisUI.ExtendedSearch.invokeSearch(false);
            }
        }
    },

    // Done
    validateSearchString: function() {
        //console.log('CALLING: validateSearchString');
        try { if (timer != null) window.clearInterval(timer); } catch (er) { }
        var imageNumbersValue = '';
        if ($(CorbisUI.ExtendedSearch.vars.ImageNumbers)) {
            imageNumbersValue = $(CorbisUI.ExtendedSearch.vars.ImageNumbers).value.trim();
            if (imageNumbersValue == this.vars.ImageNumbersText) {
                imageNumbersValue = '';
            }
        }

        var keywordValue = CorbisUI.ExtendedSearch.vars.KeywordSearch.value.trim();
        if (keywordValue == CorbisUI.ExtendedSearch.vars.SearchImages) {
            keywordValue = '';
        }

        if (imageNumbersValue != '' || keywordValue != '') {
            this.vars.noSearchMsg = false;
        }
    },

    validateMarketingCollections: function() {
        //console.log('CALLING: validateMarketingCollections');
        $$('div.MSO_toggler').each(function(el) {
            var elementId = el.id.toString();
            var items = CorbisUI.ExtendedSearch.vars.MSO.collections[elementId].domObj.getNext('div.MSO_element').getElements('input[type=checkbox]');
            var numTotal = 0;
            var numChecked = 0;
            items.each(function(item) {
                numTotal++;
                if (item.checked) {
                    numChecked++;
                }
            });
            if (numTotal > numChecked) {
                CorbisUI.ExtendedSearch.vars.noSearchMsg = false;
            }
        });
    },

    validateMSO: function() {
        //console.log('CALLING: validateMSO');
        // if MSO is null, either the user is looking at a previously-validated search result
        // or they are using the default settings.
        if ($('moreSearchOptionsWindow') == null || !$(this.vars.DateCreated)) {
            return true;
        }
        // Check Categories and License types
        CorbisUI.ExtendedSearch.vars._MSOErrorString = '';
        var pop = $('noSearchResultsWarning');
        if (!this.testNoSearchResult(true)) {
            if (CorbisUI.ExtendedSearch.vars.noResults)
                CorbisUI.ExtendedSearch.appendEr(pop.getElement('p[textKey=NoResults]').get('text'));
            //if (CorbisUI.ExtendedSearch.vars.noCat)
            //    CorbisUI.ExtendedSearch.appendEr(pop.getElement('p[textKey=Category]').get('text'));
            alert(CorbisUI.ExtendedSearch.vars._MSOErrorString);
            return false;
        }
        // Check for "ITEMS IN THE LAST X DAYS"
        var IMA_last_items = $('moreSearchOptions').getElement('div.IMA_lastDays').getElements('input[type=text]').get('value');
        //check that number of days is indeed a number
        var daysRadio = $(CorbisUI.ExtendedSearch.vars.DaysButton);
        if (daysRadio.checked) {
            if (isNaN(IMA_last_items) || IMA_last_items < 0) {
                CorbisUI.ExtendedSearch.appendEr(pop.getElement('p[textKey=NotNumeric]').get('text'));
                alert(CorbisUI.ExtendedSearch.vars._MSOErrorString);
                var theField = $('moreSearchOptions').getElement('div.IMA_lastDays').getElements('input[type=text]');
                theField[0].focus();
                return false;
            } else {
                try {
                    if (!isNaN(parseInt(IMA_last_items, 10))) {
                        this.vars.noSearchMsg = false;
                    }
                } catch (ex)
                { }
            }
        }

        if (!CorbisUI.MSOSearch.checkDateValues()) {
            return false;
        }

        // Check Marketing Collections
        this.validateMarketingCollections();
        // Check for Date Created
        if ($(this.vars.DateCreated).value.trim() != '') {
            this.vars.noSearchMsg = false;
        }

        // Check for Location
        if ($(this.vars.Location).value.trim() != '') {
            this.vars.noSearchMsg = false;
        }

        // Check for Photographer
        if ($(this.vars.Photographer).value.trim() != '') {
            this.vars.noSearchMsg = false;
        }

        // Check for Provider
        if ($(this.vars.Provider).value.trim() != '') {
            this.vars.noSearchMsg = false;
        }

        // Check for Point of View
        if ($(this.vars.PointOfView).selectedIndex > 0) {
            this.vars.noSearchMsg = false;
        }

        // Check for ImmediateAvailablility
        if ($(this.vars.ImmediateAvailablility).selectedIndex > 0) {
            this.vars.noSearchMsg = false;
        }

        return true;
    },

    appendEr: function(sErr) {
        CorbisUI.ExtendedSearch.vars._MSOErrorString += sErr;
    },

    showCalendar1: function() {
        $find(CorbisUI.ExtendedSearch.vars.MSOStartDateExtend).show();
        radioClicked('radioBetweenDiv');
        $find(CorbisUI.ExtendedSearch.vars.MSOStartDateExtend).onfocus = CorbisUI.ExtendedSearch.showCalendar1;
    },

    showCalendar2: function() {
        $find(CorbisUI.ExtendedSearch.vars.MSOEndDateExtend).show();
        radioClicked('radioBetweenDiv');
        $find(CorbisUI.ExtendedSearch.vars.MSOEndDateExtend).onfocus = CorbisUI.ExtendedSearch.showCalendar2;
    },
    hideCalendar1: function() {
        $find(CorbisUI.ExtendedSearch.vars.MSOStartDateExtend).hide();
    },

    hideCalendar2: function() {
        $find(CorbisUI.ExtendedSearch.vars.MSOEndDateExtend).hide();
    },

    hijackTheEnter: function(e) {
        if (!e) var e = window.event;
        e = e || window.event;
        var code = e.keyCode || e.which;
        if (code == 13) {

            //We don't want to auto search if a user is selecting an autocomplete term with 'enter'
            //22759
            if (!$("KeywordsAutoComplete_Window")
                || ($("KeywordsAutoComplete_Window").getStyle('display') == "none")
                || (CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete == false)) {
                CorbisUI.ExtendedSearch.combineSearchBuddy();
            }

            if ($("KeywordsAutoComplete_Window")) {
                $("KeywordsAutoComplete_Window").setStyle('display', 'none');
            }
            //Stop any further attempts by IE to submit everything on the internet with one key
            e.returnValue = false;
            return false;
        }
        else {

            //This guarantees that any changes to a search term dont register an autocomplete search
            CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete = false;

            //For accented chracters, ensure that webservice is called with the concatenated accented
            //character. We never get a keyup event for these (Alt-0233 for example)
            //Keypress comes but the entire content is not yet there in textbox.value
            var newSearchText = $(CorbisUI.SearchAutoComplete.vars.keyWordSearch).value + String.fromCharCode(code);
            if (!CorbisUI.SearchAutoComplete.isMultiByteLanguage()) {
                if (code >= '128' && code <= '255') {
                    if (CorbisUI.SearchAutoComplete.enableWebservice(newSearchText)) {
                        Corbis.Web.UI.SearchOld.AutoCompleteService.Complete(newSearchText, CorbisUI.SearchAutoComplete.vars.noOfRecord, CorbisUI.SearchAutoComplete.vars.languageCode, CorbisUI.SearchAutoComplete.OnWSRequestComplete, CorbisUI.methodFailed);
                    }
                }
            }
        }
    },

    // Determines if we should show the option applied notice on the search box
    showOptionAppliedStyle: function() {
        var getOptionsAppliedStyle = $(CorbisUI.GlobalVars.Search.showOptionsAppliedStyle);
        if (getOptionsAppliedStyle.value == 'true' || getOptionsAppliedStyle.value == 'True') {
            this.applyOptionStyles();
        }
    },

    // Applies the options applied notice on the search box
    applyOptionStyles: function() {
        try {
            CorbisUI.ExtendedSearch.vars.HiddenMSOValue.value = "UnOpened";
        }
        catch (e) { }
        $$("#Search .Keywords").addClass("optionsApplied");
        if ($type($$("#Search .Keywords").getElement('input[type=text]'))) {
            $$("#Search .Keywords").getElement('input[type=text]').setStyle('background-color', '#ffffcc');
        }
        if ($type($('optionsAppliedDiv')) == 'element') {
            $("optionsAppliedDiv").addClass("optionsAppliedDiv").setStyle("display", "block");
        }
        if ($('optionsAppliedDiv') != null) {
            $$('#Search .optionsApplied input').addClass("optionsAppliedInput");
        }
    },
    autoShowOptionsApplied: function() {
        if (CorbisUI.ExtendedSearch.vars._isResultsPage == true) {
            CorbisUI.ExtendedSearch.OpenOptionsAppliedModal();
            setTimeout(function() {
                CorbisUI.EnlargementTimerSearch.HideAppliedOptionsWindow();
            }, 10000);
        }
    },
    nextPage: function() {
        if (this.vars.currentPage && this.vars.currentPage < this.vars.totalPages)
            this.gotoPage(this.vars.currentPage + 1);
    },
    //22337
    isDetailedLayout: function(pageName) {
        var isDetailedLayout = false;
        if (CorbisUI.ExtendedSearch.getCookieValue('PagePrefs', pageName + '.aspx_Layout') == 'details') {
            isDetailedLayout = true;
        }
        return isDetailedLayout;
    },

    getCookieValue: function(name, optionName) {
        //console.log('CALLING: getCookieValue');       
        var myURI = (location.hostname).toString();
        var domain = '';
        domain = (myURI.contains(CookieDomain)) ? CookieDomain : ".corbis.pre";
        if (document.cookie.length > 0) {
            var c_start = document.cookie.indexOf(name + "=");
            if (c_start != -1) {
                c_start = c_start + name.length + 1;
                c_end = document.cookie.indexOf(";", c_start);
                if (c_end == -1) c_end = document.cookie.length;
                var cookieValue = unescape(document.cookie.substring(c_start, c_end));
                c_start = cookieValue.indexOf(optionName + "=");
                if (c_start != -1) {
                    var tempCookieValues = cookieValue.substring(c_start + optionName.length + 1).split("&");
                    return tempCookieValues[0];
                }
            }
        }
        return "";
    },

    // Start 20697 for search
    searchWindowResize: function() {
        var currentPageName;
        var totalImages = CorbisUI.DomCache.get('ProductResults').getElements('span.ProductBlock').length;
        var width = parseInt(CorbisUI.ExtendedSearch.getWidth());
        var oneImageWidth;
        var browser = navigator.appName;
        if (browser == "Netscape") {
            oneImageWidth = parseInt(193);
        }
        else {
            oneImageWidth = parseInt(186);
        }
        currentPageName = window.location.href.toLowerCase().contains('imagegroups.aspx') ? 'imagegroups' : 'SearchResults';
        var constantWidth = parseInt(230);
        var actualWidth = parseInt(width - constantWidth);
        var imagesToBeDisplayed = Math.floor(actualWidth / oneImageWidth);
        var nextImageDiv = $('nextImageDiv');
        if (parseInt(totalImages) % parseInt(imagesToBeDisplayed) == 0) {
            nextImageDiv.setStyle("display", "none");

        }
        else if (CorbisUI.ExtendedSearch.vars.currentPage && CorbisUI.ExtendedSearch.vars.currentPage < CorbisUI.ExtendedSearch.vars.totalPages && !CorbisUI.ExtendedSearch.isDetailedLayout(currentPageName)) {
            nextImageDiv.inject($('ProductResults'), 'bottom');
            nextImageDiv.setStyle("display", "inline");
        }
        else {
            nextImageDiv.setStyle("display", "none");
        }
    },

    getWidth: function() {
        var x = 0;
        if (self.innerHeight) {
            x = self.innerWidth;
        }
        else if (document.documentElement && document.documentElement.clientHeight) {
            x = document.documentElement.clientWidth;
        }
        else if (document.body) {
            x = document.body.clientWidth;
        }
        return x;
    },
    // End 20697 for search

    previousPage: function() {
        if (this.vars.currentPage && this.vars.currentPage > 1)
            this.gotoPage(this.vars.currentPage - 1);
    },

    pageNumberKeypress: function(event, element) {
        // on CR redirect to new page number
        if (event.keyCode == 13) {
            if (element.value != '' && !isNaN(element.value) && this.vars.totalPages && element.value <= this.vars.totalPages && element.value >= 1)
                this.gotoPage(element.value);
            return false;
        }
        //allow numbers and control characters only for fireefox
        else if (Browser.Engine.gecko) {
            if ((event.charCode < 48 || event.charCode > 57) && (event.keyCode == 0) && !event.ctrlKey && !event.altKey)
                return false;
        }
        //allow numbers and control characters only for others
        else if ((event.keyCode < 48 || event.keyCode > 57) && event.keyCode > 31 && event.keyCode != 127 && !event.ctrlKey && !event.altKey)
            return false;

        return (WebForm_TextBoxKeyHandler(event));
    },

    // redirects to new page
    gotoPage: function(pageNo) {
        //console.log('CALLING: gotoPage');
        if (pageNo <= this.vars.totalPages && pageNo >= 1) {
            CorbisUI.ExtendedSearch.vars._isSearching = true;
            this.ShowSearchProgIndicator();
            var newLoc = location.search;
            if (newLoc.match(/\&p\=/)) {
                newLoc = newLoc.replace(/\&p\=[0-9]+/, "&p=" + pageNo);
            }
            else {
                newLoc += "&p=" + pageNo;
            }

            // only save the page turn cookie on results from a manual search.
            if (this.vars.IsManualSearch) {
                this.SetSearchCookie(UrlEncode(newLoc.substr(1)));
            }

            location.search = newLoc;
        }
    }
}


MSOaccordion = new Class({
    Implements: [Options, Events],
    options: {
        toggler: 'div.MSO_toggler',
        elements: 'div.MSO_element'
    },
    // object references
    accordion: null, // accordian wrapper dom object
    collections: {},

    initialize: function(options) {
        if (options) this.setOptions(options);
        this.accordion = $('MSO_accordion');

        // grab needed dom objects

        var sa, dsa;
        var collectionGroups = this;

        this.accordion.getElements('div.MSO_toggler').each(function(el) {
            var elementId = el.id.toString();
            collectionGroups.collections[elementId] = { domObj: null, span: null, total: 0, checked: 0 };
            collectionGroups.collections[elementId].domObj = el;
            collectionGroups.collections[elementId].span = el.getElement('span.counts');
            collectionGroups.updateStatCounts(elementId, true);
            collectionGroups.setupMultiselectors(elementId);
            el.addEvents({
                'mouseover': function() {
                    if (!this.hasClass('MSO_togglerHover')) this.addClass('MSO_togglerHover');
                },
                'mouseout': function() {
                    if (this.hasClass('MSO_togglerHover')) this.removeClass('MSO_togglerHover');
                }
            });
        });
        
        // Added for fix of bug 19140
        $('moreSearchOptions').getElements('div.checkLblPair').each(function(el){
	        var checkboxImage = el.getElement('div.checkedImage');
	        if(!checkboxImage)
	        {
	            checkboxImage = el.getElement('div.uncheckedImage');
	        }
	        var checkboxText = checkboxImage.getParent().getNext('span');
	        checkboxText.addEvent('click',function(e){
		        this.onclick();
	        }.bindWithEvent(checkboxImage));
	        });
	        
        // setup accordion  
        this.setupAccordion();
    },

    setupMultiselectors: function(section) {
        // sa = select all link
        // dsa = deselect all link
        var sa, dsa;
        sa = this.collections[section].domObj
            .getNext('div.MSO_element')
            .getElement('a.selectAllLink');
        sa.store('section', section)
            .addEvent('click', this.selectAll.bindWithEvent(this, sa));

        dsa = this.collections[section].domObj
            .getNext('div.MSO_element')
            .getElement('a.deselectAllLink');
        dsa.store('section', section)
            .addEvent('click', this.deselectAll.bindWithEvent(this, dsa));
    },

    // select all
    selectAll: function(e, ele) {
        var section = ele.retrieve('section');
        var items = this.collections[section].domObj
                         .getNext('div.MSO_element')
                         .getElements('input[type=checkbox]');

        items.each(function(item) {
            if (!item.checked) {
                CorbisUI.ImageCb.getImageCbObject(item).setCheckState(true, false);
            }
        }, this);

        this.updateStatCounts(section);
    },

    // deselect all
    deselectAll: function(e, ele) {
        var section = ele.retrieve('section');
        var items = this.collections[section].domObj
                         .getNext('div.MSO_element')
                         .getElements('input[type=checkbox]');

        items.each(function(item) {
            if (item.checked) {
                CorbisUI.ImageCb.getImageCbObject(item).setCheckState(false, false);
            }
        }, this);

        this.updateStatCounts(section);

    },

    // checkbox click event

    checkboxClickEvent: function(e, ele) {
        this.updateStatCounts(ele.retrieve('section'));
    },

    updateStatCounts: function(section, setup) {
        var items = this.collections[section].domObj.getNext('div.MSO_element').getElements('input[type=checkbox]');
        this.collections[section].total = 0;
        this.collections[section].checked = 0;
        items.each(
                function(item) {
                    this.collections[section].total = this.collections[section].total + 1;
                    if (item.checked) {
                        this.collections[section].checked = this.collections[section].checked + 1;
                    }
                    if (setup) {
                        var decoyCheckbox = item.getParent().getPrevious();
                        var decoyCheckboxLabel = item.getParent();
                        decoyCheckbox.store('section', section);
                        item.store('section', section);
                        decoyCheckbox.addEvent('click', this.checkboxClickEvent.bindWithEvent(this, decoyCheckbox));
                        decoyCheckboxLabel.addEvent('click',this.checkboxClickEvent.bindWithEvent(this, decoyCheckbox)); // for bug 19766
                    }
                },
                this
            );
        var formatCountObject = { "0": this.collections[section].checked, "1": this.collections[section].total };
        this.collections[section].span.set('text', this.collections[section].checked + '/' + this.collections[section].total);
        this.collections[section].span.set('title', CorbisUI.MSOSearch.vars.CollectionCountStringFormat.substitute(formatCountObject));
    },

    setupAccordion: function() {
    //This conditional adjusts the location of the rounded corners for the collections accordian
    // according to which browser a MAC user is using. FF3 and Safari4 require different paddings
    //when operating on the MAC platform.
    if(Browser.Platform.mac){
        $$('div.MSO_element .elementFooter').each(function(el){el.setStyle('bottom',((Browser.Engine.gecko)?4:2));});
     }
        new Accordion(this.accordion, this.options.toggler, this.options.elements, {
            opacity: true,
            height: true,
            fixedHeight: 210,
            onActive: function(toggler, element) {
                toggler.addClass('MSO_togglerOn');
                var sibling = toggler.getNext();
                sibling.getElement('.collectionOptionsWrap').setStyle('overflow', 'hidden');
            },
            onBackground: function(toggler, element) {
                toggler.removeClass('MSO_togglerOn');
                var sibling = toggler.getNext();
                sibling.getElement('.collectionOptionsWrap').setStyle('overflow', 'hidden');
            },
            onComplete: function(toggler, element) {
                var sibling = toggler.getNext();
                $('MSO_accordion').getElements('.MSO_element').each(
                    function(el) {
                        if (el.getStyle('height') != '0px')
                            el.getElement('.collectionOptionsWrap').setStyle('overflow', 'auto');
                    });
            }
        });
    }
});


String.prototype.endsWith = function(str)
{ return (this.match(str + "$") == str) }

// for bug 22057
if (Browser.Engine.webkit) {
    //New pages have removed the div required in this function so check first
    if(CorbisUI.DomCache.get('ProductResults') != null) {
        window.addEvent('domready', function() {
            (function() {
                CorbisUI.ExtendedSearch.searchWindowResize(); 
            }).delay(200);
        });
    }
}

// For Auto Complete Funtionality

CorbisUI.SearchAutoComplete = {
    vars: {
        searchFromAutoComplete: false,
        selectedClass: 'AutoExtenderHighlight',
        notSelectedClass: 'AutoExtenderList',
        choices: null,
        noOfRecord: 10,
        languageCode: null,
        textTurnoffAutoComplete: null,
        keyWordSearch: null,
        saveContents: '',
        width: 335
    },

    initializeAutoComplete: function(varHeight) {
        var KeywordsAutoComplete_Window = new MochaUI.Window({
            id: 'KeywordsAutoComplete_Window',
            loadMethod: 'html',
            type: 'notification',
            content: 'temp1',
            x: 21,
            y: 143,
            width: CorbisUI.SearchAutoComplete.vars.width,
            height: varHeight,
            padding: { top: 0, right: 0, bottom: 0, left: 0 },
            shadowBlur: 1
        });
        $('KeywordsAutoComplete_Window').setStyle('display', 'block');
        CorbisUI.SearchAutoComplete.vars.choices = $('KeywordsAutoComplete_Window_content');
    },

    fetchResultsAutoComplete: function(e, searchText) {
        if ($('varDivAc_chkStatus')) {
            if ($('varDivAc_chkStatus').innerHTML.toLowerCase() == 'false') {
                CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete = false;
                return;
            }
        }
        var keycode;
        if (window.event) keycode = window.event.keyCode;
        else keycode = e.which;
        if (keycode == '40' || keycode == '38' || keycode == '13') {
            CorbisUI.SearchAutoComplete.textboxOnKeyUp(e);
        }
        else if (keycode == '27') {//Esc Key
            CorbisUI.SearchAutoComplete.hideWindowAutoComplete();
            CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete = false;
            return;
        }
        else {
            if (CorbisUI.SearchAutoComplete.enableWebservice(searchText)) {
                CorbisUI.ServiceManager.SearchOld.AutoCompleteService.Complete(searchText, CorbisUI.SearchAutoComplete.vars.noOfRecord, CorbisUI.SearchAutoComplete.vars.languageCode, CorbisUI.SearchAutoComplete.OnWSRequestComplete, CorbisUI.methodFailed);
            }
        }
    },

    hideWindowAutoComplete: function() {
        if ($("KeywordsAutoComplete_Window")) {
            $("KeywordsAutoComplete_Window").setStyle('display', 'none');
        }
    },

    OnWSRequestComplete: function(results) {
        if (results != null) {
            CorbisUI.SearchAutoComplete.autoCompleteListSearch(results);
        }
    },

    enableWebservice: function(searchText) {
        var languageCode = CorbisUI.SearchAutoComplete.vars.languageCode;
        if (languageCode == 'zh-CHS' || languageCode == 'ja-JP') {
            if (searchText.length == 0) {
                CorbisUI.SearchAutoComplete.hideWindowAutoComplete();
                return false;
            }
        }
        else if (searchText.length < 3) {
            CorbisUI.SearchAutoComplete.hideWindowAutoComplete();
            return false;
        }
        return true;
    },

    autoCompleteListSearch: function(results) {
        if (results.length == 0) {
            CorbisUI.SearchAutoComplete.hideWindowAutoComplete();
        }
        else {
            var searchText = $(CorbisUI.SearchAutoComplete.vars.keyWordSearch).value;
            var htmlDiv = "";
            for (var k = 0; k < results.length; k++) {
                var formattedText = CorbisUI.SearchAutoComplete.formatBold(results[k]);
                htmlDiv += "<div id='Name" + k.toString() + "' class='AutoExtenderList' onclick='CorbisUI.SearchAutoComplete.autoClick(this);' onmouseOver='CorbisUI.SearchAutoComplete.autoMouseOver(this);' onmouseOut='CorbisUI.SearchAutoComplete.autoMouseOut(this);' ><span class='AutoExtenderListSpan'>" + formattedText.toString() + "</span></div>";
            }
            var divTurnOff = "<div id='divTurnoffAutoComplete' style='display:block;'>" +
                "<div id='divAnchorTurnOff'>" +
                "<a id='anchorTurnoffAutoComplete' onclick='CorbisUI.SearchAutoComplete.clickTurnOff();'>" +
              $(CorbisUI.SearchAutoComplete.vars.textTurnoffAutoComplete).innerHTML + "</a>" + "</div></div>";
            htmlDiv = htmlDiv + divTurnOff;

            var varHeight = 0;
            var varHeightIe = 0;
            var varHeightMoz = 0;
            varHeightIe = 35 + (results.length * 16);
            varHeightMoz = 35 + (results.length * 18);
            if (navigator.userAgent.indexOf('MSIE') != -1) {
                varHeight = varHeightIe;
            }
            else {
                varHeight = varHeightMoz;
            }
            if (!$("KeywordsAutoComplete_Window")) {
                CorbisUI.SearchAutoComplete.initializeAutoComplete(varHeight);
            }
            else {
                $('KeywordsAutoComplete_Window').retrieve('instance').resize({
                    width: CorbisUI.SearchAutoComplete.vars.width, 
                    height: varHeight, 
                    centered: false 
                });
            }

            $('KeywordsAutoComplete_Window_content').innerHTML = htmlDiv;
            $('KeywordsAutoComplete_Window_content').setStyle('margin-top', '10px');
            $('KeywordsAutoComplete_Window').setStyle('display', 'block');
            var valueOpacity = 9.5;
            if (navigator.appVersion.contains('MSIE 6')) {
                $('KeywordsAutoComplete_Window').setStyle('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(' + valueOpacity * 10 + ',sizingMethod = scale)');
                $('KeywordsAutoComplete_Window').setStyle('margin-top', '30px');
                $('KeywordsAutoComplete_Window').setStyle('top', '170px');
            }
            else {
                $('KeywordsAutoComplete_Window').style.opacity = valueOpacity / 10;
                $('KeywordsAutoComplete_Window').style.filter = 'alpha(opacity=' + valueOpacity * 10 + ')';
            }
            $('KeywordsAutoComplete_Window_content').style.backgroundColor = "#F7F6F4";
        }
    },
    autoClick: function(obj) {
        var index = CorbisUI.SearchAutoComplete.getSelectedforKeyUp();
        var choices = CorbisUI.SearchAutoComplete.vars.choices;
        var hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;
        if (!hasInnerText)
            $(CorbisUI.SearchAutoComplete.vars.keyWordSearch).value = choices.childNodes[index].textContent;
        else
            $(CorbisUI.SearchAutoComplete.vars.keyWordSearch).value = choices.childNodes[index].innerText;
        CorbisUI.SearchAutoComplete.hideWindowAutoComplete();
        //22759
        CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete = true;
        //22846
        CorbisUI.ExtendedSearch.showSearchFlyout();
    },
    autoMouseOver: function(obj) {
        $(obj).addClass('AutoExtenderHighlight');
        $(obj).removeClass('AutoExtenderList');
    },

    autoMouseOut: function(obj) {
        $(obj).addClass('AutoExtenderList');
        $(obj).removeClass('AutoExtenderHighlight');
    },

    clickTurnOff: function() {
        var result = false;
        Corbis.Web.UI.SearchOld.SearchScriptService.displayOptionsAutoComplete(result, CorbisUI.SearchAutoComplete.clickTurnOffInner, CorbisUI.methodFailed);
        
        // disable auto complete on menu
        try {
            CorbisUI.SearchMVC.userDisplayOptions.autocomplete = false;
        } catch(e) {}
    },

    formatBold: function(str) {
        var searchText = $(CorbisUI.SearchAutoComplete.vars.keyWordSearch).value;
        var lenSearchText = searchText.length;
        var substr = str.substring(lenSearchText, str.length);

        //22759
        var finalString = str.substring(0, 1).toUpperCase() + str.substring(1, searchText.length) + "<span class='autoCompleteBold'>" + substr + "</span>";
        return finalString;
    },

    textboxOnKeyUp: function(evt) {
        var keycode;
        var choices = CorbisUI.SearchAutoComplete.vars.choices;
        if (window.event) keycode = window.event.keyCode;
        else if (evt) keycode = evt.which;

        if (keycode == '38' || keycode == '40') {
            CorbisUI.SearchAutoComplete.checkUpDownArrows(keycode);
        }
        else if (keycode == '13') {
            var index = CorbisUI.SearchAutoComplete.getSelectedforKeyUp();
            if (index >= 0) {
                CorbisUI.SearchAutoComplete.autoClick($(choices.childNodes[index]));
            }
            else {
                //22897
                var searchText = $(CorbisUI.SearchAutoComplete.vars.keyWordSearch).value;
                if (navigator.appName == 'Netscape' && CorbisUI.SearchAutoComplete.enableWebservice(searchText) && CorbisUI.SearchAutoComplete.vars.saveContents != searchText) {
                    Corbis.Web.UI.SearchOld.AutoCompleteService.Complete(searchText, CorbisUI.SearchAutoComplete.vars.noOfRecord, CorbisUI.SearchAutoComplete.vars.languageCode, CorbisUI.SearchAutoComplete.OnWSRequestComplete, CorbisUI.methodFailed);
                }
            }
        }
    },

    autoCompleteKeyDown: function(searchText) {
        CorbisUI.SearchAutoComplete.vars.saveContents = searchText;
    },

    checkUpDownArrows: function(characterCode) {
        var choices = CorbisUI.SearchAutoComplete.vars.choices;
        if (choices.style.display == "none") return;
        var selIndex = CorbisUI.SearchAutoComplete.getSelectedforKeyUp();
        var children = CorbisUI.SearchAutoComplete.vars.choices.childNodes;

        if (selIndex == -1) {
            if (characterCode == 38) {
                CorbisUI.SearchAutoComplete.setSelected(0, children.length - 1);
            } else if (characterCode == 40) {
                CorbisUI.SearchAutoComplete.setSelected(0, 0);
            }
        }
        else if (characterCode == 38)// Up Key
        {
            if (selIndex >= 1) {
                CorbisUI.SearchAutoComplete.setSelected(selIndex, selIndex - 1);
            } else if (children.length > 0) {
                CorbisUI.SearchAutoComplete.setSelected(selIndex, children.length - 2);
            }
        }
        else if (characterCode == 40) // Down Key
        {
            if (selIndex + 1 < children.length - 1) {
                CorbisUI.SearchAutoComplete.setSelected(selIndex, selIndex + 1);
            } else {
                CorbisUI.SearchAutoComplete.setSelected(selIndex, 0);
            }
        }
    },
    // Unselects div at oldIndex while selecting newIndex
    setSelected: function(oldIndex, newIndex) {
        var children = CorbisUI.SearchAutoComplete.vars.choices.childNodes;
        if (children) {
            children[oldIndex].className = CorbisUI.SearchAutoComplete.vars.notSelectedClass;
            children[newIndex].className = CorbisUI.SearchAutoComplete.vars.selectedClass;
            CorbisUI.SearchAutoComplete.vars.searchFromAutoComplete = true;
        }
    },
    // Returns the index of the div that is selected.  Returns -1 if nothing is selected
    getSelectedforKeyUp: function() {
        var choices = CorbisUI.SearchAutoComplete.vars.choices;
        var choiceStr = "";
        if (choices) {
            var size = (choices.childNodes == null) ? 0 : choices.childNodes.length;
            for (var i = 0; i < size; i++) {
                choiceStr += choices.childNodes[i].className + "\n";
                if (choices.childNodes[i].className == CorbisUI.SearchAutoComplete.vars.selectedClass) return i;
            }
        }
        return -1;
    },

    clickTurnOffInner: function(result) {
        CorbisUI.SearchAutoComplete.hideWindowAutoComplete();
        if ($('varDivAc_chkStatus')) {
            $('varDivAc_chkStatus').innerHTML = "false";
        }
        // Set chkBox
        if ($('moreDisplayOptionsWindow')) {
            var var_AC = $('moreDisplayOptionsWindow').getElement('div[id$=chk_AutoComplete]');
            if (var_AC) {
                CorbisUI.ImageCb.getImageCbObject(var_AC).setCheckState(false, false);
            }
        }
    },

    isMultiByteLanguage: function() {
        var languageCode = CorbisUI.SearchAutoComplete.vars.languageCode;
        return languageCode == 'zh-CHS' || languageCode == 'ja-JP';
    }
}

//End: /Scripts/ExtendedSearch.js
//Begin: /scripts/ImageRadio.js

function radioClicked(parent)
{
    parent =  $(parent);
    var rb = parent.getElement('input[type=radio]');
    $('moreSearchOptions').getElements('input[name=' + rb.getProperty('name') + ']').each(function(r){
                r.checked = false;
                r.getParent().getParent().getElement('img').setProperty('src', '/images/radio_off.png');
            });
    var img = parent.getElement('img');
    rb.checked = true;
    img.setProperty('src', '/images/radio_on.png');
}

function setRadioNoEvent(parent, checked)
{
    parent = $(parent);
    var rb = parent.getElement('input');
    var img = parent.getElement('img');
    rb.checked = checked;
    img.setProperty('src', checked ? '/images/radio_on.png' : '/images/radio_off.png');
}

function getRadioState(parent)
{
    parent = $(parent);
    var rb = parent.getElement('input');
    return rb.checked;
}
//End: /scripts/ImageRadio.js
//Begin: /scripts/glassbutton.js

function setGlassButtonDisabled(btn, disable) {
    btn = $(btn);
  
    //console.log("glassbutton: " + btn.id + " disabled=" + disable);
	var center = btn.getElement('input');
	var right = btn.getElement('span');
	btn.disabled = disable;
   	center.disabled = disable;
	right.disabled = disable;
	var tip = btn.getProperty('title');

	if (disable) {

	    if (tip != null) {
	        glassButtonTooltipFix(btn, tip, true); 
	    }
		btn.addClass('DisabledGlassButton');
   		center.addClass('DisabledGlassButton');
   		right.addClass('DisabledGlassButton');

   		 
	}
	else {

	   if (tip != null) {
	        glassButtonTooltipFix(btn, tip, false);
	    }
		btn.removeClass('DisabledGlassButton');
        center.removeClass('DisabledGlassButton');
        right.removeClass('DisabledGlassButton');
        if (btn.id.contains('glassBtnId')) {
            if (btn.getParent() && btn.getParent().getElement('img'))
                btn.getParent().getElement('img').addClass('hdn');
        }
    }
}
function setOutlineButtonDisabled(btn, disable)
{
	btn = $(btn);
	var center = btn.getElement('span .Center');
	var centerLink = btn.getElement('span .Center a');
	var right = btn.getElement('span');
	btn.disabled = disable;
   	center.disabled = disable;
   	centerLink.disabled = disable;
	right.disabled = disable;
	var tip = btn.getProperty('title');

	if (disable) {

		btn.addClass('DisabledGlassButton');
		centerLink.addClass('DisabledGlassButton');
   		center.addClass('DisabledGlassButton');    		
		right.addClass('DisabledGlassButton');
	}
	else {

		btn.removeClass('DisabledGlassButton');
        center.removeClass('DisabledGlassButton');
        centerLink.removeClass('DisabledGlassButton');
		right.removeClass('DisabledGlassButton');
	}
}

function passClickToChild(btn)
{
    btn = $(btn);
	var submit = btn.getElement('input');
	try
	{
	    submit.onclick;
	    //submit.click();
	}
	catch(er)
	{
		submit.click();
    }

}

function glassButtonTooltipFix(el, tip, showtip) {

    if (showtip) {
        el.addClass('relative');
        if (!el.getElement('div.disabledButtonTip')) {
            new Element('div')
                .set('text', tip)
                .addClass('disabledButtonTip')
                .setStyles({
                    position: 'absolute',
                    top: 0,
                    left: 0,
                    right: 0,
                    bottom: 0,
                    background: 'black',
                    opacity: 0.01
                })
                .inject(el);
        }
    } else {
        if (el.getElement('div.disabledButtonTip'))
            el.getElement('div.disabledButtonTip').destroy();
    }

}

// -1: disable forever
// 0: do not disable it
function setGlassButtonDisabledWithinPeriod(btn, delayReset) {
    //display progress
 
    btn = $(btn).getParent().getParent();
    if (btn.getParent().getElement('img') && btn.id.contains('glassBtnId'))
        btn.getParent().getElement('img').removeClass('hdn');
    if (delayReset == 0)
        
        return;
    (function() { setGlassButtonDisabled(btn, true); }).delay(1);
    if (delayReset == -1) return;
   
    setTimeout("setGlassButtonDisabled('" + btn.id.toString() + "', false);", delayReset);
}

//End: /scripts/glassbutton.js
//Begin: /scripts/ImageCheckbox.js

if (typeof (CorbisUI) == 'undefined') {
    CorbisUI = {};
}

CorbisUI.ImageCb = {
    getImageCbObject: function(element) {
        if ($(element)) {
            element = $(element);
            var imageCbObject = element.retrieve('object');
            if (imageCbObject) {
                return imageCbObject;
            }
            else {
                return new CorbisUI.ImageCb.Checkbox(element);
            }
        }
    }
};

CorbisUI.ImageCb.Checkbox = new Class({
    control: null,
    image: null,
    checkbox: null,
    disabled: false,

    initialize: function(item) {
        item = $(item);

        if (item.hasClass('imageCheckbox')) {
            this.control = item;
            this.image = item.getElement('div');
            this.checkbox = item.getElement('input');
        }
        else {
            this.control = item.getParent('div.imageCheckbox');

            if (item.tagName.toLowerCase() == 'input') {
                this.checkbox = item;
                this.image = this.control.getElement('div');
            }
            else {
                this.checkbox = this.control.getElement('input');
                this.image = item
            }
        }

        this.disabled = this.control.hasClass('disabled');

        this.control.store('object', this);
        this.image.store('object', this);
        this.checkbox.store('object', this);
    },

    toggleCheckbox: function(fireEvent) {
        if (!this.disabled) {
            this.checkbox.checked = !this.checkbox.checked;
            if (fireEvent) {
                this.checkbox.onclick();
            }
            else {
                this.setImageDisplay();
            }
        }
    },

    setImageDisplay: function() {
        if (!this.disabled) {
            if (this.checkbox.checked) {
                this.image.removeClass('uncheckedImage');
                if (!this.image.hasClass('checkedImage')) this.image.addClass('checkedImage');
            }
            else {
                this.image.removeClass('checkedImage');
                if (!this.image.hasClass('uncheckedImage')) this.image.addClass('uncheckedImage');
            }
        }
    },

    setCheckState: function(checkState, fireEvent) {
        if (!this.disabled) {
            this.checkbox.checked = checkState;
            if (fireEvent) {
                this.checkbox.onclick();
            }
            else {
                this.setImageDisplay();
            }
        }
    },

    setCbEnabled: function(enabled) {
        if (enabled) {
            this.control.removeClass('disabled');
        }
        else {
            if (!this.control.hasClass('disabled')) this.control.addClass('disabled');
        }
        this.disabled = !enabled;
    },

    getCheckedState: function() {
        return this.checkbox.checked;
    },

    getCheckboxValue: function() {
        return this.checkbox.value;
    }
});

//Retain the following 2 functions to reduce size output to MSO
function toggleImg(checkbox) {
    CorbisUI.ImageCb.getImageCbObject(checkbox).setImageDisplay();
}

//set function to return false to prevent event bubbling and wasting time.
function toggleCb(image) {
    CorbisUI.ImageCb.getImageCbObject(image).toggleCheckbox(true);
    return false;
}

//End: /scripts/ImageCheckbox.js
//Begin: /scripts/TextIconButton.js

function setTextIconButtonDisabled(span, disabled)
{
    span = $(span);
    var a = span.getElement('a');
    if (disabled && !span.hasClass('disabled'))
    {
        span.addClass('disabled');
        a.addClass('disabled');
    }
    else if (!disabled && span.hasClass('disabled'))
    {
        span.removeClass('disabled');
        a.removeClass('disabled');
    }
}
function sendClickToAnchor(span)
{
	span = $(span);
	var a = span.getElement('a');
	if (!span.hasClass('disabled')) {
	    var execScript =  a.getProperty('exec');
	    execScript = execScript.replace(/THIS/i, "'" + a.id + "'");
	    eval(execScript);
	}
}
//End: /scripts/TextIconButton.js
//Begin: /Scripts/validation.js

/*
Class: FormCheck
Performs different tests on forms and indicates errors.
		
Usage:
Works with these types of fields :
- input (text, radio, checkbox)
- textarea
- select
		
You just need to add a specific class to each fields you want to check. 
For example, if you add the class
(code)
validate['required','length[4, -1]','differs[email]','digit']
(end code)
the value's field must be set (required) with a minimum length of four chars (4, -1), 
must differs of the input named email (differs[email]), and must be digit. 
		
You can perform check during the datas entry or on the submit action, shows errors as tips or in a div before or after the field, 
show errors one by one or all together, show a list of all errors at the top of the form, localize error messages, add new regex check, ...
		
The layout is design only with css. Now I added a hack to use transparent png with IE6, so you can use png images in formcheck.css (works only for theme, so the file must be named formcheck.css). It can also works with multiple forms on a single html page.
The class supports now internationalization. To use it, simply specify a new <script> element in your html head, like this : <script type="text/javascript" src="formcheck/lang/fr.js"></script>.

If you add the class
(code)
validate['submit']
(end code)
to an element like an anchor (or anything else), this element will act as a submit button.
		
N.B. : you must load the language script before the formcheck and this method overpass the old way. You can create new languages following existing ones. You can otherwise still specifiy the alerts' strings when you initialize the Class, with options.
If you don't use a language script, the alert will be displayed in english.
	
Test type:
You can perform various test on fields by addind them to the validate class. Be careful to *not use space chars*. Here is the list of them.
			
required 					- The field becomes required. This is a regex, you can change it with class options.
alpha 						- The value is restricted to alphabetic chars. This is a regex, you can change it with class options.
alphanum 					- The value is restricted to alphanumeric characters only. This is a regex, you can change it with class options.
nodigit 					- The field doesn't accept digit chars. This is a regex, you can change it with class options.
digit 						- The value is restricted to digit (no floating point number) chars, you can pass two arguments (f.e. digit[21,65]) to limit the number between them. Use -1 as second argument to not set a maximum.
number 						- The value is restricted to number, including floating point number. This is a regex, you can change it with class options.
email 						- The value is restricted to valid email. This is a regex, you can change it with class options.
phone 						- The value is restricted to phone chars. This is a regex, you can change it with class options.
url: 						- The value is restricted to url. This is a regex, you can change it with class options.
confirm 					- The value has to be the same as the one passed in argument. f.e. confirm[password].
differs 					- The value has to be diferent as the one passed in argument. f.e. differs[user].
length 						- The value length is restricted by argument (f.e. length[6,10]). Use -1 as second argument to not set a maximum.
		
Parameters:
When you initialize the class with addEvent, you can set some options. If you want to modify regex, you must do it in a hash, like for display or alert. You can also add new regex check method by adding the regex and an alert with the same name.
		
Required:
			
form_id - The id of the formular. This is required.
			
Optional:
			
submitByAjax 			- you can set this to true if you want to submit your form with ajax. You should use provided events to handle the ajax request (see below). By default it is false.
ajaxResponseDiv 		- id of element to inject ajax response into (can also use onAjaxSuccess). By default it is false.
ajaxEvalScripts 		- use evalScripts in the Request response. Can be true or false, by default it is false.
onAjaxRequest 			- Function to fire when the Request event starts.
onAjaxSuccess 			- Function to fire when the Request receives .  Args: response [the request response] - see Mootools docs for Request.onSuccess.
onAjaxFailure 			- Function to fire if the Request fails.
			
tipsClass 				- The class to apply to tipboxes' errors. By default it is 'fc-tbx'.
errorClass 				- The class to apply to alertbox (not tips). By default it is 'fc-error'.
fieldErrorClass 		- The class to apply to fields with errors, except for radios. You should also turn on  options.addClassErrorToField. By default it is 'fc-field-error'
		
Display:
This is a hash of display settings. in here you can modify.
			
showErrors 				- 0 : onSubmit, 1 : onSubmit & onBlur, by default it is 1.
errorsLocation 			- 1 : tips, 2 : before, 3 : after, by default it is 1.
indicateErrors 			- 0 : none, 1 : one by one, 2 : all, by default it is 1.
keepFocusOnError 		- 0 : normal behaviour, 1 : the current field keep the focus as it remain errors. By default it is 0.
checkValueIfEmpty 		- 0 : When you leave a field and you have set the showErrors option to 1, the value is tested only if a value has been set. 1 : The value is tested  in any case.  By default it is 1.
addClassErrorToField 	- 0 : no class is added to the field, 1 : the options.fieldErrorClass is added to the field with an error (except for radio). By default it is 0.

fixPngForIe 			- 0 : do nothing, 1 : fix png alpha for IE6 in formcheck.css. By default it is 1.
replaceTipsEffect 		- 0 : No effect on tips replace when we resize the broswer, 1: tween transition on browser resize;
closeTipsButton 		- 0 : the close button of the tipbox is hidden, 1 : the close button of the tipbox is visible. By default it is 1.
flashTips 				- 0 : normal behaviour, 1 : the tipbox "flash" (disappear and reappear) if errors remain when the form is submitted. By default it is 0.
tipsPosition 			- 'right' : the tips box is placed on the right part of the field, 'left' to place it on the left part. By default it is 'right'.
tipsOffsetX 			- Horizontal position of the tips box (margin-left), , by default it is 100 (px).
tipsOffsetY				- Vertical position of the tips box (margin-bottom), , by default it is -10 (px).
			
listErrorsAtTop 		- List all errors at the top of the form, , by default it is false.
scrollToFirst 			- Smooth scroll the page to first error and focus on it, by default it is true.
fadeDuration 			- Transition duration (in ms), by default it is 300.
		
Alerts:
This is a hash of alerts settings. in here you can modify strings to localize or wathever else. %0 and %1 represent the argument.
			
required 				- "This field is required."
alpha 					- "This field accepts alphabetic characters only."
alphanum 				- "This field accepts alphanumeric characters only."
nodigit 				- "No digits are accepted."
digit 					- "Please enter a valid integer."
digitmin 				- "The number must be at least %0"
digitltd 				- "The value must be between %0 and %1"
number 					- "Please enter a valid number."
email 					- "Please enter a valid email: <br /><span>E.g. yourname@domain.com</span>"
phone 					- "Please enter a valid phone."
url 					- "Please enter a valid url: <br /><span>E.g. http://www.domain.com</span>"
confirm 				- "This field is different from %0"
differs 				- "This value must be different of %0"
length_str 				- "The length is incorrect, it must be between %0 and %1"
length_fix 				- "The length is incorrect, it must be exactly %0 characters"
lengthmax 				- "The length is incorrect, it must be at max %0"
lengthmin 				- "The length is incorrect, it must be at least %0"
checkbox 				- "Please check the box"
radios 					- "Please select a radio"
select 					- "Please choose a value"
		
Example:
You can initialize a formcheck (no scroll, custom classes and alert) by adding for example this in your html head this code :
		
(code)
<script type="text/javascript">
window.addEvent('domready', function() {
var myCheck = new CorbisFormValidator('form_id', {
tipsClass : 'tips_box',
display : {
scrollToFirst : false
},
alerts : {
required : 'This field is ablolutely required! Please enter a value'
}
})
});
</script>
(end code)
	
About:
formcheck.js v.1.4rc5 for mootools v1.2 - 09 / 2008
		
by Floor SA (http://www.floor.ch) MIT-style license
		
Created by Luca Pillonel, last modified by Luca Pillonel
		
Credits:
This class was inspired by fValidator by Fabio Zendhi Nagao (http://zend.lojcomm.com.br)	
*/


// TODO: make this part of the CorbisUI namespace. On request price it throws errors though.
var CorbisFormValidator = new Class({

    Implements: [Options, Events],
    container: false,
    errorDiv: false,
    errorTarget: false,
    options: {
        tipsClass: 'displayNone',
        fieldErrorClass: 'Error',
        fieldErrorClass: 'fc-field-error', //error class for elements
        submitForm: false, // button to click on submit
        containerID: 'ModalPopupContent',
        submitByAjax: false, 			//false : standard submit way, true : submit by ajax
        ajaxResponseDiv: false, 		//element to inject ajax response into (can also use onAjaxSuccess) [cronix]
        ajaxEvalScripts: false, 		//use evalScripts in the Request response [cronix]
        ajaxUrl: false,
        ajaxAsync: false,
        ajaxData: null,
        onAjaxRequest: $empty, 			//Function to fire when the Request event starts 
        onAjaxSuccess: $empty, 			//Function to fire when the Request receives .  Args: response [the request response] - see Mootools docs for Request.onSuccess
        onAjaxFailure: $empty, 			//Function to fire if the Request fails
        useStandardAjaxBehavior: false, // useStandardAjaxBehavior makes it so that we return "success" if the operation completed
        // and this script will auto-close. Otherwise, it assumes the response is a localized error
        // string that it will display in the error section
        successScript: false, // script string that closes the modal.
        failScript: false,
        resizeScript: false,
        useSubmitBehavior: false,
        highlightField: false,
        focusOnFirstElement: true,

        display: {
            indicateErrors: 2,
            listErrorsAtTop: true,
            scrollToFirst: false,
            addClassErrorToField: 2,
            showErrors: 1,
            errorsLocation: 1,
            keepFocusOnError: 0,
            checkValueIfEmpty: 1,
            fixPngForIe: 1,
            replaceTipsEffect: 1,
            flashTips: 0,
            closeTipsButton: 1,
            tipsPosition: "right",
            tipsOffsetX: -45,
            tipsOffsetY: 0,
            fadeDuration: 300,
            rowHiliteClass: 'ErrorHighlight'
        },

        alerts: {
            required: "This field is required.",
            alpha: "This field accepts alphabetic characters only.",
            alphanum: "This field accepts alphanumeric characters only.",
            cvv: "Please enter a valid credit card verification Number.",
            nodigit: "No digits are accepted.",
            digit: "Please enter a valid integer.",
            digitltd: "The value must be between %0 and %1",
            number: "Please enter a valid number.",
            email: "Please enter a valid email.",
            phone: "Please enter a valid phone.",
            url: "Please enter a valid url.",

            confirm: "This field is different from %0",
            differs: "This value must be different of %0",
            length_str: "The length is incorrect, it must be between %0 and %1",
            length_fix: "The length is incorrect, it must be exactly %0 characters",
            lengthmax: "The length is incorrect, it must be at max %0",
            lengthmin: "The length is incorrect, it must be at least %0",
            checkbox: "Please check the box",
            radios: "Please select a radio",
            select: "Please choose a value",
            wordcount: "Please enter more than one and up to %0 words"
        },
        regexp: {
            required: /[^.*]/,
            alpha: /^[a-z ._-]+$/i,
            alphanum: /^[a-z0-9 ._-]+$/i,
            cvv: /^\d{3,4}$/,
            digit: /^[-+]?[0-9]+$/,
            uszip: /(^\d{5}$)|(^\d{5}-\d{4}$)/,
            nodigit: /^[^0-9]+$/,
            number: /^[-+]?\d*\.?\d+$/,
            email: /^[\w\.-]+@([\w-]+\.)+[a-z]{2,4}$/i, 
            phone: /^[\d\-\.\+\(\)\s]{6,24}$/,
            url: /^(http|https|ftp)\:\/\/[a-z0-9\-\.]+\.[a-z]{2,3}(:[a-z0-9]*)?\/?([a-z0-9\-\._\?\,\'\/\\\+&amp;%\$#\=~])*$/i
        }
    },

    /*
    Constructor: initialize
    Constructor
	
		Add event on formular and perform some stuff, you now, like settings, ...
    */
    initialize: function(form, options) {
        //console.log('CALLING: CorbisFormValidator.initialize');
        if (this.form = $(form)) {
            this.form.isValid = true;
            this.regex = ['length'];
            this.setOptions(options);
            this.container = $(this.options.containerID);
            this.errorDiv = $(this.options.containerID).getElement('div.ValidationSummary');
            this.errorTarget = $(this.options.containerID).getElement('div.ValidationSummary ul');
            //internalization
            if (typeof (formcheckLanguage) != 'undefined') this.options.alerts = formcheckLanguage;

            this.validations = [];
            this.alreadyIndicated = false;
            this.firstError = false;

            var regex = new Hash(this.options.regexp);
            regex.each(function(el, key) {
                this.regex.push(key);
            }, this);
            var elementsToValidate = this.container.getElements("*[validate*=]");

            elementsToValidate.each(function(el) {
                //console.log('reg: ' + el.id + ', ' + this.container.id);
                el.validation = [];
                var validators = el.getProperty("validate").split(';');
                for (var i = 0; i < validators.length; i++) {
                    el.validation.push(validators[i].replace(/\s/g, ''));
                }
                this.register(el);
            }, this);

            if (this.options.useSubmitBehavior)
                this.form.addEvents({
                    "submit": this.validateAll.bind(this)
                });

            if (this.options.display.fixPngForIe) this.fixIeStuffs();
            document.addEvent('mousewheel', function() {
                this.isScrolling = false;
            } .bind(this));


            var enterKey = function(e) {
                e = e || window.event;
                var code = e.keyCode || e.which || e.code;
                if (code == 13) {
                    if (e.target && e.target.id.endsWith('username') && $('ctl00_mainContent_password') != null) {
                        setTimeout('$("ctl00_mainContent_password").focus()', 100);
                        e.stop();
                        e.returnValue = false;
                        return;
                    }

                    e.stop();
                    if (!(e.target && e.target.id == "ctl00_mainContent_projectName" && e.target.ownerDocument.location.toString().toLowerCase().indexOf('quickpic.aspx') >= 0)) {
                        _isEnterKey = true;
                        setTimeout('_isEnterKey = false', 200);
                        this.validateAll(e);
                    }
                    e.returnValue = false;
                    return false;
                }
            };
            var enterKeyHandler = enterKey.bindWithEvent(this);
            $(this.options.containerID).getElements('input[type=text]').addEvents({ 'keydown': enterKeyHandler });

            try {
                if (this.options.focusOnFirstElement)
                    if (elementsToValidate[0] != null)
                        elementsToValidate[0].focus();
            } catch (Error) {
                return;
            }

        }
    },

    /*
    Function: register
    Private method
		
		Add listener on fields
    */
    register: function(el) {
        //console.log('CALLING: CorbisFormValidator.register');
        this.validations.push(el);
        //console.log(String.format("register: {0}",el));
        el.errors = [];
        if (el.validation[0] == 'submit') {
            el.addEvent('click', function(e) {
                this.validateAll(e);
            } .bind(this));
            return true;
        }

        //errors onblur code
        //        if (!this.isChildType(el)) el.addEvent('blur', function(e) {
        //            if ((el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value)) this.manageError(el, 'blur');
        //        } .bind(this))
        //We manage errors on radio
        else if (this.isChildType(el)) {
            //We get all radio from the same group and add a blur option
            var nlButtonGroup = this.container.getElements('input[name="' + el.getProperty("name") + '"]');
            nlButtonGroup.each(function(radio) {
                radio.addEvent('blur', function() {
                    if ((el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value)) this.manageError(el, 'click');
                } .bind(this))
            }, this);
        }
    },

    /*
    Function: validate
    Private method
		
		Dispatch check to other methods
    */
    validate: function(el) {
        //console.log('CALLING: CorbisFormValidator.validate');
        el.errors = [];
        el.isOk = true;
        //On valide l'lment qui n'est pas un radio ni checkbox
        el.validation.each(function(rule) {
            if (!el.isOk) {
                return;
            }
            if (this.isChildType(el)) {
                if (!this.validateGroup(el)) {
                    el.isOk = false;
                }
            } else {
                var ruleArgs = [];

                if (rule.match(/^.+\[/)) {
                    var ruleMethod = rule.split('[')[0];
                    ruleArgs = eval(rule.match(/^.+(\[.+\])$/)[1].replace(/([A-Z\.]+)/i, "'$1'"));
                } else var ruleMethod = rule;

                if (this.regex.contains(ruleMethod) && el.get('tag') != "select") {
                    if (!this.validateRegex(el, ruleMethod, ruleArgs)) {
                        el.isOk = false;
                    }
                }
                if (ruleMethod == 'email-m') {
                    if (!this.validateMultipleEmails(el, ruleArgs)) {
                        el.isOk = false;
                    }
                }
                //console.log('-----> ' + ruleMethod);
                if (ruleMethod == 'wordcount' && el.get('tag') == "textarea") {
                    if (!this.validateWordCount(el, ruleArgs)) {
                        el.isOk = false;
                    }
                }
                if (ruleMethod.indexOf('custom') != -1) {
                    if (!this.validateCustom(el, ruleArgs, ruleMethod)) {
                        el.isOk = false;
                    }
                }
                if (ruleMethod.indexOf('popmessage') != -1) {
                    if (!this.validatePopMessage(el, ruleArgs, ruleMethod)) {
                        el.isOk = false;
                    }
                }
                if (ruleMethod == 'confirm') {
                    if (!this.validateConfirm(el, ruleArgs)) {
                        el.isOk = false;
                    }
                }
                if (ruleMethod == 'differs') {
                    if (!this.validateDiffers(el, ruleArgs)) {
                        el.isOk = false;
                    }
                }
                if ((el.get('tag') == "select" && ruleMethod.indexOf('custom') == -1) || (el.type == "checkbox" && ruleMethod == 'required')) {
                    if (!this.simpleValidate(el)) {
                        el.isOk = false;
                    }
                }
            }

        }, this);

        if (el.isOk) return true;
        else return false;
    },

    /*
    Function: simpleValidate
    Private method
		
		Perform simple check for select fields and checkboxes
    */
    simpleValidate: function(el) {
        //console.log('CALLING: CorbisFormValidator.simpleValidate');
        if (el.get('tag') == 'select' && el.selectedIndex != -1 && el.options[el.selectedIndex].text == el.options[0].text) {
            msg = el.getProperty('select_message') ?
                el.getProperty('id') + '|select|' +
                el.getProperty('select_message') :
                this.options.alerts.select;
            el.errors.push(msg);
            return false;
        }
        else if (el.type == "checkbox" && !el.checked) {
            msg = el.getProperty('checkbox_message') ?
                    el.getProperty('id') + '|checkbox|' +
                    el.getProperty('checkbox_message') :
                    this.options.alerts.checkbox;
            el.errors.push(msg);
            return false;
        }
        return true;
    },

    /*
    Function: validateRegex
    Private method
		
		Perform regex validations
    */
    validateRegex: function(el, ruleMethod, ruleArgs) {
        //console.log('CALLING: CorbisFormValidator.validateRegex');
        //console.log('el');
        //console.log(el);
        //console.log('ruleMethod: ' + ruleMethod);
        //console.log('ruleArgs: ' + ruleArgs.toSource());
        var msg = "";
        if (ruleArgs[1] && ruleMethod == 'length') {
            if (ruleArgs[1] == -1) {
                this.options.regexp.length = new RegExp("^[\\s\\S]{" + ruleArgs[0] + ",}$");
                msg = el.getProperty('lengthmin_message') ?
                    el.getProperty('id') + '|lengthmin|' +
                    el.getProperty('lengthmin_message') :
                    this.options.alerts.lengthmin.replace("%0", ruleArgs[0]);
            } else if (ruleArgs[0] == ruleArgs[1]) {
                this.options.regexp.length = new RegExp("^[\\s\\S]{" + ruleArgs[0] + "}$");
                msg = el.getProperty('length_fix_message') ? el.getProperty('length_fix_message') :
                    this.options.alerts.length_fix.replace("%0", ruleArgs[0]);
            } else {
                this.options.regexp.length = new RegExp("^[\\s\\S]{" + ruleArgs[0] + "," + ruleArgs[1] + "}$");
                msg = el.getProperty('length_str_message') ?
                    el.getProperty('id') + '|length_str|' +
                    el.getProperty('length_str_message') :
                    this.options.alerts.length_str.replace("%0", ruleArgs[0]).replace("%1", ruleArgs[1]);
            }
        } else if (ruleArgs[0] && ruleMethod == 'length') {
            this.options.regexp.length = new RegExp("^.{0," + ruleArgs[0] + "}$");
            msg = el.getProperty('lengthmax_message') ? el.getProperty('lengthmax_message') :
                    this.options.alerts.lengthmax.replace("%0", ruleArgs[0]);
        } else {
            msg = el.getProperty(ruleMethod + '_message') ?
                el.getProperty('id') + '|' + ruleMethod + '|' +
                el.getProperty(ruleMethod + '_message') :
            this.options.alerts[ruleMethod];
        }
        if (ruleArgs[1] && ruleMethod == 'digit') {
            var regres = true;
            if (!this.options.regexp.digit.test(el.value)) {
                el.errors.push(this.options.alerts[ruleMethod]);
                regres = false;
            }
            if (ruleArgs[1] == -1) {
                if (el.value >= ruleArgs[0]) var valueres = true; else var valueres = false;
                msg = el.getProperty('digitmin_message') ? el.getProperty('digitmin_message') :
                    this.options.alerts.digitmin.replace("%0", ruleArgs[0]);
            } else {
                if (el.value >= ruleArgs[0] && el.value <= ruleArgs[1]) var valueres = true; else var valueres = false;
                msg = el.getProperty('digitltd_message') ? el.getProperty('digitltd_message') :
                    this.options.alerts.digitltd.replace("%0", ruleArgs[0]).replace("%1", ruleArgs[1]);
            }
            if (!regres || !valueres) {
                el.errors.push(msg);
                return false;
            }
        } else if (!this.options.regexp[ruleMethod].test(el.value)) {
            //console.log('tested value' + el.value);
            el.errors.push(msg);
            return false;
        }
        return true;
    },

    validateMultipleEmails: function(el, ruleArgs) {
        //console.log('CALLING: CorbisFormValidator.validateMultipleEmails');
        var val = el.value;
        var msg = el.getProperty('email_message') ?
                el.getProperty('id') + '|email|' +
                el.getProperty('email_message') :
                this.options.alerts['email'];

        // maybe multiples if semicolon
        if (val.contains(';')) {
            //console.log('--[MULTIPLE EMAIL?]');
            var items = val.split(';');

            // trim all values
            items.each(function(item, index) {
                items[index] = item.trim();
            });

            // erase empty items in the array
            // ie, someone enters 'a@c.com;;;;'
            // after erase(), you will have only one item
            items.erase('');

            // if after cleaning up array you have 0 items
            // send required error message
            if (items.length == 0) {
                msg = el.getProperty('required_message') ?
                    el.getProperty('id') + '|email|' +
                    el.getProperty('required_message') :
                    this.options.alerts['required'];
                if (el.errors.length == 0) el.errors.push(msg);
                //console.log(el.errors);
                return false;
            } else {
                var goodToGo = true;
                items.each(function(item, index) {
                    // if one of the values does not pass,
                    // then mark goodToGo as false
                    // so we know to fire off error
                    if (!this.options.regexp['email'].test(item) && goodToGo) {
                        goodToGo = false;
                    }
                }, this);
                if (!goodToGo) {
                    if (el.errors.length == 0) el.errors.push(msg);
                    //console.log(el.errors);
                    return false;
                }
            }
            // single or empty
        } else {
            //console.log('--[SINGLE EMAIL?]');
            val = val.trim();
            if (!this.options.regexp['email'].test(val)) {
                //console.log('-->last');
                if (el.errors.length == 0) el.errors.push(msg);
                //console.log(el.errors);
                return false;
            }
        }

        return true;
    },

    /*
    Function: validateConfirm
    Private method
		
		Perform confirm validations
    */
    validateConfirm: function(el, ruleArgs) {
        //console.log('CALLING: CorbisFormValidator.validateConfirm');
        if (!el.validation.contains('required')) {
            el.validation.push('required');
        }
        var confirm = ruleArgs[0];
        if (el.value != this.form[confirm].value) {
            msg = el.getProperty('confirm_message') ? el.getProperty('confirm_message') :
                this.options.alerts.confirm.replace("%0", ruleArgs[0]);
            el.errors.push(msg);
            return false;
        }
        return true;
    },

    /*
    Function: validateDiffers
    Private method
		
		Perform differs validations
    */
    validateDiffers: function(el, ruleArgs) {
        //console.log('CALLING: CorbisFormValidator.validateDiffers');
        var confirm = ruleArgs[0];
        if (el.value == this.form[confirm].value) {
            msg = el.getProperty('differs_message') ? el.getProperty('differs_message') :
                    this.options.alerts.differs.replace("%0", ruleArgs[0]);
            el.errors.push(msg);
            return false;
        }
        return true;
    },
    /*
    Function: validateWordCount
    Private method
		
		Perform word count validations
    */
    validateWordCount: function(el, ruleArgs) {
        //console.log('CALLING: CorbisFormValidator.validateWordCount');
        var msg = "";

        if (!el.validation.contains('required')) {
            el.validation.push('required');
        }
        var tmpWordcount = ruleArgs[0];
        var elWordcount = el.value.split(/\b[\s,\.-:;]*/).length;


        if (elWordcount < 2) { //The Regex counts a blank space as 1 so I am setting to 2
            msg = el.getProperty('wordcount_message') ? el.getProperty('wordcount_message') :
                    this.options.alerts.wordcount.replace("%0", tmpWordcount);
            el.errors.push(msg);
            return false;
        }
        if (elWordcount > tmpWordcount) {
            msg = this.options.alerts.wordcount.replace("%0", tmpWordcount);
            el.errors.push(msg);
            return false;
        }

        return true;

    },
    /*
    Function: isChildType
    Private method
		
		Determine if the field is a group of radio or not.
    */
    isChildType: function(el) {
        //console.log('CALLING: CorbisFormValidator.isChildType');
        if (el.get('type')) {
            var elType = el.get('type').toLowerCase();
            if ((elType == "radio")) return true;
        }
        return false;
    },

    validateCustom: function(el, ruleArgs, customString) {
        //console.log('CALLING: CorbisFormValidator.validateCustom');
        if (!eval(el.getProperty(customString))) {
            el.errors = [el.getProperty('id') + '|' + customString + '|' + el.getProperty(customString + '_message')];
            //alert(el.getProperty('id') + '|' + customString + '|' + el.getProperty(customString + '_message'));
            return false;
        }
        else return true;
    },

    validatePopMessage: function(el, ruleArgs, popmessageString) {
        console.log('CALLING: CorbisFormValidator.validatePopMessage');
        var validationResult = eval(el.getProperty(popmessageString));
        if (validationResult.length > 0) {
            var vResults = validationResult.split("|");
            for (var i = 0; i < vResults.length; i++) {
                el.errors.push(el.getProperty('id') + '|' + popmessageString + '|' + vResults[i]);
            }
            return false;
        }
        else return true;
    },

    /*
    Function: validateGroup
    Private method
		
		Perform radios validations
    */
    validateGroup: function(el) {
        //console.log('CALLING: CorbisFormValidator.validateGroup');
        el.errors = [];
        var nlButtonGroup = this.form[el.getProperty("name")];
        el.group = nlButtonGroup;
        var cbCheckeds = false;

        for (var i = 0; i < nlButtonGroup.length; i++) {
            if (nlButtonGroup[i].checked) {
                cbCheckeds = true;
            }
        }
        if (!cbCheckeds) {
            el.errors.push(this.options.alerts.radios);
            return false;
        } else {
            return true;
        }
    },

    /*
    Function: listErrorsAtTop
    Private method
		
		Display errors
    */
    listErrorsAtTop: function(obj) {
        //console.log('CALLING: CorbisFormValidator.listErrorsAtTop');
        if (((obj.validation.contains('required') || obj.validation[0].indexOf('custom') == 0) && obj.errors.length > 0) ||
            (obj.errors.length > 0 && obj.value && !obj.validation.contains('required'))) {
            var erstring = '';
            obj.errors.each(function(error) {
                //console.log(error);
                errorObj = error.split('|');
                //console.log(errorObj[0] + ' : ' + errorObj[1] + ' : ' + errorObj[2]);
                if (erstring != errorObj[2]) {
                    erstring = errorObj[2];

                    var errorItem = this.errorTarget.get('html') + '<li elId=' + errorObj[0] + ' erType=' + errorObj[1] + '>' + errorObj[2] + '</li>';

                    try {
                        if (errorObj[2] && typeof (errorObj[2]) != undefined) {
                            this.errorTarget.set('html', errorItem);
                            if (this.options.display.addClassErrorToField && !this.isChildType(obj)) {
                                this.highlightRow(true, obj);
                            }
                        }
                    } catch (error) { }
                } //new Element('p').set('html', "<span>" + obj.name + " : </span>" + error).injectInside(this.form.element);
            }, this);

            this.errorDiv.removeClass('displayNone');
            if (this.options.resizeScript)
                eval(this.options.resizeScript);
        }

    },

    /*
    Function: manageError
    Private method
		
		Manage display of errors boxes
    */
    manageError: function(el, method) {
        //console.log('CALLING: CorbisFormValidator.manageError');
        var isValid = this.validate(el);
        //console.log('el, isValid, validation:' + (el.getProperty('id')) + ', ' + isValid + ', ' + el.validation);
        //console.log(el.validation.indexOf('custom'));
        this.elimiSpace(el);
        if (
            (!isValid && el.validation.contains('required')) ||
            (!el.validation.contains('required') && el.value && !isValid) ||
            (!isValid && el.validation[0].indexOf('custom') == 0)
            ) {
            if (this.options.display.listErrorsAtTop) {
                this.listErrorsAtTop(el);
                //console.log('list er: ' + el);
            }
            if (this.options.display.indicateErrors == 2 || !this.alreadyIndicated || el.name == this.alreadyIndicated.name) {
                if (!this.firstError) this.firstError = el;
                this.alreadyIndicated = el;
                if (this.options.display.keepFocusOnError && el.name == this.firstError.name) (function() { el.focus() }).delay(20);
                this.addError(el);
                //console.log('false ' + this.options.containerID);
                return false;
            }
        }
        else if ((isValid || (!el.validation.contains('required') && !el.value)) && el.element) {
            this.removeError(el);
            //console.log('true 1 ' + this.options.containerID);
            return true;
        }
        //console.log('true 2 ' + this.options.containerID);
        return true;
    },

    /*
    Function: addError
    Private method
		
		Add error message
    */
    addError: function(obj) {
        //console.log('CALLING: CorbisFormValidator.addError');
        if (!obj.element && this.options.display.indicateErrors != 0) {
            if (this.options.display.errorsLocation == 1) {
                var pos = (this.options.display.tipsPosition == 'left') ? obj.getCoordinates().left : obj.getCoordinates().right;
                var options = {
                    'opacity': 0,
                    'position': 'absolute',
                    'float': 'left',
                    'left': pos + this.options.display.tipsOffsetX,
                    'top': pos + this.options.display.tipsOffsetY
                }
                obj.element = new Element('div', { 'class': this.options.tipsClass, 'styles': options }).injectInside(this.options.containerID);
                this.addPositionEvent(obj);


            } else if (this.options.display.errorsLocation == 2) {
                obj.element = new Element('div', { 'class': this.options.errorClass, 'styles': { 'opacity': 0} }).injectBefore(obj);
            } else if (this.options.display.errorsLocation == 3) {
                obj.element = new Element('div', { 'class': this.options.errorClass, 'styles': { 'opacity': 0} });
                if ($type(obj.group) == 'object' || $type(obj.group) == 'collection')
                    obj.element.injectAfter(obj.group[obj.group.length - 1]);
                else
                    obj.element.injectAfter(obj);
            }
        }
        if (obj.element) {
            obj.element.empty();
            if (this.options.display.errorsLocation == 1) {
                var errors = [];
                obj.errors.each(function(error) {
                    errors.push(new Element('p').set('html', error));
                });
                var tips = this.makeTips(errors).injectInside(obj.element);
                if (this.options.display.closeTipsButton) {
                    tips.getElements('a.close').addEvent('mouseup', function() {
                        this.removeError(obj);
                    } .bind(this));
                }
                if (obj.get('tag') == 'textarea') {

                    obj.element.setStyle('top', this.options.display.tipsOffsetY + tips.getCoordinates().height - 15);
                } else {

                    obj.element.setStyle('top', obj.getCoordinates().top - tips.getCoordinates().height + this.options.display.tipsOffsetY);
                }


            } else {
                obj.errors.each(function(error) {
                    new Element('p').set('html', error).injectInside(obj.element);
                });
            }

            if (!Browser.Engine.trident5 && obj.element.getStyle('opacity') == 0)
                new Fx.Morph(obj.element, { 'duration': this.options.display.fadeDuration }).start({ 'opacity': [1] });
            else
                obj.element.setStyle('opacity', 1);
        }

        //if (this.options.display.addClassErrorToField && !this.isChildType(obj)) {
        //this.elimiSpace(obj);
        //            //            this.highlightRow(true, obj);
        //            //obj.addClass(this.options.fieldErrorClass);
        //}
    },

    /*
    Function: addPositionEvent
		
		Update tips position after a browser resize
    */
    addPositionEvent: function(obj) {
        //console.log('CALLING: CorbisFormValidator.addPositionEvent');
        if (this.options.display.replaceTipsEffect) {
            obj.event = function() {
                new Fx.Morph(obj.element, {
                    'duration': this.options.display.fadeDuration
                }).start({
                    'left': [obj.element.getStyle('left'), obj.getCoordinates().right + this.options.display.tipsOffsetX],
                    'top': [obj.element.getStyle('top'), obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY]
                });
            } .bind(this);

        } else {
            obj.event = function() {
                obj.element.setStyles({
                    'left': obj.getCoordinates().right + this.options.display.tipsOffsetX,
                    'top': obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY
                });
            } .bind(this)
        }
        window.addEvent('resize', obj.event);
    },

    /*
    Function: removeError
    Private method
		
		Remove the error display
    */
    removeError: function(obj) {
        //console.log('CALLING: CorbisFormValidator.removeError');
        this.firstError = false;
        this.alreadyIndicated = false;
        obj.errors = [];
        obj.isOK = true;
        window.removeEvent('resize', obj.event);
        if (this.options.display.errorsLocation == 2)
            new Fx.Morph(obj.element, { 'duration': this.options.display.fadeDuration }).start({ 'height': [0] });
        if (!Browser.Engine.trident5) {
            new Fx.Morph(obj.element, {
                'duration': this.options.display.fadeDuration,
                'onComplete': function() {
                    if (obj.element) {
                        obj.element.destroy();
                        obj.element = false;
                    }
                } .bind(this)
            }).start({ 'opacity': [1, 0] });
        } else {
            obj.element.destroy();
            obj.element = false;
        }
        if (this.options.display.addClassErrorToField && !this.isChildType(obj)) {

            this.highlightRow(false, obj);
            this.errorTarget.getElements('li[elId=' + obj.getProperty('id') + ']').each(function(li) {
                li.dispose();

            });
            if (this.errorTarget.getElements('li').length == 0) {
                this.errorDiv.addClass('displayNone');

            }
            if (this.options.resizeScript)
                eval(this.options.resizeScript);
        }
    },

    /*
    Function: focusOnError
    Private method
		
		Create set the focus to the first field with an error if needed
    */
    focusOnError: function(obj) {
        //console.log('CALLING: CorbisFormValidator.focusOnError');
        if (this.options.display.scrollToFirst && !this.alreadyFocused && !this.isScrolling) {
            if (this.alreadyIndicated.element) {
                switch (this.options.display.errorsLocation) {
                    case 1:
                        var dest = obj.element.getCoordinates().top;
                        break;
                    case 2:
                        var dest = obj.element.getCoordinates().top - 30;
                        break;
                    case 3:
                        var dest = obj.getCoordinates().top - 30;
                        break;
                }
                this.isScrolling = true;
            } else if (!this.options.display.indicateErrors) {
                var dest = obj.getCoordinates().top - 30;
            }
            if (window.getScroll.y != dest) {
                new Fx.Scroll(window, {
                    onComplete: function() {
                        this.isScrolling = false;
                        obj.focus();
                    } .bind(this)
                }).start(0, dest);
            } else {
                this.isScrolling = false;
                obj.focus();
            }
            this.alreadyFocused = true;
        }
    },

    /*
    Function: fixIeStuffs
    Private method
		
		Fix png for IE6
    */
    fixIeStuffs: function() {
        //console.log('CALLING: CorbisFormValidator.fixIeStuffs');
        if (Browser.Engine.trident4) {
            //We fix png stuffs
            var rpng = new RegExp('url\\(([\.a-zA-Z0-9_/:-]+\.png)\\)');
            var search = new RegExp('(.+)formcheck\.css');
            for (var i = 0; i < document.styleSheets.length; i++) {
                if (document.styleSheets[i].href.match(/formcheck\.css$/)) {
                    var root = document.styleSheets[i].href.replace(search, '$1');
                    var count = document.styleSheets[i].rules.length;
                    for (var j = 0; j < count; j++) {
                        var cssstyle = document.styleSheets[i].rules[j].style;
                        var bgimage = root + cssstyle.backgroundImage.replace(rpng, '$1');
                        if (bgimage && bgimage.match(/\.png/i)) {
                            var scale = (cssstyle.backgroundRepeat == 'no-repeat') ? 'crop' : 'scale';
                            cssstyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=\'' + bgimage + '\', sizingMethod=\'' + scale + '\')';
                            cssstyle.backgroundImage = "none";
                        }
                    }
                }
            }
        }
    },

    /*
    Function: makeTips
    Private method
		
		Create tips boxes
    */
    makeTips: function(txt) {
        //console.log('CALLING: CorbisFormValidator.makeTips');
        var table = new Element('table');
        table.cellPadding = '0';
        table.cellSpacing = '0';
        table.border = '0';

        var tbody = new Element('tbody').injectInside(table);
        var tr1 = new Element('tr').injectInside(tbody);
        new Element('td', { 'class': 'tl' }).injectInside(tr1);
        new Element('td', { 'class': 't' }).injectInside(tr1);
        new Element('td', { 'class': 'tr' }).injectInside(tr1);
        var tr2 = new Element('tr').injectInside(tbody);
        new Element('td', { 'class': 'l' }).injectInside(tr2);
        var cont = new Element('td', { 'class': 'c' }).injectInside(tr2);
        var errors = new Element('div', { 'class': 'err' }).injectInside(cont);
        txt.each(function(error) {
            error.injectInside(errors);
        });
        if (this.options.display.closeTipsButton) new Element('a', { 'class': 'close' }).injectInside(cont);
        //	new Element('div', {'style' : "clear:both"}).injectInside(cont);
        new Element('td', { 'class': 'r' }).injectInside(tr2);
        var tr3 = new Element('tr').injectInside(tbody);
        new Element('td', { 'class': 'bl' }).injectInside(tr3);
        new Element('td', { 'class': 'b' }).injectInside(tr3);
        new Element('td', { 'class': 'br' }).injectInside(tr3);
        return table;
    },

    /*
    Function: reinitialize
    Private method		
		
		Reinitialize form before submit check
    */
    reinitialize: function() {
        //console.log('CALLING: CorbisFormValidator.reinitialize');
        this.validations.each(function(el) {
            if (el.element) {
                el.errors = [];
                el.isOK = true;
                if (this.options.display.flashTips == 1) {
                    el.element.destroy();
                    el.element = false;
                }
            }
        }, this);
        if (this.form.element) this.form.element.empty();
        this.alreadyFocused = false;
        this.firstError = false;
        this.alreadyIndicated = false;
        this.form.isValid = true;
        try {
            this.container = $(this.options.containerID);
            this.errorDiv = this.container.getElement('div.ValidationSummary');
            this.errorTarget = this.errorDiv.getElement('ul');
        } catch (Error) {
            //console.log('error binding errordiv/target ' + this.options.containerID);
        }
        this.errorTarget.getElements('li[elId]').each(function(li) {
            li.dispose();
        });
    },

    /*
    Function: reset
    Public method
    
    Use when reopening a form
    */
    reset: function() {
        //console.log('CALLING: CorbisFormValidator.reset');
        this.reinitialize();
        this.errorDiv.addClass('displayNone');
        var hClass = this.options.display.rowHiliteClass;
        $(this.options.containerID).getElements('*.' + hClass).each(function(e) {
            e.removeClass(hClass);
        });
        eval(this.options.resizeScript);
    },
    /*
    Function: submitByAjax
    Private method		
		
		Send the form by ajax, and replace the form with response
    */

    submitByAjax: function() {

        //console.log('CALLING: CorbisFormValidator.submitByAjax');
        this.reset();
        this.fireEvent('ajaxRequest');
        //var contextToBind = this;
        new Request.HTML({
            url: this.options.ajaxUrl,
            method: 'post',
            async: this.options.ajaxAsync,
            data: this.options.ajaxData,
            evalScripts: this.options.ajaxEvalScripts,
            onFailure: function(instance) {
                this.fireEvent('ajaxFailure', instance);
            } .bind(this),

            onSuccess: function(responseTree, responseElements, responseHtml) {
                if (window.location.href.test('SignInInformationRequest.aspx')) {
                    this.fireEvent('ajaxSuccess', responseHtml.toString());
                } else {
                    this.fireEvent('ajaxSuccess', responseTree);

                }

                if (this.options.useStandardAjaxBehavior) {
                    //console.log(responseElements.getElements('ScriptServiceValidationError').length);
                    //var result = responseElements.filter('scriptservicevalidationerror');
                    var errorIndex = responseHtml.indexOf('<ScriptServiceValidationError');

                    //                    var root = '<root>' + responseHtml + '</root>', doc;
                    //                    alert('root=' + root);
                    //                    doc = new DOMParser().parseFromString(root, 'text/xml');
                    //                    alert('doc=' + doc);
                    //                    root = doc.getElementsByTagName('ScriptServiceValidationError')[0];
                    //                    alert('root=' + root);


                    if (errorIndex == -1)
                        eval(this.options.successScript);
                    else {
                        var result;
                        if (Browser.Engine.trident) {
                            result = responseElements.filter('scriptservicevalidationerror');

                        } else {
                            var test = responseHtml.split('?>');
                            test.shift();
                            test = (test.length == 1) ? test[0] : test.join('?>');
                            //alert($type(test));
                            var ser = new CorbisUI.JSSerializer();
                            test = ser.getDom(test);

                            result = $(test).getElements('ScriptServiceValidationError');
                        }


                        result.each(function(item) {
                            if (item.getElement('ClientId')) {
                                var elId = item.getElement('ClientId').get('text');
                                var doHL = item.getElement('HighlightRow').get('text') == 'true';
                                this.highlightRow(doHL, $(elId));
                                if (item.getElement('ShowInSummary').get('text') == 'true') {
                                    var errorItem = this.errorTarget.get('html') +
                                    '<li elId="' + elId + '" erType="ajax">' +
                                    item.getElement('ErrorMessage').get('text') + '</li>';
                                    this.errorTarget.set('html', errorItem);
                                    this.errorDiv.removeClass('displayNone');
                                }
                            }
                        }, this);

                        eval(this.options.resizeScript);
                    }
                }
                // useOldAjaxBehavior makes it so that we return "success" if the operation completed
                // and this script will auto-close. Otherwise, it assumes the response is a localized error
                // string that it will display in the error section
                else if (this.options.useOldAjaxBehavior) {

                    var responseText = responseHtml.toString();
                    responseText = responseText.replace(/(<([^>]+)>)/ig, "");
                    if (responseText.replace(/\s/g, '').toLowerCase() == 'success') {
                        eval(this.options.successScript);
                    }
                    else {
                        this.errorDiv.removeClass('displayNone');
                        this.errorTarget.set('html', '<li elId=wsdl>' + responseText + '</li>');
                        eval(this.options.resizeScript);
                    }
                }
                if (this.options.ajaxResponseDiv) $(this.options.ajaxResponseDiv).set('html', result);
            } .bind(this)
        }).send();
    },


    /*
    Function: validateAll
    Private method		
		
		Perform check on submit action
    */
    validateAll: function(event) {
        //console.log('CALLING: CorbisFormValidator.validateAll')
        this.container.getElements('input[type=text]').each(this.removeBraces, this);
        this.container.getElements('textarea').each(this.removeBraces, this);
        if (event) Event(event).stop();
        this.reset();
        this.errorTarget.set('html', '');
        //this.reinitialize();

        //console.log('val length: ' + this.validations.length);

        this.validations.each(function(el) {
            //console.log('about to manage : ' + el.id);
            if (!this.manageError(el, 'submit')) this.form.isValid = false;
        }, this);
        //console.log('true 2 ' + this.options.containerID);

        if (this.form.isValid) {
            if (this.options.submitByAjax) {

                this.submitByAjax();
            }
            else if (this.options.successScript) {

                eval(this.options.successScript)
            }
            else if (this.options.submitForm) {

                __doPostBack(this.container.getElement('a.ValidateClickLB').id.replace(/_/g, '$'), '');
                //            //console.log(this.container.getElement('a.ValidateClickLB').id.replace(/_/g, '$'), '');
            }
            // set either submitForm or success script
        } // Start Fixed 18772   
        else {

            if (this.validations.length > 1) {
                if (this.validations[1].value.contains('.') && this.validations[1].name.contains('newPassword') && this.options.submitByAjax) {
                    this.submitByAjax();
                }
                else {
                    this.form.isValid = false;
                    this.focusOnError(this.firstError);
                    //console.log("run failscript:" + this.options.failScript);
                    setTimeout('eval("' + this.options.failScript + '")', 500);
                }
            } // End Fixed 18772
            else {
                this.form.isValid = false;
                this.focusOnError(this.firstError);
                //console.log("run failscript:" + this.options.failScript);
                setTimeout('eval("' + this.options.failScript + '")', 500);
            }
        }
        //console.log(this.container.getElement('a.ValidateClickLB').id);
    },
    highlightRow: function(hilite, element) {
        //console.log('CALLING: CorbisFormValidator.highlightRow');
        try {
            var parentRow;
            var pattern = new Array('tr.FormRow', 'tr.Error', 'div.FormRow', 'div.Error', 'div.dataRowNoBorder');

            element = $(element.get('id'));
            if (this.options.highlightField==true) { // Bug# 18639: Original code: "if(this.options.highlightField)". In this if condition, even the value of "this.options.highlightField" is false the if condition is cheking the existance of object and it is returning true regardless of its "value" is true or false. Shortly the comparision should be in value not the existance of object.
                if (hilite)
                    element.addClass('ErrorHighlight');
                else
                    element.removeClass('ErrorHighlight');
            }
            else {
                for (var i = 0; i < pattern.length; i++) {
                    //console.log('PAT: ' + pattern[i]);
                    //console.log(element.getParent(pattern[i]));
                    if (element.getParent(pattern[i])) {
                        parentRow = element.getParent(pattern[i]);
                        //console.log(parentRow + '---' + pattern[i]);
                    }
                }
                //console.log(parentRow.get('html'));
                if (parentRow) {
                    if (hilite)
                        parentRow.addClass('ErrorHighlight');
                    else
                        parentRow.removeClass('ErrorHighlight');
                }
            }
        } catch (Error) { }
    },
    elimiSpace: function(element) {
        //console.log('CALLING: CorbisFormValidator.elimiSpace');
        try {
            if ($(element).value) $(element).value = $(element).value.trim();
            //            if (element.getProperty('value').replace(/\s/g, '') == '') {
            //                element.setProperty('value', '');
            //            }
            //
        } catch (Error) {
            //console.log(element);
        }
    },
    removeBraces: function(element) {
        //console.log('CALLING: CorbisFormValidator.removeBraces');
        //element.value = element.value.replace(/>/g, '&gt;').replace(/</g, '&lt;');
        this.elimiSpace(element);
    }

});
var _isEnterKey = false;

//End: /Scripts/validation.js
//Begin: /Scripts/BrowseBase.js

window.addEvent('load', function() {
	SetupBrowseNav();
	SetupPopupWindows();
	SetupModalWindows();
	SetupImagePreviews();
});

function SetupBrowseNav() {
    //Find the 'Motion' link in dropdown and turn it white
    if ($('dropDownMenuLeftDiv') != null){
		var spanList = $('dropDownMenuLeftDiv').getElements('span');
		spanList.each(function(el) {
			if (el.id.indexOf('Creative') >= 0) {
				var theLink = el.getParent().getParent();
				theLink.href = "javascript:void(0);";
				theLink.setStyle('cursor', 'default');
				theLink.addEvents('click', function() { return false; });
			}
			if (el.id.indexOf('Editorial') >= 0) {
				var theLink = el.getParent().getParent();
				theLink.href = "javascript:void(0);";
				theLink.setStyle('cursor', 'default');
				theLink.addEvents('click', function() { return false; });
			}
            if (el.id.indexOf('Motion') >= 0) {
				var theLink = el.getParent().getParent();
				theLink.setProperty('target', '_blank');
				theLink.href = "http://www.corbismotion.com/";
                el.setStyle('color', 'white');
                el.getParent().getParent().addEvent('mouseover', function() {
                    el.getParent().getParent().getParent().addClass('MotionHover');
                });
                el.getParent().getParent().addEvent('mouseout', function() {
                    el.getParent().getParent().getParent().removeClass('MotionHover');
                });
            }
		});
    }
}

// ----------------------------------------------------------------------------	
// POPUP windows that degrade gracefully. 
// To customize a window size add below like this "WIDTH_HEIGHT_popup"
// Javascript dependency Mootools 1.2+

function SetupPopupWindows(){
	// get all links with a rel tag ending in 'popup'
	var linkList = $(document.body).getElements('a[rel$=popup]').each(function(el){
		var href = el.href;
		var rel = el.rel;
		var metadata = rel.split('_');
		var width = metadata[0];
		var height = metadata[1];
		el.addEvent('click', function(){
			OpenPopupWindow(href, width, height);
			return false;
		});
	});
}

function OpenPopupWindow(href, width, height){
	var popped = window.open(href,'Popped','resizable=yes,scrollbars=no,width='+width+',height='+height);
	
	// Mostly for Safari - check to see if the window was actually opened
	// if not, open it in a regular window not a popup
	if (!popped || popped == undefined){
		if ($('FlashContent') != null){
			var swf = $('FlashContent');
			swf.OpenWindowFromSwf(href);
		}
	}
}

// ----------------------------------------------------------------------------	
// MODAL windows that degrade gracefully. 
// To customize a window size add below like this "WIDTH_HEIGHT_modal"
// Javascript dependency Mootools 1.2+

function SetupModalWindows(){
	// get all links with a rel tag ending in 'modal'
	var linkList = $(document.body).getElements('a[rel$=modal]').each(function(el){
		var href = el.href;
		var rel = el.rel;
		var metadata = rel.split('_');
		var width = metadata[0];
		var height = metadata[1];
		el.addEvent('click', function(){
			OpenNewIModal(href, width, height, 'Popped');
			return false;
		});
	});
	
	if ($('OutlineSignupModal') != null){
		var closeLinks = $('OutlineSignupModal').getElements('.closeLink').each(function(el){
			el.addEvent('click', function(){
				parent.MochaUI.CloseModal('Popped');
			});
		});
		
		var printLinks = $('OutlineSignupModal').getElements('.printLink').each(function(el){
			el.addEvent('click', function(){
				//alert("here");
			});
		});
	}
}

// ----------------------------------------------------------------------------	
// SEARCH RESULTS windows that degrade gracefully. 
// From popup slideshow windows, this script will detect if a parent window
// exists, if so, it will show the search results in the parent window. If not,
// it will show the search results in the current window.
// Javascript dependency Mootools 1.2+

function DisplaySearchResults(href){
	var displayWindow = window;
	
	// See if the user has closed the parent window, if not...
	if (window.opener)
		displayWindow = window.opener;
		
	// Move the window to the front and display the search results
	displayWindow.focus();
	displayWindow.location.href = "/Search#q=" + href;
}

// ----------------------------------------------------------------------------	
// IMAGE PREVIEW layers that degrade gracefully. 
// If an image has a class of "preview" it will display when it's
// associated link is moused over.
// Javascript dependency Mootools 1.2+

function SetupImagePreviews(){
	xOffset = 45;
	yOffset = 20;
	
	// get all links with a class of 'preview'
	var linkList = $(document.body).getElements('a.preview').each(function(el){
		el.addEvent('mouseover', function(){
			var preview = new Element("div", {
				"id": "preview"
			});
			var previewImage = new Element("img", {
				"src": this.rel
			});
			preview.adopt(previewImage);
			$(document.body).adopt($(preview));
			$(preview).setStyles({
				top: (el.getCoordinates().top - xOffset) + "px",
				left: (el.getCoordinates().left + el.offsetWidth + yOffset) + "px",
				display: "block",
				opacity: 0
			});
			$(preview).fade('in');
		});
		el.addEvent("mouseout", function(){
			$("preview").destroy();
		});
	});
}

function attachOnChangeEventMembership() {
	var select = $(officeListCID);
	select.addEvent('change', function(){
		var selected = select.options[select.selectedIndex].text.replace(" ","");
		setHiddenFieldValue(selected);
		show(selected);
	});
}

function setHiddenFieldValue(country){
	var emailAddress = getEmailAddress(country);
	var hiddenField = $(selectedCountryCID); 
	hiddenField.setProperty('value', emailAddress);
}

function getEmailAddress(country){
	var emailAddress = 'sales@corbis.com';
	if ($(country) == null)
		country = 'UnitedStates';
	var emails = $(country).getElements('a[href^=mailto:]');
	if (emails != null){
		emails.each(function(item){
			var href = item.getProperty('href');
			var index = href.indexOf("mailto:") + 7;
			href = href.substring(index);
			emailAddress = href;
		});
	}
	return emailAddress;		
};

function show(what){
	var showwhat = $(what);
	showwhat.addClass('active');
	hideothers(what);
}

function hideothers(exempt){
	var selector = 'li[id!=' + exempt + ']';
	var list = $('ContactInformation').getElements(selector).each(function(el){
		el.removeClass('active');
	});
}

function InitOutlineMembership() {
	window.addEvent('domready', function() {
		setHiddenFieldValue('UnitedStates');
		attachOnChangeEventMembership();
		show('UnitedStates');
	});
}

function openThankYouModal() {
	
	// window.close();
	
	
	
	
	// new CorbisUI.Popup('OutlineThankYou', {
	// 	showModalBackground: false,
	// 	closeOnLoseFocus: true,
	// 	positionVert: 'middle',
	// 	positionHoriz: 'bottom'
	// });
}

function attachOnChangeEvent(){
	var select = $(CountryListCID);
	if (select != null){
		select.addEvent('change', function(){
			var selected = select.options[select.selectedIndex].value;
			show(selected);
		});
	}
}

function show(what){
	var showwhat = $(what);
	if (showwhat != null){
		showwhat.addClass('active');
		hideothers(what);
	}
}

function hideothers(exempt){
	var selector = 'li[id!=' + exempt + ']';
	var list = $('ContactInformation').getElements(selector).each(function(el){
		el.removeClass('active');
	});
}

function clearOutlineSignupForm() {
	var control = $('OutlineMembershipForm').getElements('input');
	control.each(function(el) {
		if (el.type == "text") {
			el.value = '';
		}
	}, this);
	control = $('OutlineMembershipForm').getElements('select');
	control.each(function(el) {
		el.selectedIndex = 0;
	}, this);
}

function resizeThisModal() {
	parent.ResizeIModal('Popped', GetDocumentHeight());
}

function doClose() {
	// parent.MochaUI.CloseModal('Popped');
}

function doSuccess() {

	// Hide the content (we can't remove it, there's some code that runs on it)
	// document.getElementById("OutlineSignupModal").setAttribute('style', "display:none")
	document.getElementById("OutlineSignupModal").style.cssText = "display:none;"
	
	// Add the nice confirmation <div>
	var conirmationText = document.createElement('div');
		conirmationText.id = "confirmation";
		conirmationText.style.cssText = "margin:20px 0 0 40px; font-size:14px; line-height:18px; color:black;";
		conirmationText.innerHTML = "<p>Thank you for your inquiry. <br>A customer service representative will be in touch with you shortly.</p><p><a href='javascript:window.close()'>Close window</a></p>";
	var container = document.getElementById("OutlineSignupModal");
		container.parentNode.insertBefore(conirmationText, container);
	
	// Track clicks
	LogOmnitureEvent("event56"); // added so that the sign up form for Outline will fire the Omniture event. -brett
	
	// Old stuff
	// clearOutlineSignupForm();
	// parent.openThankYouModal();
	// doClose();
	
}

function InitOutlineSignup() {
	window.addEvent('domready', function() {
		attachOnChangeEvent();
		show('US');
	});
}

//End: /Scripts/BrowseBase.js
//Begin: /Scripts/ServiceDescription_AutoComplete.js

/*
* DEFINE SERVICES FOR 
* SearchOld/AutoComplete.asmx
* ********************************************/

// JSON RESPONSES
CorbisUI.ServiceManager.defineService('SearchOld.AutoComplete.Complete', { submissionTemplate: ["prefixText", "count", "contextKey"] });
// make an alias because the service filename doesn't match the actual service
CorbisUI.NameSpace.register('CorbisUI.ServiceManager.SearchOld.AutoCompleteService', { Alias: CorbisUI.ServiceManager.SearchOld.AutoComplete });

//End: /Scripts/ServiceDescription_AutoComplete.js
//Begin: /Scripts/ServiceDescription_SearchScriptService.js

/*
 * DEFINE SERVICES FOR 
 * SearchOld/SearchScriptService.asmx
 * ********************************************/

CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.DeleteMoreSearchOptions');
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.AddItemToQuickPick', { submissionTemplate: ["corbisID", "url128", "licenceModel", "aspectRation", "title"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.RemoveItemFromQuickPick', { submissionTemplate: ["corbisID"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.displayOptionsClarifications', { submissionTemplate: ["showclarificationstatus"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.displayOptionsAutoComplete', { submissionTemplate: ["showAutoCompleteStatus"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.Get_displayOptionsAutoComplete');
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.SavePreviewPreference', { submissionTemplate: ["previewState"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.GetLightBoxItems', { submissionTemplate: ["lightboxId"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.GetLightBoxItemsV2', { submissionTemplate: ["lightboxId"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.DeleteProductFromLightbox', { submissionTemplate: ["lightboxId", "productUid"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.AddProductToCart', { submissionTemplate: ["mediaUid", "productUID"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.GetCartMediaUidList');
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.AddSearchItemToLightbox', { submissionTemplate: ["mediaUid", "lightboxId"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.AddSearchItemToLightboxNew', { submissionTemplate: ["corbisId", "mediaUid", "lightboxId"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.AddSearchItemToSubscriptionNew', { submissionTemplate: ["corbisId", "mediaUid"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.DeleteSubscriptionItem', { submissionTemplate: ["mediaUid"] });
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.GetSubscriptionItems');
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.GetRemainingDownloadCount');
CorbisUI.ServiceManager.defineService('SearchOld.SearchScriptService.GetSubscriptionItemsCount');

CorbisUI.NameSpace.register('CorbisUI.ServiceManager.SearchOld.SearchScriptService', { Alias: CorbisUI.ServiceManager.SearchOld.SearchScriptService });
//End: /Scripts/ServiceDescription_SearchScriptService.js
//Begin: /Scripts/ServiceDescription_SignInStatus.js

/*
* DEFINE SERVICES FOR 
* Registration/SignInStatus.asmx
* ********************************************/

// XML RESPONSES
CorbisUI.ServiceManager.defineService('Registration.SignInStatus.SignInState', { async: false, responseType: "XML" });
CorbisUI.ServiceManager.defineService('Registration.SignInStatus.SignInStateAndCountry', { fetchOnly: true, async: false, responseType: "XML" });
//End: /Scripts/ServiceDescription_SignInStatus.js
//Begin: /Scripts/ServiceDescription_CustomerServiceWebService.js

/*
* DEFINE SERVICES FOR 
* CustomerService/CustomerServiceWebService.asmx
* ********************************************/

// JSON RESPONSES
CorbisUI.ServiceManager.defineService('CustomerService.CustomerServiceWebService.GetContactCorbisOffice');
CorbisUI.ServiceManager.defineService('CustomerService.CustomerServiceWebService.GetStates', { submissionTemplate: ["country"] });

//End: /Scripts/ServiceDescription_CustomerServiceWebService.js
//Begin: /Scripts/CorbisUI.ScriptLoader.js

ScriptLoader = {
    //loads a single script, performs callback, prevents duplication
    scripts: {},
    Load: function(scriptPath, scriptName, callback) {
        if (!document.getElementById(scriptName)) {
            this.scripts[scriptName] = {
                loaded: false,
                handlers: []
            };
            if (callback) {
                this.scripts[scriptName].handlers.push(callback);
            }
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = scriptPath;
            script.id = scriptName;
            script.onload = script.onreadystatechange = function() {
                var rs = this.readyState;
                if (rs && rs != 'complete' && rs != 'loaded') {
                    return;
                }
                var handlers = ScriptLoader.scripts[scriptName].handlers;
                while (handlers.length) {
                    var handler = handlers.shift();
                    if (typeof handler == "function") {
                        handler();
                    }
                }
                ScriptLoader.scripts[scriptName].loaded = true;
            };
            document.getElementsByTagName("head")[0].appendChild(script);
        }
        else {
            if (this.scripts[scriptName].loaded) {
                if (callback) {
                    callback(scriptName);
                }
            }
            else {
                this.scripts[scriptName].handlers.push(callback);
            }
        }
    },
    LoadPackage: function(packageName) {
    this.Load("/jspkg/" + Math.floor(Math.random() * 100 * 100 * 100) + "/en-US/ff/" + packageName + ".js", "Package_" + packageName);
    },
    //loads a list of scripts, runs callback when all are done.
    multiScripts: {},
    LoadMulti: function(listName, scriptList, callback) {
        this.multiScripts[listName] = {};
        var listLength = scriptList.length;
        while (listLength--) {
            var currentScript = scriptList[listLength];
            this.multiScripts[listName][currentScript] = false;
            this.Load(currentScript.scriptPath, currentScript.scriptName, this.multiComplete(listName, currentScript.scriptName, callback));
        }
    },
    multiComplete: function(listName, scriptName, callback) {
        return new function() {
            ScriptLoader.multiScripts[listName][scriptName] = true;
            var scriptList = ScriptLoader.multiScripts[listName];
            var scriptListLength = scriptList.length;
            var areAllLoaded = true;
            while (scriptListLength--) {
                if (!scriptList[scriptListLength]) {
                    areAllLoaded = false;
                    break;
                }
            }
            if (areAllLoaded) {
                if (callback) {
                    callback(listName);
                }
            }
        }
    },
    //queues up scripts to be loaded sequentially and executes callbacks as they complete
    queue: [],
    LoadQueue: function(scriptPath, scriptName, callback) {
        this.queue[this.queue.length] = [scriptPath, scriptName, callback];
    },
    ProcessQueue: function() {
        if (this.queue.length > 0) {
            this.processQueueItem(this.queue.shift());
        }
    },
    processQueueItem: function(item) {
        var callback = item[2];
        if (this.queue.length > 0) {
            var nextItem = this.queue.shift();
            var self = this;
            callback = function(scriptName) {
                if (item[2]) {
                    item[2](scriptName);
                }
                self.processQueueItem(nextItem);
            }
        }
        this.Load(item[0], item[1], callback);
    },
    //script names to keep everything uses defined names and not hard coded values
    Names: {
        jQuery: "jquery",
        corbisToolTips: "corbistooltips",
        corbisLightbox: "corbislightbox",
        closureTemplates: "closuretemplates",
        minSearch: "minsearch"
    }
}

//End: /Scripts/CorbisUI.ScriptLoader.js
CorbisUI.debug = true;