"use strict";

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

    RepresentationModule.addInitializer(function(options){

        RepresentationModule.registerMaster({
            id: "entity.recording.default",
            inherit: "entity._default",


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

            __domEventHandlerToPlayAudio: function() {
                var $this = $(this);
                App.play($this.data("uri"));
            },

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

            prepareConfigGridPanelMainArea: function(configGridPanelView) {
                var $audioLink = configGridPanelView._$mainArea.find(".cgpma__pseudo-link_action_audio");
                configGridPanelView._$mainArea.data("$audioLink", $audioLink);
                $audioLink.click(this.__domEventHandlerToPlayAudio);

                var $affiliationAudio = configGridPanelView._$mainArea.find(".cgpma__element_affiliation_audio");
                var $affiliationNoAudio = configGridPanelView._$mainArea.find(".cgpma__element_affiliation_no-audio");
                configGridPanelView._$mainArea.data("$affiliationAudio", $affiliationAudio);
                configGridPanelView._$mainArea.data("$affiliationNoAudio", $affiliationNoAudio);
            },


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

            syncConfigGridPanelMainArea: function(configGridPanelView, instant) {
                var recordingAttributes = configGridPanelView._cachedDynamicDerivedConfigData.attributes.dynamicDefinitionForRecording.attributes;
                if (!recordingAttributes.label) {
                    configGridPanelView._$mainArea.data("$affiliationAudio").hide();
                    configGridPanelView._$mainArea.data("$affiliationNoAudio").hide();
                } else {
                    if (recordingAttributes.audio) {
                        configGridPanelView._$mainArea.data("$affiliationAudio").show();
                        configGridPanelView._$mainArea.data("$affiliationNoAudio").hide();
                        configGridPanelView._$mainArea.data("$audioLink").data("uri", configGridPanelView._cachedConfig.getParameterValue("recordingURI"));
                    } else {
                        configGridPanelView._$mainArea.data("$affiliationAudio").hide();
                        configGridPanelView._$mainArea.data("$affiliationNoAudio").show();
                    };
                }
            },



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

            _generateHeaderLabel1: function(viewHeader) {
                var rawConfigParameters = viewHeader.options.config.attributes.parameters.attributes;
                var attributesOfDefinitionForOverlayedRecording = viewHeader.dynamicDerivedConfigData.attributes.dynamicDefinitionForRecording.attributes;
                var labelParts = [];

                var recordingURI = rawConfigParameters.recordingURI;
                if (recordingURI) {
                    var label = attributesOfDefinitionForOverlayedRecording.label;
                    if (_.isString(label)) {
                        labelParts.push(label);
                    } else if (label === null) {
                        labelParts.push("updating label...");
                    } else {
                        labelParts.push("could not get recording label");
                    }
                } else {
                    labelParts.push("no recording selected");
                }

                return labelParts.join("");
            },

            _generateHeaderLabel2: function(viewHeader) {
                var attributesOfDefinitionForOverlayedRecording = viewHeader.dynamicDerivedConfigData.attributes.dynamicDefinitionForRecording.attributes;
                var labelParts = [];

                if (attributesOfDefinitionForOverlayedRecording.composer && attributesOfDefinitionForOverlayedRecording.composer.length) {
                    labelParts.push("composed by ", attributesOfDefinitionForOverlayedRecording.composer[0]);
                }
                return labelParts.join("");
            },


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

            __upateMethodOfDynamicDerivedConfigData: function() {
                if (this.attributes.dynamicDefinitionForRecording.attributes.errors) {
                    this.attributes.dynamicDefinitionForRecording.update(true);
                }
            },

            generateDynamicDerivedConfigData: function(config, configGrid) {
                var dynamicDefinitionForRecording         = App.dynamicDefinitionProviderForRecordings.get(config);

                var dynamicDerivedConfigData = new RepresentationModule.DynamicDerivedConfigData({
                    dynamicDefinitionForRecording: dynamicDefinitionForRecording,
                });

                dynamicDerivedConfigData.listenTo(dynamicDefinitionForRecording, "change", function() {
                    dynamicDerivedConfigData.trigger("change:dynamicDefinitionForRecording");
                    dynamicDerivedConfigData.trigger("change");
                });

                dynamicDerivedConfigData.update = this.__upateMethodOfDynamicDerivedConfigData;

                return dynamicDerivedConfigData;
            },


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


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

            __optionsOfDynamicDerivedVisInstanceDataForBase: {
                attributesToExcludeFromHash: ["apiResponse"],
                customHashSuffixGenerator: function (attributes) {
                    if (attributes.apiResponse) {
                        return JSON.stringify(attributes.apiResponse.errors);
                    } else {
                        return typeof attributes.apiResponse;
                    }
                }
            },


            __upateMethodOfDynamicDerivedVisInstanceDataForBase: function(force) {
                var visInstanceView = this.options.visInstanceView;
                var dynamicDefinitionForRecording = visInstanceView.dynamicDerivedConfigDataForEntity.attributes.dynamicDefinitionForRecording;
                var entityConfig = visInstanceView.options.entityConfig;
                if (!dynamicDefinitionForRecording) { // entity kind has changed (e.g. a grid was reset)
                    return;
                }
                if (this.attributes.apiResponse !== null) { // null = waiting
                    var recordingLabel = dynamicDefinitionForRecording.attributes.label;
                    if (recordingLabel === undefined) {
                        this.set({
                            apiRequestURI:        undefined,
                            apiRequestParamsHash: undefined,
                            apiResponse:          undefined
                        });
                        return;
                    }

                    var requestParams = _.clone(visInstanceView.dynamicDerivedConfigDataForView.attributes.basePerspectiveRequestParams);
                    if (!requestParams) {
                        return;
                    }
                    requestParams.uri = entityConfig.attributes.parameters.attributes.recordingURI;

                    var apiRequestParamsHash = JSON.stringify(requestParams);
                    if (!force && apiRequestParamsHash == this.attributes.apiRequestParamsHash) {
                        return;
                    }

                    var _this = this;
                    var apiRequestURI = App.DataModule.CliopatriaAPI.request("getRecordingPerspective", requestParams, function(data){
                        if (JSON.stringify(requestParams) != _this.attributes.apiRequestParamsHash) {
                            return;
                        }
                        _this.set({
                            apiRequestParamsHash: undefined,
                            apiResponse: data
                        });
                    });

                    this.set({
                        apiRequestURI: apiRequestURI,
                        apiRequestParamsHash: apiRequestParamsHash,
                        apiResponse: null
                    });
                }
            },


            generateDynamicDerivedVisInstanceDataForBase: function(visInstanceView) {
                var optionsOfThisDynamicDerivedVisInstanceDataForBase = _.clone(this.__optionsOfDynamicDerivedVisInstanceDataForBase);
                optionsOfThisDynamicDerivedVisInstanceDataForBase.visInstanceView = visInstanceView;

                var dynamicDerivedVisInstanceDataForBase = new RepresentationModule.DynamicDerivedVisInstanceData({
                    apiRequestURI:        undefined,
                    apiRequestParamsHash: undefined,
                    apiResponse:          undefined
                }, optionsOfThisDynamicDerivedVisInstanceDataForBase);

                dynamicDerivedVisInstanceDataForBase.update = this.__upateMethodOfDynamicDerivedVisInstanceDataForBase;

                dynamicDerivedVisInstanceDataForBase.listenTo(visInstanceView.dynamicDerivedConfigDataForEntity, "change:dynamicDefinitionForRecording", dynamicDerivedVisInstanceDataForBase.update);
                dynamicDerivedVisInstanceDataForBase.listenTo(visInstanceView.dynamicDerivedConfigDataForView, "change:basePerspectiveRequestParams", dynamicDerivedVisInstanceDataForBase.update);

                dynamicDerivedVisInstanceDataForBase.update();

                return dynamicDerivedVisInstanceDataForBase;
            },


            verifyAllDataForVisInstanceBase: function(visInstanceView) {
                this._verifyThatViewIsNotEmptyOrUnknown(visInstanceView);

                var attributesOfDerivedConfigDataForEntity = visInstanceView.dynamicDerivedConfigDataForEntity.attributes;
                var dynamicDefinitionForRecording = attributesOfDerivedConfigDataForEntity.dynamicDefinitionForRecording;
                var attributesOfRecording = dynamicDefinitionForRecording ? dynamicDefinitionForRecording.attributes : {};
                var attributesOfEntityConfig = visInstanceView.options.entityConfig.attributes.parameters.attributes;

                if (!attributesOfEntityConfig.recordingURI) {
                    throw new RepresentationModule.Error({type: "recording_undefined"});
                }
                if (attributesOfRecording.label === undefined) {
                    throw new RepresentationModule.Error({type: "api-error_entity-derived", apiErrors: attributesOfRecording.errors, coverTapAction: this.__coverTapActionThatUpdatesDynamicDerivedData, derivedDataToUpdate: "entity"});
                }

                var attribytesOfDerivedVisInstanceDataForBase = visInstanceView.dynamicDerivedVisInstanceDataForBase.attributes;
                if (!attribytesOfDerivedVisInstanceDataForBase.apiResponse) {
                    throw new RepresentationModule.Error({type: "data-preparing_base"});
                }
                if (attribytesOfDerivedVisInstanceDataForBase.apiResponse.errors) {
                    throw new RepresentationModule.Error({type: "api-error_base", apiErrors: attribytesOfDerivedVisInstanceDataForBase.apiResponse.errors, coverTapAction: this.__coverTapActionThatUpdatesDynamicDerivedData, derivedDataToUpdate: "base"});
                }
            }
        });
    });
}, Logger);
