// jQuery Template for navigation
(function ($) {
    // Create template markup
    var markup =
        '<table id="navMenuTable">' +
            '<tr>' +
                '<td style="width:194px" class="navMenuLeft">' +
                    // Ensure the NavItems are ordered properly, it should be Parent -> Child -> SubChild in the row order
                    //      otherwise this will NOT work.
                    '{{each NavItems}}' +
                    '{{if ParentID == 0}}' +
                        '{{if $index > 0}}' +
                            '</ul>' +
                        '</div>' +
                        '{{/if}}' +
                        '<div id="nav-container-${NavID}" class="nav-container" style="display:none;" data-id="${NavID}">' +
                            '<ul>' +
                    '{{else}}' +
                            '<li class="nav-item{{if Flyout && Flyout.length > 0}} hasFlyoutOff hasFlyoutArrow{{/if}}" id="${IdTree}">' +
                                '<a target="${Target}" {{if URL && URL != "#"}}title="${InnerHtml}" {{/if}}href="{{if URL && URL != "#"}}${UrlPrefix}${URL}{{else}}#{{/if}}" class="nav-link{{if Level > 1}} childItem{{/if}}{{if (!URL) || URL == "#"}} empty-link{{/if}}" data-id="${NavID}">' +
                                    '${InnerHtml}' +
                                '</a>' +
                            '</li>' +
                    '{{/if}}' +
                    '{{/each}}' +
                    '{{if NavItems.length > 0}}' +
                            '</ul>' +
                        '</div>' +
                    '{{/if}}' +
                '</td>' +
                '<td class="nav-content-container" style="background-color:#fefefe; max-width:724px; width:724px; margin:0px" />' +
            '</tr>' +
        '</table>';
    // Compile the template as named template
    
	$.template("navMenuTable", markup);
})(jQuery);

// jQuery method to rig up events to the navMenuTable after the template is used
var navDataItems;
function navMenuTableTemplate(navItemsJson) {
    navDataItems = navItemsJson.NavItems || [];
    $(document).ready(function () {
        $.tmpl("navMenuTable", navItemsJson).appendTo($('#navMenu').empty());
        $('#navMenuTable,#navMenuLeft').hover(function () { clearTimeout(menuTimeout); });
        $('tbody', '#navMenuTable').hover(function () { clearTimeout(menuTimeout); });
        $('tr', '#navMenuTable').hover(function () { clearTimeout(menuTimeout); });
        $('td', '#navMenuTable').hover(function () { clearTimeout(menuTimeout); });
        $('.nav-item', '#navMenuTable').hover(function () { clearTimeout(menuTimeout); });
        $('.hasFlyoutOff', '#navMenuTable').hover(function () { clearTimeout(menuTimeout); });
        $('.nav-link', '#navMenuTable').hover(function () { clearTimeout(menuTimeout); });
        $('.nav-item:not(.hasFlyoutOff)', '#navMenuTable').hover(function () { $(this).show(); });

        $('.nav-item', '#navMenuTable').hover(function (e) {
            $(this).addClass('hovering');
            if (menuTimeout) { clearTimeout(menuTimeout); menuTimeout = null; }
            showContentContainer(e, $(this));
        }, function () {
            $(this).removeClass('hovering');
            // Restart the start time if this is the active element
            if ($(this).hasClass('hasFlyoutOn')) {
                $(this).data('start', new Date().getTime()); // ticks from start time
                _showNavEvent = e;
            }
        });
        $('.nav-content', '#navMenuTable').hover(function () { }, function () {
            // Ensure once we're working with content that we don't pretend like the
            //      navigation setting should still be remembered
            _showNavEvent = null;
            if (_showNavContentTimeout) { clearTimeout(_showNavContentTimeout); }
            _showNavContentTimeout = null;
        });
        $('#mainnav a').hover(function (e) { showContentContainer(e, $(this)); });// showMainNav(e, $(this));
		//$('#mainnav a').hover(function (e) { showContentNav(e, $(this)); });
    });
}

var _showNavContentTimeout = null;
var _showNavEvent = null;

function showContentContainer(originalEvent, targetElement) {
    // Ensure we don't have a pending timeout window
    if (_showNavContentTimeout) {
        clearTimeout(_showNavContentTimeout);
        _showNavContentTimeout = null;
    }
    
    // Ensure they intend to the change (hoverIntent wasn't cutting it, so switched to manual detection)
    var currentElement = targetElement;
    if (currentElement.hasClass('nav-item')) {
        // Ensure we're still hovering
        if (!currentElement.hasClass('hovering')) {
            return;
        }
        var lastActiveElement = currentElement.siblings('.hasFlyoutOn');
        
        var startTicks = lastActiveElement.data('start'); // ticks from start time
        if (typeof startTicks != "undefined") {
            // Determine the minimum duration (in milliseconds) between changes
            var minimumDuration = 150;
            
            // Check how far we've moved
            if (_showNavEvent) {
                var delta = { X: (originalEvent.pageX - _showNavEvent.pageX), Y: (originalEvent.pageY - _showNavEvent.pageY) };
                if (delta.X > 100) {
                    // They've moved drastically to the right, definitely going to the flyout
                    minimumDuration = 3000;
                } else if (delta.X > 40) {
                    // Fairly confident now
                    minimumDuration = 1800;
                } else if (delta.X > 25) {
                    // They're definitely going right, but let's not get ahead of ourselves yet
                    minimumDuration = 1200;
                } else if (delta.X > 15) {
                    // They're still moving to the right, they might want the flyout
                    minimumDuration = 800;
                } else if (delta.X > 8) {
                    // Gaining momemtum now, keep giving them more slack
                    minimumDuration = 500;
                } else if (delta.X > 5) {
                    // They could have had a spasm, but it's still moving to the right                        
                    minimumDuration = 300;
                } else if (delta.X > 0) {
                    // Their mouse slipped to the right, give them a little more time to make a decision.
                    minimumDuration = 200;
                }
            }

            var duration = (new Date().getTime() - startTicks);
            if (duration < minimumDuration) {
                // After minimum duration, they can change elements, before then
                //      the last active element still has precedent.
                _showNavContentTimeout = setTimeout(function() {
                    _showNavContentTimeout = null;
                    showContentContainer(originalEvent, currentElement);
                }, 50);
                return;
            }

            lastActiveElement.removeData('start');
        }
    }

    // Remove existing flyouts
    $('.nav-item.hasFlyoutOn').removeClass('hasFlyoutOn').addClass('hasFlyoutOff');
    $('.nav-content', '#navMenuTable').removeClass('flyoutOn').addClass('flyoutOff');

    // Show the existing nav link
    var dataId = null;
    if (currentElement.hasClass('nav-item')) {
        currentElement.data('start', new Date().getTime()).removeClass('hasFlyoutOff').addClass('hasFlyoutOn');
		_showNavEvent = originalEvent;
        dataId = $('.nav-link', currentElement).attr('data-id');
    } else {
        dataId = currentElement.attr('data-id');
    }
    
    showContent(currentElement, dataId);
}

function showContent(currentElement, dataId) {    
    var navContent = $('#nav-content-' + dataId);
    
	if (navContent.length == 0) {
        
		navContent = loadContent(dataId);
		
        if (!currentElement.hasClass('nav-item') && !navContent) {
            return;
        }

   
        if (currentElement.hasClass('nav-item') && (!navContent || navContent.size() == 0)) {
            navContent = getDefaultContent(currentElement);
        }
    }
    
    navContent.removeClass('flyoutOff').addClass('flyoutOn');
}

function loadContent(dataId) {
	
    var navDataItem = getNavDataItem(dataId);
    if (!navDataItem || !navDataItem.Flyout) return;
    
    return $('<div id="nav-content-' + navDataItem.NavID + '" class="nav-content flyoutContainer flyoutOff" />')
            .html(navDataItem.Flyout)
            .appendTo($(".nav-content-container"));
}

function getDefaultContent(currentElement) {
    var navContainer = currentElement.closest('.nav-container');
    return $('#nav-content-' + navContainer.attr('data-id'));
}

function getNavDataItem(itemId) {
    var item;
    $.each(navDataItems, function () {
        if (this.NavID == itemId) {
            item = this;
            return;
        }
    });
    return item;
}
