    //Saxonbury-specific stuff:
    var sxb_forceRefresh = true;
    var sxb_contentReady = false;
    var sxb_readyTransitionIn = true;
    
    var g_doDebug = false;

    //Generic navigation: (a bit heavyweight!)
    function sxb_navigate( idx )
    {
        dhtmlHistory.add( 'p_'+idx );
        sxb_navigateInternal( idx );
        return false;
    }
    function sxb_navigateInternal( idx )
    {
        if ( g_underConstructionIdx )
        {
            idx = g_underConstructionIdx;
        }
        var openPage = true;        
        if ( openPage )
        {
            var closePageLink = GetElem('sidebarLink_'+g_pageIdx);
            if (closePageLink)
            {
                swapAllParentClasses( closePageLink, "pageListItemSel", "pageListItemUnsel" );
            }
            var openPageLink = GetElem('sidebarLink_'+idx);
            if (openPageLink)
            {
                swapAllParentClasses( openPageLink, "pageListItemUnsel", "pageListItemSel" );
            }

            g_pageIdx = idx;
            sxb_contentReady = false;
            sxb_readyTransitionIn = false;
            sxb_transitionOut();
            if ( idx )
            {
                //put in sxbCache temporarily
                RequestURL( "updateContent.php?page="+idx, "", "sxbCache", sxb_finishedCaching );
            }
            else
            {
                GetElem( 'sxbCache' ).innerHTML = 'Page is under construction. Please come back later...';
                sxb_finishedCaching();
            }
        }
    }

    function sxb_immediateRefresh()
    {
        RequestURL( "updateContent.php?page="+g_pageIdx, "", "sxbCache", sxb_transferCache );
    }

    function sxb_transferCache()
    {
        var c = GetElem( 'sxbCache' );
        sxb_processContent(c);
        var bc = GetElem( 'bodyContent' );
        bc.innerHTML = c.innerHTML;
        c.innerHTML = '';

        //Update window title:
        document.title = GetElem('pageTitle').innerHTML;

        sxb_transitionIn();
    }
    function sxb_finishedCaching()
    {
        sxb_contentReady = true;
        if ( sxb_readyTransitionIn )
        {
            sxb_transferCache();
        }
    }

    //Opening a page:
    function sxb_transitionIn()
    {
        //For splash sequence:
        var sc = GetElem('splashBackground');
        var ce = GetElem('content');
        if ( sc && ce )
        {
            if ( g_pageIdx == g_homePageIdx )
            {
                ce.style.visibility = 'hidden';
                sc.src = 'images/splashBack.jpg';
            }
            else
            {
                sc.src = 'images/splashBackSubtle.jpg';
                ce.style.visibility = '';
            }
        }
    }
    //Close current page
    function sxb_transitionOut()
    {
        //For splash sequence:
        sxb_readyTransitionIn = false;
        var sc = GetElem('splashBackground');
        var ce = GetElem('content');
        if ( sc && ce )
        {
            ce.style.visibility = 'hidden';
            sc.src = 'images/splashBack.jpg';
        }
        //Could animate, call at end:
        sxb_transitionInReady();
    }
    //ready to transition in:
    function sxb_transitionInReady()
    {
        sxb_readyTransitionIn = true;
        if ( sxb_contentReady )
        {
            sxb_transferCache();
        }
    }

    //Utility to swap the classes of all parent elements:
    function swapAllParentClasses( _elem, _fromClass, _toClass )
    {
        if ( _elem )
        {
            if ( _elem.className == _fromClass )
            {
                _elem.className = _toClass;
            }
            swapAllParentClasses( _elem.parentNode, _fromClass, _toClass );
        }        
    }

    //For Saxonbury:
    var bubbleTimer = null;
    var bubbleElem = null;
    function closeBubble()
    {
        clearTimeout( bubbleTimer );
        bubbleTimer = null;
        if ( bubbleElem != null && bubbleElem.parentNode != null )
        {
            bubbleElem.parentNode.removeChild( bubbleElem );
        }
        bubbleElem = null;
    }
    function BulletExtendedStyleClick( _evt, _oc )
    {
        closeBubble();
        _evt = ReconcileEvent( _evt );

		if ( _oc.substr(0,5) == 'open(' )
		{
			var idx = parseInt(_oc.substr(5));
			if ( idx > 0 )
			{
				OpenWindow("miniPage.php?idx="+idx, 600 );
			}
		}
		else
		{
			//Open some kind of dialog; popup a 'bubble' and have it close on a timeout?
			var guiElem = GetElem( "GUILayer" );
			if ( guiElem )
			{
				bubbleElem = document.createElement( 'div' );
	
				//todo: set location
				bubbleElem.className = 'BulletBubble_callout';
				bubbleElem.innerHTML = '<div class="BulletBubble_container"><div class="BulletBubble">'+_oc+"</div></div>";
	
				var xPos = _evt.clientX;
				//xPos -= 235; //If on right side of screen?
				bubbleElem.style.left = xPos+'px';
				bubbleElem.style.top  = (_evt.clientY-20)+'px';
				guiElem.appendChild( bubbleElem );
	
				guiElem.style.visibility = '';
	
				bubbleTimer = setTimeout( 'closeBubble();', '5000' );
			}
		}
    }

    //Find WIDTH!
    function FindMaximumChildExtent( _elem, _maxVal )
    {
        if ( !_elem ) 
        {
            return 0;
        }

        var p = 0;
        var i;
        for ( i=0;i<_elem.childNodes.length;i++ )
        {
            var kid = _elem.childNodes[i];
            var extent = parseInt( kid.offsetWidth + kid.offsetLeft );
            if ( isNaN(extent) || extent >= _maxVal )
            {
                    extent = 0;
            }
            var kidExtent = FindMaximumChildExtent(kid, _maxVal);
            extent = Math.max(extent, kidExtent );
            p = Math.max(p, extent);
            DebugOut( extent+", "+p );
        }
        return p;
    }

    function DebugOut( _value )
    {
        if ( g_doDebug )
        {
            var dd = GetElem('debugDiv');
            if ( dd == null )
            {
                dd = document.createElement('div');
                document.body.appendChild( dd );
                dd.style.border = '1px solid #000';
                dd.id = 'debugDiv';
            }
            dd.innerHTML += _value+'<br/>';
        }
    }

    function sxb_makeQuoteBlock( _type )
    {
        var d = document.createElement('span');
        d.className = 'quote_'+_type;
        var i = document.createElement('span');
        i.className = 'quote_int';
        d.appendChild( i );
        return d;
    }

    //Process content; a replacement for broken css in IE
    function sxb_processContent( _content )
    {
        //Recursively process all children - any pb_quotes get an extra img at the start and end
        if ( _content )
        {
            if ( _content.className == 'pb_quote' )
            {
                var firstText = _content.childNodes[0];
                var i;
                for (i=0;i<_content.childNodes.length;i++)
                {
                    if ( _content.childNodes[i].nodeType == 3)
                    {
                        firstText = _content.childNodes[i];
                        break;
                    }                    
                }

                _content.insertBefore( sxb_makeQuoteBlock('start'), firstText );
                _content.appendChild( sxb_makeQuoteBlock('end') );
            }
            var i;
            for (i=0;i<_content.childNodes.length;i++)
            {
                sxb_processContent( _content.childNodes[i] );
            }
        }
    }

    function WindowResized()
    {
        var mainElem = GetElem('main');
        //Resize to fit screen:
        var h = GetWindowHeight();
        h -= 260;
        mainElem.style.height = h+'px';

        //Centre menu bar (have to use this as IE 7 (ONLY!) doesn't support centering in CSS
        var w = GetWindowWidth();
        var menu = GetElem('menubarInner');
		if ( menu )
		{
        	var menuWidth = FindMaximumChildExtent( menu, menu.offsetWidth ); //Find child size
        	menu.style.left = parseInt((w-menuWidth)/2)+'px';
        	menu.style.position = 'absolute';
		
		    reinitialiseSplash();
		}
    }

    //Back button restore:
    window.dhtmlHistory.create();
    function HistoryListener(newLocation, historyData) 
    {
        if ( newLocation.substr(0,2) == 'p_' )
        {
            sxb_navigateInternal( newLocation.substr(2) );
        }
        else
        {
            sxb_navigateInternal( g_originalPageIdx );
        }
    }

    var g_originalPageIdx = g_pageIdx;
    loadHandlers.push(  
        function() 
        {
            WindowResized();

            if ( g_editing )
            {
                var tb = GetElem('topbar');
				if ( tb != null )
				{
					tb.style.height="120px";
				}
            }

            dhtmlHistory.initialize();
            dhtmlHistory.addListener( HistoryListener );

            var initialLocation = dhtmlHistory.getCurrentLocation();

            if ( initialLocation != '' )
            {
                if ( initialLocation.substr(0,2) == 'p_' )
                {
                    sxb_navigate( initialLocation.substr(2) );
                }
            }

            sxb_processContent( GetElem('bodyContent') );
        } );