$(function () {
   
   // set some global variables for our event handlers
   scrollingFlag = false;
   
   
   
   
   // Begin functions for easy navigation 
   function doCallback(f){
		if (f !== undefined) {
			f();
		}
	}
   
   // takes a #_hash or #hash returns only the hash hurray!
	function stripHash(hash){
		return hash.replace(/^(#\/|#)/,"");
	}
     
	function setHash(hash, f){
		window.location.hash = '#/' + hash;
		doCallback(f);
	}
		
	function scrollmeTo(slink,f) {
		scrollingFlag = true;
		hide_all_content(); // current location
		
		var scrollParams;
			if($.browser.msie){ 
			 	scrollParams = {queue:true,easing:'easeInOutExpo',onAfter:afterScroll(slink)}
			} else {
				 scrollParams = {easing:'easeInOutExpo',onAfter:afterScroll(slink)}
			}
		
		$.scrollTo('#'+slink,1000, scrollParams);
	}
	
	function afterScroll(thelink){
		scrollingFlag = false;
		show_content(thelink);
	}
      
   function show_content(alink, f) {
		 
       //if($.support.opacity) {  // check for IE opacity support... if not don't hide content (filters are very slow!! and don't work well with jquery scrollTo)
           $('div#'+ alink + ' .content').fadeIn('slow', function(){
               // so on callback make sure there is not any styling issues.
			if($.browser.msie){
               $(this).attr('style',' ');
			} 
           });
       //}
       //animate({'opacity':1}, 'slow');
      // $('div#'+ link + ' .content').attr('style',"");
  
     doCallback(f);
       
       
   }
   
   function hide_all_content(f){
       //if($.support.opacity) {
        $('.content').stop().hide();
        //}
       doCallback(f);
   }
   
   function update_nav(blink,f){
       // first check to see if the link is in the expanded branch
       var mylink = $('#nav [hash=#'+blink.toLowerCase()+']');
       
      // if it is do nothing since we have it expanded already
       if( mylink.parents('.expanded').length){
           //kj('my parent expanded');
           return false;
       } else if (mylink.siblings('.expanded').length) {
           return false;
       } else {
           
              hide_subnav();  // should work
              show_subnav(blink);
       }
       
        remove_selected();
        add_selected(blink);
        doCallback(f);
   }
   
   function hide_subnav(f){
       $('.subnav').hide('fast').addClass('collapsed').removeClass('expanded');
       doCallback(f);
   }
   
   function show_subnav(clink, f){
        var subnav = $('#nav [hash=#'+clink+ ']').next('.subnav'); 
        // if the link is a main node link then expand the proper (next) sibling .subnav
        if(!$('#nav .subnav [hash=#'+ clink +']').length) {
            //subnav = $('#nav [hash=#'+clink+ ']').next('.subnav'); 
            subnav.removeClass('collapsed');
            //subnav.show('slow');
            subnav.slideDown()
            subnav.addClass('expanded');
        } else {
       
            // otherwise we're below the .subnav and we need to traverse up until we find the proper subnav
           subnav =  $('#nav [hash=#'+clink+ ']').parents('.subnav');
           //subnav.show('slow');
           subnav.slideDown()
           subnav.addClass('expanded').removeClass('collapsed');
        }
         
       
       doCallback(f);
       
       // otherwise we need to show the proper nav
   }
   
   function remove_selected(f){

       $('#nav').find('.selected').removeClass('selected');
       doCallback(f);
   }
   
   function add_selected(dlink,f){
       $('#nav [hash=#'+dlink+ ']').parent('li').addClass('selected');
   }
   
   // event handlers
   function onHashChange(e){   
        e.preventDefault();
        var elink = stripHash(window.location.hash);
		show_content(elink);
		update_nav(elink);
   }
   
   function onClickChange(e){
		e.preventDefault();
		
		// get the link
		var flink = $(this).attr('href');

		// do two things... set the hash and scroll to the link
		setHash(stripHash(flink));    
		scrollmeTo(flink);
	}
   
   var lastLink = "welcome";
   
   function navigate(){
		timer = 0;
		var glink = $('.hittest:in-viewport:first').parent().attr('id') || "";
		// if scrolling more is not disabled if !(scrollingFlag)
		// then if we hit a new link then we want to fire the thing that shows our content, should be simple and straightforward
		// so if the hit test = something that is not the hash (and it is not empty)
		if (glink.length && (glink !== stripHash(window.location.hash))) {
			if(!scrollingFlag) {  // if we're already scrolling skip this stuff
				lastLink = glink;
				hide_all_content();
	    		show_content(glink);
	        	update_nav(glink);
	      		setHash(stripHash(glink));		
			}
		}		
	
   }
   
   
   // set all internal links to set the proper navigation and scroll to the appropraite page (by setting the hash?)
     
   // init click handler
   $('a[href*=#]').not('.selflink').bind('click',onClickChange );
        
    // bind the hashchange to the window
   $(window).bind('hashchange', onHashChange );
	var timer = 0;

   $(window).bind('scroll',function(){

	if($.browser.msie){ 		
		return false;//@todo check for IE'
	} else {
		if(timer){
			clearTimeout(timer);
			timer = 0;
		}
		timer = setTimeout(navigate,150);
	}
		
   });  
    // hide all content!
    
         
    // init the hit test boxes (class is set to the page incase we want to set the position in css?)
    $('.page').append('<div class="hittest" style="position:absolute; top:200px; left:260px;width:10px;height:10px;"></div>');
    // init the content (hide it all)
    hide_all_content();
    
    // if we load up and we aren't in the right place
    
	if(stripHash(window.location.hash).length){
		update_nav(stripHash(window.location.hash));
		scrollmeTo(stripHash(window.location.hash)); 
	}
	
	$(window).trigger('hashchange');
});

$().load(function(){
	if(stripHash(window.location.hash).length){
		update_nav(stripHash(window.location.hash));
		scrollmeTo(stripHash(window.location.hash)); 
	}
});

