/*global jQuery, IAD
*/
// Initialize IAD and IAD.travel namespaces
var IAD = IAD || {};
IAD.travel = IAD.travel || {};

IAD.travel.navigators_prepackage = function ($) {

    function set() {
        var internal_map = {};
        for (var i = 0; i < arguments.length; i++) {
            internal_map[arguments[i]] = true;
        }

        this.add = function(item) {
            internal_map[item] = true;
        };
        this.remove = function(item) {
            internal_map[item] = false;
        };
        this.values = function() {
            var result = [];
            for (var key in internal_map) {
                if (internal_map[key]) {
                    result.push(key);
                }
            }
            return result;
        };
    }

    function any(value, collection, predicate) {
        var result = false;
        $.each(collection, function(i, item) {
            if(predicate(value, item)) {
                result = true;
                return false;
            }
        });
        return result;
    }

    function value_in(value, collection) {
        return any(value, collection, function(value, item) {
            return value == item;
        });
    }

    function get_input(form, field_name, type) {
        var selector = "input[name=" + field_name + "]";
        if (type) {
            selector += "[type=" + type + "]";
        }
        return $(selector, form);
    }

    /**
     * Check if atleast one checkbox is checked
     * @param checkboxes
     */
    function is_checked(checkboxes) {
        var result = false;
        checkboxes.each(function() {
            if(this.checked) {
                result = true;
                return false;
            }
        });
        return result;
    }

    /**
     * Get a callback to use on submit that will replace/remove the parameter.
     *
     * @param primary_param The parameter that takes precedence
     * @param secondary_param The parameter that falls away
     */
    function get_replace_params_on_submit_callback(primary_param, secondary_param) {
        return function() {
            var primary = get_input(this, primary_param);
            if (is_checked(primary)) {
                var secondary = get_input(this, secondary_param);
                secondary.val("");
            }
        };
    }

    /**
     * Set up the hook to replace/remove a parameter on submit
     *
     * @param form The form to hook on to
     * @param primary_param The parameter that takes precedence
     * @param secondary_param The parameter that falls away
     */
    function hook_parameter_replace(form, primary_param, secondary_param) {
        $(form).submit(get_replace_params_on_submit_callback(primary_param, secondary_param));
    }

    /**
     * Find all input elements for areaId, and remove the given value.
     * @param form The form to look in
     * @param areaIds The value to remove
     */
    function remove_areaids(form, areaIds) {
        var inputs = get_input(form, "areaId", "hidden");
        inputs.each(function() {
            var input = $(this);
            var oldAreaIds = input.val().split(";") || [];
            var newAreaIds = [];
            $.each(oldAreaIds, function(i, value) {
                if (!value_in(value, areaIds)) {
                    newAreaIds.push(value);
                }
            });
            input.val(newAreaIds.join(";"));
        });
    }

    /**
     * Get the parent areaid from the given input element.
     * Parent areaid is assumed to be available in the custom attribute 'data-parentAreaId'
     * @param input Input field
     */
    function get_parent_areaids(input) {
        return $(input).attr("data-parentAreaIds").split(";");
    }

    /**
     * Find all selected areaIds, and remove parent areaids from the form
     */
    function remove_parent_areaids() {
        var form = this;
        var checkboxes = get_input(form, "areaId", "checkbox");
        var parentAreaIds = new set();
        checkboxes.each(function() {
            var input = this;
            if(input.checked) {
                $.each(get_parent_areaids(input), function(i, value) {
                    parentAreaIds.add(value);
                });
            }
        });
        remove_areaids(form, parentAreaIds.values());
    }

    /**
     * Set up the hook to remove parent areaids on submit
     * @param form The form to hook on to
     */
    function hook_areaid_hack(form) {
        $(form).submit(remove_parent_areaids);
    }

    return {
        hook_parameter_replace: hook_parameter_replace,
        hook_areaid_hack: hook_areaid_hack
    };
}(jQuery);
