"use strict";

App.module("RepresentationModule", function(RepresentationModule, App, Backbone, Marionette, $, _, Logger) {

    RepresentationModule.addInitializer(function(options){

        /**
         * Base structure and functionality of all masters of any dimension
         * All masters inherit from the given object
         */
        RepresentationModule.registerMaster({
            id: "_",

            options: {
            },

            defaultConfigParameterValues: {
                kind: "",
            },

            initialize: function() {
            },


            // =================================================================
            // housekeeping

            generateDynamicDerivedConfigData: function(config, configGrid) {
                return new RepresentationModule.DynamicDerivedConfigData();
            },


            configGridParameterHasDefaultValue: function(config, parameterName) {
                return this.getConfigParameterValueOrDefaultValue(config, parameterName) == this.defaultConfigParameterValues[parameterName];
            },


            getConfigParameterValueOrDefaultValue: function(config, parameterName, trimResult) {
                var value = config.getParameterValue(parameterName);
                if (!_.isUndefined(value)) {
                    return (trimResult && _.isString(value)) ? _.str.trim(value) : value;
                } else {
                    return this.defaultConfigParameterValues[parameterName];
                }
            },


            getConfigPlannedParameterValueOrDefaultValue: function(config, parameterName) {
                var value = config.getPlannedParameterValue(parameterName);
                if (!_.isUndefined(value)) {
                    return value;
                } else {
                    return this.defaultConfigParameterValues[parameterName];
                }
            },

            getSupportedKind: function() {
                if (this._cachedSupportedKind === undefined) {
                    this._cachedSupportedKind = this.id.split(".")[2];
                }
                return this._cachedSupportedKind;
            },


            planConfigParameterUpdateWithRespectToValueAndDefaultValue: function(config, parameterName, parameterValue) {
                var defaultParameterValue = this.defaultConfigParameterValues[parameterName];
                var currentParameterValue = config.getParameterValue(parameterName);
                var plannedParameterValue = parameterValue;

                if (currentParameterValue === undefined && plannedParameterValue === "" + defaultParameterValue) {
                    config.cancelPlannedParameterUpdate(parameterName);
                } else {
                    config.planParameterUpdate(parameterName, plannedParameterValue);
                }
            },


            extractCleanedConfigParameterValuesFromPlannedParameterValues: function(config) {
                var result = config.getPlannedParameterValues();

                // make sure no redundant parameters are set
                for (var key in result) {
                    if (result.hasOwnProperty(key)) {
                        if (this.defaultConfigParameterValues[key] === undefined) {
                            delete result[key];
                        }
                    }
                }

                // make sure all parameters are set to defaults if missing
                for (var key in this.defaultConfigParameterValues) {
                    if (this.defaultConfigParameterValues.hasOwnProperty(key)) {
                        if (!result.hasOwnProperty(key)) {
                            result[key] = "" + this.defaultConfigParameterValues[key];
                        }
                    }
                }

                return result;
            },

            cleanConfigPlannedParameterValuesAndApplyThem: function(config) {
                var newParameterValues = this.extractCleanedConfigParameterValuesFromPlannedParameterValues(config);
                config.unserialize({
                    parameters: newParameterValues,
                    plannedParameterUpdates: {},
                    tempParameters: {}
                });
            },


            // =================================================================
            // config grid panel


            parseAutocompleteSuggestions: function(rawAutocompleteSuggestions) {
                if (!_.isString(rawAutocompleteSuggestions) || !rawAutocompleteSuggestions) {
                    return null;
                }
                var rawAutocompleteAsArray = rawAutocompleteSuggestions.split(";");
                var result = {};
                _.each(rawAutocompleteAsArray, function(item) {
                    var parts = item.split("|");
                    if (parts.length == 2) {
                        result[parts[0]] = parts[1];
                    } else {
                        result[parts[0]] = parts[0];
                    }
                });
                return result;
            },


            // -----------------------------------------------------------------
            // config grid panel - prepare

            prepareConfigGridPanelMainArea: function(configGridPanelView) {

                // text fields
                var $textfields = configGridPanelView._$mainArea.find(".cgpma__textfield");
                configGridPanelView._$mainArea.data("$textfields", $textfields);

                var master = this;

                $textfields.each(function() {
                    var $textfield = $(this);
                    if (!$textfield.data("cgpma-textfield")) {
                        $textfield.textfield({
                            autocompleteSuggestions: master.parseAutocompleteSuggestions($textfield.data("autocomplete-suggestions")),
                            autocompleteIsAdvisory: $textfield.data("autocomplete-is-advisory"),
                            autocompleteSort: $textfield.data("autocomplete-sort"),
                            autocompleteCSSClasses: "ui_config-grid-type_" + configGridPanelView._cachedConfigGridType
                        });
                    } else {
                        $textfield.unbind("textfieldchangevalue");
                        $textfield.unbind("textfieldapply");
                        $textfield.unbind("textfielddiscard");
                    }
                    $textfield.data("configGridPanelView", configGridPanelView);
                    $textfield.bind("textfieldchangevalue", master.__panelInputChangeValueHandler);
                    $textfield.bind("textfieldapply", master.__panelInputApplyHandler);
                    $textfield.bind("textfielddiscard", master.__panelInputDiscardHandler);
                });

                // tick boxes
                var $tickboxes = configGridPanelView._$mainArea.find(".cgpma__tickbox");
                configGridPanelView._$mainArea.data("$tickboxes", $tickboxes);

                $tickboxes.each(function() {
                    var $tickbox = $(this);
                    if (!$tickbox.data("cgpma-tickbox")) {
                        $tickbox.tickbox();
                    }
                    $tickbox.data("configGridPanelView", configGridPanelView);
                    $tickbox.bind("tickboxchangevalue", master.__panelInputChangeValueHandler);
                });

                // input blocks
                var $inputBlocks = configGridPanelView._$mainArea.find(".cgpma__input-block");
                configGridPanelView._$mainArea.data("$inputBlocks", $inputBlocks);
                $inputBlocks.each(function() {
                    var $inputBlock = $(this);
                    var inputBlockName = $inputBlock.data("name");
                    if (!inputBlockName) {
                        var $firstElementWithParameterNameInsideInputBlock = $inputBlock.find("[data-parameter-name]").first();
                        inputBlockName = $firstElementWithParameterNameInsideInputBlock.data("parameter-name");
                    }
                    configGridPanelView._$mainArea.data("$inputBlock_" + inputBlockName, $inputBlock);
                });

                // initial population of the data
                var $allInputs = $tickboxes.add($textfields);
                configGridPanelView._$mainArea.data("$allInputs", $allInputs);
            },


            __panelInputChangeValueHandler: function(event) {
                var $this = $(this);
                var parameterName = $this.data("parameter-name");
                if (!parameterName) {
                    return;
                }

                var configGridPanelView = $this.data("configGridPanelView");
                var config = configGridPanelView._cachedConfig;
                var master = configGridPanelView._masterBehindMainArea;
                var value = undefined;
                if ($this.data("cgpma-tickbox")) {
                    value = $this.tickbox("option", "value");
                } else {
                    value = $this.textfield("option", "value");
                }
                master.planConfigParameterUpdateWithRespectToValueAndDefaultValue(config, parameterName, value);
            },

            __panelInputApplyHandler: function() {
                var $this = $(this);
                var configGridPanelView = $this.data("configGridPanelView");
                configGridPanelView._masterBehindMainArea.cleanConfigPlannedParameterValuesAndApplyThem(configGridPanelView._cachedConfig);
            },


            __panelInputDiscardHandler: function() {
                var $this = $(this);
                var configGridPanelView = $this.data("configGridPanelView");
                configGridPanelView._cachedConfig.cancelPlannedParameterUpdates();
            },


            // -----------------------------------------------------------------
            // config grid panel - sync

            syncConfigGridPanelMainArea: function(configGridPanelView, instant) {
                var $inputs = configGridPanelView._$mainArea.data("$allInputs");
                if ($inputs) {
                    var _this = this;
                    $inputs.each(function() {
                        var $input = $(this);
                        var parameterName = $input.attr("data-parameter-name");
                        if (parameterName) {
                            var widgetType = "textfield";
                            if ($input.data("cgpma-tickbox")) {
                                widgetType = "tickbox";
                            }
                            $input[widgetType]("option", {
                                "value":     "" + _this.getConfigPlannedParameterValueOrDefaultValue(configGridPanelView._cachedConfig, parameterName),
                                "baseValue": "" + _this.getConfigParameterValueOrDefaultValue(configGridPanelView._cachedConfig, parameterName),
                            });
                        }
                    });
                }
            },


            // -----------------------------------------------------------------
            // config grid panel - destroy

            destroyConfigGridPanelMainArea: function() {
            },


            // ===========================
            // config grid header

            renderHeaderContent: function(headerView, instant) {
                var newHashRelatedToOwnData = this._generateHeaderContentHashRelatedToOwnData(headerView);

                if (newHashRelatedToOwnData !== headerView._cachedContentHashRelatedToOwnData) {
                    this._doRenderHeaderContentRelatedToOwnData(headerView, instant);
                    headerView._cachedContentHashRelatedToOwnData = newHashRelatedToOwnData;
                }

                var newHash = this._generateHeaderContentHashRelatedToGridLayout(headerView);
                if (newHash !== headerView._cachedContentHashRelatedToGridLayout) {
                    this._doRenderHeaderContentRelatedToGridLayout(headerView, instant);
                    headerView._cachedContentHashRelatedToGridLayout = newHash;
                }
             },


            _renderHeaderContentRelatedToGridLayout: function(headerView, instant) {},


            _generateHeaderContentHashRelatedToOwnData: function(headerView) {
                return headerView.options.config.getHashForParameters() + (headerView.options.config.hasPlannedParameterUpdates() ? "1" : "0") + headerView.dynamicDerivedConfigData.getHash();
            },


            _generateHeaderContentHashRelatedToGridLayout: function(headerView) {}
        });
    });
}, Logger);
