/**
 * Author: Jason Webb (Gyro)
 * Date: July 18, 2011
 * 
 * Primary purpose of this file is to handle all navigation related functionality
 * for the gyro.com website.  Such functionality includes everything from large
 * tasks such as asynchronously loading content to the much smaller tasks of
 * changing the url hash in the url bar of the browser.
 * 
 * NOTE: The maximum expected level of depth within the navigation is 2 levels.
 * example:  contact -> this office
 * 
 * The address plugin is used for much of the heavy lifting used for the hash
 * coordination. $.address.*
 * @see: http://www.asual.com/jquery/address/
 */

/*********************************
 * Globals
 *********************************/
_currentHash = null;
_uri_segments = null;
_externalChange = false;

$(document).ready(function() {   
    /**
     * Since the url hash doesn't get sent to the server there
     * is no way to determine which page is actually being
     * loaded.  Therefore we have to break the url hash down
     * in order to set the active states of the navigation
     **/
    var updateMainNav = function(segments){
        
        if(typeof segments != 'undefined')
        {
            _uri_segments = segments;
        }
        
        // NOTE: for links that have a subnav, but no index page this will
        // have 2 array items because the parent has the same url as the
        // first subnav item
        // NOTE: two levels deep is the maximum for the side bar nav
        uriMatch = (_uri_segments.length > 1) ? 
                        '/' + _uri_segments[0] + '/' + _uri_segments[1] + '/' :
                        '/' + _uri_segments + '/';
        $currentLink = $('#mainNav a[href="' + uriMatch + '"]');        

        // if homepage or the link doesn't exist in the mainNav (i.e. legal, privacy)
        if($currentLink.length == 0) 
        {
            $('#mainNav .subnav').slideUp();
            $('#mainNav a').removeClass('active');
            
            return true;
        }


        $isParent = $($currentLink).next('.subnav');
        $isChild = $($currentLink).parents('.subnav');

        if($isParent.length > 0)
        {
            // A -> li -> li's -> a's
            $($currentLink).parent().siblings().find('a').removeClass('active'). siblings('.subnav').slideUp();

            // when a new parent is clicked, remove active state from
            // all child elements (good things)
            $($currentLink).next().find('a').removeClass('active');

            $($isParent).slideDown();
        }

        // This link is a child link, therefore we
        // ascend the dom, activating any links along the path
        if($isChild.length > 0)
        {
            // deactivate any other links
            $($isChild).find('a').removeClass('active');   

            // if an external url change is made we do these steps
            // external = back/forward button clicked, page refresh
            if(_externalChange)
            {
                // deactivate any non-related links
                $($isChild).parent().siblings().find('a').removeClass('active');
                // activate parent
                $($isChild).prev().addClass('active');
                // deactivate other subnavs
                $($isChild).parent().siblings().find('.subnav').slideUp();
                // activate subnav
                $($isChild).slideDown();
            }
            else
            {
                // confirm parents/grandparents are active
                // if not active, activate, DUH!!!
                if( ! $isChild.is(':visible'))
                {
                    $($isChild).slideDown().prev().addClass('active');
                }
            }
        }

        $($currentLink).addClass('active');
        
        _externalChange = false;
        
        return true;
    }

    /**
     * Binds a function to be executed whenever the address changes.
     * 
     * @see: http://www.asual.com/jquery/address/docs/
     **/
    $.address.change(function(event){
        _currentHash    = event.path;
        _uri_segments = _currentHash.replace(/^\//, '').replace(/\/$/, '').split('/');
    });
    
    /**
     * Binds a function to be executed whenever the address is changed
     * from within side of the page.
     * 
     * @see: http://www.asual.com/jquery/address/docs/
     **/
    $.address.internalChange(function(event) {
        updateMainNav();   
    });
    
    /**
     * Binds a function to be executed whenever the address is changed
     * from outside of the page.  Refresh, back button, forwards button
     * pushed.
     * 
     * @see: http://www.asual.com/jquery/address/docs/
     **/    
    $.address.externalChange(function(event){
        // this will stop an ajax call from happening when:
        // 1.) someone visits home page        
        if(_currentHash == '/' && location.pathname == '/')
        {
            return false;
        }
        // 2.) someone visits the site using regular url notation instead of
        //     utilizing the hash system.  This happens when someone types in their
        //     url or if they visit the site from a third party site (google analytics)
        else if(_currentHash == '/' && location.pathname != '/')
        {
            // update navigation on this url notation page
            updateMainNav(segmentizeLocPath());
            return true;
        }

        _externalChange = true;

        updateMainNav();
        
        pageLoad(_currentHash);
    });
    

    //  Internal address changes
    $('a.transition').live('click', function(e) {
        
        // can't transition, revert to refreshing
        if( ! _canTransition) { return true; }
      
        var $hash = $(this).attr('href');
        
        // don't do anything if they are already on this page
        if(_currentHash == $hash) {return false;}

        // Redirect to hash notation site when the url has a pathname and a
        // hash set. This will happen when someone visits the site using url
        // notation, then clicks on a transition link.  Their url will look
        // similar to this: http://.../contact-us-now/everywhere/#/what-we-do/our-mission
        //
        // Since this ultimately looks terribles and will have an impact on the 
        // site we simply redirect to the homepage with
        if(location.pathname != '/')
        {
            location.href = '/#' + $hash;
            e.preventDefault();
        }
        else
        {
            // internal page link (links not in menu)
            if($(this).hasClass('iplink')) { _externalChange = true; }        

            $.address.value($hash);  

            pageLoad($hash);

            return false;
        }
    });
    
    var pageLoad = function(hash){

        var ajaxSettings = {
            url: hash,
            success: function(data, status, xhr) {
                var $currTransContainer = $('.transitionContainer');
                var $newTransContainer = $('<div class="transitionContainer">' + data.payload + '</div>').hide();
                
                // bodyid is the last segment of the uri
                var bodyid = (_uri_segments.length == 0) ? 'body-home' : 'body-' + _uri_segments[_uri_segments.length - 1];

                $($currTransContainer).after($newTransContainer).fadeOut('fast').remove();
                $.address.title(data.title + ' | gyro');
                
                // Set metadata
                $('meta[name=Keywords]').attr('content', data.meta_keywords);
                $('meta[name=Description]').attr('content', data.meta_description);
                       
                $($newTransContainer).fadeIn(1000);
                
                $('#bot-addthisLnk').attr('addthis:title', data.title + ' | gyro');
                $('#bot-addthisLnk').attr('addthis:url', _currentHash);
                
                // Refresh the Bizo iframe so another pageview gets tracked
                if ($("#bizoIFrame")[0]) {
                    var src = $("#bizoIFrame").attr("src");
                    $("#bizoIFrame").attr("src", "about:blank");
                    $("#bizoIFrame").attr("src", src);
                }                          

                // set new body id and class attributes (the class attribute is primarily)
                // used to identify a specific template to load
                $('body').attr('id', bodyid);
                document.getElementById('tplHolder').className = document.getElementById('tplHolder').className.replace(/(tpl-[^\s]*)|^(tpl-[^\s]*)/gi, data.tplclass);
                
                // primarily for any browser that won't automaticatlly go back to the top of the page
                 $('html, body').animate({scrollTop:0}, 'slow');
            },
            dataType: "json"
        }
        
        $.ajax(ajaxSettings);        
    } 
    
    // Check for for ie acceptance. If not accepted, we force load the nav
    if( ! ie_accept())
    {
        updateMainNav(segmentizeLocPath());
    }    
});


///-------------------------- CUSTOM METHODS --------------------------------///

/**
 * This function breaks the current url path (not including hash info) into
 * an array of segments.  Each segments consists of information between the path
 * slashes (/).
 * 
 * Example: 
 * path = /test/example2/
 * segmentArray = ['test','example2'];
 */
function segmentizeLocPath(path)
{
    return location.pathname.replace(/^\//, '').replace(/\/$/, '').split('/');
}
