(function ($) {
    $.fn.attachChildAgeSelector = function (options) {
        var settings = $.extend({
            minAge: 0,
            maxAge: 20,
            panelClass: "ChildAgeSelector",
            ageSelectorClass: "ChildAgeContainer",
            numberOfChildrenDropDownSelector: ".NumberOfChildrenDropDown",
            childAgesInputSelector: ".ChildAges",
            childAgeHeaderSelector: ".ChildAgeHeader",
            Translations: {
                yearsOld: "år",
                child: "Barn",
                chooseAge: "Välj ålder"
            }
        }, options);       

        $(this).each(function () {            
            initializeNumberOfChildrenSelector($(this), settings);
        });

        return this;
    };

    function initPanel(panel, settings) {
        panel.numberOfChildrenDropDown = $(settings.numberOfChildrenDropDownSelector, panel);
        panel.childAgesInput = $(settings.childAgesInputSelector, panel);
    }

    function initializeNumberOfChildrenSelector(panel, settings) {
        initPanel(panel, settings)

        setTextBoxVisibilityFromNumberOfChildren(panel, settings);

        panel.numberOfChildrenDropDown
            .change(function () {
                setTextBoxVisibilityFromNumberOfChildren(panel, settings);

            })
            .keyup(function () {
                setTextBoxVisibilityFromNumberOfChildren(panel, settings);
            });

        panel.childAgesInput.focusin(function () {
            displayChildAgeSelectorPanel(panel, settings);
            hookUpHideEvent(panel);
        });
    }

    function setTextBoxVisibilityFromNumberOfChildren(panel, settings) {
        if (panel.numberOfChildrenDropDown.val() === "0") {
            panel.childAgesInput.hide();
            panel.childAgesInput.val("");
            $(settings.childAgeHeaderSelector).hide();
        }
        else {
            panel.childAgesInput.fadeIn();
            $(settings.childAgeHeaderSelector).fadeIn();
        }
    }

    function getSelectedNumberOfChildren(panel) {
        return parseInt(panel.numberOfChildrenDropDown.val());
    }

    function displayChildAgeSelectorPanel(panel, settings) {
        if (panel.childAgeDialog) {
            return;
        }

        panel.childAgeDialog = $("<div></div>")
						.addClass(settings.panelClass)
						.append($("<div></div>")
								.text(settings.Translations.chooseAge)
								.addClass("Header"));

        for (var i = 0; i < getSelectedNumberOfChildren(panel); ++i) {
            appendChildAgeSelector(panel.childAgeDialog, i, settings);
        }

        updatePanelFromTextBox(panel, settings);

        $("select", panel.childAgeDialog).change(function () { updateTextBoxFromPanel(panel); });
        panel.childAgesInput.keyup(function () { updatePanelFromTextBox(panel, settings); });
        panel.append(panel.childAgeDialog);
    }

    function appendChildAgeSelector(dialog, childIndex, settings) {
        var dropDown = $("<select></select>");

        for (var i = settings.minAge; i <= settings.maxAge; ++i) {
            var optionGroup = $("<option></option>")
								.val(i)
								.text(i + " " + settings.Translations.yearsOld);

            dropDown.append(optionGroup);
        }

        var childAgeSelector = $("<div></div>")
		                        .addClass(settings.ageSelectorClass)
								.append("<label>" + settings.Translations.child + " " + (childIndex + 1) + "</label>")
								.append(dropDown);

        dialog.append(childAgeSelector);
    }

    function hookUpHideEvent(panel) {
        panel.childAgeDialog.click(function () {
            return false;
        });

        panel.myTextBoxWasClicked = false;

        panel.childAgesInput.keydown(function (event) {
            if (event.keyCode == '9') {
                hideDialog(panel);
            }
        });

        panel.childAgesInput.keyup(function (event) {
            if (event.keyCode == '27') {
                hideDialog(panel);
            }
        });

        panel.childAgesInput.click(function () {
            panel.myTextBoxWasClicked = true;
            return true;
        });

        panel.bodyClickListener = function (event) {
            if (!panel.myTextBoxWasClicked) {
                hideDialog(panel);
            }

            panel.myTextBoxWasClicked = false;
        };

        $("body").click(panel.bodyClickListener);
    }

    function hideDialog(panel) {
        if (panel.childAgeDialog) {
            updateTextBoxFromPanel(panel);

            panel.childAgeDialog.hide();
            panel.childAgeDialog.remove();
            panel.childAgeDialog = null;

            $("body").unbind("click", panel.bodyClickListener);
            panel.childAgesInput.unbind("click");
            panel.childAgesInput.unbind("keydown");
            panel.childAgesInput.unbind("keyup");
        }
    }

    function updateTextBoxFromPanel(panel) {
        var selectedAges = $("select", panel.childAgeDialog);
        var ages = $.map(selectedAges, function (x) { return $(x).val(); });
        panel.childAgesInput.val(ages.join(", "));
    }

    function updatePanelFromTextBox(panel, settings) {
        var selectedAges = panel.childAgesInput.val().split(",");
        var i = 0;
        $("select", panel.childAgeDialog).each(function () {
            age = parseAge(selectedAges[i++], settings);

            $(this).val(age);
        });
    }

    function parseAge(ageString, settings) {
        var result = parseInt(ageString);

        if (!result) {
            return settings.minAge;
        }
        else if (result < settings.minAge) {
            return settings.minAge;
        }
        else if (result > settings.maxAge) {
            return settings.maxAge;
        }
        return result;
    }
})(jQuery);
