var webkitcache = $H();

// YUI global objects
var globalY;

if (document.observe) {
	document.observe('dom:loaded', function() {	
		if (!$('styleoverrides')) {
			$$("head")[0].insert({'bottom':'<style type="text/css" id="styleoverrides"></style>'});
		}
		
		// YUI history markup
		if (!$('yui-history-field')) {
			$(document.body).insert({top:'<iframe id="yui-history-iframe" src="/nm_webkit/libs/yui-history-blank.html"></iframe><input id="yui-history-field" type="hidden" />'});
			if ($('yui-history-iframe').visible()) {
				$('yui-history-iframe').setStyle({display:'none'});
			}
		}
		
		if (typeof YUI !== "undefined") {
			webkit.initYUIHistory(); 						
		}
		
		// hide all but the last jsondatablock
		
		// find total number of blocks
		var totaljsonblocks;
		$$('.jsondatablock').each(function(o,i) {
			totaljsonblocks = i;
		});
		
		// remove all but last block contents
		$$('.jsondatablock').each(function(o,i) {
			if (i !== totaljsonblocks && o.id == "jsondata") {
				o.remove();
			}
		});
		
		if ($('pagecontent')) {
			// set cache on initial load (for sites that utilize AJAX navigation)
			if (location.pathname !== '/') {
				var cacheToken = location.pathname.replace(/\//g,'_');				
			}
			else {
				var cacheToken = "home";
			}
			webkit.cacheset('ajaxnav', cacheToken, $('pagecontent'));
			
			if (!$('jsondata')) {
				// JSON data block doesn't exist, create empty block
				$('pagecontent').insert({'after':'<div class="jsondatablock" id ="jsondata"></div>'});
			}
			else {
				webkit.jsondata = $('jsondata').innerHTML.evalJSON();
			}
		}
	});	
}

function webkit() {
	
	this.waitHTML = '<div class="waitHTML"></div>';
	this.lastbanner = 0;
	this.bannerspaused = false;	
	
	this.cursorLink = function() {
		$(document.body).addClassName('cursorLink');
	}

	this.cursorClear = function() {
		$(document.body).removeClassName('cursorLink');
	}
	
	this.cacheset = function(owner, datarequest, object) {
		// assigns object to webkitcache global hash
		
		if ($(object)) {
			// part of DOM, create clone
			webkitcache.set(owner + '_' + datarequest, object.cloneNode(true));			
		}
		else {
			webkitcache.set(owner + '_' + datarequest, object );
		}
	}
	
	this.cacheget = function(owner, datarequest) {
		// checks to see if cache for datarequest exists
		
		if (webkitcache.get(owner + '_' + datarequest)) {
			return true;
		}
		return false;
	}
	
	this.cacheoutput = function(owner, datarequest, object) {
		if ($(object)) {
			// replace entire object with cached object
			$(object).replace(webkitcache.get(owner + '_' + datarequest).cloneNode(true));
		}
		else {
			// updating using cache contents
			$(object).update(webkitcache.get(owner + '_' + datarequest));
		}
	}
	
	this.modinit = function(module, customCSS) {
		var configObj = {
			base: '/nm_webkit/libs/yui/',
			insertBefore: 'styleoverrides',
			modules: {
				'photogallery': {
					requires: ['photogallerycss','lightwindow'],
					fullpath: ('/nm_webkit/libs/gallery.js')
				},
				'photogallerycss': {
					fullpath: ('/nm_webkit/CSS/photogallery_defaults.css'),
					type: 'css'
				},
				'lightwindow': {
					requires: ['lightwindowcss'],
					fullpath: ('/nm_webkit/libs/lightwindow/javascript/lightwindow.js')
				},
				'lightwindowcss': {
					fullpath: ('/nm_webkit/libs/lightwindow/css/lightwindow.css'),
					type: 'css'
				},
				'soundclips': {
					fullpath: ('/nm_webkit/libs/soundclips.js')
				},
				'eventscalendar_css': {
					fullpath: '/nm_webkit/user_CSS/' + customCSS,
					type: 'css'
				},
				'eventscalendar_defaultcss': {
					fullpath: '/nm_webkit/CSS/eventscalendar_defaults.css',
					type: 'css'
				},
				'eventscalendar': {
					fullpath: '/nm_webkit/libs/calendar.js',
					requires: ['eventscalendar_css','eventscalendar_defaultcss']
				},
				'lightbox_css': {
					fullpath: '/nm_webkit/libs/lightbox/css/lightbox.css',
					type: 'css'
				},
				'lightbox': {
					fullpath: '/nm_webkit/libs/lightbox/js/lightbox.js',
					requires: ['lightbox_css']
				},
				'mailinglist_css': {
					fullpath: '/nm_webkit/CSS/mailinglist_defaults.css',
					type: 'css'
				},
				'mailinglist': {
					fullpath: '/nm_webkit/libs/mailinglist.js',
					requires: ['mailinglist_css']
				},
				'contact_css': {
					fullpath: '/nm_webkit/CSS/contactform_defaults.css',
					type: 'css'
				},
				'contact': {
					fullpath: '/nm_webkit/libs/contact.js',
					requires: ['contact_css']
				},
				'links_css': {
					fullpath: '/nm_webkit/CSS/links_defaults.css',
					type: 'css'
				},
				'links': {
					requires: ['links_css']
				}
			}
		};
		
		switch (module) {
			case 'photogallery':
			YUI(configObj).use('photogallery', function(Y) {
				Y.log('init photogallery');	
				webkitgallery.galleryObservers();										
			});
			break;
			case 'soundclips':
			YUI(configObj).use('soundclips', function(Y) {
				Y.log('init soundclips');
				soundclips.soundClipsListing();
				if (webkit.jsondata.medialoaderID) { 
					soundclips.mediaLoaderObservers(webkit.jsondata.medialoaderID); 
				}
			});
			break;
			case 'lightbox':
			YUI(configObj).use('lightbox', function(Y) {
				Y.log('init lightbox');
				initLightbox();
			});
			break;
			case 'lightwindow':
			YUI(configObj).use('lightwindow', function(Y) {
				Y.log('init lightwindow');
				lightwindowInit();
			});
			break;
			case 'eventscalendar':
			YUI(configObj).use('eventscalendar', function(Y) {
				Y.log('init eventscalendar');
				nmcalendar.initCalendar();
				if (typeof calCustomObservers == "function") {
					calCustomObservers();
				}
			});
			break;
			case 'mailinglist':
			YUI(configObj).use('mailinglist', function(Y) {
				Y.log('init mailinglist');
				mailinglist.initObservers();
			});
			break;	
			case 'contact':
			YUI(configObj).use('contact', function(Y) {
				Y.log('init contact links');
				contact.initObservers();
			});	
			break;
			
			case 'links':
			YUI(configObj).use('links_css', function(Y) {
				Y.log('init links');				
			})
			break;
		}
	}
	
	this.playsong = function (songID,playerID) {
		// sends track load info to Flash mediaplayer

		// make sure module has been inited
		webkit.modinit('soundclips');

		if (typeof playsong_precallback !== "undefined") {
			playsong_precallback(playerID);
		}

		// set default playerID if not defined
		if (typeof playerID == "undefined") {
			playerID = 'mediaplayer';
		}
		
		// create/recreate JSON data object
		var mediaplayer = $('jsondata').innerHTML.evalJSON();

		if (songID == 'inorder') {
			// playlist preserved in proper order
			var flashID = "global";
		}
		else if (songID == 'random') {
			// establish random playing order

			var flashID = "global";

			// create tmpPlaylist of playlist component of mediaplayer JSON object
			var tmpPlaylist = Object.toJSON(mediaplayer.mpsettings.playlist).evalJSON();
			var tmpShuffle = [];
			$H(tmpPlaylist).each(function(pair,idx) {
				tmpShuffle[idx] = pair.key;
			});		
			tmpShuffle.sort(function() {
				return 0.5 - Math.random();
			});
			// create trackorder hash
			var trackorder = $H();
			var playlist = $H();
			tmpShuffle.each(function(o,idx) {
				trackorder.set(idx,o);
				playlist.set(o,mediaplayer.mpsettings.playlist[o]);
			});
			mediaplayer.mpsettings.trackorderJSON = trackorder.toJSON();
			mediaplayer.mpsettings.playlistJSON = playlist.toJSON();
		}
		else {
			// specific song
			
			var flashID = songID;
			
			mediaplayer.mpsettings.playlistJSON = "";
			if ($('replacecliplink_' + songID)) {
				var replacelink = $('replacecliplink_' + songID).innerHTML;
				var replaceclass = $('replacecliplink_' + songID).className.replace(/\s?replacecliplink\s?/,'');
			}
		}

		// stop all mediaplayers
		if ($(playerID) && $(playerID).className) {
			var clipClass = $(playerID).className;
			$$('.' + clipClass).each(function(o) {
				o.update('');				
			});	
		}

		if (mediaplayer.mpsettings.mpWidth) {
			var mpwidth = mediaplayer.mpsettings.mpWidth;
		}
		else {
			var mpwidth = $(playerID).getWidth();
		}
		if (mediaplayer.mpsettings.mpHeight) {
			var mpheight = mediaplayer.mpsettings.mpHeight;
		}
		else {
			var mpheight = $(playerID).getHeight();
		}

		// load into div tag
		var flashObject = new SWFObject('/nm_webkit/mediaplayer/' + mediaplayer.mpsettings.mpMediaplayer, "mediaplayer_" + flashID, mpwidth, mpheight, "9", "");	
		if (songID == "random" || songID == "inorder") {
			flashObject.addVariable("playlist", escape(mediaplayer.mpsettings.playlistJSON));
			flashObject.addVariable("trackorder", escape(mediaplayer.mpsettings.trackorderJSON));
		}
		else {
			mediaplayer.mpsettings.mpFirstload = false;
			flashObject.addVariable("filename", mediaplayer.mpsettings.playlist[songID].filename);
			flashObject.addVariable("name", mediaplayer.mpsettings.playlist[songID].name);
			flashObject.addVariable("artist", mediaplayer.mpsettings.playlist[songID].artist);
			flashObject.addVariable("album", mediaplayer.mpsettings.playlist[songID].album);	
			flashObject.addVariable("length", mediaplayer.mpsettings.playlist[songID].length);	
			//new Effect.ScrollTo(playerID, { duration:0.5});							
		}		
		flashObject.addParam("wmode", "transparent");
		flashObject.addVariable("firstload", mediaplayer.mpsettings.mpFirstload);
		flashObject.addVariable("width", mpwidth);
		flashObject.write(playerID);
	}
	
	this.emailformObservers = function() {
		if ($('contactname')) {
			$('contactname').focus();
		}

		if ($('contactclosebutton')) {
			$('contactclosebutton').observe('click', function(e) {
				Modalbox.hide();
			});
		}
		if ($('contactsendemail')) {
			$('contactsendemail').observe('click', function(e) {
				webkit.emailform();
			});
		}
		if ($('contactcontent')) {
			var origContent = $('contactcontent').getValue();
			$('contactcontent').observe('focus', function() {
				if ($('contactcontent').getValue() == origContent) {
					$('contactcontent').value = "";
				}
			});	
		}
	}
	
	this.emailform = function(formID,formpost) {
		// submit Modalbox email form

		if (formID) {
			var submitby = $(formID).submitby.value;
			var name = $(formID).name.value;
			var content = $(formID).content.value;
			var ref = $(formID).ref.value;
		}
		else {
			var submitby = $('contactsubmitby').getValue();
			var name = $('contactname').getValue();
			var content = $('contactcontent').getValue();
			if ($('ref')) {
				var ref = $('ref').getValue();				
			}
			else {
				var ref = "";
			}
		}

		if (!submitby || !name || !content) {
			if (!$('contactformfeedback')) {
				$('MB_content').insert({'bottom':'<div id="contactformfeedback"></div>'});
			}
			$('contactformfeedback').update('You are missing some fields, please correct this and try again');
			Modalbox.resizeToContent();
			return;
		}
		else if (!submitby.match(/.+?@.+?\..+/)) {
			if (!$('contactformfeedback')) {
				$('MB_content').insert({'bottom':'<div id="contactformfeedback"></div>'});
			}
			$('contactformfeedback').update('Invalid email address');
			Modalbox.resizeToContent();		
			return;
		}

		if (!formpost) {
			// set default
			var formpost = "/contact.php";
		}
		// look for shortname
		if ($('shortnameJSON')) {
			var shortnameJSON = $('shortnameJSON').innerHTML.evalJSON();
			if (shortnameJSON.formpost) {
				// override formpost address
				var formpost = shortnameJSON.formpost;
			}
			if (shortnameJSON.name) {
				var shortname = shortnameJSON.name;
			}
		}

		var ajaxParameters = 'ajaxreload=1&formsubmit=true&submitby=' + submitby + '&name=' + name + '&content=' + content + '&ref=' + ref;
		if (typeof shortname !== "undefined") {
			ajaxParameters += '&shortname=' + shortname;
		}

		new Ajax.Updater('MB_content', formpost, {
			method: 'get',
			parameters: ajaxParameters,
			onComplete: function(transport) {
				Modalbox.resizeToContent();
				if ($('thanksclose')) {
					$('thanksclose').observe('click', function() {
						Modalbox.hide();
					});
				}
			}
		})
	}
	
	this.homeBanners = function(i) {
		if (!$('bannerconfig')) { 
			globalY.log('ERROR: no banner JSON data found');
			return; 
		}
		var banners = $('bannerconfig').innerHTML.evalJSON();
		
		if ($('banneroverrides') && $('banneroverrides').innerHTML) {
			var banneroverrides = $('banneroverrides').innerHTML.evalJSON();
		}	
		
		// hide all div blocks for HTML snippets (for YUI back button)
		$$('#homebanner_upper div').each(function(o) {
			if (o.id !== "homebanner_links" && !o.hasClassName('cnav')) {
				o.addClassName('displaynone');				
			}
		});
		
		if (!i) {
			// no rotate iteration set, start from beginning
			i = 0;
		}	
		var nexti = parseInt(i) + 1;
		if (nexti == banners.length) { nexti = 0; }
		
		if ($('homebanner_links') && !$('homebanner_links').innerHTML) {
			webkit.genHomebannerLinks();
			webkit.genBannerNavObservers();
		}
		
		if ($('homebanner_links')) {
			$$('#homebanner_links .bannerlinkwrapper .bannerlinks').each(function(o) {
				o.removeClassName('banneron');
			});
			$('bannerlink_' + i).addClassName('banneron');		
		}
		
		// set top and bottom layer images
		var thisImage = 'url(/styles/images/' + banners[i].pic + ')';
		var nextImage = 'url(/styles/images/' + banners[nexti].pic + ')';		

		$('homebanner_upper').setStyle({backgroundImage:thisImage});
		$('homebanner_lower').setStyle({backgroundImage:nextImage,display:'none'});
		
		if (banners[i].divblock && $(banners[i].divblock).hasClassName('displaynone')) {
			if (webkit.lastbanner == i) {
				// banner hasn't changed, don't redo appear of div block
				$(banners[i].divblock).removeClassName('displaynone');	
			}
			else {
				$(banners[i].divblock).setStyle({display:'none'});
				$(banners[i].divblock).removeClassName('displaynone');							
				new Effect.Appear(banners[i].divblock, {duration:0.6, afterFinish:function() {
					if (!webkit.lastbanner) { 
						// first banner shown, set to first in index to prevent redo appear of div block on first banner
						webkit.lastbanner = 0; 
					}					
				}});
			}
		}

		$('homebanner_upper').stopObserving('click');
		
		$('homebanner_upper').stopObserving('mouseover');
		$('homebanner_upper').stopObserving('mouseout');
		
		if (typeof banners[i].clickurl !== "undefined" && banners[i].clickurl !== "") {
			$('homebanner_upper').observe('click', function(e) {
				e.stop();
				if (banners[i].clickurl.match(/^http:\/\//)) {
					// external redirect				
					window.location = banners[i].clickurl;
				}
				else {
					if (typeof bannerClick == "function") {
						bannerClick(banners[i].clickurl);
					}
					else {
						window.location = banners[i].clickurl;
					}
				}
			});
		}		
		$('homebanner_upper').observe('mouseover', function() {
			if (banners[i].clickurl) {
				webkit.cursorLink();
			}
			globalY.log('pausing');
			// cancel rotation
			clearTimeout(webkit.rotationtimer);	
			// cancel rotate pause tracker 
			clearInterval(webkit.rotatepausetimer);
		});
		$('homebanner_upper').observe('mouseout', function() {
			if (banners[i].clickurl) {
				webkit.cursorClear();
			}
			if (!webkit.bannerspaused) {
				// resume banners
				globalY.log('resuming');
				webkit.homeBanners(i);				
			}
		});

		if (typeof banneroverrides !== "undefined" && banneroverrides.rotationtime) {			
			// use specified rotation time
			webkit.rotatetime = banneroverrides.rotationtime;
		}			
		else {
			// set default
			webkit.rotatetime = 5000;
		}
		
		if (!webkit.rotatepause) { webkit.rotatepause = webkit.rotatetime; }  // initial init
		
		webkit.rotationtimer = setTimeout(function() {					
			new Effect.Appear('homebanner_lower', { duration:1, afterFinish: function() {
				if (banners[i].divblock) {
					$(banners[i].divblock).addClassName('displaynone');					
				}
				// update link location
				i++;			
				if (i == banners.length) {
					i = 0;
				}
				webkit.homeBanners(i);
				// reset rotatepause tracker
				webkit.rotatepause = webkit.rotatetime;			
				webkit.lastbanner = i;
			}});
		}, webkit.rotatepause);
		
		// cancel existing rotatepause trackers so that there is only one running at any time
		clearInterval(webkit.rotatepausetimer);  
		
		webkit.rotatepausetimer = setInterval(function() {
			webkit.rotatepause -= 500;
			if (webkit.rotatepause < 0) { webkit.rotatepause = webkit.rotatetime; }
			//globalY.log('rotate pause ' + webkit.rotatepause);
		},500)
	}
	
	this.rotatePics = function(i) {
		if (!$('galleryconfig')) {
			globalY.log('no gallery config found, exiting');
			return;
		}
	
		var gallery = $('galleryconfig').innerHTML.evalJSON();
		
		if (!i) {
			// no rotate iteration set, start from beginning
			i = 0;
		}	
		var nexti = parseInt(i) + 1;
		if (nexti == gallery.length) { nexti = 0; }

		// set top and bottom layer images
		var thisImage = 'url(/nm_webkit/gallery_pics/' + gallery[i].pic + ')';
		var nextImage = 'url(/nm_webkit/gallery_pics/' + gallery[nexti].pic + ')';

		$('galleryupper').className = 'pic_' + i;
		$('galleryupper').setStyle({backgroundImage:thisImage,display:''});
		$('gallerylower').setStyle({backgroundImage:nextImage,display:'none'});

		$('galleryupper').stopObserving('mouseover');
		$('galleryupper').stopObserving('mouseout');

		$('galleryupper').observe('mouseover', function() {
			globalY.log('pausing');
			// cancel rotation
			clearTimeout(webkit.rotationtimer);	
			// cancel rotate pause tracker 
			clearInterval(webkit.rotatepausetimer);
		});
		$('galleryupper').observe('mouseout', function() {
			if (!webkit.picspaused) {
				// resume banners
				globalY.log('resuming');
				webkit.rotatePics(i);				
			}
		});

		if (typeof banneroverrides !== "undefined" && banneroverrides.rotationtime) {			
			// use specified rotation time
			webkit.rotatetime = banneroverrides.rotationtime;
		}			
		else {
			// set default
			webkit.rotatetime = 5000;
		}

		if (!webkit.rotatepause) { webkit.rotatepause = webkit.rotatetime; }  // initial init

		webkit.rotationtimer = setTimeout(function() {
			if (webkit.picspaused) { return; }
			new Effect.Fade('galleryupper', { duration:1, afterFinish:function() {							
				new Effect.Appear('gallerylower', { duration:1, afterFinish: function() {
					// update link location					
					i++;			
					if (i == gallery.length) {
						i = 0;
					}
					webkit.rotatePics(i);
					// reset rotatepause tracker
					webkit.rotatepause = webkit.rotatetime;			
				}});
			}});							
		}, webkit.rotatepause);

		// cancel existing rotatepause trackers so that there is only one running at any time
		clearInterval(webkit.rotatepausetimer);  

		webkit.rotatepausetimer = setInterval(function() {
			webkit.rotatepause -= 500;
			if (webkit.rotatepause < 0) { webkit.rotatepause = webkit.rotatetime; }
			//globalY.log('rotate pause ' + webkit.rotatepause);
		},500)
	}
	
	this.rotatePicNav = function() {
		$('picnext').observe('click', function(e) {
			e.stop();
			webkit.rotatePicsNext();
		});
		$('picnext').observe('mouseover', function() {
			globalY.log('pausing');
			webkit.picspaused = true;			
		});
		$('picnext').observe('mouseout', function() {
			if (!$('picpause').hasClassName('paused')) {
				globalY.log('resuming');				
				webkit.picspaused = false;				
			}
		});
		$('piclast').observe('click', function(e) {
			e.stop();
			webkit.rotatePicsLast();
		});
		$('piclast').observe('mouseover', function() {
			globalY.log('pausing');			
			webkit.picspaused = true;			
		});
		$('piclast').observe('mouseout', function() {
			if (!$('picpause').hasClassName('paused')) {
				globalY.log('resuming');				
				webkit.picspaused = false;				
			}
		});
		$('picpause').observe('click', function(e) {
			e.stop();
			webkit.rotatePicsPause();
		});
	}
	
	this.rotatePicsNext = function() {
		var gallery = $('galleryconfig').innerHTML.evalJSON();
		
		// find current pic
		var currentimage = $('galleryupper').className.replace(/^pic_/,'');
		gallery.each(function(o,idx) {
			if (idx == currentimage) {							
				var nextpic = idx + 1;
				if (nextpic > gallery.length) {
					nextpic = 0;
				}
				clearTimeout(webkit.rotationtimer);				
				webkit.rotatePics(nextpic);
			}
		})	
	}
	
	this.rotatePicsLast = function() {
		var gallery = $('galleryconfig').innerHTML.evalJSON();
		
		// find current pic
		var currentimage = $('galleryupper').className.replace(/^pic_/,'');
		gallery.each(function(o,idx) {
			if (idx == currentimage) {							
				var lastpic = idx - 1;
				if (lastpic < 0) {
					lastpic = 0;
				}
				clearTimeout(webkit.rotationtimer);				
				webkit.rotatePics(lastpic);
			}
		})	
	}
	
	this.rotatePicsPause = function() {
		if (!$('picpause').hasClassName('paused')) {
			// cancel rotation
			clearTimeout(webkit.rotationtimer);	
			// cancel rotate pause tracker 
			clearInterval(webkit.rotatepausetimer);	
			
			webkit.picspaused = true;			
			$('picpause').addClassName('paused');
		}
		else {
			var currentimage = $('galleryupper').className.replace(/^pic_/,'');
			webkit.picspaused = false;			
			webkit.rotatePics(currentimage);
			$('picpause').removeClassName('paused');
		}	
	}
	
	this.genHomebannerLinks = function() {
		var banners = $('bannerconfig').innerHTML.evalJSON();	
		var bannerlinks = "";
		for (var i=0; i < banners.length; i++) {
			bannerlinks += '<div class="bannerlinkwrapper"><a href = "" class="bannerlinks" id="bannerlink_' + i + '" />banner ' + i + '</a></div>';			
		}
		var bannerlinks = '<div id="banneroncache" class="banneron displaynone"></div>' + bannerlinks;
		$('homebanner_links').update(bannerlinks);
	}
	
	this.genBannerNavObservers = function() {
		$$('#homebanner_links .bannerlinkwrapper .bannerlinks').each(function(o) {
			o.observe('mouseover', function() {
				if (!o.hasClassName('banneron')) {
					o.addClassName('bannerlinkover');
				}
			});
			o.observe('mouseout', function() {
				o.removeClassName('bannerlinkover');
			});			
			o.observe('click', function(e) {
				e.stop();
				var gotobanner = o.id.replace(/^bannerlink_/,'');
				clearTimeout(webkit.rotationtimer);
				webkit.homeBanners(gotobanner);
			});
		});
	}
	
	this.ajaxPageload = function(page,queryString) {
		// loads target page in div tag rather than forcing a page reload that 
		// interrupts the global mediaplayer
		
		if (page == "_") {
			// no path, cancel function
			return;
		}
		else if (page == "/reloadhome") {
			// trigger to reload homepage
			if (typeof webkit.yuihome !== "undefined") {
				page = webkit.yuihome;
			}
			else {
				page = "/";				
			}
			var searchCache = "home";
		}
		else {
			var searchCache = page.replace(/\//g,'_');
			page = page.replace(/_/g,'/');	
			origpage = page;  // page w/o ajaxreload URL suffix		
		}

		if (!page) {
			page = "index.php";
		}

		if (typeof ajaxpage_precallback == "function") {
			ajaxpage_precallback(page);
		}

		globalY.log('search cache for ' + searchCache);
		if (webkit.cacheget('ajaxnav', searchCache)) {
			globalY.log('outputting cache');
			webkit.cacheoutput('ajaxnav', searchCache, $('pagecontent'));
			if ($('ajax_calendar')) {
				nmcalendar.initCalendar();	
			}
			else {
				webkit.initAjaxLinks();
			}
			
			webkit.setPageTitles(page);
			
			if (typeof ajaxpage_callback == "function") {
				ajaxpage_callback(page);
			}	
		}
		else {
			globalY.log('trigger AJAX load');
			// make AJAX call
			
			$('pagecontent').setOpacity(0.5);
			
			var ajaxParameters = 'ajaxreload=1';	
			if (typeof queryString !== "undefined") {
				ajaxParameters += '&' + queryString;
			}
			if ($('jsondata') && $('jsondata').innerHTML) {
				var menuData = $('jsondata').innerHTML.evalJSON();
				if (menuData.cisite) {
					var ajaxParameters = '';
					page = page + '/ajaxreload';					
				}				
			}
	
			new Ajax.Updater('pagecontent', page, {
				method: 'get',
				parameters: ajaxParameters,
				onComplete: function(transport) {
					$('pagecontent').setOpacity(1);
					
					// update cache
					webkit.cacheset('ajaxnav', searchCache, $('pagecontent'));

					if ($('ajax_calendar') && typeof nmcalendar == "object") {
						nmcalendar.initCalendar();
					}
					else {
						webkit.initAjaxLinks();	
					}
										
					webkit.setPageTitles(origpage);
					
					if (typeof ajaxpage_callback == "function") {
						ajaxpage_callback(origpage);
					}						
				}
			});
		}
	}
	
	this.fileIcon = function(filetype) {
		// looks for links linking to filetype and adds class to these a tags
		$$('#pagecontent a').each(function(o) {
			var matchpattern = '\.' + filetype + '$';
			if (o.href.match(matchpattern)) {
				o.addClassName(filetype + 'icon');
			}
		});	 
	}
	
	this.setPageTitles = function(page) {
		// set page titles by first looking at top level menu items in menu JSON object, submenu,
		// and then custom JSON object set in controller
		
		if ($('jsondata') && $('jsondata').innerHTML) {
			var menuData = $('jsondata').innerHTML.evalJSON();	
			if (!page.startsWith('/')) {
				var menuMatch = "/" + page;
			}
			else {
				var menuMatch = page;
			}
			//globalY.log('look for ' + menuMatch);
			var matchFound=false;
			for (var i in menuData.nm_menuItems) {
				if (matchFound) { break; }
				//globalY.log(menuData.nm_menuItems[i].href + ' ' + menuMatch);
				if (menuData.nm_menuItems[i].href.match(menuMatch)) {
					globalY.log('set page title to ' + i);							
					document.body.className = 'nm_currentPage_' + i;
					document.title = menuData.nm_siteTitle + ': ' + menuData.nm_menuItems[i].title;
					matchFound=true;
					break;
				}
				else if (menuData.nm_menuItems[i].submenu) {
					// search submenus
					var thisSubmenu = menuData.nm_menuItems[i].submenu;
					for (var s in thisSubmenu) {
					//	globalY.log(thisSubmenu[s].href + ' ' + menuMatch);						
						if (thisSubmenu[s].href.match(menuMatch)) {
							globalY.log('set page title to ' + i);							
							document.body.className = 'nm_currentPage_' + i;
							document.title = menuData.nm_siteTitle + ': ' + menuData.nm_menuItems[i].title;
							matchFound=true;
							break;
						}
					}
				}
			}
			
			if (!matchFound && $('nm_pageTitle')) {
				var pagedata = $('nm_pageTitle').innerHTML.evalJSON();
				document.body.className = 'nm_currentPage_' + pagedata.thispage;
				document.title = menuData.nm_siteTitle + ': ' + menuData.nm_menuItems[pagedata.thispage].title;
			}
		}
	}
	
	this.recordHistory = function(page) {
		page = page.replace(/\//g,'_');
		if (page == "page-") { 
			page = "page-home" ;
		}
		globalY.History.navigate("p", page);
	}
	
	this.loadContent = function(page) {
		if (page.match(/^page-/)) {
			if (page.match(/.+?\?.*/)) {
				// URL contains query string, capture query string
				var queryString = Object.toQueryString(o.href.toQueryParams());
			}
			else {
				var queryString = '';
			}
			page = page.replace(/^page-/,'');
			if (page == "home") {
				page = "reloadhome";
			}
			globalY.log('load page ' + page);
			webkit.ajaxPageload('/' + page, queryString);
		}
		else if (page.match(/^photocollection-/)) {
			collection = page.replace(/^photocollection-/,'');
			
			if (!$('gallerywrapper')) {
				// switch to gallery page
				
				if (!webkit.jsondata.gallerybase) {
					// set default					
					webkit.jsondata.gallerybase = '/gallery';
				}
				webkit.ajaxPageload(webkit.jsondata.gallerybase);
			}
			
			globalY.log('queue load collection ' + collection);
			webkit.queueLoad(collection, 'photogallery');				
		}
		else if (typeof customYUINav == "function") {
			// not a Webkit history token, try custom nav function
			customYUINav(page);
		}
	}
	
	this.queueLoadTimer = 0;
	this.queueLoad = function(ID, module) {
		// loads content once existence of class has been confirmed to prevent race conditions
		// with content dynamically loaded via YUI
		clearTimeout(webkit.queueLoadTimeout);
		webkit.queueLoadTimeout = setTimeout(function() {
			switch (module) {
				case 'photogallery':
				if (typeof webkitgallery !== 'undefined') {
					// loaded, exit
					clearTimeout(webkit.queueLoadTimeout);
					globalY.log('show collection ' + ID);
					webkitgallery.showCollection(ID);
				}
				else {
					globalY.log('class not found');
					webkit.queueLoadTimer += 500;
					webkit.queueLoad(ID, module);
				}
				break;
			}
		}, webkit.queueLoadTimer);
	}
	
	this.initYUIHistory = function() {
		webkitYUI = {
			base: '/nm_webkit/libs/yui/',
			insertBefore: 'styleoverrides'
		}

		YUI(webkitYUI).use('history', function(Y) {			
			globalY = Y;
			globalY.log('init YUI history');

			// Register YUI history
			globalY.History.initialize('#yui-history-field', '#yui-history-iframe');

			// determine and register start page
			var bookmarkedSection = globalY.History.getBookmarkedState('p');
			var querySection = globalY.History.getQueryStringParameter('p');					
			var initSection = bookmarkedSection || querySection || 'page-home';
			globalY.History.register("p", initSection).subscribe("history:moduleStateChange", webkit.loadContent);

			// switch to start page										
			globalY.History.subscribe("history:ready", function () {
				var startPage = globalY.History.getCurrentState("p");
				globalY.History.navigate("p", startPage);	
				if (initSection !== "page-home") {
					webkit.loadContent(startPage);										
				}
			});
		});

	}
	
	this.initAjaxLinks = function(divtag) {
		// attaches event observers to all links in given divtag, passes to ajax()
		
		webkit.metaKey();

		if (!divtag) {
			// default to #pagecontent
			divtag = "pagecontent";
		}
		var thisDomain = '^(http|https):\/\/' + window.location.hostname.replace('.','\.');
		$$('#' + divtag + ' a').each(function(o) {
			if (o.href.match(/#$/)) {
				o.observe('click', function(e) {
					e.stop();
				});
			}
			else if (!o.href.match(/^(mailto|javascript):/) && !o.href.match(/^#/) && o.href.match(thisDomain) && !o.href.match(/\.(pdf|mp3)$/i)) {
				//console.log('creating ajax link for ' + o.href);
				o.stopObserving('click');
				o.observe('click', function(e) {
					e.stop();					
					if (webkit.metaKeyPressed) { return; }
					if (o.hasClassName('disableclick')) { return; }
					var page = o.pathname;
					if (page.match(/^\//)) {
						// remove leading slash
						var page = page.replace(/^\//,'');
					}
					webkit.recordHistory('page-' + page);
					//ajax(o.pathname,queryString);
				});	
			}
		});
	}
	
	this.metaKeyPressed = false;
	this.metaKey = function() {
		document.observe('keydown', function(e) {
			var key = e.which || e.keyCode;
			if ((e.metaKey && navigator.platform.match(/^Mac/)) || (e.ctrlKey && navigator.platform.match(/^(Win|Linux)/))) {
				webkit.metaKeyPressed = true;
			}
			else {
				webkit.metaKeyPressed = false;
			}
		});
		
		document.observe('keyup', function(e) {
			webkit.metaKeyPressed = false;
		});
	}
	
	this.loadJSCSSfile = function(filename, filetype){
		if (!$('styleoverrides')) {
			$$("title")[0].insert({'after':'<style type="text/css" id="styleoverrides"></style>'});
		}
		
		if (filetype=="js"){ //if filename is a external JavaScript file
			var fileref=document.createElement('script')
			fileref.setAttribute("type","text/javascript")
			fileref.setAttribute("src", filename)
		}
		else if (filetype=="css"){ //if filename is an external CSS file
			var fileref=document.createElement("link")
			fileref.setAttribute("rel", "stylesheet")
			fileref.setAttribute("type", "text/css")
			fileref.setAttribute("href", filename)
		}
		if (typeof fileref!="undefined") {
			$$('head')[0].insert({'top':fileref});	
		}
	}
	
	this.addTS = function(pathname) {
		// adds leading slash so that element.pathname in IE matches element.pathname in W3C browsers
		if (!pathname.match(/^\//)) {
			globalY.log('add trailing slash');
			return "/" + pathname;
		}
		else {
			return pathname;
		}
	}
	
	this.buttonMouseEffect = function(button, state) {
		if (state == "over") {
			webkit.cursorLink();
			$(button).addClassName('buttonover');			
		}
		else {
			webkit.cursorClear();
			$(button).removeClassName('buttonover');
		}
	}
	
	this.setupButton = function(ID, clickFunction, funcArgs) {
		$(ID).observe('mouseover', function() {
			if ($('link-' + ID).hasClassName('active')) { return; }
			webkit.buttonMouseEffect(ID, 'over');
		});
		$(ID).observe('mouseout', function() {
			webkit.buttonMouseEffect(ID, 'out');
		});
		// capture clicks on both a tag and button wrapper
		var thisbutton = $(ID).select('.buttonCenter a');
		thisbutton[0].observe('click', function(e) {
			e.stop();
			webkit.buttonMouseEffect(ID, 'out');			
			clickFunction(funcArgs);	
		});
		$(ID).observe('click', function(e) {
			e.stop();
			webkit.buttonMouseEffect(ID, 'out');			
			clickFunction(funcArgs);
		});
	}
	
	this.clickButton = function(ID) {				
		webkit.buttonMouseEffect(ID, 'out');			
		webkit.recordHistory('tab-' + ID); 				
	}
	
	this.tabMouseEffect = function(tab, state) {
		if ($(tab).hasClassName('activeTab')) { return; }
		if (state == "over") {
			webkit.cursorLink();
			$(tab).addClassName('tabover');			
		}
		else {
			webkit.cursorClear();
			$(tab).removeClassName('tabover');
		}
	}
	
	this.makeTabActive = function(tab, olddiv, newdiv) {
		// make all other tabs inactive		
		$$('.tabWrapper').each(function(o) {
			o.removeClassName('activeTab');
		});
		$(tab).addClassName('activeTab');
		
		$$('.tabWrapper div').each(function(o) {
			if (o.hasClassName('activeTabLeft')) {
				o.removeClassName('activeTabLeft');
			}
			else if (o.hasClassName('activeTabCenter')) {
				o.removeClassName('activeTabCenter');
			}
			else if (o.hasClassName('activeTabRight')) {
				o.removeClassName('activeTabRight');
			}
		});
		
		// make tab active
		$$('#' + tab + ' div').each(function(o) {
			if (o.hasClassName('tabLeft')) {
				o.addClassName('activeTabLeft');
			}
			else if (o.hasClassName('tabCenter')) {
				o.addClassName('activeTabCenter');
			}
			else if (o.hasClassName('tabRight')) {
				o.addClassName('activeTabRight');
			}
		});
		
		new Effect.Fade(olddiv, { duration:0.3, afterFinish:function() {
			$(olddiv).addClassName('displaynone');
			$(newdiv).setStyle({display:'none'});
			$(newdiv).removeClassName('displaynone');
			new Effect.Appear(newdiv, { duration:0.3});
		}});	
	}
	
	this.setupTab = function(ID) {
		$(ID).observe('mouseover', function() {
			webkit.tabMouseEffect(ID, 'over');
		});
		$(ID).observe('mouseout', function() {
			webkit.tabMouseEffect(ID, 'out');
		});		
		// capture clicks on both a tag and tab wrapper		
		var thistab = $(ID).select('.tabCenter a');
		thistab[0].observe('click', function(e) {
			e.stop();
			webkit.clickTab(ID);			
		});
		$(ID).observe('click', function(e) {
			e.stop();
			webkit.clickTab(ID);
		});
	}
	
	this.clickTab = function(ID) {				
		webkit.tabMouseEffect(ID, 'out');
		if ($(ID).hasClassName('activeTab')) { return; }			
		webkit.recordHistory('tab-' + ID); 				
	}
	
	this.contactNavButton = function(ID, alturl) {
		if (!ID) { 
			// set default
			ID = 'nm_id_contact'; 
		}
		var contactbutton = $(ID).select('a');
		contactbutton[0].stopObserving('click');
		contactbutton[0].observe('click', function(e) {
			e.stop();
			contact.invokeModalbox(contactbutton[0], alturl);
		});
	}
	
	this.initNewsCrawl = function(divblock) {
		webkit.newsCrawlPaused = false;
		var crawler = setInterval(function() {
			if (webkit.newsCrawlPaused) { return; }
			$$('#' + divblock + ' .newscrawl').each(function(o) {								
				if (!o.hasClassName('displaynone')) {				
					var nextID = parseInt(o.id.replace(/^newscrawl_/,'')) + 1;
					if (!$('newscrawl_' + nextID)) {
						nextID = 1;
					}
					new Effect.Fade(o.id, { duration:0.75, afterFinish:function() {
						$(o.id).addClassName('displaynone');
						$('newscrawl_' + nextID).setStyle({display:'none'});
						$('newscrawl_' + nextID).removeClassName('displaynone');
						new Effect.Appear('newscrawl_' + nextID, { duration:0.75})
					}});
				}
			});
		}, 5000);
		
		$(divblock).observe('mouseover', function() {
			webkit.newsCrawlPaused = true;
		});
		$(divblock).observe('mouseout', function() {
			webkit.newsCrawlPaused = false;
		});			
	}
	

	return true;
}

var webkit = new webkit();


var loading = new Image();
loading.src = "/nm_webkit/libs/images/loading.gif";

var waitHTML = '<div class="waitHTML"><img src = "' + loading.src + '"></div>';

// **** some DEBUGGING if necessary
function consoler(s) {
	/*
	if (window.console) {
		if (console.log) {
			console.log(s);
		}
	}
	*/
}

function ajax (page,queryString) {
	// legacy function
	webkit.ajaxPageload(page,queryString);
}

function initAjaxLinks(divtag) {
	// legacy function
	webkit.initAjaxLinks(divtag);
}

function webkit_playsong(songID,playerID) {
	webkit.playsong(songID,playerID);
}

function MBcontact(URL, title, width, overlayClose, recipient) {
	// invokes Modalbox contact form
	
	if (recipient) {
		URL += "?recipient=" + recipient;
	}
	
	Modalbox.show(URL, { title:title, width:width, overlayClose:overlayClose, afterLoad: function() {
		inspectMBheight();
	}});
}

var showscrollbar = 0;
function inspectMBheight() {
	// adjusts Modalbox sheet height to fit content, but unlike Modalbox provided function,
	// makes sure height does not exceed total browser height
	
	// make sure height is no larger than browser height minus offset, show scrollbar where necessary
	if ($('MB_content').getHeight() > browserheight() - 70) {
		// shrink window, add scrollbars if necessary
		var windowheight = browserheight() - 70;
		var contentheight = windowheight - 38;
		$('MB_window').setStyle({height: windowheight + "px"});
		$('MB_content').setStyle({overflow:"auto",height:contentheight + 'px'});
		showscrollbar = 1;
	}
	else if (showscrollbar) {
		// release constraints
		$('MB_window').style.height = "";
		$('MB_content').style.height = "";	
		showscrollbar = 0;	
		// make sure that height content has grown to with constraints gone does not exceed browserheight
		inspectMBheight();
	}
}

function emailform(formID) {
	webkit.emailform(formID);
}

function emailformObservers() {
	webkit.emailformObservers();
}

function browserheight() {
	// returns browser's height
	
	if (navigator.appName=="Netscape") {
	  winW = window.innerWidth;
	  winH = window.innerHeight;
	 }
	 if (navigator.appName.indexOf("Microsoft")!=-1) {
	  winW = document.body.offsetWidth;
	  winH = document.body.offsetHeight;
	 }
	return winH;
}

function check_address (ID, email, action) {
	// checks provided email address against Mailman list
	
	var ajaxParameters = 'ID=' + ID + '&email=' + email + '&action=' + action;
	
	new Ajax.Updater(ID, 'nm_webkit/templates/maillist_template_xhtml.php', {
		method: 'get',
		parameters: ajaxParameters,
		onComplete: function(transport) {
			if (transport.responseText && $('mailman_error')) {
				new Effect.Pulsate('mailman_error', {duration: 3, from:0.25, pulses:3});
			}
		}
	});
}

var rotatetimerheadline;
var paused_headline = 0;

function webkit_startrotateheadline() {
	clearTimeout(rotatetimerheadline);
	paused_headline = 0;
	rotatetimerheadline = setTimeout('webkit_rotateheadline()', headline_rotatespeed);
	return false;
}

function webkit_rotateheadline(nav) {
	var nextpic;
	var curpic;
	var lastpic;
	for (var x=0;$('crawler_' + x); x++) {
		
		if ($('crawler_' + x).style.display !== 'none') {
			// found current displayed pic		
			nextpic = x + 1;
			if (!$('crawler_' + nextpic) && headline_continuousrotation) {
				nextpic = 0;
			}
			curpic = x;
			lastpic = x - 1;
			if (lastpic < 0) { lastpic = 0; }
			
			if (nav == "pause") {
				// pause
				paused = 1;					
				clearTimeout(rotatetimerheadline);
			}
			else if ((nav && nav == "next" && !paused) || !nav) {
				new Effect.Fade('crawler_' + x, { duration:headline_fadeduration, afterFinish: function() {
					new Effect.Appear('crawler_' + nextpic, { duration:headline_fadeduration })									
					webkit_startrotateheadline();
					}});
			}	
			else if (nav && nav == "last" && !paused) {									
				new Effect.Fade('crawler_' + x, { duration:1, afterFinish: function() {
					new Effect.Appear('crawler_' + lastpic, { duration:headline_fadeduration })									
					webkit_startrotateheadline();
					}});
			}
		}
	}
}

function scrollto(anchor) {
	new Effect.ScrollTo(anchor, { duration: 0.5});
}

Element.addMethods({
	// rounded corner function
	
	corner: function( element, hash ) {
		element = $(element);
		var container = element.wrap( 'span', {'class' : 'rounderContainer'} );
		var width = hash.width;
		var height = hash.height;
		var spriteSource = hash.spriteSource;
		container.setStyle({
			margin : 0,
			padding : 0,
			position : 'relative',
			display: 'inline-block'
		});
		if (element.hasClassName('alignright')) {
			container.setStyle({float:'right'});
		}
		else if (element.hasClassName('alignleft')) {
			container.setStyle({float:'left'});
		}
		container.style.zoom = "1";
		if (container.style.display != "inline-block") {return;} // firefox2 fails here
		if (Prototype.Browser.IE) {
			var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); // IE version number
			reIE.test(navigator.userAgent);
			var version = parseFloat(RegExp["$1"]);
			if (version < 7) { // if IE less than 7, exit
				return;
			}
		}
		['top left','top right','bottom right','bottom left'].each( function(corners, index) {
			var newCorner = new Element('div');
			var backgroundPosition = hash[corners.replace(/\s/,'')];
			newCorner.setStyle({
				margin: 0,
				padding: 0,
				display  : 'block',
				position : 'absolute',
				height :   height + 'px',
				width :    width  + 'px',
				backgroundImage :   'url(' + spriteSource + ')',
				backgroundRepeat :  'no-repeat',
				backgroundPosition : backgroundPosition 
			});
			$w(corners).each( function( flushTo ) {
				newCorner.setStyle(
					flushTo + ': 0'
				);
			});
			container.insert( newCorner );
		});
		return container;
	}
});

/* Author: Christopher E. Walker */

/*jslint browser: true, debug: true */
/*global $, $$, Effect, Position, Template, console */

function showEvent(e, ethis) {
	var temp = new Template("INFO: e.type: #{etype}; this: #{ethis}; e.element(): #{eelement}; e.relatedTarget: #{erelated};");
	var s = { etype: e.type,
		ethis: ethis.nodeName + "." + ethis.className,
		eelement: e.element().nodeName     + "." + e.element().className,
		erelated: e.relatedTarget.nodeName + "." + e.relatedTarget.className };
	consoler(temp.evaluate(s));
}
// **** end of DEBUG
function initDropDown(element, options) {
	// initialize dropdown menus
	
	element = $(element);
	var theID = element.identify();
	// **** Default transitions if none specified
	var reveal = (options && options.reveal) ? options.reveal : Effect.Appear.bindAsEventListener(Effect, {
		duration: 0.2
	});
	var disappear = (options && options.disappear) ? options.disappear : Effect.Fade.bindAsEventListener(Effect, {
		duration: 0.2
	});
	var revealDelay = (options && options.revealDelay) ? options.revealDelay : .3;

	if ( options.topLinkOnClick ) {
		element.select('.topLink').each( function(o) {
			o.observe( 'click', function(e) {
				options.topLinkOnClick(e);
			});
		});
	}
	else {
		element.select('.topLink').each( function(o) {
			o.observe( 'click', function(e) {
				if (o.href.match(/#$/)) {
					// don't show hash in address bar
					e.stop();
				}
			});
		});
	}

	if ( options.clickEffect ) {
		element.select('ul > li > ul a').each( function(o) {
			o.observe( 'click', function(e) {
				surroundList = o.up( '.wrapper');
				surroundList.parentNode.removeClassName( 'active' );
				options.clickEffect( o );
				e.stop();
			});
		});
	};
	// ******************************
	// **** wrap up in several <div>s
	var bottomUls = element.select("ul > li > ul");
	bottomUls.each( function(bottomUl) {
		//bottomUl.wrap('div').wrap('div').wrap('div', {'class':'wrapper', 'style':'position:relative;'});
		bottomUl.removeClassName('noJavaScript');
		bottomUl.wrap('div').wrap('div').wrap('div');
        });
	// **** dynamically set static width (IE needs)
        element.select("ul > li > div").each( function(divWrapper) {
		divWrapper.className = 'wrapper';
		if (window.dropdownBrowserIsIELessThan7) {
			divWrapper.select("ul")[0].style.width = (divWrapper.getWidth() + 2) + "px"; // for ie6
		}
		divWrapper.select('ul li a').each( function(a) {
			a.style.display = "block";
			a.style.position = "relative";
		});
                divWrapper.hide();
        });

	// mouseover and mouseout on the toplink <a> 
	var topLinks = $$('#' + theID + " > ul > li > a");
	topLinks.each( function(toplink) {
                toplink.addClassName('topLink');
		toplink.observe("mouseover", function(e) {
			// if coming up from lower wrapper:
			consoler('mouseover on A, deciding...');
			if (e.relatedTarget) {
				if ($(e.relatedTarget).descendantOf(this.parentNode) || (e.relatedTarget == this.parentNode) ) {
				    e.stop();
				    consoler('a toplink mouseover: e.relatedTarget =< this.parentNode \ncoming up from lower wrapper');
				    return;
                                }
			}
			if ($(this.parentNode).hasClassName("active")) {
			    e.stop();
			    consoler('a toplink mouseover: already active');
			    return;
			}
			$(this.parentNode).siblings().each( function(li) {
				if ($(li).hasClassName("active")) {
					disappear(li.select('.wrapper')[0]);
					consoler('remove active classname from sibling');
					$(li).removeClassName("active");
                                }
                        });
			this.parentNode.addClassName("active");
			var surroundList =  $($(this).nextSiblings()[0]);
			if (!surroundList) {
				consoler('has NO surroundlist, no reveal');
				return;
			}
			//surroundList.writeAttribute("style", "display: none; position: relative;");
			surroundList.style.display = "none";
			surroundList.style.position = "relative";
			surroundList.style.top = "0";
			surroundList.style.left = "0";
			surroundList.style.height = "auto";
			surroundList.style.width = "auto";
			consoler('let reveal');
			e.stop();

			/*new PeriodicalExecuter( function(pe) {
				if ( surroundList.parentNode.hasClassName( 'active' ) ) {
					reveal( surroundList );
				} else {
				}
				pe.stop();
			}, 2);*/

			setTimeout( function() {
				if ( surroundList.parentNode.hasClassName( 'active' ) ) {
					consoler( 'waited one sec? ');
					reveal( surroundList );
				}
			}, revealDelay * 1000 );

		}); 
		toplink.observe("mouseout", function(e) {
			var surroundList =  $(this.nextSiblings()[0]);
			if (!surroundList) {
				consoler('mouseout on upper A, but no wrapper so exit');
				$(this.parentNode).removeClassName("active");
				e.stop();
				return;
			}
			var x = e.pointerX();
			var y = e.pointerY();
			var bWithin = false;
			/*if (!Position.within(surroundList, x, y)) {
				disappear($(surroundList));
				consoler('DO: mouseout on topList A not in surroundList');
				$(surroundList.parentNode).removeClassName("active");
                        }*/
			if ($(e.relatedTarget).descendantOf(this.parentNode)) {
				consoler('descendant in surroundlist!!! \ncoming down from upper A');
				bWithin = true;
                        }
			if (!bWithin) {
				if ( $(surroundList.parentNode).hasClassName( 'active' ) ) {
					consoler( 'was active: ' + $(surroundList.parentNode).hasClassName( 'active' ) );
					$(this.parentNode).removeClassName("active");
					if (surroundList.style.display != "none" ) {
						disappear(surroundList);
					}
					consoler('mouseout on A: not within original surroundList');
				}
                        }
			e.stop();
		});
	});


	// **** mouseout on the lowerlevel <a> tags
	var topListItems = element.select("ul > li ul > li > a");
	topListItems.each( function(topListItem) {
		topListItem.observe("mouseout", function(e) {
			var surroundList = $(topListItem.parentNode.parentNode.parentNode.parentNode.parentNode);
			var topLink = surroundList.parentNode.select("A")[0];
			var x = e.pointerX();
			var y = e.pointerY();
			var bWithin = false;
			if (e.relatedTarget) {
				if ($(e.relatedTarget).descendantOf(surroundList)) {
					consoler('mouseout on lower As: inside surround DOM methods');
					bWithin = true;
				}
			}
			if (Position.within(topLink, x, y)) {
				consoler('mouseout on lower As: within method toplink');
				bWithin = true;
			}
			if (Position.within(surroundList.parentNode, x, y)) {
				consoler('mouseout on lower As: within method surroudList');
				bWithin = true;
			}
			surroundList.select('a').each( function(a) {
				if (Position.within(a, x, y)) {
					consoler('within method one of the <a>s');
					bWithin = true;
				}
			});
			if (e.relatedTarget) {
				if (e.relatedTarget.nodeName == "LI") {
					consoler('not in UL e.relatedTarget.nodeName == "LI"');
					bWithin = false;
				}
			}
			// if cursor not in UL:
			if (!bWithin) {
				if ( $(surroundList.parentNode).hasClassName( 'active' ) ) {
					consoler( 'was active: ' + $(surroundList.parentNode).hasClassName( 'active' ) );
					$(surroundList.parentNode).removeClassName('active');
					disappear(surroundList);
					consoler('mouseout on lower As');
				}
                        }
			e.stop();
		});
	});
}

function cursorLink() {
	webkit.cursorLink();
}

function cursorClear() {
	webkit.cursorClear();
}

function rotateContent(i) {
	if (!i) {
		// no rotate iteration set, start from beginning
		i = 0;
	}
	switch (rotatesettings.get('content')) {
		case 'image':
		// find next width and height
		nexti = parseInt(i) + 1;
		if (nexti == rotatecontentdata.length) { nexti = 0; }
		var thisWidth = rotatecontentdata[i][4] + 'px';
		var thisHeight = rotatecontentdata[i][5] + 'px';
		var nextWidth = rotatecontentdata[nexti][4] + 'px';
		var nextHeight = rotatecontentdata[nexti][5] + 'px';
		// set top and bottom layer images
		var thisImage = 'url(/nm_webkit/gallery_pics/' + rotatecontentdata[i][0] + ')';
		var nextImage = 'url(/nm_webkit/gallery_pics/' + rotatecontentdata[nexti][0] + ')';		

		$(rotatesettings.get('divID') + '_upper').setStyle({width:thisWidth,height:thisHeight,backgroundImage:thisImage});
		$(rotatesettings.get('divID') + '_lower').setStyle({width:nextWidth,height:nextHeight,backgroundImage:nextImage,display:'none'});
		if ($(rotatesettings.get('divID') + '_href')) {
			$(rotatesettings.get('divID') + '_href').setStyle({width:thisWidth,height:thisHeight});
		}
		
		switch (rotatesettings.get('effect')) {
			case 'crossfade':
			setTimeout(function() {			
				new Effect.Appear($(rotatesettings.get('divID') + '_lower'), { duration:1, afterFinish: function() {
					i++;
					if (i == rotatecontentdata.length) {
						i = 0;
					}
					rotateContent(i);
				}});
			}, rotatesettings.get('rotateDelay'));
			break;
			
			case 'fadeout':
			break;
			
			case 'slideup':
			break;
			
			case 'slidedown':
			break;
			
			case 'slideleft':
			break;
			
			case 'slideright':
			break;
			
			case 'blindup':
			break;
			
			case 'blinddown':
			break;
			
			case 'blindleft':
			break;
			
			case 'blindright':
			break;
		}
		
		break;
		
		case 'text':
		break;
	}
}

function loadJSCSSfile (filename, filetype){
	webkit.loadJSCSSfile(filename, filetype);
}


/***********************************/
/********* legacy functions ********/
/***********************************/

var dev;

/*
function ajax_regex (htmlcontent,divtag) {
	// convert hrefs to ajax links
	var swap_exp = /href(\s)*?=(\s)*?"([^"]+)"/im;                                                                   
	var search_page = htmlcontent;     
	// count number of instances
	//var exparray = swap_exp.exec(search_page);
	//alert (exparray[3] + exparray[4]);
	var swap;                                                                                                        
	var swap_check;                                                                                                  
	var ajax_page;                                                                                                   
	var swap_found = new Array(); 
	var search_iteration = 0;                                                                                   

	while (swap_check !== -1) { 
		search_iteration++;  
	//	if (search_iteration == 25) { alert ('overflow'); }                                                                                  
		swap_check = search_page.search(swap_exp);                                                               
		if (swap_check == -1 || search_iteration > 25) {                                                                                  
			// exit loop if no more links found, or break out of loop after 25 iterations                                                              
			break;                                                                                           
		}                                                                                                        
		swap = swap_exp.exec(search_page);  
		if (swap[3].substring(0,7) !== "http://" && swap[3].substring(0,8) !== "https://" && swap[3].substring(0,11) !== "javascript:" && swap[3].substring(0,7) !== "mailto:") { 
			// delete leading slash from URL, if necessary                                                   
			if (swap[3].substring(0,1) == "/") {
				// absolute link
			//	ajax_page = swap[3].substring(1);
				ajax_page = swap[3];
			}
			else {
				ajax_page = swap[3];
			}
			if (ajax_page) {
				htmlcontent = htmlcontent.replace(swap[0], "href=\"javascript:ajax('" + ajax_page + "')\"");
			}
			// delete from search string                                                                     
			search_page = search_page.replace(swap[0], "");
		}
		else {
			// external or AJAX link already processed, delete from search                                   
			search_page = search_page.replace(swap[0], "");
		}
		document.getElementById(divtag).innerHTML = htmlcontent;
	}
}
*/

function webkit_playsonglegacy (songID,playerID) {
	// sends track load info to Flash mediaplayer
	
	if (typeof playsong_precallback !== "undefined") {
		playsong_precallback();
	}
	
	if (typeof mpsettings_1 !== "undefined") {
		// using hash for multiple mediaplayers
		
		// set playerID to default if not passed to function
		if (typeof playerID == "undefined") {
			if (typeof default_playerID !== "undefined") {
				playerID = default_playerID;	
			}
			else {
				// no default defined, use player 1
				playerID = 1;
			}
		}
		
		// set mpsettings object to selected hash
		var mpsettings = eval('mpsettings_' + playerID);
		
		// determine how many players have been initialized
		for (x=1;$('mediaplayer_' + x);x++) { }
		var numPlayers = x-1;

		// stop any other players currently playing audio
		var thisQuerystring;
		var tmpMpsettings;
		for (x=1;x<=numPlayers;x++) {
			if (x !== playerID) {
				tmpMpsettings = eval('mpsettings_' + x);
				thisQuerystring = 'width=' + tmpMpsettings.get('mpWidth') + '&height=' + tmpMpsettings.get('mpHeight') + '&downloadbutton=' + tmpMpsettings.get('mpDlButton') + '&medialoader=' + tmpMpsettings.get('mpLoader') + '&firstload=1&altmediaplayer=' + tmpMpsettings.get('mpAltmediaplayer');
				
				// stop audio
				self.frames['mediaplayer_' + x].location.href='/nm_webkit/templates/mediaplayer.php?' + thisQuerystring;
				if (tmpMpsettings.get('mpScrollto') !== "undefined") {
					new Effect.ScrollTo('mediaplayerframe_' + x, { duration: 0.5});
				}
			}
		}
		
		// set defaults
		if (mpsettings.get('mpWidth') == "undefined") {
			mpsettings.set('mpWidth',400);
		}
		if (mpsettings.get('mpHeight') == "undefined") {
			mpsettings.set('mpHeight',40);
		}
		if (mpsettings.get('mpDlbutton') == "undefined") {
			mpsettings.set('mpDlbutton',false);
		}
		if (mpsettings.get('mpLoader') == "undefined") {
			mpsettings.set('mpLoader',true);
		}
		if (mpsettings.get('mpFirstload') == "undefined") {
			mpsettings.set('mpFirstload',true);
		}
		if (mpsettings.get('mpAltmediaplayer') == "undefined") {
			mpsettings.set('mpAltmediaplayer','');
			var mediaplayer = "mediaplayer.swf";
		}
		else {
			var mediaplayer = mpsettings.get('mpAltmediaplayer');
		}
		
		if (songID) {  
			var queryString = 'width=' + mpsettings.get('mpWidth') + '&height=' + mpsettings.get('mpHeight') + '&downloadbutton=' + mpsettings.get('mpDlButton') + '&medialoader=' + mpsettings.get('mpLoader') + '&firstload=' + mpsettings.get('mpFirstload') + '&altmediaplayer=' + mpsettings.get('mpAltmediaplayer') + '&songID=' + songID;
			
			if (mpsettings.get('mpDivTag')) {
				// insert music below div tag
				if ($('mediaplayerframe_' + playerID)) {
					// avoid duplicate players
					$('mediaplayerframe_' + playerID).remove();
				}
				$(mpsettings.get('mpDivTag')).insert('<div id = "mediaplayerframe_' + playerID + '"><iframe id = "mediaplayer_' + playerID + '" name = "mediaplayer_' + playerID + '" src = "/nm_webkit/templates/mediaplayer.php?' + queryString + '" width = "' + mpsettings.get('mpWidth') + '" height = "' + mpsettings.get('mpHeight') + '" scrolling = "no" marginwidth = "0" marginheight = "0" frameborder = "0"></iframe></div>');
			}
			else {
				// use iframe
				self.frames['mediaplayer_' + playerID].location.href='/nm_webkit/templates/mediaplayer.php?' + queryString;
				if (mpsettings.get('mpScrollto') !== "undefined") {
					new Effect.ScrollTo('mediaplayerframe_' + playerID, { duration: 0.5});
				}
			}
		}
	}
	else {
		// using global variables for single mediaplayer
		
		// set defaults
		if (typeof webkitMpWidth == "undefined") {
			webkitMpWidth = 400;
		}
		if (typeof webkitMpHeight == "undefined") {
			webkitMpHeight = 40;
		}
		if (typeof webkitMpDlButton == "undefined") {
			webkitMpDlButton = false;
		}
		if (typeof webkitMpLoader == "undefined") {
			webkitMpLoader = true;
		}
		if (typeof webkitMpFirstload == "undefined") {
			webkitMpFirstload = true;
		}
		if (typeof webkitAltmediaplayer == "undefined") {
			webkitAltmediaplayer = "";
		}
		if (songID) {   
			var queryString = 'width=' + webkitMpWidth + '&height=' + webkitMpHeight + '&downloadbutton=' + webkitMpDlButton + '&medialoader=' + webkitMpLoader + '&firstload=0&altmediaplayer=' + webkitAltmediaplayer + '&songID=' + songID;
			        
			if (typeof webkitMpDivtag !== "undefined") {
				// use div tag
				if ($('mediaplayerframe')) {
					// avoid duplicate players
					$('mediaplayerframe').remove();
				}
				$(webkitMpDivtag).insert('<div id = "mediaplayerframe"><iframe id = "mediaplayer" name = "mediaplayer" src = "/nm_webkit/templates/mediaplayer.php?' + queryString + '" width = "' + webkitMpWidth + '" height = "' + webkitMpHeight + '" scrolling = "no" marginwidth = "0" marginheight = "0" frameborder = "0"></iframe></div>');
			}
			else {
				// use iframe
				self.frames['mediaplayer'].location.href='/nm_webkit/templates/mediaplayer.php?' + queryString;
				if (webkitMpScrollto !== "undefined") {
					new Effect.ScrollTo('mediaplayer_frame', { duration: 0.5});
				}
			}
		}
	}

}

function ajax_regex (htmlcontent,divtag) {
	// converts standard hrefs into inline javascript ajax() calls, legacy purposes
	webkit.initAjaxLinks();
}

function checkrequired(which) {
	var pass=true;
	if (document.images) {
		for (i=0;i<which.length;i++) {
			var tempobj=which.elements[i];
			if (tempobj.name.substring(0,8)=="required") {
				if (((tempobj.type=="text"||tempobj.type=="textarea")&&
				tempobj.value=='')||(tempobj.type.toString().charAt(0)=="s"&&
				tempobj.selectedIndex==0)) {
					pass=false;
					break;
				}
			}
		}
	}
	if (!pass) {
		shortFieldName=tempobj.name.substring(8,30).toUpperCase();
		alert("There are missing fields in this form. Please make sure that all required fields are properly completed.");
		return false;
	}
	else
	return true;
}

function clearfield(textareaID) {
	if (textareaID) {
		if (document.getElementById(textareaID) && document.getElementById(textareaID).value == "enter the content of your email message here") {
			document.getElementById(textareaID).value = '';
		}
	}
	else if (typeof document.contact.requiredcontent !== "undefined" && document.contact.requiredcontent.value == "enter the content of your email message here") {
		document.contact.requiredcontent.value = '';
	}
}

function stopEventBubble (evt) {
	var e=(evt)?evt:window.event;
	if (window.event) {
		//alert ('cancel bubble');
		e.cancelBubble=true;
	} else {
		//alert ('stop propagation');
		e.stopPropagation();
	}
}

function hidemenus (menu) {
	// hide other menus that may be open
	var menunum = parseInt(menu.replace('menu',''));
	for (var m=1;m <= totalmenus;m++) {
		if (menunum !== m && document.getElementById("menu" + m) && document.getElementById("menu" + m).style.display == "block") {
			togglemenu ("menu" + m, "hide");
		}
	}
}

function togglemenu (menu, action, overColor, outColor) {
	overColor = "#" + overColor;
	outColor = "#" + outColor;
	
	if (action == "show") {
		// change link colors to accommodate :hover background color change
		var thismenuoption;
		for (var x=1;eval("document.getElementById('" + menu + "_" + x + "')");x++) {
			thismenuoption = menu + "_" + x;
			document.getElementById(thismenuoption).onmouseover = function () {
				this.firstChild.style.color = overColor;
			}
			document.getElementById(thismenuoption).onmouseout = function () {				
				this.firstChild.style.color = outColor;
			}
			document.getElementById(thismenuoption).onclick = function () {
				// load page after slight delay to prevent conflict with click of href link
			//	setTimeout("delayLoadPage(\"" + this.firstChild.href + "\")",100);
				window.location = this.firstChild.href;
			}
		}
	}
	
	var thisbutton = menu.replace('menu','butt');
	if (action == "show") {
		hidemenus(menu);  // hide any other menus that are currently visible
		document.getElementById(menu).style.opacity = 0.8;
		document.getElementById(menu).style.display = 'block';
		setTimeout('showmenu = 1', 1000);  // prevent conflict with window.onclick listener
	}
	else if (action == "hide") {
		new Effect.Fade(menu, { duration:0.25, afterFinish: function() {
			img_inact(thisbutton);
			showmenu = 0;
			}});
	}
}

/*
function delayLoadPage(page) {
	if (typeof loadingPage !== "undefined" && loadingPage == 0) { window.location = page; }
}
*/

/*
if (typeof totalmenus !== "undefined") {
	// clicking anywhere when menu is visible will hide all menus
	document.onclick=function(){
		for (m=1;m <= totalmenus;m++) {
			if (document.getElementById("menu" + m) && document.getElementById("menu" + m).style.display == "block" && showmenu) {
				togglemenu ("menu" + m, "hide");
			}
		}
	}
}
*/

if (typeof YUI == "undefined") {
	// force load YUI
	loadJSCSSfile('/nm_webkit/libs/yui/yui/yui-min.js', 'js');
}