/* -*- C -*- */

/* --------------------------------------------------------------------
 * Shine: The Become Interactive Client Application Framework
 * @(#) $Id$
 * --------------------------------------------------------------------
 * Copyright (c) 2006 Become Interactive
 * http://www.becomeinteractive.co.uk
 * All rights reserved.
 * --------------------------------------------------------------------
 * This software is the confidential and proprietary information of
 * Become Interactive ("Confidential Information").
 *
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * with the terms of the license agreement you entered into with
 * Become Interactive.
 * --------------------------------------------------------------------
 */

var Shine;

if(typeof com == "undefined") var com = new Object();
if(typeof com.uk == "undefined") com.uk = new Object();
if(typeof com.uk.become == "undefined") com.uk.become = new Object();
if(typeof com.uk.become.shine == "undefined") com.uk.become.shine = new Object();

var ua = navigator.userAgent.toLowerCase();
var opera = (ua.indexOf("opera") != -1);
var ie = (ua.indexOf("msie") != -1 && !opera && (ua.indexOf("webtv") == -1))
var root_path = "/";
var html_path = "/";
var toggle_layer = "";
var input_error = (typeof input_error=='undefined' ? [] : input_error);

/**
 * com.uk.become.shine.Browser
 *
 * Provides information about the host browser.
 */

com.uk.become.shine.Browser = function()
{
	var ua;
	
	ua = navigator.userAgent.toLowerCase();	
	this.userAgent = navigator.userAgent;
	this.isOpera = ((ua.indexOf("opera") != -1) || window.opera);
	this.isWebTV = (ua.indexOf("webtv") != -1);
	this.isIE = (ua.indexOf("msie") != -1) && !com.uk.become.shine.Browser.isOpera && !com.uk.become.shine.Browser.isWebTV;
	this.isWebKit = (ua.indexOf('applewebkit') != -1);
	this.ieVersion = false;
	if(document.createElementNS)
		{
			this.isDOM = true;
		}
	else
		{
			this.isDOM = false;
		}
	if(this.ieIE)
		{
			this.ieVersion = navigator.appVersion.match(/MSIE (\d.\d)/)[1];
		}
}

/**
 * com.uk.become.shine.Core
 *
 * A layer of cross-browser glue for event handling, class-triggered behaviours,
 * and other support functions. 
 */

com.uk.become.shine.Core = function(window, document)
{
	this.version = '$Id$';
	this.basePath = '/includes/';
	this.rootPath = '/';
	this.tplPath = '/';
	this._abort = false;
	this._window = window;
	this._document = document;
	this._loaded = false;
	this._loadHandlers = new Array();
	this._validating = false;
	this._fieldValidators = new Array();
	this._forms = new Array();
	this._validateInterval = false;
	this._popupCount = 0;
	this._formDirty = 0;
	this._shineDebug = false;
	this._requiredModules = new Object();
	this._requiredModules['com.uk.become.shine.core'] = true;
	this.body = false;	
	this.browser = new com.uk.become.shine.Browser();
	if(this.browser.isIE && (this.browser.isVersion < 5 || this.browser.isVersion >= 7))
	{
		this._abort = true;
		return false;
	}
	if(typeof shineDebugMode != 'undefined' && shineDebugMode)
	{
		this._shineDebug = true;
	}
	if(this._shineDebug)
	{
		this.debug('Shine:', this.version);
	}
/*	if (this.browser.isDOM)	
		{
			this.addEventHandler(document, 'DOMContentLoaded', { host: this, handler: this.loaded });
		} */
	return this;
}
com.uk.become.shine.Core.prototype.debug = function()
{
	var args, a, debugContainer, p;
	
	args = new Array();
	d = args.length;	
	for(c = 0; c < arguments.length; c++)
		{
			args[d] = arguments[c];
			d++;
		}
	args = args.join(' ');	
	if(!arguments.length)
		{
			return false;
		}
	if(this.browser.isWebKit || window.console)
		{
			if(window.console && this.browser.isWebKit)
				{
					window.console.log(args);
				}
			else if(window.console)
				{
					window.console.log("%s", args);
				}	   
		}
	else if(this.browser.isIE)
	{
		debugContainer = document.getElementById('shine-debug-container');
		if(debugContainer)
		{
			if(!debugContainer.shineVisible)
			{
				debugContainer.shineVisible = true;
				debugContainer.style.display = 'block';
				debugContainer.style.position = 'fixed';
				debugContainer.style.overflow = 'scroll';
				debugContainer.style.height = '64px';
				debugContainer.style.left = '0px';
				debugContainer.style.width = '100%';
				debugContainer.style.bottom = '0px';
				debugContainer.style.borderTop = 'solid #000 2px';
				debugContainer.style.margin = '0';
				debugContainer.style.padding = '0';
				debugContainer.style.backgroundColor = '#fff';
				debugContainer.style.color = '#000';
			}
			p = Shine.createHTMLElement('p');
			p.appendChild(document.createTextNode(args));
			debugContainer.appendChild(p);
		}
	}
	else if(this.browser.isOpera && window.opera.postError)
		{
			window.opera.postError(args);
		}
	else if(document.createEvent && window.dispatchEvent)
		{
			printfire = new Object();
			printfire.args = new Array(args);
			var ev = document.createEvent('Events');
			ev.initEvent('printfire', false, true);
			try
				{
					dispatchEvent(ev);
				}
			catch(e)
				{
				}
		}
	return true;
}
com.uk.become.shine.Core.prototype.createHTMLElement = function(tagName, attrs)
{
	var html, i, el;
	
	if(this.browser.isDOM)
	{
		el = document.createElementNS('http://www.w3.org/1999/xhtml', tagName);
		if(el)
		{
			if(typeof attrs !== 'undefined')
			{
				for(i in attrs)
				{
					this.setAttribute(el, i, attrs[i]);
				}
			}
		}
		return el;
	}
	if(typeof attrs !== 'undefined')
	{
		html = '<' + tagName;
		for(i in attrs)
		{
			if((i == 'checked' || i == 'selected') && attrs[i])
			{
				html += i;
			}
			else
			{
				html += ' ' + i + '="' + attrs[i] + '"'
			}
		}
		html += '>';
		return document.createElement(html);
	}
	return document.createElement(tagName);
}
com.uk.become.shine.Core.prototype.createRequest = function(method, uri)
{
	return new com.uk.become.shine.Request(method, uri);
}
com.uk.become.shine.Core.prototype._loadScript = function(path)
{
	var sel, heads;
	
	this.debug('Shine:', 'Loading script from ' + path);
	if(this.browser.isDOM)
	{
		heads = document.getElementsByTagName('head');
		if(heads && heads.length)
		{
			heads = heads[0];
		}
		else
		{
			return false;
		}
		sel = this.createHTMLElement('script');
		this.setAttribute(sel, 'type', 'text/javascript');
		this.setAttribute(sel, 'src', path);
		heads.appendChild(sel);
	}
	else
	{
		document.write('<' + 'script type="text/javascript" src="' + path + '"></script>');
	}
}
com.uk.become.shine.Core.prototype.importStylesheet = function(path, media)
{
	var sel, heads;
	
	this.debug('Shine:', 'Loading stylesheet from ' + path);
	if(this.browser.isDOM)
	{
		heads = document.getElementsByTagName('head');
		if(heads && heads.length)
		{
			heads = heads[0];
		}
		else
		{
			return false;
		}
		sel = this.createHTMLElement('link');
		this.setAttribute(sel, 'type', 'text/css');
		this.setAttribute(sel, 'media', media);
		this.setAttribute(sel, 'href', path);
		this.setAttribute(sel, 'rel', 'stylesheet');
		heads.appendChild(sel);
	}
	else
	{
		document.write('<' + 'link rel="stylesheet" type="text/css" href="' + path + '" media="screen,projection" />');
	}
}
com.uk.become.shine.Core.prototype.require = function(path, base, id)
{
	var req;

	if(typeof path == 'undefined')
		{
			Shine.debug('Attempt to require undefined path');
			return false;
		}
	if(typeof this._requiredModules[id] != 'undefined')
	{
		return true;
	}
	this._requiredModules[id] = this.basePath + path;
	if(base == 1)
		{
			path = this.basePath + path;
		}
	else if(base == 2)
		{
			path = this.rootPath + path;
		}
	return this._loadScript(path);
}
com.uk.become.shine.Core.prototype.setAttribute = function(element, name, value)
{
	if(this.browser.isDOM)
		{
			element.setAttribute(name.toLowerCase(), value);
		}
	else
		{
			if(name == 'class')
			{
				name = 'className';
			}
			else if(name == 'checked' || name == 'selected')
			{
				if(value)
				{
					value = true;
				}
				else
				{
					value = false;
				}
			}
			eval('element.' + name + '= value');
		}
}
com.uk.become.shine.Core.prototype.addEventHandler = function(element, eventName, handler)
{
	var force, _Shine = this;
	
	force = false;
	if(typeof element == 'string')
		{
			element = document.getElementById(element);
		}
	if(!element)
		{
			return false;
		}
	if(!handler || !handler.handler)
		{
			Shine.debug('Shine:', 'Invalid handler passed for event on' + eventName);
			return false;
		}
	if(!element.shineEventHandlers)
	{
		element.shineEventHandlers = new Array();
	}
	if(!element.shineEventHandlers[eventName])
	{
		element.shineEventHandlers[eventName] = new Array();
		if(this.browser.isWebKit && eventName == 'click')
		{
			force = true;
		}
		if(this.browser.isDOM && element.addEventListener && !force)
		{
			element.addEventListener(eventName, 
								 	function(ev) { 
										return _Shine._eventHost(eventName, element, ev);
								 		}, false);
		}
		else if(element.attachEvent && element.attachEvent && !force)
		{
			element.attachEvent('on' + eventName, function(ev) { return Shine._eventHost(eventName, element, (ev ? ev : window.event)); });
		}
		else
		{
			eval('element.on' + eventName + ' = function(ev) { return Shine._eventHost(eventName, element, (ev ? ev : window.event)); }');
		}
	}
	element.shineEventHandlers[eventName].unshift(handler);
}
com.uk.become.shine.Core.prototype._eventHost = function(evtype, sender, ev)
{
	var handlers;
	
	if(!sender.shineEventHandlers || !sender.shineEventHandlers[evtype])
	{
		return true;
	}
	for(c in sender.shineEventHandlers[evtype])
	{
		if(!this.callEventHandler(sender, ev, sender.shineEventHandlers[evtype][c]))
		{
			if(ev.stopPropagation)
			{
				ev.stopPropagation();
			}
			if(ev.preventDefault)
			{
				ev.preventDefault();
			}
			ev.cancelBubble = true;
			return false;
		}
	}
	return true;
}
com.uk.become.shine.Core.prototype.callEventHandler = function(sender, event, handler)
{
	if(!handler.host)
		{
			handler.host = window;
		}
	handler.host._shineHandler = handler.handler;
	return handler.host._shineHandler(this, sender, event, handler.data);
}
com.uk.become.shine.Core.prototype.getAttribute = function(element, name)
{
	if(this.browser.isDOM)
		{
			return element.getAttribute(name);
		}
	if(name == 'class')
		{
			name = 'className';
		}
	return eval('element.' + name);
}
com.uk.become.shine.Core.prototype.getElementClass = function(element, forceDirect)
{
	var cn;

	if(element.shineStyleTarget && !forceDirect)
		{
			element = element.shineStyleTarget;
		}
	cn = this.getAttribute(element, 'class');
	if(typeof cn != 'string')
		{
			return '';
		}
	return cn;
}
com.uk.become.shine.Core.prototype._initStyles = function(element)
{
	if(element.shineStyleTarget)
	{
		element = element.shineStyleTarget;
	}
	if(typeof element.shineOriginalClass != 'string')
	{
		element.shineOriginalClass = this.getElementClass(element);
	}
	if(typeof element.shineClasses == 'undefined')
	{
		element.shineClasses = new Array();
	}
	return element;
}
com.uk.become.shine.Core.prototype._updateElementClass = function(element)
{
	var cn, cn2;
	
	cn = this.getAttribute(element, 'class');
	cn2 = element.shineOriginalClass + ' ' + element.shineClasses.join(' ');
	if(cn != cn2)
		{
			this.setAttribute(element,  'class', cn2);
		}
	return true;
}
com.uk.become.shine.Core.prototype.beginUpdate = function(element)
{
	element = this._initStyles(element);
	element._shineUpdating = true;
	return true;
}
com.uk.become.shine.Core.prototype.endUpdate = function(element)
{
	element = this._initStyles(element);
	element._shineUpdating = false;
	return this._updateElementClass(element);
}
com.uk.become.shine.Core.prototype.resetElementClass = function(element)
{
	element = this._initStyles(element);
	element.shineClasses = new Array();
	if(element._shineUpdating)
		{
			return true;
		}
	return this._updateElementClass(element);
}
com.uk.become.shine.Core.prototype.addElementClass = function(element, classname)
{
	var c;
		
	element = this._initStyles(element);
	for(c in element.shineClasses)
	{
		if(element.shineClasses[c] == classname)
		{
			return false;
		}
	}
	element.shineClasses[element.shineClasses.length] = classname;
	if(element._shineUpdating)
		{
			return true;
		}
	return this._updateElementClass(element);
}
com.uk.become.shine.Core.prototype.removeElementClass = function(element, classname)
{
	var c;
	
	element = this._initStyles(element);
	for(c in element.shineClasses)
	{
		if(element.shineClasses[c] == classname)
		{
			element.shineClasses.splice(c, 1);
		}
	}
	if(element._shineUpdating)
		{
			return true;
		}	
	return this._updateElementClass(element);
}
com.uk.become.shine.Core.prototype.hasElementClass = function(element, classname, forceDirect)
{
	var cn;

	if(!forceDirect)
		{
			forceDirect = false;
		}
	cn = ' ' + this.getElementClass(element, forceDirect) + ' ';
	if(cn.indexOf(' ' + classname + ' ') != -1)
		{
			return true;
		}
	return false;
}													
com.uk.become.shine.Core.prototype._inputHandler = function(shine, sender, event)
{
	var valid, empty, focussed, s;
	
	valid = true;
	s = false;
	prevalidated = false;
	if(typeof sender.defaultValue != 'undefined')
		{
			if(sender.value == sender.defaultValue && sender.acErrorField)
				{
					valid = false;
					prevalidated = true;
				}
		}
	empty = (sender.value ? false : true);	
	focussed = (sender.focussed ? true: false);
	if(!prevalidated && !empty && sender.shineValidator)
		{
			if(sender.shineValidatedValue && sender.shineValidatedValue == sender.value)
			{
				return true;
			}
			ev = new Object();
			ev.value = sender.value;
			ev.target = sender;
			ev.empty = empty;
			ev.focussed = focussed;
			valid = this.callEventHandler(sender, ev, sender.shineValidator);
			sender.shineValidatedValue = sender.value;
		}
	if(typeof sender.shinePrevValue == 'undefined' ||
	   sender.value != sender.shinePrevValue)
		{			
			this._formDirty++;
			sender.shinePrevValue = sender.value;
		}
	this.beginUpdate(sender);
	this.addElementClass(sender, 'shine-input');
	if(sender.shineSubField)
	{
		this.addElementClass(sender, 'shine-subfield');
	}
	this.removeElementClass(sender, 'shine-input-progress');
	this.removeElementClass(sender, 'shine-input-ok');
	this.removeElementClass(sender, 'shine-input-bad');
	this.removeElementClass(sender, 'shine-input-empty');	
	this.removeElementClass(sender, 'shine-input-focus');	
	if(sender.shineValidateInProgress)
	{
		this.addElementClass(sender, 'shine-input-progress');
		sender.shineValidated = false;
		sender.shineIncomplete = false;		
	}
	else if(empty)
	{
		this.addElementClass(sender, 'shine-input-empty');
		sender.shineValidated = false;
		sender.shineIncomplete = true;
	}
	else if(valid)
	{
		this.addElementClass(sender, 'shine-input-ok');
		sender.shineValidated = true;
		sender.shineIncomplete = false;
	}
	else
	{
		this.addElementClass(sender, 'shine-input-bad');
		sender.shineValidated = false;
		sender.shineIncomplete = false;
	}
	if(focussed)
	{
		this.addElementClass(sender, 'shine-input-focus');
	}
	this.endUpdate(sender);
	return true;
}
com.uk.become.shine.Core.prototype.validateField = function(sender, event)
{
	return this._inputHandler(this, sender, event);
}
com.uk.become.shine.Core.prototype._inputFocus = function(shine, sender, event)
{
	if(sender.focussed) return true;
	sender.focussed = true;
	this._inputHandler(shine, sender, event);
	return true;
}
com.uk.become.shine.Core.prototype._inputBlur = function(shine, sender, event)
{
	if(!sender.focussed) return true;
	sender.focussed = false;
	this._inputHandler(shine, sender, event);
	return true;
}
com.uk.become.shine.Core.prototype._inputKeyUp = function(Shine, sender, event, data)
{
	var h;
	
	if(event.keyCode == 13)
		{
			if(sender.form && sender.tagName.toLowerCase() != 'textarea')
				{
					if(data)
					{
						h = Shine.createHTMLElement('input');
						Shine.setAttribute(h, 'type', 'hidden');
						Shine.setAttribute(h, 'name', data.name);
						Shine.setAttribute(h, 'value', data.value);
						sender.form.appendChild(h);
					}
					sender.form.submit();
					return false;
				}
		}
	return true;
}
com.uk.become.shine.Core.prototype.addInputHandlers = function(elements, validator, data)
{
	var c;
	
	for(c = 0; c < elements.length; c++)
		{
			this.addInputHandler(elements[c], validator, data);
		}
}
com.uk.become.shine.Core.prototype.addLinkHandlers = function(elements, handler)
{
	var c;
	
	for(c = 0; c < elements.length; c++)
		{
			this.addLinkHandler(elements[c], handler);
		}
}
com.uk.become.shine.Core.prototype.addSubmitReplacements = function(elements)
{
	var c;
	
	for(c = 0; c < elements.length; c++)
		{
			this.addSubmitReplacement(elements[c]);
		}
}
com.uk.become.shine.Core.prototype.addSubmitReplacement = function(element)
{
	var link, span, tn, inputs;
	
	link = this.createHTMLElement('a');
	span = this.createHTMLElement('span');
	span.shineLink = link;
	link._shineForm = element.form;
	if(element.form)
	{
		if(!element.form._submitButton && !Shine.hasElementClass(element, 'not-default-submit'))
		{
			element.form._submitButton = element;
			inputs = element.form.getElementsByTagName('input');
			for(i = 0; i < inputs.length; i++)
			{
				this.addEventHandler(inputs[i], 'keyup', { host: this, handler: this._inputKeyUp, data: element });
			}
		}
	}
	link._shineSubmitButton = element;
	this.setAttribute(link, 'href', 'javascript:void(0);');
	this.setAttribute(span, 'class', 'shine-replaced-button');
	id = this.getAttribute(element, 'id');
	if(id)
	{
		this.setAttribute(span, 'id', 'sr-' + id);
	}
	this.addEventHandler(link, 'click', { host: this, handler: this._submitHandler });
	span.appendChild(link);
	tn = document.createTextNode(this.getAttribute(element, 'value'));
	link.appendChild(tn);
	element.parentNode.replaceChild(span, element);
}
com.uk.become.shine.Core.prototype._submitHandler = function(Shine, sender, ev, data)
{
	var node;
	
	if(sender._shineForm)
	{
		node = this.createHTMLElement('input');
		this.setAttribute(node, 'type', 'hidden');
		this.setAttribute(node, 'name' , this.getAttribute(sender._shineSubmitButton, 'name'));
		this.setAttribute(node, 'value', this.getAttribute(sender._shineSubmitButton, 'value'));
		sender._shineForm.appendChild(node);
		sender._shineForm.submit();
	}
	return false;
}
com.uk.become.shine.Core.prototype.addLinkHandler = function(element, handler)
{
	element.shineLinkRef = this.getAttribute(element, 'href');
	return this.addEventHandler(element, 'click', handler);
}
com.uk.become.shine.Core.prototype._createStyleWrapper = function(element)
{
	var newel;
	
	/* Create a wrapper element around an element, and set the child's
	 * .shineStyleTarget property to point to the new element. Useful for
	 * elements which can't really be styled themselves (e.g., list/drop-down
	 * boxes)
	 */
	if(element.parentNode && element.parentNode.shineStyleSource)
		{
			element.shineStyleTarget = element.parentNode;
			return element.parentNode;
		}
	newel = this.createHTMLElement('span');
	element.parentNode.replaceChild(newel, element);
	newel.appendChild(element);
	newel.shineStyleSource = true;
	element.shineStyleTarget = newel;
	return newel;
}
com.uk.become.shine.Core.prototype.addInputHandler = function(element, handler)
{
	if(typeof element == 'string')
		{
			element = document.getElementById(element);
		}
	if(!element)
		{
			return false;
		}
	this._createStyleWrapper(element);
	if(element.form)
		{
			if(!element.form.shineFields)
				{
					element.form.shineFields = new Array();
				}
			element.form.shineFields[element.form.shineFields.length] = element;
			if(!element.form.shineForm)
				{
					element.form.shineForm = true;
					this._forms[this._forms.length] = element.form;
				}
		}
	this.addElementClass(element, 'shine-input');
	if(this.hasElementClass(element, 'subfield', true))
	{
		element.shineSubField = true;
		this.addElementClass(element, 'shine-subfield');
	}
	else
	{
		element.shineSubField = false;
	}
	element.shineValidator = handler;
	element.shineValidatorData = handler.data;
	element.shineValidated = false;
	element.shineIncomplete = true;
	element.shineValidateInProgress = false;
	this._fieldValidators[this._fieldValidators.length] = element;
	this.addEventHandler(element, 'focus', { host: this, handler: this._inputFocus });
	this.addEventHandler(element, 'blur', { host: this, handler: this._inputBlur });
	return element;
}
com.uk.become.shine.Core.prototype._validateFields = function()
{
	var e, complete, valid;
	
	if(this._validating)
		{
			return true;
		}
	if(!this._formDirty)
		{
			return true;
		}
	this._validating = true;
	for(e in this._fieldValidators)
		{
			this._inputHandler(this, this._fieldValidators[e], false);
		}
	for(f in this._forms)
		{
			complete = true;
			valid = true;			
			for(e in this._forms[f].shineFields)
				{
					if(this._forms[f].shineFields[e].shineIncomplete)
						{
							complete = false;
						}
					if(!this._forms[f].shineFields[e].shineValidated)
						{
							valid = false;
						}
				}
			s = '';
			this.beginUpdate(this._forms[f]);
			this.removeElementClass(this._forms[f], 'form-complete');
			this.removeElementClass(this._forms[f], 'form-incomplete');
			this.removeElementClass(this._forms[f], 'form-valid');
			this.removeElementClass(this._forms[f], 'form-invalid');			
			this.removeElementClass(this._forms[f], 'form-valid-complete');
			this.removeElementClass(this._forms[f], 'form-not-valid-complete');						
			if(complete)
				{
					this.addElementClass(this._forms[f], 'form-complete');
				}
			else
				{
					this.addElementClass(this._forms[f], 'form-incomplete');
				}
			if(valid)
				{
					this.addElementClass(this._forms[f], 'form-valid');
				}
			else
				{
					this.addElementClass(this._forms[f], 'form-invalid');
				}
			if(complete && valid)
				{
					this.addElementClass(this._forms[f], 'form-valid-complete');
				}
			else
				{
					this.addElementClass(this._forms[f], 'form-not-valid-complete');					
				}
			this.endUpdate(this._forms[f]);
		}
	this._validating = false;
	if(this.formDirty > 0)
		{
			this._formDirty--;
		}
}
com.uk.become.shine.Core.prototype.getElementsByClass = function(root, el, classname)
{
	var c, nl, nlc, nodes, node;
	
	nodes = root.getElementsByTagName(el);
	nl = new Array();
	nlc = 0;
	for(c = 0; c < nodes.length; c++)
		{
			node = nodes[c];
			if(this.hasElementClass(node, classname, true))
				{					
					nl[nlc] = node;
					nlc++;
				}
		}
	return nl;
}
com.uk.become.shine.Core.prototype.insertAfter = function(parent, newChild, refChild) 
{ 
	if(refChild.nextSibling) 
	{ 
		return parent.insertBefore(newChild, refChild.nextSibling); 
	} 
	return parent.appendChild(newChild); 
}
com.uk.become.shine.Core.prototype.removeElement = function(element) 
{ 
	if(element.parentNode) 
	{ 
		return element.parentNode.removeChild(element); 
	} 

	return false; 
}
com.uk.become.shine.Core.prototype.addLoadHandler = function(obj)
{
	var ev;
	
	if(this._loaded)
	{
		ev = new Object();
		if(typeof obj.ondocumentloaded == 'undefined')
		{
			Shine.debug('Shine', "Warning: Load handler doesn't implement ondocumentloaded");
		}
		else
		{
			obj.ondocumentloaded(Shine, Shine, ev)
		}
	}
	else
	{
		this._loadHandlers[this._loadHandlers.length] = obj;
	}
}
com.uk.become.shine.Core.prototype.createPopup = function(url, w, h, name)
{
	var win, x, y, settings;
	
	x = (screen.width - w) / 2;
	y = (screen.height - h) / 2;
	settings = 'height=' + h +',';
	settings += 'width=' + w + ',';
	settings += 'top=' + y + ',';
	settings += 'left=' + x + ',';
	settings += 'scrollbars=yes,';
	settings += 'resizable=yes,';
	settings += 'status=no,';
	settings += 'titlebar=no,';
	settings += 'toolbar=no,';
	if(typeof name == undefined || !name)
		{
			name = 'win' + this._popupCount;
		}
	this._popupCount++;
	win = window.open(url, name, settings);
	if(win)
		{
			try
				{
					if(win.focus) win.focus();
				}
			catch(e)
				{
				}
			return false;
		}
	return true;
}
com.uk.become.shine.Core.prototype.popupLinkHandler = function(Shine, sender, ev, data)
{
	if (ev.shiftKey || ev.altKey || ev.ctrlKey || ev.metaKey)
		{
			return true;
		}
	return Shine.createPopup(sender.shineLinkRef, 400, 500);
}
com.uk.become.shine.Core.prototype.largePopupLinkHandler = function(Shine, sender, ev, data)
{
	if (ev.shiftKey || ev.altKey || ev.ctrlKey || ev.metaKey)
		{
			return true;
		}	
	return Shine.createPopup(sender.shineLinkRef, 600, 600);
}
com.uk.become.shine.Core.prototype.contentPopupLinkHandler = function(Shine, sender, ev, data)
{
	if (ev.shiftKey || ev.altKey || ev.ctrlKey || ev.metaKey)
		{
			return true;
		}	
	return Shine.createPopup(sender.shineLinkRef, 800, 600);
}	
com.uk.become.shine.Core.prototype.debugPopupLinkHandler = function(Shine, sender, ev, data)
{
	if (ev.shiftKey || ev.altKey || ev.ctrlKey || ev.metaKey)
		{
			return true;
		}	
	return Shine.createPopup(sender.shineLinkRef, 800, 600);
}
com.uk.become.shine.Core.prototype.externalLinkHandler = function(Shine, sender, ev, data)
{
	var win;
	if (ev.shiftKey || ev.altKey || ev.ctrlKey || ev.metaKey)
		{
			return true;
		}	
	win = window.open(sender.shineLinkRef, '_blank');
	if(win && win.window && win.window.focus) win.window.focus();
	return (win ? false : true);
}
com.uk.become.shine.Core.prototype._createHandlers = function()
{
	var c, n;
	
	nodes = this.getElementsByClass(document, 'a', 'shine-popup-link');
	this.addLinkHandlers(nodes, { host: Shine, handler: Shine.popupLinkHandler });
	nodes = this.getElementsByClass(document, 'a', 'shine-largepopup-link');
	this.addLinkHandlers(nodes, { host: Shine, handler: Shine.largePopupLinkHandler });
	nodes = this.getElementsByClass(document, 'p', 'shine-largepopup-link');
	for(c = 0; c < nodes.length; c++)
		{
			n = nodes[c].getElementsByTagName('a');
			this.addLinkHandlers(n, { host: Shine, handler: Shine.largePopupLinkHandler });
		}
	nodes = this.getElementsByClass(document, 'a', 'shine-contentpopup-link');
	this.addLinkHandlers(nodes, { host: Shine, handler: Shine.largePopupLinkHandler });
	nodes = this.getElementsByClass(document, 'a', 'shine-debugpopup-link');
	this.addLinkHandlers(nodes, { host: Shine, handler: Shine.debugPopupLinkHandler });
	nodes = this.getElementsByClass(document, 'a', 'shine-external-link');
	this.addLinkHandlers(nodes, { host: Shine, handler: Shine.externalLinkHandler });
	nodes = this.getElementsByClass(document, 'a', 'shine-nonhtml-link');
	this.addLinkHandlers(nodes, { host: Shine, handler: Shine.externalLinkHandler });
	nodes = this.getElementsByClass(document, 'input', 'shine-submit-button');
	this.addSubmitReplacements(nodes);
	/* Set up form field validation */
	Shine._validatorInterval = window.setInterval(function() {  Shine._validateFields(); }, 250);
	this._validateFields();	
}
com.uk.become.shine.Core.prototype.loaded = function(Shine, sender, ev, data)
{
	var nodes;

	if(this._loaded)
		{
			return true;
		}
	else if(this._abort)
		{
			return false;
		}
	this.body = document.getElementsByTagName('body').item(0);
	this._loaded = true;
	this._createHandlers();
	for(h in this._loadHandlers)
		{
			this._loadHandlers[h].ondocumentloaded(Shine, sender, ev, data);
		}
	return true;
}

Shine = new com.uk.become.shine.Core(window, document);

/* --------------------------------------------------------------------
 * Shine: The Become Interactive Client Application Framework
 * @(#) $Id$
 * --------------------------------------------------------------------
 * Copyright (c) 2006 Become Interactive
 * http://www.becomeinteractive.co.uk
 * All rights reserved.
 * --------------------------------------------------------------------
 * This software is the confidential and proprietary information of
 * Become Interactive ("Confidential Information").
 *
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * with the terms of the license agreement you entered into with
 * Become Interactive.
 * --------------------------------------------------------------------
 */

/**
 * com.uk.become.shine.Request
 *
 * Scripted HTTP requests on demand
 */
com.uk.become.shine.Request = function(method, uri)
{
	var r;
	var progids = [
				   'MSXML2.XMLHTTP.5.0',
				   'MSXML2.XMLHTTP.4.0',
				   'MSXML2.XMLHTTP.3.0',
				   'MSXML2.XMLHTTP',
				   'Microsoft.XMLHTTP'
				   ];
	
	this._method = method;
	this._uri = uri;
	this._req = false;
	this._loaded = false;
	this._rsInterval = null;
	this.onload = false;
	this.onerror = false;
	this.method = false;
	this.throbber = null;
	this.form = null;
	this.params = new Array();
	this.formVars = new Object();
	this._headers = new Object();
	try
		{
			r = new XMLHttpRequest();
			this._req = r;
		}
	catch(e)
		{
			for(i = 0; i < progids.length; i++)
				{
					try
						{
							r = new ActiveXObject(progids[i]);
							this._req = r;
							break;
						}
					catch(e)
						{
						}
				}
		}
	finally
		{
			return this;
		}
}
com.uk.become.shine.Request.prototype.header = function(n, v)
{
	this._headers[n] = v;
}
com.uk.become.shine.Request.prototype._throbOn = function()
{
	if(!this.throbber) return;
	if(typeof this.throbber.shineThrobDepth == 'undefined')
	{
		this.throbber.shineThrobDepth = 0;
	}
	this.throbber.shineThrobDepth++;
	if(typeof this.throbber.throbOn != 'undefined')
	{
		this.throbber.throbOn();
	}
	else
	{
		this.throbber.style.display = 'block';
	}
}
com.uk.become.shine.Request.prototype._throbOff = function()
{
	if(!this.throbber || typeof this.throbber.shineThrobDepth == 'undefined') return;
	if(this.throbber.shineThrobDepth)
	{
		this.throbber.shineThrobDepth--;
	}
	if(!this.throbber.shineThrobDepth)
	{
		if(typeof this.throbber.throbOff != 'undefined')
		{
			this.throbber.throbOff();
		}
		else
		{
			this.throbber.style.display = 'none';
		}
	}
}
com.uk.become.shine.Request.prototype._readyStateChangeHandler = function(Shine, sender, ev, data)
{
	if(sender.readyState == 4)
		{	
			window.clearInterval(this._rsInterval);
			if(this._loaded)
				{
					return false;
				}
			this._loaded = true;
			this._throbOff();
			ev = new Object();
			ev.status = sender.status;
			ev.statusText = sender.statusText;
			
			if(sender.status == 200)
				{
					if(this.onload)
						{
							ev.responseXML = sender.responseXML;
							ev.responseText = sender.responseText;
							if(typeof ev.responseXML != 'undefined' && ev.responseXML != null && typeof ev.responseXML.lastChild != 'undefined' && ev.responseXML.lastChild != null && typeof ev.responseXML.lastChild.tagName != 'undefined')
							{
								ev.responseRoot = ev.responseXML.lastChild;
							}
							else
							{
								ev.responseRoot = null;
							}
							this.onload(ev);
						}
					else
						{
							Shine.debug('Request::_readyStateChangeHandler:', 'Success: status = ' + sender.status + ' (' + sender.statusText + ')');
						}
				}
			else
				{
					if(this.onerror)
						{
							this.onerror(ev);
						}
					else
						{
							Shine.debug('Request::_readyStateChangeHandler:', 'Failed: status = ' + sender.status + ' (' + sender.statusText + ')');
						}
				}
		}
}
com.uk.become.shine.Request.prototype.open = function()
{
	var h, payload, hfv, _this = this, uri, d;
	
	if(!this._req)
		{
			Shine.debug('Request:', 'Request object has no XMLHttpRequest (' + this._method + ' ' + this._uri + ')');				
			return false;
		}
	hfv = false;
	payload = '';
	if(this.method)
		{
			this._method = 'POST';
			this.header('Content-Type', 'application/vnd.become.rpc+xml');
			payload = '<?xml version="1.0" encoding="UTF-8" ?>' + "\n";
			payload += '<methodCall>' + "\n";
			payload += ' <methodName>' + this.method + '</methodName>' + "\n";
			payload += '  <params>' + "\n";
			for(h = 0; h < this.params.length; h++)
				{
					payload += '   <param><value>';
					if(typeof this.params[h] == 'number')
						{
							payload += '<i4>' + this.params[h] + '</i4>';
						}
					else if(typeof this.params[h] == 'boolean')
						{
							payload += '<boolean>' + (this.params[h] ? '1' : '0') + '</boolean>';
						}
					else
						{
							payload += '<string>' + this.params[h] + '</string>';
						}
					payload += '</value></param>' + "\n";
				}
			payload += '  </params>' + "\n";
			payload += '</methodCall>' + "\n";
		}
	else
		{
			for(h in this.formVars)
				{
					hfv = true;					
					payload += encodeURIComponent(h) + '=' + encodeURIComponent(this.formVars[h]) + '&';
				}
			if(this.form)
			{
				hfv = true;
//				Shine.debug('Request:', 'Processing form with ' + this.form.elements.length + ' elements');
				for(i = 0; i < this.form.elements.length; i++)
				{
//					Shine.debug('Request:', 'Processing form element ' + i + ': ' + this.form.elements[i]);
					if(typeof this.form.elements[i].name == 'undefined' ||
						typeof this.form.elements[i].value == 'undefined' ||
						this.form.elements[i].name.length == 0)
					{
						continue;
					}
					if(this.form.elements[i].type == 'radio' || this.form.elements[i].type == 'checkbox')
					{
						if(!this.form.elements[i].checked) continue;
					}
					payload += encodeURIComponent(this.form.elements[i].name) + '=' + encodeURIComponent(this.form.elements[i].value) + '&';
				}
			}
			if(hfv)
				{
					payload = payload.substr(0, payload.length - 1);
					this.header('Content-Type', 'application/x-www-form-urlencoded');
				}
		}
	d = new Date();
	uri = this._uri;
	if(uri.indexOf('?') != -1)
	{
		uri += '&__ts=' + encodeURIComponent(d.getTime());
	}
	else
	{
		uri += '?__ts=' + encodeURIComponent(d.getTime());
	}
//	Shine.debug('Request:', this._method + ' ' + uri);
//	Shine.debug('Request:', payload);
	_this = this;
//	uri = 'http://tiso.maint.melo.g5.become.uk.com/test.php';
	_this._req.open(this._method, uri, true);
//	_this._req.onreadystatechange = function() { _this._readyStateChangeHandler(Shine, _this._req, false, false); }
	/* Work around WebKit bug */
	_this._req.setRequestHeader('If-Modified-Since', 'Wed, 15 Nov 1995 00:00:00 GMT');
	for(h in _this._headers)
		{
			_this._req.setRequestHeader(h, _this._headers[h]);
		}
	_this._throbOn();
	if(payload)
		{
			_this._req.send(payload);
		}
	else
		{
			_this._req.send(null);
		}
	this._rsInterval = window.setInterval(function() { _this._readyStateChangeHandler(Shine, _this._req, false, false); }, 50);
}
/* -*- C -*- */

/* --------------------------------------------------------------------
 * Shine: The Become Interactive Client Application Framework
 * @(#) $Id$
 * --------------------------------------------------------------------
 * Copyright (c) 2006 Become Interactive
 * http://www.becomeinteractive.co.uk
 * All rights reserved.
 * --------------------------------------------------------------------
 * This software is the confidential and proprietary information of
 * Become Interactive ("Confidential Information").
 *
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * with the terms of the license agreement you entered into with
 * Become Interactive.
 * --------------------------------------------------------------------
 */

/**
 * com.uk.become.shine.Validators
 *
 * Client-side form validation
 */
com.uk.become.shine.Validators = function()
{
}
com.uk.become.shine.Validators.prototype.validPassword = function(str)
{
	if(str.length <= 3)
	{
		return false;
	}
	return true;
}
com.uk.become.shine.Validators.prototype.validEmail = function(str)
{
	var ap;
	
	ap = str.indexOf('@');
	dp = str.lastIndexOf('.');
	if(ap != -1 && dp != -1 && dp > ap && dp < str.length - 2)
		{
			return true;
		}
	return false;	
}
com.uk.become.shine.Validators.prototype.validName = function(str)
{
	if(str.length > 1 && str.match(/^[^\s\d@:"$_#^&*()|]{2,}$/)) /* " */
	{
		return true;
	}
	return false;
}
/* Length-based validator */
com.uk.become.shine.Validators.prototype.lengthValidator = function(Shine, sender, event, data)
{
	if(event.value.length < data)
		{
			return false;
		}
	return true;
}
/* Name validator */
com.uk.become.shine.Validators.prototype.nameValidator = function(Shine, sender, event, data)
{
	return this.validName(sender.value);
}
/* Simple e-mail address validator */
com.uk.become.shine.Validators.prototype.emailInputValidator = function(Shine, sender, event, data)
{
	if(sender.shineValidatorPair)
	{
		Shine._inputHandler(Shine, sender.shineValidatorPair, event);
	}
	return this.validEmail(event.value);
}
com.uk.become.shine.Validators.prototype._emailCheckLoad = function(Shine, sender, event, data)
{
	if(!data || data._shineValidateRequest != sender)
	{
		return false;
	}
	if(event.responseText == 'nomatch')
	{
		data.shineValidatedOK = true;
	}
	else
	{
		data.shineValidatedOK = false;
		Shine.debug('Validators:', 'E-mail address already exists');
	}
	data.shineValidateInProgress = false;
	data.shineValidatedData = data._shineValidateValue;
	event.value = data._shineValidateValue;
	Shine.validateField(data, event);
}
/* Checking e-mail address validator */
com.uk.become.shine.Validators.prototype.emailCheckValidator = function(Shine, sender, event, data)
{
	var req;
	
	if(sender.shineValidatorPair)
	{
		Shine.validateField(sender.shineValidatorPair, event);
	}
	if(!this.validEmail(event.value))
	{
		sender.shineValidateInProgress = false;
		sender._shineValidateRequest = false;
		return false;
	}
	if(sender.shineValidateInProgress && sender._shineValidateValue == event.value) return false;
	if(!sender.shineValidatedInProgress)
	{
		if(sender.shineValidatedData == event.value)
		{
			if(sender.shineValidatedOK)
			{
				return true;
			}
			return false;
		}
	}
	sender._shineValidateValue = event.value;
	sender.shineValidateInProgress = true;
	req = Shine.createRequest('GET', Shine.rootPath + 'com.uk.become.login.component/emailcheck/?e=' + encodeURIComponent(event.value));
	Shine.addEventHandler(req, 'load', { host: this, handler: this._emailCheckLoad, data: sender })
	sender._shineValidateRequest = req;
	req.open();
	return false;
}
/* E-mail address confirmation */
com.uk.become.shine.Validators.prototype.emailConfirmInputValidator = function(Shine, sender, event, data)
{
	if(!this.validEmail(event.value))
	{
		return false;
	}
	if(!sender.shineValidatorPair && sender.form)
	{
		/* Look for a companion password field and pair with it */
		nodes = Shine.getElementsByClass(sender.form, 'input', 'shine-input-emailcheck');
		if(!nodes.length)
		{
			nodes = Shine.getElementsByClass(sender.form, 'input', 'shine-input-email');
		}
		for(c = 0; c < nodes.length; c++)
		{
			node = nodes[c];
			if(node == sender) continue;
			if(!node.shineValidatorPair)
			{
				node.shineValidatorPair = sender;
				sender.shineValidatorPair = node;
				data = node;
				break;
			}
		}
	}
	if(!sender.shineValidatorPair) return false;
	if(event.value == sender.shineValidatorPair.value)
	{
		return true;
	}
	return false;
}
/* Simple password validator */
com.uk.become.shine.Validators.prototype.passwordInputValidator = function(Shine, sender, event, data)
{
	if(sender.shineValidatorPair)
	{
		Shine.validateField(sender.shineValidatorPair, event);
	}
	return this.validPassword(event.value);
}
/* Simple password confirmation validator (simply compares the value with the first password field) */
com.uk.become.shine.Validators.prototype.passwordConfirmInputValidator = function(Shine, sender, event, data)
{
	var c, nodes, node;
	
	if(!this.validPassword(event.value))
	{
		return false;
	}
	if(!sender.shineValidatorPair && sender.form)
	{
		/* Look for a companion password field and pair with it */
		nodes = Shine.getElementsByClass(sender.form, 'input', 'shine-input-password');
		for(c = 0; c < nodes.length; c++)
		{
			node = nodes[c];
			if(node == sender) continue;
			if(!node.shineValidatorPair)
			{
				node.shineValidatorPair = sender;
				sender.shineValidatorPair = node;
				data = node;
				break;
			}
		}
	}
	if(!sender.shineValidatorPair) return false;
	if(event.value == sender.shineValidatorPair.value)
	{
		return true;
	}
	return false;
}
/* Integer input validator */
com.uk.become.shine.Validators.prototype.integerInputValidator = function(Shine, sender, event, data)
{
	if(event.value.length)
		{
			if(event.value.match(/^[0-9]+$/))
				{					
					return true;
				}
		}
	return false;
}
/* ISO7812 (credit card, smart card, ID card) input validator */
com.uk.become.shine.Validators.prototype.iso7812InputValidator = function(Shine, sender, event, data)
{
	var ccnum, sum, i, digit;
	
	if(event.value.length)
		{
			/* Strip spaces from the number */
			ccnum = event.value.replace(/\s/g, '');
			if(ccnum.length < 9 || !ccnum.match(/^[0-9]+$/))
			{
				return false;
			}
			/* Calculate the Luhn check digit */
			sum = 0;
			parity = ccnum.length % 2;
			for(i = 0; i < ccnum.length; i++) 
			{
			    digit = ccnum.charAt(i);
			    if(i % 2 == parity)
			 	{
					digit *= 2;
				}
				if(digit > 9)
				{
					digit -= 9;
				}
			    sum += parseInt(digit);
			  }
			  return (sum % 10 == 0);
		}
	return false;
}
com.uk.become.shine.Validators.prototype.cv2InputValidator = function(Shine, sender, event, data)
{
	var ccnum, sum, i, digit;
	
	if(event.value.length == 3)
	{
		return event.value.match(/^[0-9]+$/) ? true : false;
	}
	return false;
}
com.uk.become.shine.Validators.prototype.issueInputValidator = function(Shine, sender, event, data)
{
	var ccnum, sum, i, digit;
	
	if(event.value.length == 2)
	{
		return event.value.match(/^[0-9]+$/) ? true : false;
	}
	return false;
}
/* Floating-point input validator */
com.uk.become.shine.Validators.prototype.floatInputValidator = function(Shine, sender, event, data)
{
	if(event.value.length)
		{
			if(event.value.match(/^[0-9]*(\.[0-9]+)?$/))
				{
					return true;
				}
		}
	return false;
}
com.uk.become.shine.Validators.prototype.ondocumentloaded = function(Shine, sender, ev, data)
{
	var nodes, c;

	if(Shine.hasElementClass(Shine.body, 'shine-no-validation'))
		{
			return true;
		}
	nodes = document.getElementsByTagName('input');
	for(c = 0; c < nodes.length; c++)
		{
			if(Shine.hasElementClass(nodes[c], 'shine-input-email'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.emailInputValidator });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-emailcheck'))			
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.emailInputValidator });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-emailconfirm'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.emailConfirmInputValidator });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-simple'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.lengthValidator, data: 1 });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-md5'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.lengthValidator, data: 32 });
				}			
			else if(Shine.hasElementClass(nodes[c], 'shine-input-name'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.nameValidator });
				}			
			else if(Shine.hasElementClass(nodes[c], 'shine-input-password'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.passwordInputValidator });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-passconfirm'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.passwordConfirmInputValidator });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-integer'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.integerInputValidator });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-float'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.floatInputValidator });
				}
			else if(Shine.hasElementClass(nodes[c], 'shine-input-iso7812'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.iso7812InputValidator });
				}			
			else if(Shine.hasElementClass(nodes[c], 'shine-input-cv2'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.cv2InputValidator });
				}			
			else if(Shine.hasElementClass(nodes[c], 'shine-input-issue'))
				{
					Shine.addInputHandler(nodes[c], { host: this, handler: this.issueInputValidator });
				}
		}
	/* Add handlers for the various classes of Shine-enabled form fields */
	nodes = Shine.getElementsByClass(document, 'select', 'shine-input-simple');
	Shine.addInputHandlers(nodes, { host: this, handler: this.lengthValidator, data: 1 });
	nodes = Shine.getElementsByClass(document, 'textarea', 'shine-input-simple');
	Shine.addInputHandlers(nodes, { host: this, handler: this.lengthValidator, data: 1 });
}
var ShineValidators = new com.uk.become.shine.Validators();

Shine.addLoadHandler(ShineValidators);
/* -*- C -*- */

/* --------------------------------------------------------------------
 * Shine: The Become Interactive Client Application Framework
 * @(#) $Id$
 * --------------------------------------------------------------------
 * Copyright (c) 2006 Become Interactive
 * http://www.becomeinteractive.co.uk
 * All rights reserved.
 * --------------------------------------------------------------------
 * This software is the confidential and proprietary information of
 * Become Interactive ("Confidential Information").
 *
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * with the terms of the license agreement you entered into with
 * Become Interactive.
 * --------------------------------------------------------------------
 */

/**
 * com.uk.become.shine.Expanders
 *
 * Deal with collapsible blocks of content.
 */
if(typeof com == "undefined") var com = new Object();
if(typeof com.uk == "undefined") com.uk = new Object();
if(typeof com.uk.become == "undefined") com.uk.become = new Object();
if(typeof com.uk.become.shine == "undefined") com.uk.become.shine = new Object();

com.uk.become.shine.Expanders = function()
{
}
com.uk.become.shine.Expanders.prototype.addDefinitionHooks = function(nodes)
{
	var c;

	for(c = 0; c < nodes.length; c++)
		{
			this.addDefinitionHook(nodes[c]);
		}
}
com.uk.become.shine.Expanders.prototype.addDivHooks = function(nodes)
{
	var c;

	for(c = 0; c < nodes.length; c++)
		{
			this.addDivHook(nodes[c]);
		}
}
com.uk.become.shine.Expanders.prototype._onclick = function(Shine, sender, ev, data)
{
	var c;
	
	for(c = 0; c < sender.shineExpanders.length; c++)
	{
		if(sender.shineCollapsed)
		{
			Shine.removeElementClass(sender.shineExpanders[c], 'shine-collapsed');
		}
		else
		{
			Shine.addElementClass(sender.shineExpanders[c], 'shine-collapsed');
		}
	}
	sender.shineCollapsed = !sender.shineCollapsed;
}
com.uk.become.shine.Expanders.prototype.addDefinitionHook = function(element)
{
	var c, d, dt;
	
	/* Get all of the dt elements */
	for(c = 0; c < element.childNodes.length; c++)
	{
		if(element.childNodes[c].tagName && element.childNodes[c].tagName.toLowerCase() == 'dt')
		{
			element.childNodes[c].shineExpanders = new Array();
			for(d = c + 1; d < element.childNodes.length; d++)
			{
				if(!element.childNodes[d].tagName || element.childNodes[d].tagName.toLowerCase() != 'dd')
				{
					if(element.childNodes[d].tagName && element.childNodes[d].tagName.toLowerCase() == 'dt')
					{
						break;
					}
					continue;
				}
				element.childNodes[c].shineExpanders[element.childNodes[c].shineExpanders.length] = element.childNodes[d];
				Shine.addElementClass(element.childNodes[d], 'shine-collapsed');
			}
			element.childNodes[c].shineCollapsed = true;
			Shine.addElementClass(element.childNodes[c], 'shine-expander-node');
			Shine.addEventHandler(element.childNodes[c], 'click', { host: this, handler: this._onclick });
		}
	}
}
com.uk.become.shine.Expanders.prototype.addDivHook = function(element)
{
	var c, d, dt, h;
	
	for(c = 0; c < element.childNodes.length; c++)
	{
		if(element.childNodes[c].tagName)
		{
			h = element.childNodes[c].tagName.toLowerCase();
		}
		else
		{
			h = null;
		}
		if(h && (h == 'h1' || h == 'h2' || h == 'h3' || h == 'h4' || h == 'h5'))
		{
			element.childNodes[c].shineExpanders = new Array();
			for(d = c + 1; d < element.childNodes.length; d++)
			{
				if(element.childNodes[d].tagName)
				{
					h = element.childNodes[d].tagName.toLowerCase();
				}
				else
				{
					h = null;
				}
				if(h && h != 'div')
				{
					break;
				}
				if(!h)
				{
					continue;
				}
				element.childNodes[c].shineExpanders[element.childNodes[c].shineExpanders.length] = element.childNodes[d];
				Shine.addElementClass(element.childNodes[d], 'shine-collapsed');				
			}
			element.childNodes[c].shineCollapsed = true;
			Shine.addElementClass(element.childNodes[c], 'shine-expander-node');
			Shine.addEventHandler(element.childNodes[c], 'click', { host: this, handler: this._onclick });
		}
	}
}
com.uk.become.shine.Expanders.prototype.ondocumentloaded = function(Shine, sender, ev, data)
{
	var nodes;
	
	nodes = Shine.getElementsByClass(document, 'dl', 'shine-expander');
	this.addDefinitionHooks(nodes);
	nodes = Shine.getElementsByClass(document, 'div', 'shine-expander');
	this.addDivHooks(nodes);
}

Shine.addLoadHandler(new com.uk.become.shine.Expanders());
/* -*- C -*- */

/* --------------------------------------------------------------------
 * Shine: The Become Interactive Client Application Framework
 * @(#) $Id$
 * --------------------------------------------------------------------
 * Copyright (c) 2006 Become Interactive
 * http://www.becomeinteractive.co.uk
 * All rights reserved.
 * --------------------------------------------------------------------
 * This software is the confidential and proprietary information of
 * Become Interactive ("Confidential Information").
 *
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * with the terms of the license agreement you entered into with
 * Become Interactive.
 * --------------------------------------------------------------------
 */

com.uk.become.shine.Tabs = function()
{	
	this.ontabchanged = false;
}
com.uk.become.shine.Tabs.prototype._activatePage = function(page)
{
	var ev;

	if (!page.shineTabGroup.shineTabHide)
	{
		while(page.shineTabGroup.shinePageContainer.firstChild)
		{
			page.shineTabGroup.shinePageContainer.removeChild(page.shineTabGroup.shinePageContainer.firstChild);
		}		
		page.shineTabGroup.shinePageContainer.appendChild(page);
	}

	if(page.shineTab)
	{
		Shine.addElementClass(page.shineTab, 'shine-active-tab');		
	}
	page.shineTabGroup.shineActivePage = page;
	Shine.addElementClass(page, 'shine-active-sheet');
	ev = new Object();
	ev.tabGroup = page.shineTabGroup;
	ev.tabSheet = page;
	if(this.ontabchanged)
	{
		this.ontabchanged(ev);
	}
}
com.uk.become.shine.Tabs.prototype._deactivatePage = function(group)
{
	if(group.shineActivePage)
	{
		Shine.removeElementClass(group.shineActivePage, 'shine-active-sheet');
		if(group.shineActivePage.shineTab)
		{
			Shine.removeElementClass(group.shineActivePage.shineTab, 'shine-active-tab')
		}
		if (!group.shineTabHide)
		{
			group.shinePageContainer.removeChild(group.shineActivePage);
		}
		group.shineActivePage = false;
	}
}
com.uk.become.shine.Tabs.prototype.switchPage = function(page)
{
	var _this = this;
	
	if(page == page.shineTabGroup.shineActivePage)
	{
		return false;
	}
	_this._deactivatePage(page.shineTabGroup);
	_this._activatePage(page);
}
com.uk.become.shine.Tabs.prototype.ontabfocus = function(Shine, sender, event, data)
{
	if(sender.shineSheet && sender.shineTabGroup)
	{
		this.switchPage(sender.shineSheet);
	}
	return true;
}
com.uk.become.shine.Tabs.prototype.ontabclick = function(Shine, sender, event, data)
{
	if(sender.shineSheet && sender.shineTabGroup)
	{
		this.switchPage(sender.shineSheet);
	}
	return false;
}
com.uk.become.shine.Tabs.prototype.addFocusTab = function(group, element, event)
{
	var sheet;
	
	sheet = document.getElementById(element.id + '-sheet');
	if(!sheet)
	{
		Shine.debug('Tabs:', 'Can\'t locate sheet for tab ' + element.id);
		return false;
	}
	element.shineSheet = sheet;
	element.shineTabGroup = group;
	sheet.shineTab = element;
	Shine.addEventHandler(element, event, { host: this, handler: this.ontabfocus });
	return true;
}
com.uk.become.shine.Tabs.prototype.addClickTab = function(group, element, event)
{
	var sheet;
	
	sheet = document.getElementById(element.id + '-sheet');
	if(!sheet)
	{
		Shine.debug('Tabs:', 'Can\'t locate sheet for tab ' + element.id);
		return false;
	}
	element.shineSheet = sheet;
	element.shineTabGroup = group;
	sheet.shineTab = element;
	Shine.addEventHandler(element, event, { host: this, handler: this.ontabclick });
	return true;
}
com.uk.become.shine.Tabs.prototype.initTabGroup = function(element, hideMode)
{
	var containers, tabs, first, c;
	
	element.shineTabHide = hideMode;
	element.shineTabSheets = Shine.getElementsByClass(element, 'div', 'shine-tab-sheet');
	if(element.shineTabSheets.length == 0)
	{
		return false;
	}
	element.shineActivePage = false;
	containers = Shine.getElementsByClass(element, 'div', 'shine-tab-pages');
	if(containers.length == 0)
	{
		containers = Shine.getElementsByClass(element, 'span', 'shine-tab-pages');
	}
	if(containers.length == 0)
	{
		return false;
	}
	element.shinePageContainer = containers[0];
	first = false;
	tabs = Shine.getElementsByClass(element, 'input', 'shine-tab');
	/* You have to loop the tabs first -- before all of the sheets are removed
	 * from the DOM.
     */
	for(c in tabs)
	{
		this.addFocusTab(element, tabs[c], 'focus');
	}
	tabs = Shine.getElementsByClass(element, 'a', 'shine-tab');
	for(c in tabs)
	{
		this.addClickTab(element, tabs[c], 'click');
	}
	tabs = Shine.getElementsByClass(element, 'span', 'shine-tab');
	for(c in tabs)
	{
		this.addClickTab(element, tabs[c], 'click');
	}
	for(c in element.shineTabSheets)
	{
		if(!first)
		{
			first = element.shineTabSheets[c];
		}
		if(!element.shineActiveTab && 
			Shine.hasElementClass(element.shineTabSheets[c], 'active'))
		{
			element.shineActivePage = element.shineTabSheets[c];
		}
		element.shineTabSheets[c].shineTabGroup = element;
		if (!element.shineTabHide)
		{
			element.shineTabSheets[c].parentNode.removeChild(element.shineTabSheets[c]);
		}
	}
	if(!element.shineActivePage)
	{
		element.shineActivePage = first;
	}
	this._activatePage(element.shineActivePage);
	Shine.addElementClass(element, 'shine-tabs-enabled');
}
com.uk.become.shine.Tabs.prototype.ondocumentloaded = function(Shine, sender, ev, data)
{
	var tabgroups, c;

	tabgroups = Shine.getElementsByClass(document, 'div', 'shine-tab-group');
	for(c in tabgroups)
	{	
		this.initTabGroup(tabgroups[c], false);
	}
	tabgroups = Shine.getElementsByClass(document, 'div', 'shine-tab-group-hide');
	for(c in tabgroups)
	{	
		this.initTabGroup(tabgroups[c], true);
	}
	return true;
}
com.uk.become.shine.TabManager = new com.uk.become.shine.Tabs();
Shine.addLoadHandler(com.uk.become.shine.TabManager);

function debugConsole(n)
{
 	var debugWindow, cw;
	cw = "debugWindow";
	
	debugWindow = window.open(root_path+'index.php?debug_console=1&debug_id=' + n, cw, 'toolbar=no,location=no,status=yes,directories=no,menubar=no,scrollbars=yes,resizable=yes,width=450,height=600,left=10,top=10');
	debugWindow.focus();
}

$(document).ready(function() {
	Shine.loaded(Shine, Shine, false);
	if(typeof document.loadHooks!="undefined")
	{
		var hl = document.loadHooks; document.loadHooks = [];
		for(var _h in hl)
		{
			hl[_h]();
		}
	}
	if(typeof document.postLoadHooks!="undefined")
	{
		var hl = document.postLoadHooks; document.postLoadHooks = [];
		for(var _h in hl)
		{
			hl[_h]();
		}
	}
});
$(document).ready(function() {
  var el;
  for(i=0;i<input_error.length;i++){
    if( input_error[i] != "" ){
      el = document.getElementById(input_error[i]);
      if(el) {
        el.className += " errorField";
        el.acErrorField = true;
        el = el.parentNode;
        while(el) {
          if(el.tagName.toLowerCase() == "div" || el.tagName.toLowerCase() == "dl") {
            el.className += " errorSurround";
            el.acErrorSurround = true;
            break;
          }
          el = el.parentNode;
        }
      }
    }
  }
});
