// Global vars

// Variable to tell IE if hero is open for calendar placement
var ieHeroOpen = true;

// mootools 1.11 predates ie8, so ie8 looks like ie7
if (window.ie7 && window.postMessage) { // postMessage only exists in ie8
  window.ie7 = undefined; // set to undefined, in line with other browser booleans
  window.ie8 = true;
}

/// this fires when the dom tree is loaded
window.addEvent('domready', function(){
	
	// add withjs class to page container for js related styling
	$('pagecontainer').addClass('withjs');
	
	/*var pgForms = $('pagecontainer').getElements('form');
	if(pgForms.length > 0){
		pgForms.each(function(frm,i){
			frm.addEvent('keypress', function(evt){
				if(evt.keyCode == 13){
					frm.submit();
					return false;	
				}
			});
		});
	}*/

	// set up login dropdown
	if($('logininner')){
		loginBox = new Fx.Styles($('logininner'), {duration: 1000, wait: true, transition: Fx.Transitions.linear}).set({'opacity':0});
	}

	// set up the sub navigation
	$$('div.subnav').each(function(e){
		var csNavigation = new subnavObj($$('ul.subnav'), $$('ul.nav li a'), 'mouseover', false);
		$$('div#login','div#roadmap','div#content','div#breadcrumbs','div#footer').addEvent('mouseover', function(e){ csNavigation.closeall(); } );
	});

	// Hero Show Hide Toggle
	if($('herotoggle') != null){
		var heroShowAndHide = new heroShowHide();
		var isHeroHidden = Cookie.get('heroshot');
		if(!isHeroHidden) {
			// default to visible
			isHeroHidden = 'visible';
			ieHeroOpen = true;
		}
		if(isHeroHidden != 'visible'){ 
			heroShowAndHide.heroFx.set(0);
			heroShowAndHide.overlayFx.set(0);
			heroShowAndHide.toggleShowHideButton();
			ieHeroOpen = false;
		}
	}
	
	// Heroshot randomisation
	var ranNo = Math.floor((Math.random()*10)+1);
	// set up the heroshot
	if($('roadmapnewimage') != null){
		$('roadmapnewimage').getFirst().setProperty('src','/images/heroshots/' + ranNo + '.jpg');
	}
	if($('heroshotnewimage') != null){
	    $('heroshotnewimage').getFirst().setProperty('src','/images/heroshots/' + ranNo + '.jpg');
    }
	// set up the matching eye candy
	if($('imgholder') != null){
		var el = $('imgholder');
		var elImg = el.getFirst();
		el.setStyle('background','transparent url(/images/eyecandy/' + ranNo + '.jpg) no-repeat 1px 5px');
		if(window.ie6){
			elImg.setProperty('src','/images/eyecandy/window.gif');
		} else {
			elImg.setProperty('src','/images/eyecandy/window.png');
		}
	}
	
	// Heroshot Overlay
	if($('herooverlay') != null){
	    var heroOverlay = new heroShotOverlay();
    }
	
	// members only links
	if($$('a.membersonlycheck').length>0){
		new memberOnlyPopup();
	}
	
	// set up expander boxes used on category pages
	if($$('div.expanderbox').length > 0 && $$('p.expanderlink').length > 0){
		var expandingBox = new expanderBox($$('div.expanderbox'),$$('p.expanderlink'));
	}

	// set up the case study content
	if($$('div.cscontent').length > 0){
		var csContents = new contentObj($$('div.cscontent'), $$('ul.menulist li a'), 'click', true);
	}
	
	// set up the category show/hide for news and events
	if($$('span.categoryContainer').length > 0){
		var catContents = $$('span.categoryContainer');
		catContents.each(function(el,i){
			var aCats = el.getText().split(', ');
			if(aCats.length > 3){
				var trimmed = aCats[0] + ', ' + aCats[1] + ', ' + aCats[2] + ' ';
				var full = el.getText() + ' ';
				el.setHTML(trimmed);
				var anCat = new Element('a',{'href':'#','class':'categorylink'}).setHTML('[More Categories]').injectAfter(el);
				anCat.addEvents({
					'click':function(e){
						if(!el.className.match('open')){
							el.setHTML(full).addClass('open');
							anCat.setText('[Less Categories]');
						} else {
							el.setHTML(trimmed).removeClass('open');
							anCat.setText('[More Categories]');
						}
						e = new Event(e).stop();
					}
				});
				
			}
		});
	}
	
	// set up the category carousel
	if($$('div.categorycarousel').length > 0){
		var catCar = new catCarousel($$('div.categorycarousel')[0]);
	}
	
	// set up the hoizontal alphabet navigation content
	if($$('div.alphacontent').length > 0){
		var alphaContents = new alphaObj($$('div.alphacontent'), $$('ul.hozmenulist li a'));
	}
  
  // set up the hoizontal alphabet faq style content
  var alphaContentHeaders = $$('div.alphacontent h4');
  if(alphaContentHeaders.length > 0){
    var alphaContent = new faqObj(alphaContentHeaders);
  }
  var alphaContentDivs = $$('div.alphacontent div.faqheader');
	if(alphaContentDivs.length > 0){
		var alphaContent = new faqObj(alphaContentDivs);
	}

	// set up the roadmap news carousel
	if($$('div#roadmapnews div.newsitem').length > 0){
		var newsCarousel = new newsObj($('roadmapnews'));
	}
	
	// set up the hero shot news carousel
	if($$('div#heroshotnews div.newsitem').length > 0){
	   var newsCarousel = new newsObj($('heroshotnews'));
	}

	// set up Calendar
	if($chk('calendarObject') == true){ new createCalendar($('calendar')); };

	// set up the Concertina
	$$('div.concertina').each(function(e){ new createConcertina(e); new createContentSwap(e); });

	// Configure elements for JS use
	$$('div.ourgroupmembers').each(function(el,i){ new createMemberList(el,i) });

	// Configure fake select boxes
	$$('div.fakeselect186dummy').each(function(e){ new createFakeSelect(e) });
	$$('div.fakeselect378dummy').each(function(e){ new createFakeSelect(e) });

	// Configure fake upload boxes
	$$('div.fakefileupload').each(function(e){ new createFakeUpload(e) });
	
	// Configure check boxes
	$$('div.fakecheckboxes input').each(function(e){ new FakeCheckBox(e); });
	
	// Configure questionnaire radio groups
	$$('div.qcontainer').each(function(e){
	  new QuestionnaireContainer(e);
	});
	
	// set up the member filters
	if($chk('filtergroups') == true){ var filterGroup = new filterGroupObj($('filtergroups'),$$('div.ourgroupmembers')); }

	// set up the roadmap filter
	//if($chk('roadmapfilter') == true){ new createRoadmapFilter(); }
	
	// init questionnaire 
	var questionInfos = $$('span.questioninfo');
	if(questionInfos.length > 0) {
	  questionInfos.each( function(e, i){new QuestionPopUp(e, i)} );
	}
	
	var searchInput = $('memberNamePart');
	if (searchInput) {
	  // need to add this after other JS has loaded
	  Autocompleter.Ajax.JsonElData = Autocompleter.Ajax.Json.extend({
	    // pass element data through in onSelect
	    choiceSelect: function(el) {
	      var data = el.data; // el destroyed in hideChoices
	      this.observer.value = this.element.value = el.inputValue;
	      this.hideChoices();
	      this.fireEvent('onSelect', [this.element, data], 20);
	    }
	  });
	  // init selector
	  new OrganisationSelector(searchInput);
	}
	
	if ($$('div.questionnaire').length) {
	  var faqLinks = $$('a.faqlink');
	  faqLinks.each(function(el) {
      el.addEvent('click', function(e) {
        //console.log(el.getAttribute('href'));
        e = new Event(e).stop();
        var win = window.open(el.getAttribute('href'), 'faqPopup', 'width=630,height=450,scrollbars=1');
      }.bind(this));
    });
	}
});

/// this fires when the actual page has finished loading
window.addEvent('load', function(){

	// Formatting for Top, Icon and Date Lists
	$$('ul.toplist','ul.iconlist','ul.datelist').each(function(e) {
		if($chk(e.getFirst())){
			e.getFirst().setStyles({
				'border':'0',
				'padding-top':'0'
			});
		}
	});

	// Formatting for Task Lists
	$$('ul.tasklist').each(function(e) {
		if(e.getPrevious().className != 'tasklist'){
			e.setStyles({
				'border':'0',
				'padding-top':'0'
			});
		}
	});

	// Formatting for Forum Lists
	$$('ul.forumlist').each(function(e) {
		if(e.getPrevious().className != 'forumlist'){
			e.setStyles({
				'border':'0',
				'padding-top':'0'
			});
		}
		if(e.getNext().className != 'forumlist'){
			if(!window.ie){
				e.setStyles({
					'margin-bottom':'10px'
				});
			}
		}
	});
	
	// Clear Live Search textbox on focus
	$$('div.livesearch input.text','div.embeddedsearch input.text').each(function(e) {
		e.addEvent('focus', function(e) { if(this.value=='Live Search'){this.value=''} });
		e.addEvent('blur', function(e) { if(this.value==''){this.value='Live Search'} });
	}.bind(this));

	// Set footer search title with textbox on focus
	$$('div#footer input.text').each(function(e) {
		e.addEvent('focus', function(e) { this.getParent().getParent().addClass('selected'); });
		e.addEvent('blur', function(e) { this.getParent().getParent().removeClass('selected'); });
	}.bind(this));

	// Login toggle
	$$('a.login','input.login').each(function(e) {
		e.addEvent('click', function(e) {
			if($('logininner').getStyle('visibility') == 'hidden'){
				if(window.ie6){
					loginBox.set({'opacity':1});
					loginBox.start({ 'margin-top':[-200, 0] });
				} else {
					loginBox.start({ 'opacity':[0,1], 'margin-top':[-200,0] });
				}
			} else {
				if(window.ie6){
					loginBox.start({ 'opacity':[1,0], 'margin-top':[0, -200] });
				} else {
					loginBox.start({ 'opacity':[1,0], 'margin-top':[0, -200] });
				}
			}
			e = new Event(e).stop();
		});
	}.bind(this));
	
	// Roadmap toggles
	$$('div#nonroadmap a.iconbutton').each(function(e) {
		e.addEvent('click', function(e) {
			if($('nonroadmap').getStyle('visibility') == 'visible'){
				roadmapFocus.start({ 'opacity':[1,0] }).chain(function(){
					$('nonroadmap').getParent().addClass('open');
					new createRoadMapClass('yearView')
					roadmapBlur.start({ 'opacity':[0,1] });
					$clear(newsRepeat);
				});
			}
			e = new Event(e).stop();
		});
	}.bind(this));
	
	// Roadmap toggles
	$$('div#openroadmap a.smliconbutton').each(function(e) {
		e.addEvent('click', function(e) {
			if($('nonroadmap').getStyle('visibility') == 'hidden'){
				roadmapBlur.start({ 'opacity':[1,0] }).chain(function(){
					$('nonroadmap').getParent().removeClass('open');
					roadmapFocus.start({ 'opacity':[0,1] });
					if(window.ie6){
						$('lbulge').getFirst().setProperty('src','/images/bulge-l-s.gif');
						$('rbulge').getFirst().setProperty('src','/images/bulge-r-s.gif');
					} else {
						$('lbulge').getFirst().setProperty('src','/images/bulge-l-s.png');
						$('rbulge').getFirst().setProperty('src','/images/bulge-r-s.png');
					}
					new newsObj($('roadmapnews'));
					$('roadmapcontainer').empty();
					var URL = '/site/roadmap/get-year-view';
					var refreshRoadmapAjaxRequest = new Ajax(URL, {
						method: 'get',
						onComplete: function(response) {
							$('roadmapcontainer').setHTML(response);
						}.bind(this)
					});
					refreshRoadmapAjaxRequest.request();
					e = new Event(e).stop();
				});
			}
			e = new Event(e).stop();
		});
	}.bind(this));
	
	if($('btnmoreinfoclose')){
		$('btnmoreinfoclose').addEvent('click',function(e){ $('btnmoreinfoclose').getParent().getParent().setStyle('display','none') });
	}
	// Initialise 'add new user' form
	if($('addUserPersonForm')){
		addUserPersonForm = new newUserForm(
			'addUserPersonForm', 
			'/site/members/add-user-person-ajax', 
			new Array('user_limit_count', 'user_limit_msg', 'newusersubmit')
		);
	}
	// Initialise 'update member' form
	if($('updateMember')) {
		new updateMemberForm('updateMember', '/site/members/update-member-ajax');
	}
	// Initialise the list / form combinations: update user, update user password, delete user
	if($('update_user_list') && $('update_user_form')) {
		listFormCombos.push(new updateUserListFormCombo('update_user', '/site/members/update-user-person-ajax'));
	}
	if($('update_user_pw_list') && $('update_user_pw_form')) {
		listFormCombos.push(new updateUserPwListFormCombo('update_user_pw', '/site/members/update-user-person-pw-ajax'));
	}
	if($('delete_user_list') && $('delete_user_form')) {
		listFormCombos.push(new deleteUserListFormCombo('delete_user', '/site/members/delete-user-person-ajax'));
	}
	if($('filterMemberDirectoryForm')) {
	  new filterMemberDirectoryForm('filterMemberDirectoryForm', '/site/questionnaire/results-ajax', 'directorylist');
	}

	// Specific Browser Tweaks!!
	if(window.opera){
		$$('input.imagesubmit').each(function(e){
			e.setStyle('position','relative');
		});
		$$('div#footer input.imagesubmit').each(function(e){
			e.setStyles({
				'float':'right',
				'margin-right':'3'
			});
		});
		$$('div.docheader div.button').each(function(e){
			e.setStyle('margin-top','-35px');
		});
		$('btnloginclose').setStyle('margin-left','385px');
	}
	if(window.ie6){
		$$('input.imagesubmit').each(function(e){
			e.setStyles({ 
				'float':'right',
				'margin-right':'3'
			});
		});
	}
	if(window.webkit){
		$('btnloginclose').setStyle('margin-left','380px');
	}
	
	// Configure button rollovers
	$$('input.button','div.button img','li.button img','p.button img').each(function(e) {
		var fileType;
		if(e.src.match(/.gif/)){ fileType = '.gif'; }
		if(e.src.match(/.png/)){ fileType = '.png'; }
		if(e.src.match(/.jpg/)){ fileType = '.jpg'; }
		var imgSrc = e.src;
		if(e.src.match(/-o./)){ imgSrc.replace(/-o./,'.') }
		imgSrc = e.src.split(fileType);
		e.addEvent('mouseover', function(e) { this.setProperty('src', imgSrc[0] + '-o' + fileType) });
		e.addEvent('mouseout', function(e) { this.setProperty('src', imgSrc[0] + fileType) });
	}.bind(this));
	
	// forum preview link config
	$$('div.forumpreview img').each(function(el,i) {
		el.addEvents({
			'click': function(e){
				togglePreviews();
				if(!el.getProperty('src').contains('hidepost')){
					el.setProperty('src','/images/btn-hidepost.gif');
				} else {
					el.setProperty('src','/images/btn-showpost.gif');
				}
				el.removeEvents('mouseover','mouseout');
				var fileType;
				if(el.src.match(/.gif/)){ fileType = '.gif'; }
				if(el.src.match(/.png/)){ fileType = '.png'; }
				if(el.src.match(/.jpg/)){ fileType = '.jpg'; }
				var imgSrc = e.src;
				if(el.src.match(/-o./)){ imgSrc.replace(/-o./,'.') }
				imgSrc = el.src.split(fileType);
				el.addEvent('mouseover', function(e) { this.setProperty('src', imgSrc[0] + '-o' + fileType) });
				el.addEvent('mouseout', function(e) { this.setProperty('src', imgSrc[0] + fileType) });
				e = new Event(e).stop();
			}
		});
	});
	if(window.ie6){
		var ie6Fixing = $('pagecontainer').getElements('img');
		ie6Fixing.each(function(el,i){
			var imgSrc = el.getProperty('src');
			if(imgSrc.match('.png')){
				imgSrc = imgSrc.replace(/.png/,'.gif');
				el.setProperty('src',imgSrc);
			}
		});
	}
	
	// Set up initial Roadmap call
	if($('closedtoolbar') != null){
		$('closedtoolbar').getFirst().addEvent('click', function(e){
			e = new Event(e).stop();
			new retrieveRoadmapContent('initial','yrview');
		}.bind(this));
	}
	
	if(window.location.href.match(/roadmap/)){
		new retrieveRoadmapContent('initial','yrview');	
	}
	
	// Set up media player if available
	if($chk($('mediaplayer'))){
		var thisPlayer = new loadPlayer();
	}


});



//////////////////////// Classes to include in seperate files(?) ////////////////////////////////////

// Global Variables
var loginBox;
var roadmapFocus;
var roadmapBlur;
var newsRepeat;
// Globals for forms -- only relevant for member home page
var addUserPersonForm;
var listFormCombos = [];

// News carousel
var newsObj = new Class({
	initialize: function(el){
		this.story = 1;
		this.laststory = 0;
		this.children = el.getChildren();
		this.slides = new Array();
		this.children.each(function(el,i){
			this.slides[i] = new Fx.Styles(el, {duration: 1000, wait: true, transition: Fx.Transitions.linear}).set({'opacity':0});
			el.removeClass('newsitem');
		}.bind(this));
		this.slides[this.laststory].set({'opacity':1})
		newsRepeat = (function(){
			if( this.story == (this.children.length) ){
				this.story = 0;
			}
			this.cycleNews(this.laststory,this.story);
		}.bind(this)).periodical(7000)
	},
	cycleNews: function(o,i){
		if(window.ie){
			this.slides[o].set({'opacity':0})
		} else {
			this.slides[o].start({'opacity':[1,0]});
		}
		this.laststory = i;
		if(window.ie){
			var ieCycle = (function(){
				this.slides[i++].set({'opacity':1});
				this.story = i++;
			}.bind(this)).delay(1000)
		} else {
			this.slides[i++].start({'opacity':[0,1]});
			this.story = i++;
		}
	}
});

// Dynamic Alphabet navigation style content panels
var alphaObj = new Class({
	initialize: function(content, links){
		this.contentPanels = content;
		this.contentTogglers = links;
		
		this.contentPanels.each(function(el,i){
			el.addClass('closed');
		}.bind(this));
		
		this.contentTogglers.each(function(el,i){
			el.addEvents({
				'click': function(e){
					this.contentPanels.each(function(el,i){
						el.addClass('closed');
					});
					this.contentTogglers.each(function(el,i){ el.removeClass('selected'); });
					this.contentPanels[i].removeClass('closed');
					el.addClass('selected');
					e = new Event(e).stop();
				}.bind(this)
			});
		}.bind(this));
		
		if (this.contentPanels.length > 0) {
		  this.contentPanels[0].removeClass('closed');
		}
		if (this.contentTogglers.length > 0) {
		  this.contentTogglers[0].addClass('selected');
		}
	}
});

// Dynamic FAQ style headers & content
var faqObj = new Class({
	initialize: function(faqHeaders){
		this.faqHeaders = faqHeaders;
		this.faqHeaders.each(function(el,i){
			var faqContent = el.getNext();
			el.addEvents({
				'click': function(e){
					if(el.className.match('selected')){
						el.removeClass('selected');
						faqContent.removeClass('open');
					} else {
						el.addClass('selected');
						faqContent.addClass('open');
					}
				}
			});
		});
	}
});

// Hero Show/Hide
var heroShowHide = new Class({
	targetButton:null,
	buttonContainer:null,
	heroFx:null,
	initialize: function(){
		this.buttonContainer = $('herotoggle');
		this.targetButton = this.buttonContainer.getElement('img');
		this.setUpTransition();
		this.setUpToggleButton()
	},
	setUpTransition: function(){
		if($('infocentreimage')){
			this.heroFx = new Fx.Style('infocentrecontent', 'height', {duration:250});
		} else {
			this.heroFx = new Fx.Style('heroshotcontent', 'height', {duration:250});
		}
		//this.heroFx = new Fx.Style('heroshotcontent', 'height', {duration:250});
		this.overlayFx = new Fx.Style('herooverlay', 'height', {duration:250});
	},
	openHeroShot: function(){
		this.heroFx.start(0, 263);
		this.overlayFx.start(0, 236);
		this.toggleShowHideButton();
		ieHeroOpen = true;
		Cookie.set('heroshot','visible', {path:'/',duration:7});
	},
	closeHeroShot: function(){
		this.heroFx.start(263, 0);
		this.overlayFx.start(236, 0);
		this.toggleShowHideButton();
		ieHeroOpen = false;
		Cookie.set('heroshot','hidden', {path:'/',duration:7});
	},
	setUpToggleButton: function(){
		this.targetButton.addEvent('click', function(evt){
			var targetButton = this.targetButton.getAttribute('src');
			if(targetButton.match('hide')){
				this.closeHeroShot();
			} else {
				this.openHeroShot();
			}
			evt = new Event(evt).stop();
		}.bind(this));
	},
	toggleShowHideButton: function(){
		var targetButton = this.targetButton.getAttribute('src');
		var switchButtonTo;
		if(targetButton.match('hide')){
			switchButtonTo = 'show';
		} else {
			switchButtonTo = 'hide';
		}
		var switchButtonExt;
		if(targetButton.match('.png')){
			switchButtonExt = '.png';
		} else {
			switchButtonExt = '.gif';
		}
		this.targetButton.setAttribute('src','/images/eyecandy/' + switchButtonTo + '-hero' + switchButtonExt);
	}
});

// Heroshot Overlay
var heroShotOverlay = new Class({
	rotating:true,
	currentOverlay:0,
	contentContainer:null,
	heroNav:null,
	imageMarkers:null,
	initialize: function(){
		var overlay = $('herooverlay');
		this.heroNav = overlay.getFirst().getElements('a');
		this.imageMarkers = overlay.getFirst().getElements('img');
		this.contentContainer = overlay.getLast();
		
		this.setUpNavigation();
		this.setImageMarker(0);
		var delayedOverlay = function(){
			this.rotateOverlays();
		}.delay(5000,this);
	},
	setUpNavigation: function(){
		this.heroNav.each(function(item,i){
			item.addEvent('click',function(evt){
				this.rotating = false;
				this.getTargetOverlay(item.getProperty('href').replace(/#/,''));
				this.setImageMarker(i);
				evt = new Event(evt).stop();
			}.bind(this));
		}.bind(this));
	},
	rotateOverlays: function(){
		if(this.rotating){
			this.currentOverlay++;
			if(this.currentOverlay > this.heroNav.length-1){
				this.currentOverlay = 0;
				this.rotating = false;
			}
			this.getTargetOverlay(this.heroNav[this.currentOverlay].getProperty('href').replace(/#/,''));
			this.setImageMarker(this.currentOverlay);
			var delayedOverlay = function(){
				this.rotateOverlays();
			}.delay(5000,this);
		}
	},
	setImageMarker: function(targetImage){
		this.imageMarkers.each(function(img,i){
			if(targetImage == (i)){
				img.src = '/images/eyecandy/bullet-green.gif';
			} else {
				img.src = '/images/eyecandy/bullet-grey.gif';
			}
		});
	},
	getTargetOverlay: function(idToSubmit){
		
		var URL = '/site/hero-shot/get-message?messageId=' + idToSubmit;
		
		var makeOverlayAjaxRequest = new Ajax(URL, {
			method: 'get',
			onComplete: function(response){
				this.contentContainer.setHTML(response);			
			}.bind(this)
		});
		makeOverlayAjaxRequest.request();
		
	}
});

// Member filters
var filterGroupObj = new Class({
	initialize: function(selectMaster, filterContent){
		this.filterContent = filterContent;
		this.filterContent.each(function(el){ el.setStyle('display','none'); });
		this.togglers = selectMaster.getNext().getElements('span');
		this.togglers.each(function(el,i){
			el.addEvents({
				'mousedown': function(e){
					this.filterContent.each(function(el){ el.setStyle('display','none'); });
					this.filterContent[i].setStyle('display','block');
				}.bind(this)
			});
		}.bind(this));
		this.filterContent[0].setStyle('display','block');
	}
});

// Category Carousel
var catCarousel = new Class({
	firstLayerLists: [],
	secondLayerLists: [],

	layerLists: [],
	layerHeights: [],
	liHeight: 21,
	liIeHeight: 24,
	listActivators: [],
	listFx: [],
	
	anchorList: [],
	selectedList: null,
	selectedAnchor: null,
		
	plusIconPath: '/images/btn-cat-plus.gif',
	minusIconPath: '/images/btn-cat-minus.gif',
	
	initialize: function(carouselObj){
		
		if(window.ie){
			this.liHeight = this.liIeHeight;
		}
		
		this.anchorList = carouselObj.getElements('a');
		var categoryUrl = document.location.href.split('?id=');
		if(categoryUrl[1]){
			this.setSelected(categoryUrl[1]);
		}
		this.firstLayerLists = carouselObj.getElements('ul li ul');
		this.secondLayerLists = carouselObj.getElements('ul li ol');
		this.layerLists = this.firstLayerLists.merge(this.secondLayerLists);

		this.layerLists.each(function(list,i){
			// Generate Heights
			if(list.getTag() == 'ul'){
				this.getListHeights(list,i,'first');				
			} else {
				this.getListHeights(list,i,'second');
			}
			// Add Icon
			this.addIcon(list,i);
		}.bind(this));
		
		// open child list of selected item (determined by the ID in the query string), if one exists
		// - the index we need to pass to openList is relative to activators rather than lists
		for(var i = 0; i < this.listActivators.length; i++) {
		  if(this.listActivators[i].getParent() == this.selectedList) {
        this.openList(this.selectedList, i);
        this.selectedList.addClass('opencategory');
      }
		}
	},
	getListHeights: function(list,i,type){
		switch(type){
			case 'first':
				var liElements = list.getElements('li');
				var liChildren = 0;
				liElements.each(function(item,j){
					var testType = item.getParent().getTag();
					if(testType == ('ol')){
						liChildren++;
					}
				}.bind(this));
				this.layerHeights[i] = (liElements.length-liChildren) * this.liHeight;
			break;
			case 'second':
				var liElements = list.getElements('li');
				var liChildren = 0;
				this.layerHeights[i] = (liElements.length-liChildren) * this.liHeight;
			break;
			default:
		}
	},
	openList: function (list, i) {
	  var listType = list.getParent().getLast();
    if(listType.getTag() == 'ol'){
      var listParent = list.getParent();
      var listTopParent = list.getParent().getParent();
      this.layerLists.each(function(list,j){
        if(list == listTopParent){
          var curHeight = listTopParent.getStyle('height').toInt();
          if(listParent.hasClass('opencategory')){
            this.listFx[j].start((curHeight + this.layerHeights[i]), (curHeight - this.layerHeights[i]));
          } else {
            this.listFx[j].start(curHeight, (curHeight + this.layerHeights[i]));
          }
        }
      }.bind(this));
    }
    this.toggleLayerHeight(list,i);
	},
	addIcon: function(list,i){
		
		this.listFx[i] = this.setUpTransition(list);
		if(list.hasChild(this.selectedList)){
			if(list.getTag() == 'ol'){
				list.getParent().addClass('opencategory');
			} else {
				list.getParent().addClass('opencategory');
			}
			var initialIcon = new Element('img',{'src':this.minusIconPath});
		} else {
			var initialIcon = new Element('img',{'src':this.plusIconPath});
			this.listFx[i].set(0);
		}
		if(this.selectedAnchor != null){
			this.selectedAnchor.getParent().addClass('selected');
		}
		this.listActivators[i] = initialIcon;
		
		initialIcon.addEvents({
		  'click': function (evt) {
		    this.openList(list, i);
  		}.bind(this),
			'mouseover': function(evt){
				var now = initialIcon.getProperty('src');
				initialIcon.setProperty('src',now.replace(/.gif/,'-o.gif'));
			}.bind(this),
			'mouseout': function(evt){
				var now = initialIcon.getProperty('src');
				initialIcon.setProperty('src',now.replace(/-o.gif/,'.gif'));
			}.bind(this)
		});
		initialIcon.injectTop(list.getParent());
	},
	toggleLayerHeight: function(list,i){
		var liParent = list.getParent();
		if(liParent.hasClass('opencategory')) {
			liParent.removeClass('opencategory');
			this.listFx[i].start(this.layerHeights[i], 0);
			this.listActivators[i].setProperty('src',this.plusIconPath);
			var hasOlLists = list.getElements('ol');
			if(hasOlLists.length > 0){
				hasOlLists.each(function(olList,j){
					this.layerLists.each(function(layerList,k){
						if(olList == layerList){
							if(olList.getParent().hasClass('opencategory')){
								this.listFx[k].start(this.layerHeights[k], 0);
								this.listActivators[k].setProperty('src',this.plusIconPath);
								olList.getParent().removeClass('opencategory');
							}
						}
					}.bind(this));
				}.bind(this));
			}
			
		} else {
			this.listFx[i].start(0, this.layerHeights[i]);
			this.listActivators[i].setProperty('src',this.minusIconPath);
			liParent.addClass('opencategory');
		}
	},
	setUpTransition: function(container){
		return new Fx.Style(container, 'height', {duration:250});
	},
	setSelected: function(categoryId){
	  this.anchorList.each(function(anchor,i){
			var href = anchor.getProperty('href').split('?id=');
			if(href[1].match(categoryId) && href[1].length == categoryId.length){
				this.selectedList = anchor.getParent();
				this.selectedAnchor = anchor;
			}
		}.bind(this));
	}
});

// Expanding boxes
// The figures 190 and 500 are specific to the expanding boxes on the info 
// centre pages - 190 is the size of the 'closed' box and 500 is the extra
// padding that is used to make sure the 'hidden' text stays off the screen
var expanderBox = new Class({
	expanderFx:null,
	initialize: function(expBox, expLinks){
		
		this.container = expBox[0];
		this.openLink = expLinks[0].getFirst();
		this.closeLink = expLinks[1].getFirst();
		this.maxheight = this.container.getSize().size.y;
		
		this.setUpTransition();
		this.setUpButtons();
		
		this.expanderFx.set(190);
		//this.container.setStyle('height','190px');
		
	},
	setUpTransition: function(){
		this.expanderFx = new Fx.Style(this.container, 'height', {duration:250});
	},
	openHeroShot: function(){
		this.expanderFx.start(190, (this.maxheight-500));
		this.openLink.getParent().setStyle('display','none');
		this.closeLink.getParent().setStyle('display','block');
	},
	closeHeroShot: function(){
		this.expanderFx.start((this.maxheight-500), 190);
		this.closeLink.getParent().setStyle('display','none');
		this.openLink.getParent().setStyle('display','block');
	},
	setUpButtons: function(){
		
		this.openLink.addEvent('click', function(evt){
			this.openHeroShot();
			evt = new Event(evt).stop();
		}.bind(this));
		
		this.closeLink.addEvent('click', function(evt){
			this.closeHeroShot();
			evt = new Event(evt).stop();
		}.bind(this));
	}
	
});

// Dynamic navigation (used for sub nav)
var subnavObj = new Class ({
	initialize: function (contentObjs, toggleObjs, eventType, showDefault) {
		this.contentObjs = contentObjs;
		this.toggleObjs = toggleObjs;
		if ((this.contentObjs.length > 0) && (this.toggleObjs.length > 0)) {
			// create slide objs for each content element and hide each one
			this.slideObjs = this.contentObjs.map(function(el){ return new Fx.Slide(el).hide(); });
			
			// show first content element & set appropriate toggle class
			if(showDefault == true){
				this.slideObjs[0].show();
				this.toggleObjs[0].getParent().addClass('selected');
			}

			var scope = this;
			var tempFunc = function(e) { scope.setContent(e,this);  e = new Event(e).stop(); };
			this.toggleObjs.addEvent(eventType, tempFunc);
		}
	},
	setContent: function(e, el) {
		var currEl = $('html_' + el.id);
		if (currEl){ 
			this.setOn(currEl);
			el.getParent().addClass('selected');
		};
		return false;
	},
	setOn: function(currEl) {
		this.toggleObjs.each(function(el){
			if (currEl){ el.getParent().removeClass('selected'); };
		});
		this.slideObjs.each(function(el){
			el.hide();
			if (el.element.id == currEl.id) { el.show(); };
		});
	},
	closeall: function() {
		this.slideObjs.each(function(el){ el.hide(); });
	}
});

// Dynamic content (case study)
var contentObj = new Class ({
	initialize: function (contentObjs, toggleObjs, eventType, showDefault) {
		this.contentObjs = contentObjs;
		this.toggleObjs = toggleObjs;
		if ((this.contentObjs.length > 0) && (this.toggleObjs.length > 0)) {
			// create slide objs for each content element and hide each one
			this.slideObjs = this.contentObjs.map(function(el){ return new Fx.Slide(el).hide(); });
			
			// show first content element & set appropriate toggle class
			if(showDefault == true){
				this.slideObjs[0].show();
				this.toggleObjs[0].getParent().addClass('selected');
			}

			var scope = this;
			var tempFunc = function(e) { scope.setContent(e,this);  e = new Event(e).stop(); };
			this.toggleObjs.addEvent(eventType, tempFunc);
		}
	},
	setContent: function(e, el) {
		var currEl = $('html_' + el.href.split('#')[1]);
		if (currEl){ 
			this.setOn(currEl);
			el.getParent().addClass('selected');
		};
		return false;
	},
	setOn: function(currEl) {
		this.toggleObjs.each(function(el){
			if (currEl){ el.getParent().removeClass('selected'); };
		});
		this.slideObjs.each(function(el){
			el.hide();
			if (el.element.id == currEl.id) { el.show(); };
		});
	},
	closeall: function() {
		this.slideObjs.each(function(el){ el.hide(); });
	}
});

var memberOnlyOffset = 0;
// Member Only restrictions
var memberOnlyPopup = new Class({
	initialize: function(){
		this.generateMembersLinks();
	},
	generateMembersLinks: function(){
		var membersLinks = $$('a.membersonlycheck');
		membersLinks.each(function(link,i){
			link.addEvents({
				'mouseenter': function(e){
					this.generateMouseOver(link, e, i);
				}.bind(this),
				'click': function(e){
					e = new Event(e).stop();
					e = new Event(e).stopPropagation();
				}.bind(this)
			});
			link.removeClass('membersonlycheck');
		}.bind(this));
		
	},
	generateMouseOver: function(link,e,i){
		var hozOffset = 0;
		if(link.getParent().hasClass('audio') || link.getParent().hasClass('video')){
			hozOffset = 0;
			parentLeft = link.getParent().getParent().getParent().getParent().getLeft();
			linkLeft = link.getLeft();
			initOffset = linkLeft - parentLeft;
			if((initOffset - (memberOnlyOffset * 520)) == 101){
				hozOffset = 101;
			}
			if((initOffset - (memberOnlyOffset * 520)) == 361){
				hozOffset = 361;
			}
			// 101 first place
			// 361 second place
		}
		
		var pos = link.getPosition();
		var siz = link.getSize();
		
		var t = pos.y;
		var r = pos.x + siz.size.x;
		var b = pos.y + siz.size.y;
		var l = pos.x;
		
		var centralVertical = b - ((siz.size.y/2)-12);
		//var centralVertical = b - siz.size.y;
		if(hozOffset != 0){
			var centralHorizontal = (parentLeft + hozOffset) + (siz.size.x/2);
		} else {
			var centralHorizontal = r - (siz.size.x/2);
		}
		
		var popup, hOffset;
		if(link.getParent().hasClass('event')) {
		  popup = $('membersonlyeventpopup');
		  hOffset = 180;
		} else {
		  popup = $('membersonlypopup');
		  hOffset = 153;
		}
		
		popup.setStyles({ 'left':(centralHorizontal - 116),'top':(centralVertical - hOffset),'display':'block' });
		popup.addEvent('mouseleave',function(e){ popup.setStyles({ 'display':'none','left':'0','top':'0' }) });
	}
});

var QuestionPopUp = new Class({
  initialize: function(el, index) {
    this.el = el;
    this.index = index;
    this.popup = $('questionpopup');
    this.popupContent = $$('#questionpopup div.content');
    this.popupCloseBtn = $$('#questionpopup span.closequestion');
    
    this.popupCloseBtn.addEvents({
      'click': function() { 
        this.popup.setStyles({'display':'none'}); 
      }.bind(this)
    });
    
    el.addEvents({
      'click': function(e){
        console.log(this.index + ': ' + this.el.getText());
        var objLoc = this.el.getPosition();
        
        this.popupContent.empty();
        this.popupContent.setText(this.index + ': ' + this.el.getText());
        
        this.popup.setStyles({
          'top': (objLoc.y - 40) + 'px',
          'left': (objLoc.x + 10) + 'px',
          'display':'block'
        });
      }.bind(this)
    });
  }
});


// Create Calendar
var createCalendar = new Class({
	initialize: function(el){
		this.calMonth = el.getChildren()[1];
		this.calItems = el.getChildren()[2];
		this.setMonth(this.calMonth);
		this.setDays(this.calMonth);
		this.calItems.addClass('open');
		var scope = this;
		this.calItems.getChildren().each(function(el,i){
			if(el.getFirst()){
				scope.generateMarkers(el);
			}
		});
	},
	setMonth: function(el){
		var elTxt = el.getText();
		el.empty();
		var scope = this;
		var slc = new Element('span',{'class':'lc'}).injectInside(el);
		var slcimg = new Element('img',{'src':'/images/icon-chevron-grey-l.gif','alt':'','width':'5','height':'7'}).injectInside(slc);
		slcimg.addEvent('mouseover',function(e){ slcimg.src = '/images/icon-chevron-pink-l.gif' });
		slcimg.addEvent('mouseout',function(e){ slcimg.src = '/images/icon-chevron-grey-l.gif' });
		slcimg.addEvent('click',function(e){ scope.refreshCalendar('previous'); e = new Event(e).stop(); });

		new Element('span',{'class':'mc'}).setHTML(elTxt).injectInside(el);

		var src = new Element('span',{'class':'rc'}).injectInside(el);
		var srcimg = new Element('img',{'src':'/images/icon-chevron-grey.gif','alt':'','width':'5','height':'7'}).injectInside(src);
		srcimg.addEvent('mouseover',function(e){ srcimg.src = '/images/icon-chevron-pink.gif' });
		srcimg.addEvent('mouseout',function(e){ srcimg.src = '/images/icon-chevron-grey.gif' });
		srcimg.addEvent('click',function(e){ scope.refreshCalendar('next'); e = new Event(e).stop(); });
	},
	setDays: function(el){
		var ul = new Element('ul',{'class':'calendardays'}).injectAfter(el);
		new Element('li').setHTML('M').injectInside(ul);
		new Element('li').setHTML('T').injectInside(ul);
		new Element('li').setHTML('W').injectInside(ul);
		new Element('li').setHTML('T').injectInside(ul);
		new Element('li').setHTML('F').injectInside(ul);
		new Element('li').setHTML('S').injectInside(ul);
		new Element('li').setHTML('S').injectInside(ul);
	},
	generateMarkers: function(el){
		var children = el.getFirst().getChildren();
		var d = new Element('div',{'class':'eventcontainer'}).injectTop(children[0]);
		var scope = this;
		children.each(function(el,i){
			if(i!=0){
				if(i<4){
					var type = el.className.replace(/activity /,'');
					switch(type){
						case 'eventtype1':
							var im = new Element('img',{'class':'activity' + i,'src':'/images/icon-dot-green-sml.gif','alt':'','width':'6','height':'6'}).injectInside(d);
						break;
						case 'eventtype2':
							var im = new Element('img',{'class':'activity' + i,'src':'/images/icon-dot-pink-sml.gif','alt':'','width':'6','height':'6'}).injectInside(d);
						break;
						case 'eventtype3':
							var im = new Element('img',{'class':'activity' + i,'src':'/images/icon-dot-orange-sml.gif','alt':'','width':'6','height':'6'}).injectInside(d);
						break;
						default:
							return;
					}
					im.addEvent('mouseover',function(e){ $('calendarpopup').empty(); scope.generateMouseOver(el,e,i,type) });
				}
			}
		});
		
	},
	generateMouseOver: function(el,e,i,type){
	  var children = el.getChildren();
		var childrenLower = children[1].getChildren();
		var d = new Element('div',{'class':'calendarpopup'}).injectInside($('calendarpopup'));
		switch(type){
			case 'eventtype1':
				var h = new Element('h4').setHTML('UK-GBC Member<br />Event').injectInside(d);
				var i = new Element('img',{'src':'/images/popup-icon-ukgbc-green.gif','alt':'','width':'45','height':'50'}).injectTop(d);
			break;
			case 'eventtype2':
				var h = new Element('h4').setHTML('UK-GBC Meeting').injectInside(d);
				var i = new Element('img',{'src':'/images/popup-icon-ukgbc-pink.gif','alt':'','width':'45','height':'50'}).injectTop(d);
			break;
			case 'eventtype3':
				var h = new Element('h4').setHTML('UK-GBC Supported Event').injectInside(d);
				var i = new Element('img',{'src':'/images/popup-icon-ukgbc-orange.gif','alt':'','width':'45','height':'50'}).injectTop(d);
			break;
		}
		var p = new Element('p').setHTML(children[0].getText() + '<br />' + childrenLower[0].getText()).injectInside(d);
		var a = new Element('a',{'href':childrenLower[1].getProperty('href')}).setHTML('Read more...').injectInside(d);
		var loc = el.getPosition();
		var left = e.clientX - 237;
		var top = (e.clientY + window.getScrollTop()) - 175;
		if(!window.ie){
			$('calendarpopup').setStyles({'left':left,'top':top});			
		} else {
		  if (window.ie6) {
        if (ieHeroOpen) {
          ieHorizontalAdjustment = 170;        
          ieVerticalAdjustment = 427;
        } else {
          ieHorizontalAdjustment = 170;
          ieVerticalAdjustment = 161;
        }
		  } else if (window.ie7) {
		    if (ieHeroOpen) {
		      ieHorizontalAdjustment = 170;
          ieVerticalAdjustment = 417;
		    } else {
          ieHorizontalAdjustment = 172;
          ieVerticalAdjustment = 151;
		    }
		  } else {
		    ieHorizontalAdjustment = 0;
        ieVerticalAdjustment = 0;
		  }
			$('calendarpopup').setStyles({'left':(left - ieHorizontalAdjustment),'top':(top - ieVerticalAdjustment)});
		}
		$('calendarpopup').addClass('calendarpopup ' + type);
		$('calendarpopup').addEvent('mouseleave',function(e){ $('calendarpopup').removeClass('calendarpopup ' + type); $('calendarpopup').empty(); });
	},
	refreshCalendar: function(dir){
		var currentCalendar = $$('div#calendar h3')[0].getText();
		var caldendarSettings = currentCalendar.split(' ');
		var newMth = this.getMonth(caldendarSettings[0]);
		if(dir == 'next'){ newMth++ } else { newMth-- }
		var newYr = caldendarSettings[1];
		if(newMth == 0){ newYr--; newMth = 12 }
		if(newMth == 13){ newYr++; newMth = 1 }
		var URL = '/site/Calendar?m=' + newMth + '&y=' + newYr;
		var refreshCalendarAjaxRequest = new Ajax(URL, {
			method: 'get',
			onComplete: function(response) {
				$('calendarObject').setHTML(response);
				new createCalendar($('calendar'));
			}.bind(this)
		});
		refreshCalendarAjaxRequest.request();
	},
	getMonth: function(n){
		var mth;
		switch(n.toLowerCase()){
			case 'january': mth = 1; break;
			case 'february': mth = 2; break;
			case 'march': mth = 3; break;
			case 'april': mth = 4; break;
			case 'may': mth = 5; break;
			case 'june': mth = 6; break;
			case 'july': mth = 7; break;
			case 'august': mth = 8; break;
			case 'september': mth = 9; break;
			case 'october': mth = 10; break;
			case 'november': mth = 11; break;
			case 'december': mth = 12; break;
		}
		return mth;
	}
});

var EventTicketDropDown = new Class({

  options: {
    ddlDays: false, 
    ddlTickets: false, 
    ddlTicketsNonMem: false,
    spanPriceUpper: false,
    spanPriceLower: false,
    spanTotalUpper: false,
    spanVatUpper: false,
    spanVatLower: false,
    spanTotalUpper: false,
    spanTotalLower: false,
    spanNumTicketLower: false,
    spanDateLower: false,
    divAttendees: false,
    ticketJson: [{ }], 
    availableMessage: ' seats available.', 
    selectDateMessage: 'Please select a date.',
    isChargeable: false,
    pricePerSeat: 0,
    vatPerSeat: 0,
    totalPerSeat: 0,
    pricePerNonMemberSeat: 0,
    vatPerNonMemberSeat: 0,
    totalPerNonMemberSeat: 0,
    selectedNumTickets: false,
    selectedNumTicketsNonMember: false
  }
  
, initialize: function(options) {
	  this.setOptions(options);
    this.ddlDays = $(this.options.ddlDays);
    this.ddlTickets = $(this.options.ddlTickets);
    this.spanPriceUpper = $(this.options.spanPriceUpper);
    this.spanPriceLower = $(this.options.spanPriceLower);
    this.spanVatUpper = $(this.options.spanVatUpper);
    this.spanVatLower = $(this.options.spanVatLower);
    this.spanTotalUpper = $(this.options.spanTotalUpper);
    this.spanTotalLower = $(this.options.spanTotalLower);
    this.spanNumTicketLower = $(this.options.spanNumTicketLower);
    this.spanDateLower = $(this.options.spanDateLower);
    this.divAttendees = $(this.options.divAttendees);
    this.ticketJson = this.options.ticketJson;
    this.isChargeable = this.options.isChargeable;
    this.pricePerSeat = this.options.pricePerSeat;
    this.vatPerSeat = this.options.vatPerSeat;
    this.totalPerSeat = this.options.totalPerSeat;
    this.pricePerNonMemberSeat = this.options.pricePerNonMemberSeat;
    this.vatPerNonMemberSeat = this.options.vatPerNonMemberSeat;
    this.totalPerNonMemberSeat = this.options.totalPerNonMemberSeat;
    this.selectedNumTickets = this.options.selectedNumTickets;
    this.selectedNumTicketsNonMember = this.options.selectedNumTicketsNonMember;
    
    this.ddlTicketsNonMem = null;
    if (this.options.ddlTicketsNonMem) {
      this.ddlTicketsNonMem = $(this.options.ddlTicketsNonMem);
    }
    
    /* for fancy select - got rid of fancy dropdowns for this
    this.togglers = this.ddl.getNext().getElements('span');
    this.togglers.each(function(item) {
      item.addEvent('mouseup', this.handleChange.bind(this, item));
    }.bind(this));
    */
    
    this.ddlDays.addEvent('change',this.handleDayChange.bind(this));
    this.ddlTickets.addEvent('change',this.handleTicketChange.bind(this));
    if (this.ddlTicketsNonMem) {
      this.ddlTicketsNonMem.addEvent('change',this.handleTicketChange.bind(this));
    }
    
    // call once in case there is a vlaue selected
    this.handleDayChange();
  } ,

  handleDayChange: function() {
    var ddlVal = $(this.ddlDays.options[this.ddlDays.options.selectedIndex]).getProperty('value');
    var currentTicket = this.ticketJson.filter(function(item, index){ return ($chk(item) && item.dayId == ddlVal); });
    
    this.ddlTickets.empty();
    if (this.ddlTicketsNonMem) {
      this.ddlTicketsNonMem.empty();
    }
    
    if ($chk(currentTicket[0])) {
      // populate main ticket number drop down
      this.populateDropDown(
        this.ddlTickets,
        1,
        currentTicket[0].maxBookable,
        "Your organisation's ticket allocation has been used", 
        this.selectedNumTickets
      );
      // populate non-member drop down if applicable
      if (this.ddlTicketsNonMem) {
        this.populateDropDown(
          this.ddlTicketsNonMem,
          0,
          currentTicket[0].maxBookableNonMember,
          "The non-member ticket allocation has been used", 
          this.selectedNumTicketsNonMember
        );
      }
    }
    
    this.handleTicketChange();
  }

, populateDropDown: function(ddl, start, max, overflowMsg, selected) {
    if (max > 0) {
      for (i = start; i <= max; i++) {
        var option = new Element('option', {'value': i}).setHTML(i + ' Seat' + (i != 1 ? 's' : ''));
        if (selected && selected == i) {
          option.setProperty('selected', 'selected');
        }
        option.injectInside(ddl);
      }
    } else {
      new Element('option', {'value': 0}).setHTML(overflowMsg).injectInside(ddl);
    }
  }

, handleTicketChange: function() {
    var selectedDayOp = $(this.ddlDays.options[this.ddlDays.options.selectedIndex]);
    
    var selectedTicketOp, numTickets, numNonMemberTickets;
    if (this.ddlTickets.options.length > 0) {
      selectedTicketOp = $(this.ddlTickets.options[this.ddlTickets.options.selectedIndex]);
      numTickets = parseInt(selectedTicketOp.getProperty('value'));
    } else {
      selectedTicketOp = null;
      numTickets = 1;
    }
    
    if (this.ddlTicketsNonMem && this.ddlTicketsNonMem.options.length > 0) {
      numNonMemberTickets = parseInt(
          $(this.ddlTicketsNonMem.options[this.ddlTicketsNonMem.options.selectedIndex])
          .getProperty('value')
      );
    } else {
      numNonMemberTickets = 0;
    }
    
    this.setAttendeeFormDivs(numTickets + numNonMemberTickets);
    
    //
    
    var priceVal, priceStr, vatVal, vatStr, totalVal, totalStr, dateStr, numTicketsStr;
    
    //alert(selectedDayOp.getProperty('value'));
    if (selectedTicketOp != null && selectedDayOp.getProperty('value') > 0) {
      if (this.isChargeable) {
        priceVal = (this.pricePerSeat*numTickets) + (this.pricePerNonMemberSeat*numNonMemberTickets);
        priceStr = '£'+priceVal.toFixed(2);
        vatVal = (this.vatPerSeat*numTickets) + (this.vatPerNonMemberSeat*numNonMemberTickets);
        vatStr = '£'+vatVal.toFixed(2);
        totalVal = (this.totalPerSeat*numTickets) + (this.totalPerNonMemberSeat*numNonMemberTickets);
        totalStr = '£'+totalVal.toFixed(2);
      }
      dateStr = selectedDayOp.getText();
      numTicketsStr = numTickets;
    } else {
      if (this.isChargeable) {
        priceVal = 0;
        priceStr = '&nbsp;';
        vatVal = 0;
        vatStr = '&nbsp;';
        totalVal = 0;
        totalStr = '&nbsp;';
      }
      dateStr = '&nbsp;';
      numTicketsStr = '&nbsp;';
    }
    
    if (this.isChargeable) {
      this.spanPriceUpper.innerHTML = priceStr;
      this.spanPriceLower.innerHTML = priceStr;
      this.spanVatUpper.innerHTML = vatStr;
      this.spanVatLower.innerHTML = vatStr;
      this.spanTotalUpper.innerHTML = totalStr;
      this.spanTotalLower.innerHTML = totalStr;
    }
    this.spanDateLower.innerHTML = dateStr;
    this.spanNumTicketLower.innerHTML = numTicketsStr;
  }

, setAttendeeFormDivs: function(numTickets) {
    var attendeeDivs = this.divAttendees.getChildren();
    var numAttendeeDivs = attendeeDivs.length + 1; // first one is permanent
    
    if (numTickets > numAttendeeDivs) {
      //alert('add');
      for (var i = numAttendeeDivs; i < numTickets; i++) {
        this.getAttendeeFormElements(i).injectInside(this.divAttendees);
      }
    } else if (numTickets < numAttendeeDivs) {
      //alert('remove');
      var now = attendeeDivs.getLast();
      var next = null;

      while (numAttendeeDivs > numTickets) {
        if (!now) {
          break;
        }
        
        next = now.getPrevious();
        now.remove();
        now = next;
        
        numAttendeeDivs--;
      }
    } else {
      //alert('do nothing');
    }
  }

, getAttendeeFormElements: function(num) {
    var top = new Element('div');
    top.setProperty('class', 'attendee');
    top.setProperty('id', 'top'+num);
    
    var heading = new Element('h4');
    heading.appendText(this.getOrdinalStr(num + 1) + ' Attendee Details');
    top.appendChild(heading);
    
    var idPrefix = 'attendees[' + num + ']';
    
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[name]', 'First Name *'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[surname]', 'Surname *'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[company]', 'Company *'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[jobTitle]', 'Job Title *'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[email]', 'Email Address *'));
    
    return top;
  }

, getAttendeeTextInput: function (elementId, labelStr) {
    var top = new Element('div');
    top.setProperty('class', 'formrow');
    
    var label = new Element('label');
    label.setProperty('for', elementId);
    label.appendText(labelStr);
    top.appendChild(label);
    
    var input = new Element('input');
    input.setProperty('id', elementId);
    input.setProperty('name', elementId);
    input.setProperty('class', 'text');
    input.setProperty('type', 'text');
    input.setProperty('value', '');
    top.appendChild(input);
    
    return top;
  }

, getOrdinalStr: function (num) {
    var remainder = num % 10;
    var ordinalStr;
    
    switch (remainder) {
      case 1:
        ordinalStr = num + 'st';
        break;
      case 2:
        ordinalStr = num + 'nd';
        break;
      case 3:
        ordinalStr = num + 'rd';
        break;
      default:
        ordinalStr = num + 'th';
    }
    
    return ordinalStr;
  }

});
EventTicketDropDown.implement(new Options);

/**
 * @todo need to merge common functionality from EventTicketDropDown and
 * SimpleEventTicketDropDown - need to separate calculation from view, and where
 * the selected date is set (how to handle the money stuff?)
 */
var SimpleEventTicketDropDown = new Class({

  options: {
    ddlDays: false, 
    ddlTickets: false, 
    ddlTicketsNonMem: false,
    divAttendees: false,
    ticketJson: [{ }], 
    availableMessage: ' seats available.', 
    selectDateMessage: 'Please select a date.',
    isChargeable: false,
    pricePerSeat: 0,
    vatPerSeat: 0,
    totalPerSeat: 0,
    pricePerNonMemberSeat: 0,
    vatPerNonMemberSeat: 0,
    totalPerNonMemberSeat: 0,
    selectedNumTickets: false,
    selectedNumTicketsNonMember: false
  }
  
, initialize: function(options) {
    this.setOptions(options);
    this.ddlDays = $(this.options.ddlDays);
    this.ddlTickets = $(this.options.ddlTickets);
    this.divAttendees = $(this.options.divAttendees);
    this.ticketJson = this.options.ticketJson;
    this.isChargeable = this.options.isChargeable;
    this.pricePerSeat = this.options.pricePerSeat;
    this.vatPerSeat = this.options.vatPerSeat;
    this.totalPerSeat = this.options.totalPerSeat;
    this.pricePerNonMemberSeat = this.options.pricePerNonMemberSeat;
    this.vatPerNonMemberSeat = this.options.vatPerNonMemberSeat;
    this.totalPerNonMemberSeat = this.options.totalPerNonMemberSeat;
    this.selectedNumTickets = this.options.selectedNumTickets;
    this.selectedNumTicketsNonMember = this.options.selectedNumTicketsNonMember;
    
    this.ddlTicketsNonMem = null;
    if (this.options.ddlTicketsNonMem) {
      this.ddlTicketsNonMem = $(this.options.ddlTicketsNonMem);
    }
    
    this.ddlDays.addEvent('change',this.handleDayChange.bind(this));
    this.ddlTickets.addEvent('change',this.handleTicketChange.bind(this));
    if (this.ddlTicketsNonMem) {
      this.ddlTicketsNonMem.addEvent('change',this.handleTicketChange.bind(this));
    }
    
    // call once in case there is a vlaue selected
    this.handleDayChange();
  } ,

  handleDayChange: function() {
    var ddlVal = $(this.ddlDays).getProperty('value');
    var currentTicket = this.ticketJson.filter(function(item, index){ return ($chk(item) && item.dayId == ddlVal); });
    
    this.ddlTickets.empty();
    if (this.ddlTicketsNonMem) {
      this.ddlTicketsNonMem.empty();
    }
    
    if ($chk(currentTicket[0])) {
      // populate main ticket number drop down
      this.populateDropDown(
        this.ddlTickets,
        1,
        currentTicket[0].maxBookable,
        "Your organisation's ticket allocation has been used", 
        this.selectedNumTickets
      );
      // populate non-member drop down if applicable
      if (this.ddlTicketsNonMem) {
        this.populateDropDown(
          this.ddlTicketsNonMem,
          0,
          currentTicket[0].maxBookableNonMember,
          "The non-member ticket allocation has been used", 
          this.selectedNumTicketsNonMember
        );
      }
    }
    
    this.handleTicketChange();
  }

, populateDropDown: function(ddl, start, max, overflowMsg, selected) {
    if (max > 0) {
      for (i = start; i <= max; i++) {
        var option = new Element('option', {'value': i}).setHTML(i);
        if (selected && selected == i) {
          option.setProperty('selected', 'selected');
        }
        option.injectInside(ddl);
      }
    } else {
      new Element('option', {'value': 0}).setHTML(overflowMsg).injectInside(ddl);
    }
  }

, handleTicketChange: function() {
    var selectedDayOp = this.ddlDays; 
    
    var selectedTicketOp, numTickets;
    if (this.ddlTickets.options.length > 0) {
      selectedTicketOp = $(this.ddlTickets.options[this.ddlTickets.options.selectedIndex]);
      numTickets = parseInt(selectedTicketOp.getProperty('value'));
    } else {
      selectedTicketOp = null;
      numTickets = 1;
    }
    
    this.setAttendeeFormDivs(numTickets);
  }

, setAttendeeFormDivs: function(numTickets) {
    var attendeeRowDivs = this.divAttendees.getChildren();
    var numAttendeeRowDivs = attendeeRowDivs.length;
    
    var attendeeDivs = $$('div.attendee');
    var numAttendeeDivs = attendeeDivs.length; // first one is permanent
    
    var numRowsRequired = Math.ceil(numTickets / 2);
    var rowRemainder = numTickets % 2;
    
    //alert(numAttendeeDivs + ", " + numTickets + "; " + numAttendeeRowDivs + ", " + numRowsRequired);
    
    if (numTickets > numAttendeeDivs) {
      //alert('add');
      
      // check if we need to add second column first...
      if (numAttendeeDivs % 2 == 1) {
        var lastRow = attendeeRowDivs.getLast();
        var lastCol = $E('.boxsplitright', lastRow);
        if (lastCol) {
          this.getAttendeeDiv(numAttendeeDivs).injectInside(lastCol);
        }
        numAttendeeDivs++;
      }
      
      // add rows
      for (var i = numAttendeeRowDivs; i < numRowsRequired; i++) {
        if ((i+1) == numRowsRequired && rowRemainder == 1) {
          // add row with one column if last row and odd number of tickets
          this.getAttendeeRow(i*2, 1).injectInside(this.divAttendees);
        } else {
          // add row with 2 columns
          this.getAttendeeRow(i*2, 2).injectInside(this.divAttendees);
        }
      }
    } else if (numTickets < numAttendeeDivs) {
      //alert('remove');
      var now = attendeeRowDivs.getLast();
      var next = null;

      // remove whole rows
      while (numAttendeeRowDivs > numRowsRequired) {
        if (!now) {
          break;
        }
        
        next = now.getPrevious();
        now.remove();
        now = next;
        
        numAttendeeRowDivs--;
      }
      
      // remove single column if number is odd
      if (numTickets % 2 == 1) {
        // get attendeeRowDivs again, still includes removed rows
        attendeeRowDivs = this.divAttendees.getChildren();
        var lastRow = attendeeRowDivs.getLast();
        var lastAttendee = $E('.boxsplitright .attendee', lastRow);
        if (lastAttendee) {
          lastAttendee.remove();
        }
      }
      
    } else {
      //alert('do nothing');
    }
  }

, getAttendeeRow: function(firstNum, columns) {
    var row = new Element('div');
    row.setProperty('class', 'boxsplitcontainer');
    
    var leftCol = new Element('div');
    leftCol.setProperty('class', 'boxsplitleft');
    leftCol.appendChild(this.getAttendeeDiv(firstNum));
    
    var rightCol = new Element('div');
    rightCol.setProperty('class', 'boxsplitright');
    if (columns > 1) {
      rightCol.appendChild(this.getAttendeeDiv(firstNum+1));
    }
    
    var divider = new Element('div');
    divider.setProperty('class', 'divider');
    
    row.appendChild(leftCol);
    row.appendChild(rightCol);
    row.appendChild(divider);

    return row;
  }

, getAttendeeDiv: function(num) {
    var top = new Element('div');
    top.setProperty('class', 'attendee');
    top.setProperty('id', 'top'+num);
    
    var headingDiv = new Element('div');
    headingDiv.setProperty('class', 'formrow');
    var heading = new Element('h4');
    heading.appendText(this.getOrdinalStr(num + 1) + ' Attendee Details');
    headingDiv.appendChild(heading);
    top.appendChild(headingDiv);
    
    var idPrefix = 'attendees[' + num + ']';
    
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[name]', 'First Name *'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[surname]', 'Surname *'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[company]', 'Company *'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[jobTitle]', 'Job Title'));
    top.appendChild(this.getAttendeeTextInput(idPrefix+'[email]', 'Email Address *'));
    
    // begin checkbox
    
    var memberDiv = new Element('div');
    memberDiv.setProperty('class', 'formrow');
    
    var label = new Element('label');
    label.setProperty('for', idPrefix+'[hasMember]');
    label.appendText('\u00a0'); // &nbsp;
    memberDiv.appendChild(label);
    
    var checkDiv = new Element('div');
    checkDiv.setProperty('class', 'check');
    
    var input = new Element('input');
    input.setProperty('id', idPrefix+'[hasMember]');
    input.setProperty('name', idPrefix+'[hasMember]');
    input.setProperty('type', 'checkbox');
    input.setProperty('value', '1');
    
    checkDiv.appendChild(input);
    checkDiv.appendText('Are you from a UK-GBC Member Organisation?');
    memberDiv.appendChild(checkDiv);
    
    top.appendChild(memberDiv);
    
    // end checkbox
    
    return top;
  }

, getAttendeeTextInput: function (elementId, labelStr) {
    var top = new Element('div');
    top.setProperty('class', 'formrow');
    
    var label = new Element('label');
    label.setProperty('for', elementId);
    label.appendText(labelStr);
    top.appendChild(label);
    
    var input = new Element('input');
    input.setProperty('id', elementId);
    input.setProperty('name', elementId);
    input.setProperty('class', 'text');
    input.setProperty('type', 'text');
    input.setProperty('value', '');
    top.appendChild(input);
    
    return top;
  }

, getOrdinalStr: function (num) {
    var remainder = num % 10;
    var ordinalStr;
    
    switch (remainder) {
      case 1:
        ordinalStr = num + 'st';
        break;
      case 2:
        ordinalStr = num + 'nd';
        break;
      case 3:
        ordinalStr = num + 'rd';
        break;
      default:
        ordinalStr = num + 'th';
    }
    
    return ordinalStr;
  }

});
SimpleEventTicketDropDown.implement(new Options);

// Fake select boxes...
var createFakeSelect = new Class({
	initialize: function(el){
		this.selectcontainer = el;
		this.selectdropdown = this.selectcontainer.getFirst();
		this.selectdropdownoptions = this.selectdropdown.getChildren();
		this.selectedItem = this.selectdropdown.selectedIndex;
		
		var c = this.selectcontainer.className;
		this.selectcontainer.className = c.replace(/dummy/,'');

		var scope = this;
		var s = new Element('span').setText(this.selectdropdownoptions[this.selectedItem].getText());
			s.addEvent('click', function(el){
				this.selectcontainer.addClass('open');
				window.addEvent('mouseup', function(e) { scope.selectcontainer.removeClass('open'); window.removeEvents('mouseup') });
			}.bind(this));
			s.injectTop(this.selectcontainer);

		var u = new Element('ul').injectInside(this.selectcontainer);
		u.addEvent('mouseup', function(e){ e = new Event(e).stopPropagation() });
		this.selectdropdownoptions.each(function(e,i){ 
			var l = new Element('li').injectInside(u);
			var ls = new Element('span').setHTML(e.getText());
				ls.addEvent('click', function() {
					scope.selectcontainer.removeClass('open');
					scope.selectcontainer.getFirst().setHTML(ls.getText());
					scope.selectdropdown.selectedIndex = i;
				}.bind(this));
				ls.injectInside(l);
		});
	}
});

// Fake file upload boxes...
var createFakeUpload = new Class({
	initialize: function(el){
		var upload = el.getFirst();
		upload.addEvents({
			'change':function(e){
				inp.setText(el.getFirst().value);
			}
		});
		
		var inp = new Element('span',{'class':'fakeuploadtext'}).setText('Select a file...').injectInside(el);
		if(window.opera){
			inp.setStyles({
				'width':'210px',
				'margin-top':'0'
			});
		}
		var img = new Element('img',{'src':'/images/btn-browse.gif','alt':'Browse'}).injectAfter(inp);
	}
});

var FakeCheckBox = new Class({
  
  initialize: function(checkbox) {
    this.checkbox = checkbox;
    this.label = this.getLabel();
    this.enabled = true;

    var src;
    if (checkbox.checked) {
      src = '/images/tick-box-s.gif';
    } else {
      src = '/images/tick-box.gif';
    }
    this.img = new Element('img',{'src':src,'alt':''}).injectBefore(checkbox);

    if (window.ie) {
      this.label.addEvents({
        'click':this.onClick.bind(this),
        'mouseover':this.onMouseOver.bind(this),
        'mouseout':this.onMouseOut.bind(this)
      });
    } else {
      checkbox.addEvents({
        'change':this.onChange.bind(this)
      });
    }

    this.img.addEvents({
      'click':this.onClick.bind(this)
    });
    
    checkbox.setOpacity(0);
  },
  
  onClick: function(e) {
    if (this.enabled) {
      if (!this.checkbox.checked){
        this.checkbox.checked = true;
        this.img.src = '/images/tick-box-s.gif';
      } else {
        this.checkbox.checked = false;
        this.img.src = '/images/tick-box.gif';
      }
      if (window.ie) {
        //console.log('Forcing checkbox click event');
        this.checkbox.fireEvent('click');
      } else {
        this.checkbox.fireEvent('change');
      }
    }
  },
  
  onChange: function(e) {
    if (this.enabled) {
      if (this.checkbox.checked){
        this.img.src = '/images/tick-box-s.gif';
      } else {
        this.img.src = '/images/tick-box.gif';
      }
    }
  },
  
  onMouseOver: function(e) {
    this.label.addClass('hover');
  },
  
  onMouseOut: function(e) {
    this.label.removeClass('hover');
  },
  
  getLabel: function(e) {
    return this.checkbox.getNext();
  },
  
  getElement: function() {
    return this.checkbox;
  },
  
  setDisabled: function(disabled) {
    this.enabled = !disabled;
    this.checkbox.setProperty('disabled', disabled);
    this.img.setOpacity(disabled ? 0.4 : 1);
  }
  
});

var FakeRadioGroup = new Class({
  
  ICON_SRC_SELECTED: '/images/tick-box-s.gif',
  ICON_SRC_DESELECTED: '/images/tick-box.gif',
  
  initialize: function(el) {
    this.enabled = true;
    this.fieldName = null;
    this.radios = new Array();
    this.images = new Array();
    
    // get matching radio elements
    el.getElements('input').each(this.initRadio.bind(this)); // 'input[type=radio]' ?
  },
  
  initRadio: function(radio) {
    var src, img, index;
    
    if (radio.getProperty('type') == 'radio') {
      // get name from first radio, ignore others that have different name
      if (this.fieldName == null) {
        this.fieldName = radio.getProperty('name');
      } else if (this.fieldName != radio.getProperty('name')) {
        return;
      }
      
      // inject overlay image
      src = this.ICON_SRC_DESELECTED;
      if(radio.checked){
        src = this.ICON_SRC_SELECTED;
      }
      img = new Element('img',{'src':src,'alt':''}).injectBefore(radio);
      
      index = this.radios.push(radio);
      this.images.push(img);
      
      img.addEvents({
        'click':function(e){
          this.selectRadio(index-1);
        }.bind(this)
      });
      
      radio.setOpacity(0);
    }
  },
  
  selectRadio: function(index) {
    if (this.enabled) {
      this.radios[index].checked = true;
      
      this.images.each(
        function(el, i) {
          if (i == index) {
            el.src = this.ICON_SRC_SELECTED;
          } else {
            el.src = this.ICON_SRC_DESELECTED;
          }
        }.bind(this)
      );
    }
  },
  
  disable: function(disable) {
    this.enabled = !disable;
    
    for (var i = 0; i < this.radios.length; i++) {
      this.radios[i].disabled = disable;
      
      if (disable) {
        this.images[i].setOpacity(0.4);
      } else {
        this.images[i].setOpacity(1);
      }
    }
  },
  
  clearSelection: function() {
    // no way to clear the selection of a radio group, so create a new radio,
    // select it, then delete it
    var el = new Element('input');
    el.setAttribute('type', 'radio');
    el.setAttribute('name', this.fieldName);
    el.setOpacity(0);
    el.injectAfter(this.radios[0]);
    el.checked = true;
    el.remove();
    
    for (var i = 0; i < this.images.length; i++) {
      this.images[i].src = this.ICON_SRC_DESELECTED;
    }
  }
});

var QuestionnaireContainer = new Class({
  
  initialize: function(container) {
    var qId = container.getProperty("id");
    this.radioGroup = new FakeRadioGroup(container);
    this.fakeCheckbox = new FakeCheckBox($(qId + '_await'));
    this.fileInput = $(qId + '_file');
    this.commentInput = $(qId + '_comment');
    
    //console.log(qId);
    if (container.hasClass('disabled')) {
      this.setElementsDisabled(true, true);
    } else {
      if (window.ie) {
        this.fakeCheckbox.getElement().addEvents({
          'click':this.toggle.bind(this)
        });
      } else {
        this.fakeCheckbox.getElement().addEvents({
          'change':this.toggle.bind(this)
        });
      }
      
      this.toggle();
    }
  },
  
  toggle: function() {
    var disabled = this.fakeCheckbox.getElement().checked;
    this.setElementsDisabled(disabled, false);
  },
  
  setElementsDisabled: function(disabled, includeFakeCheckbox) {
    if (this.radioGroup.radios.length > 0) {
      if (disabled) {
        this.radioGroup.clearSelection();
      }
      this.radioGroup.disable(disabled);
    }
    if (this.fileInput != null) this.fileInput.disabled = disabled;
    if (this.commentInput != null) this.commentInput.disabled = disabled;
    
    if (includeFakeCheckbox) {
      this.fakeCheckbox.setDisabled(disabled);
    }
  }
  
});

// Concertina setup
var createConcertina = new Class({
	initialize: function(segmentLinks, segmentContent){
		this.concertinaLinks = $$('div.concertina div.boxtop h2');
		this.concertinaContent = $$('div.concertina div.boxcontent');
		var scope = this;
		this.concertinaLinks.each(function(e){ 
			e.setProperty('id', e.getText().replace(/ /g,'_'));
			e.addEvent('click', function() { scope.shrink(e.getProperty('id')) });
		});

		this.concertinaContent.each(function(e){ e.setProperty('id', 'html_' + e.getParent().getFirst().getText().replace(/ /g,'_')) });
		this.concertinaSlides = this.concertinaContent.map(function(el){ return new Fx.Slide(el,{ wait: false, transition: Fx.Transitions.linear, duration: 750 }).hide() });
		this.concertinaSlides[0].show();
		//this.concertinaSlides[this.concertinaSlides.length - 1].show();

	},
	shrink: function(e){
		var scope = this;
		this.concertinaSlides.each(function(el){
			el.slideOut();
			//el.hide();
			if(el.element.id.contains(e)){ scope.expand(el) };
		});
	},
	expand: function(el){
		el.slideIn();
		//el.show();
	}
});

// Concertina setup
var createContentSwap = new Class({
	initialize: function(segmentConcertina){
		var concertinaLinks = $$('div.concertina ul.menulist li a');
		var allContent = new Array();
		var scope = this;
		concertinaLinks.each(function(el,i){
			var linkContent = el.getProperty('href').split('#');
			if (linkContent.length == 2) {
  			allContent.include(linkContent[1]);
  			$(linkContent[1]).setStyle('display','none');
  			el.addEvent('click', function(e) {
  				allContent.each(function(el,i){
  					$(el).setStyle('display','none');
  				});
  				$(linkContent[1]).setStyle('display','block');
  				concertinaLinks.each(function(el,i){
  					el.getParent().removeClass('selected');
  				});
  				el.getParent().addClass('selected');
  				e = new Event(e).stop();
  			});
			}
		});
		$(allContent[0]).setStyle('display','block');
	}
});

// Member List setup
var createMemberList = new Class({
	initialize: function(el,i){
		this.memberlist = $$('div.halfdoublebox')[i];
		this.memberfulllist = $$('div.halfdoublebox ul li.fulllist')[i];
		this.membermorelink = $$('div.halfdoublebox ul li.morelink')[i];

		this.memberlist.setStyle('position','absolute');
		
		if(this.memberfulllist){
			this.memberfulllist.setStyle('display','none');
			var l = new Element('a',{ 'href':'' }).setText('More...');
			l.addEvent('click', function(e){ this.showlist(this.memberfulllist,this.membermorelink); e = new Event(e).stop(); }.bind(this));
			l.injectInside(this.membermorelink);
			this.membermorelink.setStyle('display','block');
		}

	},
	showlist: function(el,ele){
		if(el.getStyle('display') == 'none'){ 
			el.setStyle('display','block');
			ele.getFirst().setText('Less...');
		} else {
			el.setStyle('display','none');
			ele.getFirst().setText('More...');
		}
	}
});

// Generic form class
var genericForm = new Class({
	
	/**
	 * Constructor. Initialise class vars, set form submission handler.
	 * 
	 * @param {String} form ID of target form element 
	 * @param {String} ajaxAction URL of ajax friendly form action
	 */
	initialize: function(form, ajaxAction) {
		this.form = $(form);
		this.form.setProperty('action', ajaxAction);
		
		this.form.addEvent('submit', this.onSubmit.bindAsEventListener(this), false);
		
		this.formElements = this.form.getFormElements();
		this.errorElements = new Array;
	},

	/**
	 * Form submission handler. Stop event, assign ajax event handlers
	 * 
	 * @param {Object} event Submit event object
	 */
	onSubmit: function(event) {
		var event = new Event(event);
		event.stop();
				
		// do validation
		
		this.form.send({		
			onRequest: this.onRequest.bind(this),
			onSuccess: this.onSuccess.bind(this),
			onFailure: this.onFailure.bind(this)
		});
	},
	
	/**
	 * Clear values of all form elements
	 * 
	 * @TODO At the moment this will only clear text elements. Need to extend it
	 * to handle other inputs, but not things like buttons (?) and submits 
	 */
	/*clearFormElements: function() {
		this.formElements.each(function(el) { if (el.getProperty('type') == 'text') el.value=''; });
	},*/
	
	/**
	 * 
	 */
	disableFormElements: function() {
		this.formElements.each(function(el) { el.setProperty('disabled', true); });
	},
	
	/**
	 * 
	 */
	enableFormElements: function() {
		this.formElements.each(function(el) { el.setProperty('disabled', false); });
	},
	
	/**
	 * 
	 */
	reset: function() {
		this.form.reset();
	},
	
	/**
	 * Add error elements to form. Creation of error element is handled by 
	 * createErrorElement, insertion into the DOM by injectErrorElement.
	 * 
	 * @param {Object} messages List of error messages, indexed by name of relevant form element
	 */
	addErrorElements: function(messages) {
		var fEl, eEl, fElName; // form element, error element, form element name
		
		for (var i = 0; i < this.formElements.length; i++) {
			fEl = this.formElements[i];
			fElName = fEl.getProperty('name');
			
			//alert(fElName + ': ' + messages[fEl.getProperty('name')]); 

			if($defined(messages[fElName])) {
				// if there is an error for the current form element
				eEl = this.createErrorElement(messages[fElName]);
				this.injectErrorElement(eEl, fEl);				
				this.errorElements.push(eEl);
			}
		}
	},
	
	/**
	 * 
	 */
	removeErrorElements: function() {
		var el;
		
		for (var i = 0; i < this.errorElements.length; i++) {
			el = this.errorElements[i];
			el.remove();
		}
		
		// reset array
		this.errorElements = new Array();
	},
	
	/**
	 * Default action when form submission is sent
	 */
	onRequest: function() {
		this.removeErrorElements();
		this.disableFormElements();
	},
	
	/**
	 * Default action when form submission is successful
	 */
	onSuccess: function() {
		this.reset();
		this.enableFormElements();
	},
	
	/**
	 * Default action when form submission fails
	 */
	onFailure: function() {
		alert("An error has occured. Please try sending the form again.");
		this.enableFormElements();
	},
	
	/**
	 * Default error element creation
	 * 
	 * @param {String} message
	 */
	createErrorElement: function(message) {
		return new Element('p').addClass('errorMessage').appendText(message);
	},
	
	/**
	 * Default error element injection
	 * 
	 * @param {Element} eEl The error element to be inserted
	 * @param {Element} fEl The form element the error relates to
	 */
	injectErrorElement: function(eEl, fEl) {
		eEl.injectBefore(fEl);
	},
	
	/**
	 * 
	 * @param {Object} values
	 */
	populate: function(values) {
		var fEl, eEl, fElName; // form element, error element, form element name
		
		for (var i = 0; i < this.formElements.length; i++) {
			fEl = this.formElements[i];
			fElName = fEl.getProperty('name');
			
			if($defined(values[fElName])) {
				// if there is an error for the current form element
				fEl.setProperty('value', values[fElName]);
			}
		}
	}
});

var ukgbcMemberPageForm = genericForm.extend({
	
	injectErrorElement: function(eEl, fEl) {
		
		if(fEl.getPrevious()) {
			eEl.injectBefore(fEl.getPrevious());
		}
	}
});

var filterMemberDirectoryForm = genericForm.extend({
  
  initialize: function(form, ajaxAction, listDivId) {
    this.parent(form, ajaxAction);
    this.listDiv = $('directorylist');
  },
  
  onRequest: function() {
    this.parent();
    this.listDiv.empty();
  },
  
  onSuccess: function(jsonResponse) {
    var response = Json.evaluate(jsonResponse);
    
    if (response.length > 0) {
      // scrolling container div
      var container = new Element('div', {'class': 'memberscroller'});
      var row, name, moreLink, surveyLink, aDiv;
      
      response.each(function(item){
        // create div row for each member returned
        row = new Element('div', {'class': 'formrow'});
        
        name = new Element('strong');
        name.appendText(item.memberName);
        row.appendChild(name);
        
        moreLink = new Element('a', {'href': '/site/members/member-details?id='+item.memberId});
        moreLink.appendText("Find out more about this member");
        aDiv = new Element('div');
        aDiv.appendChild(moreLink);
        row.appendChild(aDiv);
        
        /* 20091222 commented out until some members have filled out the survey
        surveyLink = new Element('a', {'href': '/site/questionnaire/results/memberId/'+item.memberId});
        surveyLink.appendText("See how this member measures and reports on their sustainability impacts");
        aDiv = new Element('div');
        aDiv.appendChild(surveyLink);
        row.appendChild(aDiv);*/
        
        container.appendChild(row);
      });
      
      this.listDiv.appendChild(container);
    } else {
      // no members returned
      var el = new Element('p');
      el.appendText("NO MEMBERS CURRENTLY MEET THOSE CRITERIA");
      this.listDiv.appendChild(el);
    }
    
    // normal success 
    this.enableFormElements();
  }
});

var newUserForm = ukgbcMemberPageForm.extend({
	
	// countElements can be optional, ids of elements used when checking if the
	// maximum number of users has been reached
	initialize: function(form, ajaxAction, countElements) {
		this.parent(form, ajaxAction);
		this.userLimitCount = 0;
		this.userLimitMsgEl;
		this.submitEl;		
		
		if($type(countElements) == 'array' && countElements.length == 3) {
			var limitCountId = countElements[0];
			var limitMsgId = countElements[1];
			var submitId = countElements[2];
			
			if($(limitCountId)) this.userLimitCount = $(limitCountId).getValue();
			this.userLimitMsgEl = $(limitMsgId);
			this.submitEl = $(submitId);
		}		
	},
	
	// @TODO Show status messages as part of page instead of alert boxes
	onSuccess: function(jsonResponse) {
		//alert(jsonResponse);
		//document.write(jsonResponse);return;
		var response = Json.evaluate(jsonResponse);
		
		var saved = response[0];
		var validated = response[1];
		var messages = response[2];
		
		/*alert('validated: ' + validated);
		alert('messages: ' + messages);
		alert('saved: ' + saved);*/
		
		if(saved) {
			this.decrementUserLimitCount(); // decrement available users
			alert('User saved');
			
			if(listFormCombos) {
				for(var i = 0; i < listFormCombos.length; i++) {
					listFormCombos[i].list.addItem(
						messages['ukgbc_user_id'], 
						messages['ukgbc_person_name'] + ' ' + messages['ukgbc_person_surname']
					);
				}
			}
			this.reset();
		}
		else if(!validated){
			this.addErrorElements(messages);
		}
		else {
			alert('User save failed');
		}
		
		// clear fields, enable form
		this.enableFormElements();
	},
	
	incrementUserLimitCount: function() {
		// if userLimitCount is 0 incrementing it should activate the add user form
		if(this.userLimitCount == 0 && this.submitEl && this.userLimitMsgEl) {
			this.submitEl.removeAttribute('disabled');
			this.userLimitMsgEl.setStyle('display','none');
		}
		
		this.userLimitCount++;
	},
	
	decrementUserLimitCount: function() {
		// if userLimitCount is 1 decrementing it should deactivate the add user form
		if(this.userLimitCount == 1 && this.submitEl && this.userLimitMsgEl) {
			this.submitEl.setAttribute('disabled', true);
			this.userLimitMsgEl.setStyle('display','block');
		}
		
		this.userLimitCount--;
	}
});

// provide a global point of access for the increment function of the addUserPersonForm object
function incrementUserLimitCount() {
	addUserPersonForm.incrementUserLimitCount();
}

var updateMemberForm = ukgbcMemberPageForm.extend({
	
	// @TODO Show status messages as part of page instead of alert boxes
	onSuccess: function(jsonResponse) {
		//alert(jsonResponse);
		//document.write(jsonResponse);return;
		var response = Json.evaluate(jsonResponse);
		
		var saved = response[0];
		var validated = response[1];
		var messages = response[2];
		
		/*alert('validated: ' + validated);
		alert('messages: ' + messages);
		alert('saved: ' + saved);*/
		
		if(saved) {
			alert('Member saved');
		}
		else if(!validated){
			this.addErrorElements(messages);
		}
		else {
			alert('Member save failed');
		}
		
		// clear fields, enable form
		this.enableFormElements();
	}	
});

/*
 * Form to be used with listFormCombo classes
 */
var comboForm = ukgbcMemberPageForm.extend({
	
	initialize: function(formId, ajaxAction, owner) {
		this.parent(formId, ajaxAction);
		this.owner = owner;
	},
	
	onSuccess: function(jsonResponse) {
		this.owner.actionComplete(Json.evaluate(jsonResponse));
	}	
});

/*
 * LISTS
 */

/*
 * Generic user list
 */
var userList = new Class({
	
	initialize: function(listId, owner) {
		this.owner = owner;
		this.list = $(listId);
		//if(!this.list.hasClass('memberlist')) { alert('Not a memberlist element'); }// -- notify if this.list not a list element
		this.lastListItemClicked = null;
		
		var domItems = this.list.getChildren();		
		for(var i = 0; i < domItems.length; i++) {
			//this.items.push(new userListItem(domItems[i], this));
			$extend(domItems[i], userListItem.prototype);
			domItems[i].initialize(this);
		}
	},
	
	itemClick: function(item) {		
		//alert(this.list + ': ' + url);
		this.lastListItemClicked = item;
		
		var itemClickRequest = new Ajax(item.href, {
			method: 'get',
			onComplete: function(jsonResponse) {
				//alert(jsonResponse);
				this.owner.setUser(Json.evaluate(jsonResponse));
			}.bind(this)
		});
		itemClickRequest.request();
	},
	
	removeItem: function(userId) {		
		var items = this.list.getChildren();
		for(var i = 0; i < items.length; i++) {
			if(items[i].userId == userId) {
				items[i].remove();
			}
		}
	},
	
	addItem: function(userId, userName) {		
		var li = new Element('li');
		var a = new Element('a');
		a.setAttribute('href', this.owner.getListUrl(userId));
		a.setText(userName);
		a.injectInside(li);
		
		$extend(li, userListItem.prototype);
		li.initialize(this);
		
		li.injectInside(this.list);
	}
});

/*
 * Generic user list item
 */
var userListItem = new Class({
	
	initialize: function(owner) {		
		this.owner = owner;
		this.href = this.getFirst().getProperty('href');
		this.userId = this.href.toQueryObject()['id'];
		
		this.addEvent('click', function(e){
			e = new Event(e).stop();
			this.owner.itemClick(this);
		});		
	}
});

/*
 * LIST / FORM COMBINATION
 */

/*
 * Generic
 */
var listFormCombo = new Class({
	
	initialize: function(name, ajaxAction) {		
		this.list = new userList(name+'_list', this);
		this.listDiv = $(name+'_list_div'); 
		this.form = new comboForm(name+'_form', ajaxAction, this);
		this.formDiv = $(name+'_form_div');
		
		this.formDiv.setStyle('display','none'); 
		
		// convert href 'back' link to reset
		if($(name+'_form_back')) {
			$(name+'_form_back').addEvent('click', function(e) {
				e = new Event(e).stop();
				this.reset();				
			}.bind(this));
		}
	},
	
	setUser: function(user) {
		// show form panel
		this.form.removeErrorElements();
		this.listDiv.setStyle('display','none'); 
		this.formDiv.setStyle('display','block'); 
	},
	
	reset: function(e) {
		// clear form, show list panel
		this.form.reset();
		this.listDiv.setStyle('display','block'); 
		this.formDiv.setStyle('display','none');
	},
	
	actionComplete: function(response) {
		this.standardActionComplete(response, 'Success!', 'Failure!');
	},
	
	standardActionComplete: function(response, successMsg, failMsg) {
		var success = response[0];
		var validated = response[1];
		var messages = response[2];
		
		/*alert('validated: ' + validated);
		alert('messages: ' + messages);
		alert('success: ' + success);*/
		
		if(success) {
			alert(successMsg);
			this.form.reset();
			
			// show list panel
			this.listDiv.setStyle('display','block'); 
			this.formDiv.setStyle('display','none');
		}
		else if(!validated){
			this.form.addErrorElements(messages);
		}
		else {
			alert(failMsg);
		}
		
		// enable form
		this.form.enableFormElements();		
	},
	
	getListUrl: function(userId) {
		return '?id=' + userId;
	}
});

/*
 * Update user
 */
var updateUserListFormCombo = listFormCombo.extend({
	
	setUser: function(user) {
		this.form.populate(user);
		
		// show form panel
		this.parent(user);
	},
	
	actionComplete: function(response) {
		this.standardActionComplete(response, 'User updated', 'User update failed');
	},
	
	getListUrl: function(userId) {
		return '/site/members/select-user-for-update?id=' + userId;
	}
});

/*
 * Update user password
 */
var updateUserPwListFormCombo = listFormCombo.extend({
	
	setUser: function(user) {
		$('update_user_pw_name').setText(user['ukgbc_person_name'] + ' ' + user['ukgbc_person_surname']);
		this.form.populate(user);
		
		// show form panel
		this.parent(user);
	},
	
	actionComplete: function(response) {
		this.standardActionComplete(response, 'User password updated', 'User password update failed');
	},
	
	getListUrl: function(userId) {
		return '/site/members/select-user-for-pw-update?id=' + userId;
	}
});

/*
 * Delete user
 */
var deleteUserListFormCombo = listFormCombo.extend({
	
	setUser: function(user) {
		$('delete_user_name').setText(user['ukgbc_person_name'] + ' ' + user['ukgbc_person_surname']);
		this.form.populate(user);
		
		// show form panel
		this.parent(user);
	},
	
	actionComplete: function(response) {
		if($type(incrementUserLimitCount) == 'function') incrementUserLimitCount();
		// remove user from list
		if(listFormCombos) {
			for(var i = 0; i < listFormCombos.length; i++) {
				listFormCombos[i].list.removeItem(this.list.lastListItemClicked.userId);
			}
		}
		else {
			this.list.lastListItemClicked.remove();
		}
		
		this.standardActionComplete(response, 'User deleted', 'User deletion failed');
	},
	
	getListUrl: function(userId) {
		return '/site/members/select-user-for-deletion?id=' + userId;
	}
});

// member organisation auto-completion
var OrganisationSelector = new Class({
  initialize: function(searchInput){
    this.url = '/site/registration/member-suggestions';
    
    // A simple spinner div, display-toggled during request
    var indicator = new Element('div', {
        'class': 'autocompleter-loading',
        'styles': {'display': 'none'}
    }).injectAfter(searchInput); // appended after the input
    
    var idField = new Element('input', {
      'type': 'hidden',
      'name': 'memberId',
      'value': ''
    }).injectAfter(searchInput);
     
    var completer = new Autocompleter.Ajax.JsonElData(searchInput, {
        'url': this.url,
        'postVar': 'q',
        'injectChoice': function(choice, i) {
          var index = choice[0];
          var text = choice[1];
          var el = new Element('li').setHTML(this.markQueryValue(text));
          el.inputValue = text;
          el.data = {index: index};
          this.addChoiceEvents(el).injectInside(this.choices);
        },
        'onRequest': function(el) {
          indicator.setStyle('display', '');
        },
        'onComplete': function(el) {
          indicator.setStyle('display', 'none');
        },
        'onSelect': function(el, data){
          idField.setProperty('value', data.index);
        }
    });
  }
});

// Forum show hide preview function
function togglePreviews() {

	var previewDivs = $$(".preview");
	
	for(i=0; i<previewDivs.length; i++) {
		var display = previewDivs[i].getStyle("display");
		if(display == "block"){
			previewDivs[i].setStyle("display", "none");
		} else {
			previewDivs[i].setStyle("display", "block");
		}
	}
	
	return false;

}

// See http://forum.mootools.net/viewtopic.php?id=1038
String.extend({
	toQueryObject: function(){
		var o = {};
		$A(this.replace(/(^.*\?)|(#.*$)/g,'').split('&')).each(function(p){
			p = p.split("=");
			o[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
		});
		return o;
	}
});

// USED TO DEBUG
function trace(tracestring) {
  if ((typeof(debugging) == 'undefined') || !debugging) return false;
  if (!window.ie) { console.log(tracestring); }
  else {
    if (!trace.window_ || trace.window_.closed) {
      var win = window.open("", null, "width=400,height=200,scrollbars=yes,resizable=yes,status=no,location=no,menubar=no,toolbar=no");
      if (!win) return;
      var doc = win.document;
      doc.write("<html><head><title>Debug Log</title></head><body></body></html>");
      doc.close();
      trace.window_ = win;
    }
    var logLine = trace.window_.document.createElement("div");
    logLine.appendChild(trace.window_.document.createTextNode(tracestring));
    trace.window_.document.body.appendChild(logLine);
  }
}
