"use strict";

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

    RepresentationModule.addInitializer(function(options){

        RepresentationModule.registerMaster({
            id: "view._",
            inherit: "_",

            options: {
                canHaveBase: false,
                canHaveOverlay: false,
                canHaveTemp: false,

                visInstanceContentHeightMin: 20,
                visInstanceContentHeightMax: 20,
                visInstanceContentPaddingTop: 5,
                visInstanceContentPaddingBottom: 5,

                visInstanceSupportedComparisonModes: [],

                auxiliaryAssetsTimeout: 2000,
                auxiliaryAssetsCheckInterval: 500
            },

            defaultConfigParameterValues: {
                widthToHeightRatio: 2
            },


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

            initialize: function() {
                this.obtainAuxiliaryData();
                this.obtainAuxiliaryAssets();
            },


            setAuxiliaryDataStatus: function(status) {
                this.auxiliaryDataStatus = status;
                this.trigger("change:auxiliaryResourcesStatus");
            },

            setAuxiliaryAssetsStatus: function(status) {
                this.auxiliaryAssetsStatus = status;
                this.trigger("change:auxiliaryResourcesStatus");
            },


            getAuxiliaryResourcesStatus: function() {
                if (this.auxiliaryDataStatus == "fail" || this.auxiliaryAssetsStatus == "fail") {
                    return "fail";
                }
                if (this.auxiliaryDataStatus == "pending" || this.auxiliaryAssetsStatus == "pending") {
                    return "pending";
                }
                return "";
            },


            obtainAuxiliaryAssets: function() {
                if (!this.options.auxiliaryAssets || !this.options.auxiliaryAssets.length) {
                    return;
                }

                if (this.auxiliaryAssetsStatus) {
                    return
                }

                this.setAuxiliaryAssetsStatus("pending");

                var $body = $("body");
                _.each(this.options.auxiliaryAssets, function(assetURL) {
                    $body.append("<script/>")
                        .attr("script", "text/javascript")
                        .attr("src", assetURL);
                });

                this.auxiliaryAssetsIntervalCount = 0;
                this.auxiliaryAssetsInterval = setInterval($.proxy(this.auxiliaryAssetsInvervalFunction, this), this.options.auxiliaryAssetsCheckInterval);
            },


            auxiliaryAssetsInvervalFunction: function() {
                ++ this.auxiliaryAssetsIntervalCount;
                if (this.auxiliaryAssetsIntervalCount * this.options.auxiliaryAssetsCheckInterval > this.options.auxiliaryAssetsTimeout) {
                    clearInterval(this.auxiliaryAssetsInterval);
                    this.setAuxiliaryAssetsStatus("fail");
                    return;
                }
                if (this.checkIfAuxiliaryAssetsAreReady()) {
                    clearInterval(this.auxiliaryAssetsInterval);
                    this.setAuxiliaryAssetsStatus("success");
                }
            },

            checkIfAuxiliaryAssetsAreReady: function() {
                return true;
            },

            obtainAuxiliaryData: function() {
                if (!this.options.auxiliaryData) {
                    return;
                }

                if (this.auxiliaryDataStatus) {
                    return;
                }

                this.setAuxiliaryDataStatus("pending");

                var arrayOfDeferred = [];
                var keys = [];

                _.each(this.options.auxiliaryData, function(definition, key) {
                    keys.push(key);
                    arrayOfDeferred.push($.ajax(App.generateAssetURL(definition)));
//                    if (_.isFunction(definition)) {
//                    } else if (_.isString(definition)) {
//                    }
                });
                var _this = this;
                $.when.apply(null, arrayOfDeferred)
                    .then(function() {
                            var auxiliaryData = {};
                            _.each(arguments, function(argument, i) {
                                auxiliaryData[keys[i]] = argument[0];
                            });
                            _this.auxiliaryData = auxiliaryData;
                            _this.setAuxiliaryDataStatus("ready");
                        },
                        function() {
                            _this.setAuxiliaryDataStatus("fail");
                        }
                    );
            },


            verifyAuxiliaryResources: function() {
                var status = this.getAuxiliaryResourcesStatus();
                if (status == "pending" || status == "fail") {
                    throw new RepresentationModule.Error({type: "auxiliary-resources_" + status, derivedDataToUpdate: "base"});
                }
            },


            getViewName: function(viewConfig) {
                // the names are obtained from the templates that contain feature pickers
                if (!App._cachedViewNamesByViewMasterId) {
                    var master = this;
                    App._cachedViewNamesByViewMasterId = {};
                    _.each(["collection", "recording"], function(configGridType) {
                        var $featureSelector = $(Marionette.TemplateCache.get("#cgpma_" + configGridType + "_view__feature-selector")());
                        var autocompleteSuggestions = master.parseAutocompleteSuggestions($featureSelector.find("[data-autocomplete-suggestions]").data("autocomplete-suggestions"));
                        _.each(autocompleteSuggestions, function(kindName, kind) {
                            var masterIdPart = kind;
                            if (!masterIdPart) {
                                masterIdPart = "default";
                            }
                            App._cachedViewNamesByViewMasterId["view." + configGridType + "." + masterIdPart] = kindName;
                        });
                    });
                }
                var viewName = App._cachedViewNamesByViewMasterId[this.id];

                if (!viewName) {
                    viewName = _.str.trim(viewConfig.getParameterValue("kind")) || "an empty view";
                    if (viewName.length >= 4 && viewName.substring(0, 2) == "__" && viewName.substring(viewName.length - 2) == "__") {
                        viewName = viewName.substring(2, viewName.length - 2);
                    }
                    viewName = _.str.trim(viewName);
                }

                return viewName;
            },


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


            // FIXME Bug:
            // When a user changes the view kind, then modifies some parameters
            // and then returns back to the original view kind, there are still
            // pending changes, but no fields are "grey"


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


            prepareConfigGridPanelMainArea: function(configGridPanelView) {

                // feature selector
                if (!App._cached$viewPanelFeatureSelectorsByConfigGridType) {
                    App._cached$viewPanelFeatureSelectorsByConfigGridType = {};
                    _.each(["collection", "recording"], function(configGridType) {
                         var $featureSelector = $(Marionette.TemplateCache.get("#cgpma_" + configGridType + "_view__feature-selector")());
                         App._cached$viewPanelFeatureSelectorsByConfigGridType[configGridType] = $featureSelector;
                    });
                };

                var $featureSelector = App._cached$viewPanelFeatureSelectorsByConfigGridType[configGridPanelView.options.configGrid.getType()];
                configGridPanelView._$mainArea.data("$featureSelector", $featureSelector);
                configGridPanelView._$mainArea.prepend($featureSelector);
                var $inputForKind = $featureSelector.find("[data-parameter-name=kind]");
                if ($inputForKind.data("cgpma-textfield") && $featureSelector.data("savedTextRange")) {
                    $inputForKind.textfield("setTextRange", $featureSelector.data("savedTextRange"));
                    $featureSelector.removeData("savedTextRange");
                }

                // Parent master's behaviour
                RepresentationModule.getMasterById("_").prepareConfigGridPanelMainArea.apply(this, arguments);
            },


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


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

            destroyConfigGridPanelMainArea: function(configGridPanelView) {
                // save the feature selector
                var $featureSelector = configGridPanelView._$mainArea.data("$featureSelector");
                if ($featureSelector) {
                    var $inputForKind = configGridPanelView._$mainArea.find("[data-parameter-name=kind]");
                    if ($inputForKind.textfield("isFocused")) {
                        $featureSelector.data("savedTextRange", $inputForKind.textfield("getTextRange"));
                    }
                    $featureSelector.detach();
                }
            },


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

            _doRenderHeaderContentRelatedToOwnData: function(headerView, instant) {
                if (!headerView._$label) {
                    headerView._$label = $.bem.generateElement("config-grid-cells", "view-header-label").appendTo(headerView.$el);
                }
                headerView._$label.html(this._generateHeaderLabel(headerView));
            },


            _generateHeaderLabel: function(headerView) {
                var labelCore = this.getViewName(headerView.options.config) + this._generateHeaderLabelSuffix(headerView);
                if (headerView.options.config.hasPlannedParameterUpdates()) {
                    return "<span class=\"config-grid-cells__view-header-label-part_modified\">" + labelCore + "</span> – being modified";
                } else {
                    return labelCore;
                }
            },

            _generateHeaderLabelSuffix: function(headerView) {
                return "";
            },




            // =================================================================
            // dynamic derived config data

            __upateMethodOfDynamicDerivedConfigData: function() {
                var viewConfig = this.options.viewConfig;
                var viewMaster = this.options.viewMaster;
                this.set({
                    basePerspectiveRequestParams: viewMaster.generateBasePerspectiveRequestParams(viewConfig),
                    overlayPerspectiveRequestParams: viewMaster.generateOverlayPerspectiveRequestParams(viewConfig)
                });
            },

            generateDynamicDerivedConfigData: function(config, configGrid) {
                var dynamicDerivedConfigData = new RepresentationModule.DynamicDerivedConfigData({
                    basePerspectiveRequestParams: null,
                    overlayPerspectiveRequestParams: null
                }, {
                    viewConfig: config,
                    viewMaster: RepresentationModule.getMasterForConfig(config),
                });

                dynamicDerivedConfigData.update = this.__upateMethodOfDynamicDerivedConfigData;
                dynamicDerivedConfigData.listenTo(config, "change", dynamicDerivedConfigData.update);
                dynamicDerivedConfigData.update();

                return dynamicDerivedConfigData;
            },


            // =================================================================
            // dynamic derived vis instance data


            // -----------------------------------------------------------------
            // dynamic derived vis instance data - base

            generateBasePerspectiveRequestParams: function(viewConfig) {
                var viewConfigKind =  _.str.trim(viewConfig.getParameterValue("kind"));
                if (!_.isString(viewConfigKind) || this.getSupportedKind() != viewConfigKind) {
                    return null;
                }
                var result = this._generateCustomParamsForBasePerspectiveRequestParams(viewConfig);
                if (!result) {
                    return null;
                }
                if (!result.pid) {
                    result.pid = viewConfigKind.replace(/-/g, "_");
                }
                return result;
            },

            _generateCustomParamsForBasePerspectiveRequestParams: function(viewConfig) {
                return {};
            },


            // -----------------------------------------------------------------
            // dynamic derived vis instance data - overlay

            generateOverlayPerspectiveRequestParams: function(viewConfig) {
            },


            // =================================================================
            // vis instance rendering


            _groupDataForGraphicsRendering: function(visInstanceView, layer) {
                if (layer == "base") {
                    return {
                        self:  visInstanceView.dynamicDerivedVisInstanceDataForBase.attributes.apiResponse,
                        left:  visInstanceView.dynamicDerivedVisInstanceDataForBase.attributes.apiResponseOnTheLeft,
                        right: visInstanceView.dynamicDerivedVisInstanceDataForBase.attributes.apiResponseOnTheRight
                    };
                } else {
                    return null;
                }
            },

            _getVisInstanceViewComparisonMode: function(visInstanceView) {
                var comparisonMode = undefined;
                var kind = visInstanceView.options.entityConfig.getParameterValue("kind");
                if (kind === "pair") {
                    comparisonMode = RepresentationModule.getMasterById("entity.collection.pair").getConfigParameterValueOrDefaultValue(visInstanceView.options.entityConfig, "comparisonMode");
                }
                return comparisonMode;
            },

            calculateVisInstanceContentHeight: function(viewConfig, entityWidth) {
                var height = 0;

                var widthToHeightRatio = 1 * this.getConfigParameterValueOrDefaultValue(viewConfig, "widthToHeightRatio");
                if (widthToHeightRatio) {
                    height = Math.round(entityWidth / widthToHeightRatio);
                }
                if (height < this.options.visInstanceContentHeightMin) {
                    height = this.options.visInstanceContentHeightMin;
                }
                if (height > this.options.visInstanceContentHeightMax) {
                    height = this.options.visInstanceContentHeightMax;
                }
                return height + this.options.visInstanceContentPaddingTop + this.options.visInstanceContentPaddingBottom;
            },


            __domEventHandlerToSelectAllTextInTheField: function(event) {
                if (!event.shiftKey) {
                    return;
                }
                var $cover = $(this);
                var visInstanceView = $cover.data("visInstanceView");
                var attachedError = $cover.data("attachedError");
                RepresentationModule.logger.warn(_.str.sprintf("An error behind the clicked vis instance (id %s):", visInstanceView.cid), attachedError);
            },


            renderVisInstance: function(visInstanceView, deep, instant) {
                if (deep) {
                    visInstanceView._cachedRenderingHashForBase = undefined;
                    visInstanceView._cachedRenderingHashForOverlay = undefined;
                    visInstanceView._cachedRenderingHashForTemp = undefined;
                }

                var newRenderingHashForBase    = /*!this.options.canHaveBase  ||*/ this._calculateVisInstanceRenderingHashForBase(visInstanceView);
                var newRenderingHashForOverlay = !this.options.canHaveOverlay ||   this._calculateVisInstanceRenderingHashForOverlay(visInstanceView);
                var newRenderingHashForTemp    = !this.options.canHaveTemp    ||   this._calculateVisInstanceRenderingHashForTemp(visInstanceView);

                var baseHasChanged    = /*this.options.canHaveBase    && */ newRenderingHashForBase !== visInstanceView._cachedRenderingHashForBase;
                var overlayHasChanged = /*this.options.canHaveOverlay && */ newRenderingHashForOverlay !== visInstanceView._cachedRenderingHashForOverlay;
                var tempHasChanged    = /*this.options.hasTemp        && */ newRenderingHashForTemp    !== visInstanceView._cachedRenderingHashForTemp;

                var debugMode = App.options.debugAPI;

                if (!(baseHasChanged || overlayHasChanged || tempHasChanged)) {
                    return;
                }

                try {
                    if (baseHasChanged) {
                        try {
                            if (debugMode) {
                                this._prepareRenderingVisInstanceViewInDebugModeIfNeeded(visInstanceView);
                                this._doRenderVisInstanceViewInDebugMode(visInstanceView, "base");
                            } else {
                                visInstanceView._cachedEntityMaster.verifyAllDataForVisInstanceBase(visInstanceView);
                                visInstanceView._cachedViewMaster.verifyAuxiliaryResources();
                                this._prepareRenderingVisInstanceViewIfNeeded(visInstanceView);
                                this._doRenderVisInstanceViewBase(visInstanceView);
                            }

                        } catch (e) {
                            visInstanceView._cachedRenderingHashForOverlay = undefined;
                            visInstanceView._cachedRenderingHashForTemp = undefined;
                            overlayHasChanged = true;
                            tempHasChanged = true;
                            throw e;
                        }
                    }
                    if (overlayHasChanged) {
                        try {
                            if (debugMode) {
                                this._doRenderVisInstanceViewInDebugMode(visInstanceView, "overlay");
                            } else {
                                if (!baseHasChanged) {
                                    visInstanceView._cachedEntityMaster.verifyAllDataForVisInstanceBase(visInstanceView);
                                }
                                visInstanceView._cachedEntityMaster.verifyAllDataForVisInstanceOverlay(visInstanceView);
                                this._doRenderVisInstanceViewOverlay(visInstanceView);
                            }
                        } catch (e) {
                            visInstanceView._cachedRenderingHashForTemp = undefined;
                            tempHasChanged = true;
                            throw e;
                        }
                    }
                    if (tempHasChanged) {
                        if (debugMode) {
                            this._doRenderVisInstanceViewInDebugMode(visInstanceView, "temp");
                        } else {
                            if (!baseHasChanged) {
                                visInstanceView._cachedEntityMaster.verifyAllDataForVisInstanceBase(visInstanceView);
                            }
                            if (!overlayHasChanged) {
                                visInstanceView._cachedEntityMaster.verifyAllDataForVisInstanceOverlay(visInstanceView);
                            }
                            this._doRenderVisInstanceViewTemp(visInstanceView);
                        }
                    }
                    if (visInstanceView.$cover.hasClass("vis-instance__cover_visible")) {
                        visInstanceView.$cover.removeClass("vis-instance__cover_visible");
                    };
                } catch (e) {
                    var errorType = (e instanceof RepresentationModule.Error) ? e.options.type : "unknown";
                    var coverTapAction = (e instanceof RepresentationModule.Error) ? e.options.coverTapAction : null;

                    var coverContentTemplate = null;
                    try {
                        coverContentTemplate = Marionette.TemplateCache.get("#vicc__" + errorType + "__" + visInstanceView._cachedEntityMaster.id.replace(/\./g, "-"));
                    } catch (e) {
                        coverContentTemplate = Marionette.TemplateCache.get("#vicc__" + errorType);
                    }
                    var coverContent = coverContentTemplate(e.options);

                    var coverCategory = coverContent.slice(0, coverContent.indexOf("|"));
                    var coverMessage = coverContent.slice(coverCategory.length + 1);

                    if (!(e instanceof RepresentationModule.Error) || e.needToEmptyContent()) {
                        visInstanceView.$content.empty();
                    };

                    visInstanceView.$coverMessage.html(coverMessage);
                    visInstanceView.$cover
                        .addClass("vis-instance__cover_visible")
                        .unbind("click")
                        .bind("click", coverTapAction)
                        .bind("click", this.__domEventHandlerToSelectAllTextInTheField)
                        .setMod("vis-instance", "cover", "category", coverCategory)
                        .data("attachedError", e)
                        .data("visInstanceView", visInstanceView);
                }
                if (baseHasChanged)    {visInstanceView._cachedRenderingHashForBase    = newRenderingHashForBase;}
                if (overlayHasChanged) {visInstanceView._cachedRenderingHashForOverlay = newRenderingHashForBase;}
                if (tempHasChanged)    {visInstanceView._cachedRenderingHashForTemp    = newRenderingHashForBase;}
            },


            cancelVisInstancePointerHighlights: function(visInstanceView) {
                var vegaHoveredItem = visInstanceView.$content.children(0).data("vegaHoveredItem");
                if (vegaHoveredItem) {
                    App.TooltipModule.tooltipView.update();
                    var vegaObj = visInstanceView.$content.children(0).data("vegaObj");
                    vegaObj.update({items: vegaHoveredItem})
                }

            },


            // -----------------------------------------------------------------
            // vis instance rendering - base

            _calculateVisInstanceRenderingHashForBase: function(visInstanceView) {
                if (visInstanceView.options.configGrid.getType() == "collection") {
                    if (this._getVisInstanceViewComparisonMode(visInstanceView)) {
                        var result = this.getAuxiliaryResourcesStatus()
                            + visInstanceView._cachedSizeHash
                            + visInstanceView.options.entityConfig.getHashForTrimmedParameters()
                            + visInstanceView.options.viewConfig.getHashForTrimmedParameters()
                            + visInstanceView.dynamicDerivedConfigDataForEntity.getHash()
                            + visInstanceView.dynamicDerivedConfigDataForView.getHash()
                            + visInstanceView.dynamicDerivedVisInstanceDataForBase.getHash();
                        //console.log(result);
                        return result;
                    } else {
                        return  this.getAuxiliaryResourcesStatus()
                            + visInstanceView._cachedSizeHash
                            + visInstanceView.options.viewConfig.getHashForTrimmedParameters()
                            + visInstanceView.dynamicDerivedConfigDataForEntity.attributes.dynamicDefinitionForCollection.getHash()
                            + visInstanceView.dynamicDerivedConfigDataForView.getHash()
                            + visInstanceView.dynamicDerivedVisInstanceDataForBase.getHash();
                    }
                } else {
                    if (this._getVisInstanceViewComparisonMode(visInstanceView)) {
                        var result = this.getAuxiliaryResourcesStatus()
                            + visInstanceView._cachedSizeHash
                            + visInstanceView.options.entityConfig.getHashForTrimmedParameters()
                            + visInstanceView.options.viewConfig.getHashForTrimmedParameters()
                            + visInstanceView.dynamicDerivedConfigDataForEntity.getHash()
                            + visInstanceView.dynamicDerivedConfigDataForView.getHash()
                            + visInstanceView.dynamicDerivedVisInstanceDataForBase.getHash();
                        //console.log(result);
                        return result;
                    } else {
                        return  this.getAuxiliaryResourcesStatus()
                            + visInstanceView._cachedSizeHash
                            + visInstanceView.options.viewConfig.getHashForTrimmedParameters()
                            + visInstanceView.dynamicDerivedConfigDataForEntity.attributes.dynamicDefinitionForRecording.getHash()
                            + visInstanceView.dynamicDerivedConfigDataForView.getHash()
                            + visInstanceView.dynamicDerivedVisInstanceDataForBase.getHash();
                    }
                }
            },


            _prepareRenderingVisInstanceViewIfNeeded: function(visInstanceView) {},


            _doRenderVisInstanceViewBase: function(visInstanceView) {
                this._doRenderVisInstanceViewBaseWithKnownComparisonMode(visInstanceView, this._getVisInstanceViewComparisonMode(visInstanceView));
            },


            _doRenderVisInstanceViewBaseWithKnownComparisonMode: function(visInstanceView, comparisonMode) {},


            // -----------------------------------------------------------------
            // vis instance rendering - overlay

            _calculateVisInstanceRenderingHashForOverlay: function(visInstanceView) {
                return visInstanceView._cachedSizeHash
                    + visInstanceView.options.viewConfig.getHashForTrimmedParameters()
                    + visInstanceView.dynamicDerivedConfigDataForEntity.getHash()
                    + visInstanceView.dynamicDerivedConfigDataForView.getHash()
                    + visInstanceView.dynamicDerivedVisInstanceDataForOverlay.getHash();
            },


            _doRenderVisInstanceViewOverlay: function(visInstanceView) {
                this._doRenderVisInstanceViewOverlayWithKnownComparisonMode(visInstanceView, this._getVisInstanceViewComparisonMode(visInstanceView));
            },


            _doRenderVisInstanceViewOverlayWithKnownComparisonMode: function(visInstanceView, comparisonMode) {},


            // -----------------------------------------------------------------
            // vis instance rendering - temp

            _calculateVisInstanceRenderingHashForTemp: function(visInstanceView) {
                return visInstanceView._cachedSizeHash
                    + visInstanceView.options.viewConfig.getHashForParameters()
                    + visInstanceView.dynamicDerivedConfigDataForEntity.getHash()
                    + visInstanceView.dynamicDerivedConfigDataForView.getHash()
                    + visInstanceView.dynamicDerivedVisInstanceDataForTemp.getHash();
            },


            _doRenderVisInstanceViewTemp: function(visInstanceView) {
                this._doRenderVisInstanceViewTempWithKnownComparisonMode(visInstanceView, this._getVisInstanceViewComparisonMode(visInstanceView));
            },


            _doRenderVisInstanceViewTempWithKnownComparisonMode: function(visInstanceView, comparisonMode) {},


            // -----------------------------------------------------------------
            // vis instance rendering - debug mode

            _selectAllInDebugTextFieldIfNeeded: function() {
                $(this).select();
            },


            _prepareRenderingVisInstanceViewInDebugModeIfNeeded: function(visInstanceView) {
                if (!visInstanceView.$content.children(0).hasClass("vic-api-debug")) {
                    visInstanceView.$content.empty();
                    var $apiDebug = $.bem.generateBlock("vic-api-debug");
                    var mappings = visInstanceView._cachedEntityMaster._mapDerivedVisInstanceDataAttributesToDebugAPIQueryBoxes(this);
                    for (var i = 0; i < mappings.length; i++) {
                        var $queryBox = $.bem.generateElement("vic-api-debug", "query-box", ["alignment_" + mappings[i][0]]);

                        var $queryURIWrapper = $.bem.generateElement("vic-api-debug", "query-uri-wrapper");
                        var $queryResponseWrapper = $.bem.generateElement("vic-api-debug", "query-response-wrapper");

                        var $queryURI = $.bem.generateElement("input", "vic-api-debug", "query-uri").attr("type", "text")
                            .mouseup(this._avoidDeselectInDebugTextField)
                            .focus(this._selectAllInDebugTextFieldIfNeeded)
                            .attr("readonly", true);
                        var $queryResponse = $.bem.generateElement("textarea", "vic-api-debug", "query-response")
                            .attr("readonly", true);

                        $queryURIWrapper.append($queryURI);
                        $queryResponseWrapper.append($queryResponse);
                        $queryBox.append($queryURIWrapper, $queryResponseWrapper);
                        $apiDebug.append($queryBox);
                    }
                    $apiDebug.data("mappings", mappings);
                    visInstanceView.$content.append($apiDebug);
                }
            },


            _doRenderVisInstanceViewInDebugMode: function(visInstanceView, layer) {
                var $apiDebug = visInstanceView.$content.children(0);
                var mappings = $apiDebug.data("mappings");
                for (var i = 0; i < mappings.length; i++) {
                    var mapping = mappings[i];
                    if (layer != mapping[1]) {
                        return;
                    }
                    var currentDynamicDerivedVisInstanceData = null;
                    switch (layer) {
                    case "base":
                        currentDynamicDerivedVisInstanceData = visInstanceView.dynamicDerivedVisInstanceDataForBase;
                        break;
                    case "overlay":
                        currentDynamicDerivedVisInstanceData = visInstanceView.dynamicDerivedVisInstanceDataForOverlay;
                        break;
                    case "temp":
                        currentDynamicDerivedVisInstanceData = visInstanceView.dynamicDerivedVisInstanceDataForTemp;
                        break;
                    }

                    var $queryBox      = $apiDebug.children().eq(i);
                    var $queryURI      = $queryBox.children().eq(0).children();
                    var $queryResponse = $queryBox.children().eq(1).children();

                    var queryURI      = currentDynamicDerivedVisInstanceData.attributes[mapping[2]];
                    var queryResponse = currentDynamicDerivedVisInstanceData.attributes[mapping[3]];

                    var queryURIText = queryURI;
                    if (_.isString(queryURI) && queryURI.indexOf("//") === 0) {
                        var protocol = window.location.href.slice(0, window.location.href.indexOf(":"));
                        queryURIText = protocol + ":" + queryURIText;
                    }

                    var queryResponseText = "";
                    if (_.isObject(queryResponse)) {
                        queryResponseText = JSON.stringify(queryResponse, false, "    ");
                    } else if (queryResponse === null) {
                        queryResponseText = "obtaining...";
                    } else {
                        //queryResponseText =
                        //no request is being made
                    }
                    var status = "ok";
                    if (queryResponse && queryResponse.errors) {
                        status = "has-errors";
                    }


                    $queryURI.val(queryURIText);
                    $queryResponse.val(queryResponseText);
                    $queryBox.setMod("vic-api-debug", "query-box", "status", status);
                }
            },
        });
    });
}, Logger);
