// see http://www.bennadel.com/index.cfm?dax=blog:1520.view
// 
// basically, this anonymous method is immediately executed, and triggers
// jQuery events when the window.location.hash changes that we can listen for
// elsewhere. basically, every 100ms we check to see if it's changed and if it
// has, we trigger the event.
(
    function($) {
        // Default to the current location.
        var fragment = window.location.hash.slice(1);
        var prev_fragment = "";
         
        // This is how often we will be checking for changes
        var interval = 100;
         
        // Check for changes in window.location.hash
        var checkFragment = function() {
            // Check to see if the location has changed.
            if (fragment !== window.location.hash.slice(1)) {
                // Store the new and previous locations.
                prev_fragment = fragment;
                fragment = window.location.hash.slice(1);
                 
                // The location has changed. Trigger a
                // change event on the location object,
                // passing in the current and previous
                // location values.
                $(window.location).trigger('change',
                    {
                        hash: fragment,
                        previous_hash: prev_fragment
                    }
                );
            }
        }
         
        // Set an interval to check the location changes.
        setInterval(checkFragment, interval);
    }
)(jQuery);

Maplecroft = window.Maplecroft || {};

Maplecroft.init_top_navigation = function () {
    Maplecroft.not_so_mega_dropdown('top_navigation_bullet');
};


Maplecroft.not_so_mega_dropdown = function (container_id) {
    // renders a 2-level unordered list as a "mega dropdown" so sub items
    // apear in drop-down from top level list elements
    var login_form_has_focus = false;
    var login_form_inputs = $('#' + container_id + ' input');
    var top_nav = $('#' + container_id);
    var top_nav_items = $('#' + container_id + '>ul>li');
    if (top_nav_items.length == 0){ // for where we have used a div to split - LRE/PR
        top_nav_items = $('#' + container_id + '>div>ul>li');
    }
    login_form_inputs.focus(
	function () {
	    login_form_has_focus = true;
	}
    );

    login_form_inputs.blur(
	function () {
	    login_form_has_focus = false;
	}
    );

    var hide_top_nav_items = function () {
    	top_nav_items.each(hide);
    };

    // see http://stackoverflow.com/questions/152975/how-to-detect-a-click-outside-an-element
    $('body').click(hide_top_nav_items);
    top_nav.click(
	function (e) {
	    e.stopPropagation();
	}
    );

    var show = function (e) {
	// Need this because mouseout over the login box does not hide it
	// if the form has focus (to workaround a Firefox bug)
	hide_top_nav_items();
        var top_section = $(this);
	if (!(($.browser.msie && ($.browser.version == "6.0")) && (top_section.find('div').attr('class') === 'login_popdown'))) {
	    top_section.addClass('hovered');
	    top_section.find('ul').show();
	}
    };

    var hide = function (e) {
	var top_section = $(this);
	top_section.removeClass('hovered');
	top_section.find('ul').hide();
    };
    
    var hide_login = function (e) {
	if (!login_form_has_focus) {
	    var top_section = $(this);
	    top_section.removeClass('hovered');
	    top_section.find('ul').hide();
	}
    };
    
    top_nav_items.filter(':not(.loginNav)').hover(show, hide);
    // custom behaviour for the login tab
    top_nav_items.filter('.loginNav').hover(show, hide_login);    

};


Maplecroft.nested_tabs = function (spec) {
    /*
     * spec:
     *   section_controls:
     *     the set of elements to be clicked on for changing sections
     *   sections:
     *     an array of list items corresponding to each section
     *   section_divs:
     *     an array of divs containing the tabs for each section
     *   tab_controls:
     *     2d array: primary index is by section, secondary arrays contain the
     *     clickable elements for the tabs in a given section
     *   tabs:
     *     2d array: primary index is by section, secondary arrays contain the
     *     list items for a given tab
     *   preserve_tabs:
     *     if false, we don't skip to the zeroth tab when switching between
     *     sections, instead preserving the tab index. this might cause issues
     *     if there are different numbers of tabs between sections.
     */
    var that = {};
    var current_section_index;
    var current_tab_index;

    spec.section_controls.each(
        function (i, section_control) {
            $(section_control).click(
                function (e) {
                    e.preventDefault();
                    change_section(i);
                }
            );
        }
    );

    for (var i = 0; i < spec.tab_controls.length; i++) {
        if (spec.tab_controls[i].length > 0) {
            spec.tab_controls[i].each(
                function (j, tab_control) {
                    $(tab_control).click(
                        function (e) {
                            e.preventDefault();
                            change_tab(j);
                        }
                    );
                }
            );
        }
    }

    var show_section = function (section_index) {
        spec.section_controls.eq(section_index).closest('li').addClass('active');
        spec.sections[section_index].show();
        if (spec.section_divs[section_index]) {
            spec.section_divs[section_index].show();
        }
    };

    var hide_section = function (section_index) {
        spec.section_controls.eq(section_index).closest('li').removeClass('active');
        spec.sections[section_index].hide();
        if (spec.section_divs[section_index]) {
            spec.section_divs[section_index].hide();
        }
    };

    var show_tab = function (tab_index) {
        if (spec.tabs[current_section_index].length > 0) {
            spec.tab_controls[current_section_index].eq(tab_index).closest('li').addClass('active');
            spec.tabs[current_section_index][tab_index].show();
        }
    };

    var hide_tab = function (tab_index) {
        if (spec.tabs[current_section_index].length > 0) {
            spec.tab_controls[current_section_index].eq(tab_index).closest('li').removeClass('active');
            spec.tabs[current_section_index][tab_index].hide();
        }
    };

    var change_section = function (section_index) {
        if (current_section_index !== section_index) {
            hide_section(current_section_index);
            show_section(section_index);

            if (!spec.preserve_tabs) {
                hide_tab(current_tab_index);
                current_section_index = section_index;
                show_tab(0);
                current_tab_index = 0;
            } else {
                hide_tab(current_tab_index);
                current_section_index = section_index;
                show_tab(current_tab_index);
            }
        }
    };

    var change_tab = function (tab_index) {
        if (current_tab_index !== tab_index) {
            hide_tab(current_tab_index);
            show_tab(tab_index);
            current_tab_index = tab_index;
        }
    };
    
    that.init = function () {
        current_section_index = 0;
        current_tab_index = 0;

        $.each(spec.sections,
            function (i, section) {
                current_section_index = i;
                $.each(spec.tabs[i],
                    function (j, tab) {
                        hide_tab(j);
                    }
                );
                hide_section(i);
            }
        );
        change_section(0);
        change_tab(0);
    };

    return that;
};

Maplecroft.tabs = function (spec) {
    var that = {};
    var current_tab_index;

    spec.tab_controls.each(
        function (i, tab_control) {
            $(tab_control).click(
                function (e) {
                    e.preventDefault();
                    change_tab(i);
                }
            );
        }
    );

    var show_tab = function (tab_index) {
        spec.tab_controls.eq(tab_index).closest('li').addClass('active');
        spec.tabs[tab_index].show();
        if (spec.show_tabs) {
            collapse_tabs(tab_index, spec.show_tabs);
        }
    };

    var hide_tab = function (tab_index) {
        spec.tab_controls.eq(tab_index).closest('li').removeClass('active');
        spec.tabs[tab_index].hide();
    };

    var change_tab = function (tab_index) {
        if (current_tab_index !== tab_index) {
            hide_tab(current_tab_index);
            show_tab(tab_index);
            current_tab_index = tab_index;

            if (spec.tab_anchors) {
                window.location.hash = spec.tab_anchors[tab_index];
            }
        }
    };

    var collapse_tabs = function (tab_index, k) {
        // hide them all
        for (var i = 1; i < spec.tab_controls.length; i++) {
            spec.tab_controls.eq(i).hide();
            spec.tab_controls.eq(i).closest('li').addClass('hidden');
        }

        // remove any ellipsis, <, and > items we've inserted
        $('li.ellipsis').remove();
        $('li.prev').remove();
        $('li.next').remove();

        // show the first page
        if (tab_index > 1) {
            spec.tab_controls.eq(0).show();
            spec.tab_controls.eq(i).closest('li').addClass('hidden');
        }

        var start = 1;
        var end = spec.tab_controls.length;
        var ellipsis = '<li class="ellipsis">...</li>';
        var prev = '<li id="previous_tab"><a href="#">&lt;</a></li>';
        var next = '<li id="next_tab"><a href="#">&gt;</a></li>';

        $('#previous_tab').remove();
        $('#next_tab').remove();
        spec.tab_controls.eq(0).closest('li').before(prev);
        spec.tab_controls.eq(spec.tab_controls.length - 1).closest('li').after(next);

        if (tab_index > 0) {
            $('#previous_tab a').click(
                function (e) {
                    e.preventDefault();
                    change_tab(tab_index - 1);
                }
            );
        }

        if (tab_index < spec.tab_controls.length - 1) {
            $('#next_tab a').click(
                function (e) {
                    e.preventDefault();
                    change_tab(tab_index + 1);
                }
            );
        }

        // show '1 ...' at the start
        if (tab_index - k > 1) {
            start = tab_index - k;
            spec.tab_controls.eq(0).closest('li').after(ellipsis);
        }

        // show '... n' at the end
        if (tab_index + k < spec.tab_controls.length - 2) {
            end = tab_index + k;
            spec.tab_controls.eq(spec.tab_controls.length - 1).closest('li').before(ellipsis);
        }

        // show the current page & k tabs around it
        for (var i = start; i <= end; i++) {
            spec.tab_controls.eq(i).show();
            spec.tab_controls.eq(i).closest('li').removeClass('hidden');
        }

        // show the last page
        if (tab_index < spec.tab_controls.length - 1) {
            spec.tab_controls.eq(spec.tab_controls.length - 1).show();
            spec.tab_controls.eq(spec.tab_controls.length - 1).closest('li').removeClass('hidden');
        }
    };
    
    that.init = function () {
        current_tab_index = 0;
        $.each(spec.tabs,
            function (i, tab) {
                if (i > 0) {
                    hide_tab(i);
                }
            }
        );
        show_tab(0);
    };

    that.change_tab = change_tab;

    return that;
};

Maplecroft.store = function (toggle_state) {
    
    var section_toggles = $('a.toggle');
    var rows = {};

    var get_row_group_class = function (row_toggle) {
        row_toggle = $(row_toggle);
	return row_toggle.children().attr('id').replace('imgstoreC', '');
    };

    section_toggles.toggle(
	function () {
	    $(this).children().attr(
		'src', 
		GR_MEDIA_URL + 'images/store/expand_up_icon.png');
	    rows[get_row_group_class(this)].hide();
	},
	function () {
	    $(this).children().attr(
		'src', 
		GR_MEDIA_URL + 'images/store/expand_down_icon.png');
	    rows[get_row_group_class(this)].show();
	}
    );

    section_toggles.each(
	function (i, toggle) {
	    var row_group_class = get_row_group_class(toggle);
            var row_group = $('tr.' + row_group_class);
	    rows[row_group_class] = row_group;
            if (!toggle_state[row_group_class]) {
  		$(toggle).click();
	    }
	}
    );

};

/*
 * This function allows you to bind the following behaviour to input form
 * fields:
 *  - on focus:
 *    - clear the text if it is the default (eg: "search")
 *    - if 'select', then select the text otherwise
 *  - on blur:
 *    - if 'restore', then restore the original text if the field is empty
 */
Maplecroft.input_defaults = function(input_id, default_text, restore, select) {  
    if (restore) {
        $('#' + input_id).bind('blur',
            function(e) {
                if ($('#' + input_id).val() === '') {
                    $('#' + input_id).val(default_text);
                }
            }
        );
    }
    $('#' + input_id).bind('click',
        function(e) {
            if ($('#' + input_id).val() === default_text) {
                $('#' + input_id).val('');
            } else if (select) {
                $('#' + input_id).select()
            }
        }
    );
};

Maplecroft.strip_diacritics = function(str) {
    var diacritics = [
        /[\300-\306]/g, /[\340-\346]/g, // A, a
        /[\310-\313]/g, /[\350-\353]/g, // E, e
        /[\314-\317]/g, /[\354-\357]/g, // I, i
        /[\322-\330]/g, /[\362-\370]/g, // O, o
        /[\331-\334]/g, /[\371-\374]/g, // U, u
        /[\321]/g, /[\361]/g, // N, n
        /[\307]/g, /[\347]/g, // C, c
    ];

    var chars = ['A','a','E','e','I','i','O','o','U','u','N','n','C','c'];

    for (var i = 0; i < diacritics.length; i++) {
        str = str.replace(diacritics[i], chars[i]);
    }

    return str;
};

Maplecroft.slugify = function(str) {
    // the idea here is to replicate the slugify template filter, but I haven't
    // actually looked at that code to check...
    return Maplecroft.strip_diacritics(str.replace(/ /g, '-').replace(/'/g, '').toLowerCase());
};

