﻿/// <reference path="../../Scripts/jquery-1.3.2-vsdoc2.js" />

(function($) {
    $.fn.tabGroup = function(options) {
        var groupElements = new Array();
        var lastTabActionDelay = 150;
        var previousMillis = null;

        this.each(function() {
            groupElements.push($('' + this));
        });

        groupElements = $(groupElements);

        function checkIfDelayHasPassed() {
            var curr_msec = new Date().getTime();
            if (previousMillis == null || (curr_msec - previousMillis) > lastTabActionDelay) {
                previousMillis = curr_msec;
                return true;
            }
            return false;
        }

        //Capture tab, reverse tab key events
        groupElements.each(function(index, field) {
            var selectNextElement = function() {
                selectGroupElement(index + 1, false);
            }
            var selectPreviousElement = function() {
                selectGroupElement(index - 1, true);
            }

            //Opera does not support cancelling keydown events
            //And this code does not work in Firefox & co with a keypress event
            //So have to have both for now
            //Todo: Find a generic solution that is feature-based, not browser-based. SMF

            if (/Opera/.test(navigator.userAgent)) {
                this.bind('keypress', 'tab', function(e) {
                    if (typeof (e.preventDefault) == 'function') {
                        e.preventDefault();
                    }
                    else {
                        e.returnValue = false;
                    }

                    if (checkIfDelayHasPassed()) {
                        $(this).trigger("tabOut");
                        selectNextElement();
                    }

                    return false;
                });
            }
            else {
                this.bind('keydown', 'tab', function(e) {
                    if (typeof (e.preventDefault) == 'function') {
                        e.preventDefault();
                    }
                    else {
                        e.returnValue = false;
                    }

                    if (checkIfDelayHasPassed()) {
                        $(this).trigger("tabOut");
                        selectNextElement();
                    }

                    return false;
                });
            }

            if (/Opera/.test(navigator.userAgent)) {
                this.bind('keypress', 'shift+tab', function(e) {
                    if (typeof (e.preventDefault) == 'function') {
                        e.preventDefault();
                    }
                    else {
                        e.returnValue = false;
                    }

                    if (checkIfDelayHasPassed()) {
                        $(this).trigger("reverseTabOut");
                        selectPreviousElement();
                    }

                    return false;
                });
            }
            else {
                this.bind('keydown', 'shift+tab', function(e) {
                    if (typeof (e.preventDefault) == 'function') {
                        e.preventDefault();
                    }
                    else {
                        e.returnValue = false;
                    }

                    if (checkIfDelayHasPassed()) {
                        $(this).trigger("reverseTabOut");
                        selectPreviousElement();
                    }

                return false;
                });
            }
        });

        //Element selection functions
        function selectGroupElement(index, reverse) {
            var element = getGroupElement(index, reverse);
            if (element != null) {
                element.focus();
                element.trigger("tabIn");
            }
        }
        function getGroupElement(index, reverse) {
            if (index < 0 || index >= groupElements.length) {
                return null;
            }
            var elementToSelect = groupElements[index];
            if (elementToSelect.is(':disabled')) {
                if (reverse) {
                    return getGroupElement(index - 1);
                } else {
                    return getGroupElement(index + 1);
                }
            }
            return groupElements[index];
        }
    }
})(jQuery);

