function trace (s) {
	$A(arguments).each(function (s) {
		if (typeof console == 'undefined' || window.webkit) {
			if (!document.getElementById('debug')) {
				var o = document.createElement('pre');
				o.id = 'debug';
				o.style.color = 'black';
				o.style.fontSize = '10pt';
				o.style.position = 'absolute';
				o.style.top = '0px';
				o.style.right = '0px';
				o.style.textAlign = 'left';
				document.getElementsByTagName('body')[0].appendChild(o);
			}

			s = new String(s);
			s = s.replace('<', '&lt;');
			s = s.replace('>', '&gt;');
			document.getElementById('debug').innerHTML += s + '<br />';
		}
		else {
			console.log(s);
		}
	});
}

window.addEvent('domready', function () {
	//submit
	$$('.submit').each(function(e) {
		e.addEvent('click', submitForm.bindWithEvent(e, e));
	});

	//search criteria
	new CriteriaSelector();

	var e = $('banner-link');
	if (e) {
		new BannerKwick(e.getParent(), e);
	}

	// force links to open in new windows
	$$('a[href^=http]').each(function (e) {
		e.set('target', '_blank');
	});


	var e = $$('.display-case-studies');
	var a = $$('a.case');
	if (e.length && a.length) {
		e = e[0];
		a = a[0];

		var lb = new CaseStudiesLightBox(e.getElements('a'));

		e.setStyles({
			display: 'block',
			visibility: 'hidden',
			position: 'absolute'
		});
		var h = e.getSize().y;
		e.store('h', h);
		e.setStyles({
			display: 'block',
			visibility: '',
			position: '',
			height: 0
		});

		a.addEvent('click', function (evt) {
			evt.stop();
			var h = e.getStyle('height').toInt();
			if (h > 0) {
				e.tween('height', 0);
				a.removeClass('case-open');
			}
			else {
				e.tween('height', e.retrieve('h'));
				a.addClass('case-open');
			}
		});
	}
});

var CaseStudiesLightBox = new Class({
	Implements: Options,
	overlay: null,
	outer: null,
	inner: null,
	loading: null,
	elements: [],
	animating: false,
	req: null,
	visible: false,
	isIE: false,
	fx: {
		overlay: null,
		outer: null,
		inner: null,
		loading: null
	},
	options: {
		append: '',
		opacity: 0.7,
		duration: 250,
		timeout: 1000,
		fixFlash: false
	},
	initialize: function (elements, options) {
		this.setOptions(options);
		this.elements = elements;

		this.isIE = /MSIE/.test(navigator.userAgent);
		this.setup();

		this.elements.each(function (el) {
			el.addEvent('click', this.clicked.bindWithEvent(this, el));
		}, this);
	},
	setup: function () {
		var size = $(window).getScrollSize();
		this.overlay = new Element('div', {
			id: 'lb-overlay',
			styles: {
				height: size.y,
				opacity: this.options.opacity,
				visibility: 'hidden'
			}
		}).injectInside(document.body);
		this.overlay.addEvent('click', function (evt) {
			evt.stop();
			this.hide();
		}.bind(this));

		this.outer = new Element('div', {
			id: 'lb-outer',
			styles: {
				opacity: 1,
				visibility: 'hidden'
			}
		}).injectInside(document.body);
		this.outer.addEvent('click', function (evt) {
			evt.stop();
			this.hide();
		}.bind(this));

		this.inner = new Element('div', {
			id: 'lb-inner'
		}).injectInside(this.outer);
		this.inner.addEvent('click', function (evt) {
			evt.stopPropagation();
		}.bind(this));

		this.content = new Element('div', {
			id: 'lb-content'
		}).injectInside(this.inner);

		this.loading = new Element('div', {
			id: 'lb-loading',
			styles: {
				opacity: 1,
				visibility: 'hidden'
			}
		}).injectInside(this.inner);

		this.fx.overlay = new Fx.Tween(this.overlay, {
			duration: this.options.duration
		})
		this.fx.overlay.addEvent('start', this.start.bind(this));
		this.fx.overlay.addEvent('complete', this.completed.bind(this));

		this.fx.outer = new Fx.Tween(this.outer, {
			duration: this.options.duration
		})
		this.fx.outer.addEvent('start', this.start.bind(this));
		this.fx.outer.addEvent('complete', this.completed.bind(this));

		this.fx.loading = new Fx.Tween(this.loading, {
			duration: this.options.duration
		})
		this.fx.loading.addEvent('complete', this.completed.bind(this));
		this.fx.loading.addEvent('start', this.start.bind(this));
	},
	start: function (el) {
		switch (el) {
			case this.overlay:
				if (this.visible) {
					el.setStyle('display', 'block');
					this.fixFlash(true);
				}
				break;
			case this.outer:
				if (this.visible) {
					el.setStyle('display', 'block');
				}
				break;
		}
	},
	completed: function (el) {
		var visible = el.getStyle('visibility') == 'hidden' ? false : true;
		switch (el) {
			case this.overlay:
				if (!this.visible) {
					el.setStyle('display', 'none');
					this.fixFlash();
				}
				break;
			case this.outer:
				if (!this.visible) {
					el.setStyle('display', 'none');
				}
				if (visible && this.req) {
					this.req.send();
				}
				break;
		}
	},
	imageLoaded: function (el) {
		this.imageload.loaded++;
		if (this.imageload.loaded == this.imageload.images.length) {
			this.show();
		}
	},
	loaded: function (tree, elements, html) {
		this.content.setStyles({
			visibility: 'hidden'
		});

		var element = this.format(elements);
		var images = element.getElements('img');

		// load images
		this.imageload = {
			images: images,
			loaded: 0
		};
		images.each(function (el) {
			if (this.isIE && el.get('src').contains('.png')) {
				this.imageload.loaded++;
				return;
			}
			el.addEvent('load', this.imageLoaded.bind(this, el));
		}, this);


		this.content.empty();
		this.content.adopt(element);
		this.content.injectInside(this.inner);

		if (this.imageload.images.length == 0) {
			this.show();
		}
	},
	show: function () {
		this.fx.loading.start('opacity', 1, 0);

		var el = this.content.getElementById('popOver');
		var y = el.getSize().y;
		el.setStyle('height', 86);
		el.tween('height', y);

		var closes = this.content.getElements('.close');
		closes.each(function (el) {
			el.addEvent('click', function (evt) {
				evt.stop();
				this.hide();
			}.bind(this));
		}, this);

		this.content.setStyle('visibility', 'visible');
	},
	hide: function () {
		this.visible = false;
		this.fx.overlay.start('opacity', 0)
		this.fx.outer.start('opacity', 0)
	},
	clicked: function (evt, el) {
		if (evt) {
			evt.stop();
		}
		var url = el.get('href');
		if (this.options.append) {
			url += url.contains('?') ? '&' : '?';
			url += this.options.append;
		}
		this.load(url)
	},
	load: function (url) {
		this.req = new Request.HTML({
			url: url,
			onSuccess: this.loaded.bind(this),
			onFailure: function () {
				alert('The page request failed, please refresh the page and try again.');
			}
		});

		// show loading
		this.visible = true;
		this.inner.empty();
		this.fx.loading.start('opacity', 1);
		this.loading.injectInside(this.inner);

		// fade in
		this.fx.overlay.start('opacity', 0, this.options.opacity);
		this.fx.outer.start('opacity', 0, 1);
	},
	fixFlash: function (disable) {
		if (this.options.fixFlash) {
			["object", this.isIE ? "select" : "embed"].forEach(function(tag){
				Array.forEach(document.getElementsByTagName(tag), function(el){
					el.setStyle('visibility', disable ? 'hidden' : 'visible');
				});
			});
		}
	},
	format: function (elements) {
		var element = new Element('div', {
			id: 'popOver'
		});

		var header = new Element('div', {
			id: 'popOver-header'
		}).adopt(
			new Element('img', {
				src: '../images/popover_top.png',
				width: '596',
				height: '12'
			})
		);
		var footer = new Element('div', {
			id: 'popOver-footer'
		}).adopt(
			new Element('img', {
				src: '../images/popover_bottom.png',
				width: '596',
				height: '12'
			})
		);
		var inner = new Element('div', {
			id: 'popOver-content'
		});

		elements.each(function (e) {
			if (e.get('id') == 'rightCol') {
				e.getChildren().each(function (el) {
					inner.adopt(el);
				});
			}
		});

		inner.adopt(
			new Element('div', {
				id: 'popOver-close'
			}).adopt(
				new Element('a', {
					href: '#',
					text: 'Close',
					'class': 'close'
				})
			)
		);

		element.adopt(
			header,
			inner,
			footer
		);


		return element;
	}
});

var PseudoSelect = new Class({
	Implements: [Options, Events, Element],
	element: null,
	toggler: null,
	input: null,
	list: null,
	options: [],
	open: false,
	evtClose: null,
	initialize: function(element) {
		if (!element) {
			return;
		}

		//Element.extend(this);

		this.replaceSelect(element);

		if (!this.element || !this.toggler || !this.input || !this.list || !this.options) {
			return;
		}

		this.open = false;
		this.list.setStyle('display', 'none');
		this.toggler.addEvent('mousedown', this.toggleClicked.bind(this));

		// populate the selected value
		var selected = this.list.getElement('.selected');
		if (!selected) {
			selected = this.options[0];
		}
		this.setSelected(selected);


		$(document.body).addEvent('mousedown', this.close.bind(this));

		// add option events
		this.options.each(function (option) {
			option.addEvent('click', this.optionClicked.bind(this));
		}, this);

		// fix the widths of the lists
		this.list.setStyles({
			display: 'block',
			visibility: 'hidden'
		});
		var width = this.toggler.getSize().x;

		var lis = this.options;
		var w = 0;
		this.options.each(function (option) {
			var size = option.getSize();
			w = (size.x > w) ? size.x : w;
		});
		var paddings = parseInt(lis[0].getStyle('paddingLeft')) + parseInt(lis[0].getStyle('paddingRight'));
		var borders = parseInt(this.list.getStyle('borderLeftWidth')) + parseInt(this.list.getStyle('borderRightWidth'));
		if (w < width) {
			w = width;
		}
		if (!isNaN(paddings)) {
			w -= paddings;
		}
		if (!isNaN(borders)) {
			w -= borders;
		}
		if (w > 0) {
			this.options.each(function (option) {
				option.setStyle('width', w);
			});
		}

		this.list.setStyles({
			display: 'none',
			visibility: ''
		});

		// add hover styles for IE6
		this.isIE6 = /MSIE\s6/.test(navigator.userAgent);
		if (this.isIE6) {
			this.options.each(function (option) {
				option.addEvent('mouseenter', function () { this.addClass('hover'); });
				option.addEvent('mouseleave', function () { this.removeClass('hover'); });
			});
		}
		return this;
	},
	replaceSelect: function (select) {
		this.element = new Element('div', {
			'class': select.get('class')
		});
		this.element.addClass('pseudo-select');

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

		var value = select.get('value');

		this.input = new Element('input', {
			id: select.get('id'),
			type: 'hidden',
			name: select.get('name'),
			value: value
		}).inject(this.element);
		this.toggler = new Element('span').inject(this.element);
		this.label = new Element('em').inject(this.toggler);
		this.list = new Element('ul').inject(this.element);

		var label = '';
		select.getElements('option').each(function (option) {
			var li = new Element('li', {
				'class': option.get('class'),
				'html': option.get('text') + ' <span>' + option.value + '</span>'
			}).inject(this.list);
			this.options.push(li);
			if (option.value == value && !label) {
				li.addClass('selected');
				this.label.set('text', value);
			}
		}, this);

		// do the replacement
		if (select.getParent()) {
			this.element.replaces(select);
		}
	},
	toggleClicked: function (evt) {
		this.open = !this.open;
		this.list.setStyle('display', this.open ? 'block' : 'none');
		this.toggler.toggleClass('open');
	},
	optionClicked: function (evt) {
		var el = evt.target;
		if (!this.open || !el) {
			return false;
		}

		this.setSelected(el);

		this.toggleClicked();
	},
	setSelected: function (el) {
		if (!el) {
			return;
		}
		var value = el.getElement('span').get('text');

		var e = el.clone(true);
		e.getElement('span').destroy();
		var text = e.get('text');

		this.options.each(function (option) {
			this.element.removeClass(option.get('class'));
		}, this);
		this.element.addClass(el.get('class'));

		this.input.set('value', value);
		this.element.fireEvent('change');
		this.label.set('text', text);
	},
	close: function (evt) {
		if (this.open && !this.element.hasChild(evt.target)) {
			evt.stop();
			this.toggleClicked();
		}
	}
});



var BannerKwick = new Class({
	Implements: Options,
	container: null,
	element: null,
	sMax: 0,
	sMin: 0,
	fx: null,
	options: {
		duration: 300,
		transition: Fx.Transitions.Expo.easeOut,
		wait: false
	},
	initialize: function (container, element, options) {
		this.container = container;
		this.element = element;
		this.setOptions(options)

		this.container.setStyles({
			cursor: 'pointer'
		});

		// the the current position
		this.sMax = 0;
		this.sMin = -this.element.getStyle('width').toInt();

		this.fx = new Fx.Tween(this.element, this.options);
		this.fx.set('left', this.sMin);

		this.container.addEvent('mouseenter', this.enter.bind(this));
		this.container.addEvent('mouseleave', this.leave.bind(this));
		this.container.addEvent('click', this.click.bind(this));
	},
	enter: function () {
		this.fx.cancel();
		this.fx.start('left', this.sMax);
	},
	leave: function () {
		this.fx.cancel();
		this.fx.start('left', this.sMin);
	},
	click: function () {
		var e = this.element.getElement('a');
		window.location = e.get('href');
		return false;
	}
});

function submitForm(evt, e) {
	var form = null;

	// get the parent form
	$$('form').each(function (f) {
		if (f.hasChild(e)) {
			form = f;
			return;
		}
	});

	if (!form) {
		return;
	}
	if (e.get('tag') == 'a') {
		evt.stop();
		//check get variables
		var hrefParts = e.href.split('?');
		if (hrefParts.length > 1) {
			var sep = (form.action.indexOf('?') != -1) ? '&' : '?';
			form.action += sep + hrefParts[1];
		}
	}
	else if (e.get('tag') == 'select') {
		// make sure an item is selected
		var selected = 0;
		form.getElements('input[type=checkbox]').each(function (el) {
			if (el.checked) {
				selected++;
			}
		});
		form.getElements('input[type=radio]').each(function (el) {
			if (el.checked) {
				selected++;
			}
		});

		if (selected == 0) {
			alert('Please select at least one item.');
			e.selectedIndex = 0;
			return;
		}

		switch (e.value) {
			case '':
				return;
			case 'delete':
				if (!confirm('Are you sure you wish to delete this item?')) {
					e.selectedIndex = 0;
					return;
				}
				break;
		}
	}

	form.submit();
}


var CriteriaSelector = new Class({
	Implements: Options,
	rows: [],
	nextIndex: 1,
	themes: [],
	categories: [],
	values: [],
	row: null,
	options: {
		rowClass: 'criteria-row',
		fieldIdBaseName: 'criteria-value',
		btnAdd: {
			className: 'add',
			value: 'Add'
		},
		btnRemove: {
			className: 'remove',
			value: 'Remove'
		}
	},
	initialize: function(options) {
		this.setOptions(options);

		// get all the select lists for criteria
		var elements = $$('.' + this.options.rowClass + ' .criteria-field');
		if (elements && elements.length > 0) {
			var options = elements[0].getElements('option');
			options.each(function (option) {
				var field = option.get('value');
				var select = $('criteria-field-' + field);
				if (select) {
					this.values.push({
						field: field,
						select: select
					});
				}
			}, this);
		}
		/*
		var elements = $$('.' + this.options.rowClass + ' .criteria-col-field li span');
		elements.each(function (option) {
			var field = option.get('text');
			var select = $('criteria-field-' + field);
			if (select) {
				this.values.push({
					field: field,
					select: select
				});
			}
		}, this);
		*/

		//get all rows
		this.rows = $$('.' + this.options.rowClass);
		if (!this.rows.length) {
			return;
		}

		this.row = this.rows[0].clone();

		this.rows.each(function (el) {
			this.initRow(el);
		}, this);
		this.nextIndex = this.rows.length + 1;
	},
	initRow: function (el) {
		// check the field
		el.getElements('select').each(function (el) {
			new PseudoSelect(el);
		});

		var criteria = el.getElement('.criteria-field');
		var input = el.getElement('.criteria-value');

		// sort out the fields to be displayed
		if (criteria.hasClass('ltgt')) {
			var e = el.getElement('.criteria-col-operator');
			if (e) {
				e.setStyle('display', 'block');
			}
			else {
				e = new Element('div', {
					'class': 'criteria-col-operator'
				}).inject(el.getElement('.criteria-col-field'), 'after');
				var select = new Element('select', {
					name: 'criteria-operator[]'
				}).inject(e);
				new Element('option', {
					'value': 'gt',
					'text': 'Greater than'
				}).inject(select);
				new Element('option', {
					'value': 'lt',
					'text': 'Less than'
				}).inject(select);
				select = new PseudoSelect(select);
			}
			el.getElement('.criteria-col-value').addClass('criteria-col-value-short');
		}
		else {
			var e = el.getElement('.criteria-col-operator');
			if (e) {
				e.setStyle('display', 'none');
			}
			el.getElement('.criteria-col-value').removeClass('criteria-col-value-short');
		}

		var is_select = false;
		this.values.each(function (value) {
			if (value.field == criteria.get('value') && !is_select) {
				var select = value.select.clone(true, false);
				var options = select.getElements('option');
				select.set({
//					name: input.get('name'),
					name: this.options.fieldIdBaseName + '[]',
					id: input.get('id'),
					'class': input.get('class')
				});
				for (var i = 0; i < options.length; i++) {
					if (input.get('value') == options[i].get('value')) {
						select.selectedIndex = i;
						break;
					}
				}
				is_select = true;

				var p = input.getParent();
				p.empty();
				p.adopt(select);
				select = new PseudoSelect(select);
			}
		}, this);
		if (!is_select) {
			// put a text input in
			var text = new Element('input', {
				name: input.get('name'),
				id: input.get('id'),
				'class': input.get('class'),
				type: 'text',
				//value: input.get('value')
				value: ''
			});
			var p = input.getParent().adopt(text);
			input.destroy();
		}

		criteria.removeEvents('change');
		criteria.addEvent('change', this.initRow.bind(this, el));


		// add the events
		var btnAdd = el.getElement('.' + this.options.btnAdd.className);
		btnAdd.removeEvents('click');
		btnAdd.addEvent('click', function (evt) {
			evt.stop();
			this.addRow(el);
		}.bindWithEvent(this));

		var btnRemove = el.getElement('.' + this.options.btnRemove.className);
		btnRemove.addEvent('click', function (evt) {
			evt.stop();
			this.removeRow(el);
		}.bindWithEvent(this));
	},
	addRow: function (el) {
		var row = this.row.clone();
		var input = row.getElement('.criteria-value');
		if (input) {
			input.setAttribute('id', this.options.fieldIdBaseName + this.nextIndex);
			input.value = '';
		}

		// get the current criteria value and set it in the cloned row
		var field = row.getElement('.criteria-field');
		var value = el.getElement('.criteria-field').get('value');
		if (field.nodeName == 'SELECT') {
			field.getElements('option').each(function (option, i) {
				if (option.get('value') == value) {
					option.set('selected', 'selected');
					field.selectedIndex = i;
				}
			});
		}

		row.inject(el, 'after');
		this.initRow(row);
		this.rows.push(row);

		// sort out the z-indexes for IE
		var i = this.rows.length + 1;
		$$('.' + this.options.rowClass).each(function (e) {
			e.setStyle('z-index', i--);
		});
	},
	removeRow: function(el) {
		if (this.rows.length < 2) {
			this.addRow(el);
		}
		this.rows.erase(el);
		el.destroy();
	}
});

var CriteriaSelector2 = new Class({
	Implements: Options,
	rows: [],
	nextIndex: 1,
	themes: [],
	categories: [],
	values: [],
	options: {
		rowClass: 'criteria-row',
		fieldIdBaseName: 'criteria-value',
		btnAdd: {
			className: 'add',
			value: 'Add'
		},
		btnRemove: {
			className: 'remove',
			value: 'Remove'
		}
	},
	initialize: function(options) {
		this.setOptions(options);

		// get all the select lists for criteria
		var elements = $$('.' + this.options.rowClass + ' .criteria-field');
		if (elements && elements.length > 0) {
			var options = elements[0].getElements('option');
			options.each(function (option) {
				var field = option.get('value');
				var select = $('criteria-field-' + field);
				if (select) {
					this.values.push({
						field: field,
						select: select
					});
				}
			}, this);
		}

		//get all rows
		this.rows = $$('.' + this.options.rowClass);

		this.rows.each(function (el) {
			this.initRow(el);
		}, this);
		this.nextIndex = this.rows.length + 1;
	},
	initRow: function (el) {
		// check the field
		var criteria = el.getElement('.criteria-field');
		var input = el.getElement('.criteria-value');

		var is_select = false;
		this.values.each(function (value) {
			if (value.field == criteria.get('value') && !is_select) {
				var select = value.select.clone(true, false);
				var options = select.getElements('option');
				select.set({
//					name: input.get('name'),
					name: this.options.fieldIdBaseName + '[]',
					id: input.get('id'),
					'class': input.get('class')
				});
				for (var i = 0; i < options.length; i++) {
					if (input.get('value') == options[i].get('value')) {
						select.selectedIndex = i;
						break;
					}
				}
				is_select = true;
				var p = input.getParent().adopt(select);
				input.destroy();
			}
		}, this);
		if (!is_select && input.nodeName == 'SELECT') {
			// put a text input in
			var text = new Element('input', {
				name: input.get('name'),
				id: input.get('id'),
				'class': input.get('class'),
				type: 'text'
			});
			var p = input.getParent().adopt(text);
			input.destroy();
		}

		criteria.removeEvents('change');
		criteria.addEvent('change', this.initRow.bind(this, el));

		// add the events
		var btnAdd = el.getElement('.' + this.options.btnAdd.className);
		btnAdd.removeEvents('click');
		btnAdd.addEvent('click', function (evt) {
			evt.stop();
			this.addRow(el);
		}.bindWithEvent(this));

		var btnRemove = el.getElement('.' + this.options.btnRemove.className);
		btnRemove.addEvent('click', function (evt) {
			evt.stop();
			this.removeRow(el);
		}.bindWithEvent(this));
	},
	addRow: function (el) {
		// duplicate the current row and insert it under the current one
		var newRow = el.clone();
		var input = newRow.getElement('.criteria-value');
		if (input) {
			input.setAttribute('id', this.options.fieldIdBaseName + this.nextIndex);
			input.value = '';
		}

		var select = newRow.getElement('.criteria-field');
		if (select) {
			select.selectedIndex = 0;
		}

		this.initRow(newRow);

		newRow.inject(el, 'after');

		this.rows.push(newRow);
	},
	removeRow: function(el) {
		if (this.rows.length < 2) {
			this.addRow(el);
		}
		this.rows.erase(el);
		el.destroy();
	}
});
