"use strict";

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

    RepresentationModule.addInitializer(function(options){

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

            options: {
                canHaveBase: true,
                canHaveOverlay: true,
                canHaveTemp: false,
                flyingCircleSpeedMin: 200,
                flyingCircleSpeedMax: 500,
                flyingCircleDistanceForMaxSpeed: 500,

                rowHeight: 15
            },

            defaultConfigParameterValues: {
                limit: 10,
                offset: 0,
                sortBy: "label",
                widthToHeightRatio: undefined
            },

            _cachedMusicRecordingsButtonRight: null,
            _cachedMusicRecordingsButtonTop: null,


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

            _generateHeaderLabelSuffix: function(headerView) {
                return "";
                //return _.str.sprintf(" (up to %s)", this.getConfigParameterValueOrDefaultValue(headerView.options.config, "limit"));
            },


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


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

            __upateMethodOfDynamicDerivedVisInstanceDataForOverlay: function(force) {
                this.set({
                    recordingURI:  this.options.entityConfigForCollection.getParameterValue("recordingURI"),
                    recordingURIs: this.options.entityConfigsForRecordings.map(function(entityConfigForRecording) {
                            return entityConfigForRecording.getParameterValue("recordingURI");
                        })
                });
            },


            generateDynamicDerivedVisInstanceDataForOverlay: function(visInstanceView) {
                if (this._getVisInstanceViewComparisonMode(visInstanceView)) {
                    return new RepresentationModule.DynamicDerivedVisInstanceData();
                }

                var optionsForThisDynamicDerivedVisInstanceDataForOverlay = {};
                optionsForThisDynamicDerivedVisInstanceDataForOverlay.entityConfigForCollection = visInstanceView.options.entityConfig;
                optionsForThisDynamicDerivedVisInstanceDataForOverlay.entityConfigsForRecordings = visInstanceView.options.state.get("musicRecordingGrid").get("entityConfigs");

                var dynamicDerivedVisInstanceDataForOverlay = new RepresentationModule.DynamicDerivedVisInstanceData({
                    recordingURI:  undefined,
                    recordingURIs: [],
                }, optionsForThisDynamicDerivedVisInstanceDataForOverlay);

                dynamicDerivedVisInstanceDataForOverlay.update = this.__upateMethodOfDynamicDerivedVisInstanceDataForOverlay;

                dynamicDerivedVisInstanceDataForOverlay.listenTo(optionsForThisDynamicDerivedVisInstanceDataForOverlay.entityConfigForCollection, "change:properties", dynamicDerivedVisInstanceDataForOverlay.update);
                dynamicDerivedVisInstanceDataForOverlay.listenTo(visInstanceView.options.state.get("musicRecordingGrid"), "change", dynamicDerivedVisInstanceDataForOverlay.update);

                dynamicDerivedVisInstanceDataForOverlay.update();

                return dynamicDerivedVisInstanceDataForOverlay;

            },


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

            calculateVisInstanceContentHeight: function(viewConfig, entityWidth) {
                var fixedLimit = Math.max(0, 1 * this.getConfigParameterValueOrDefaultValue(viewConfig, "limit"));
                if (!(fixedLimit > 0 && Math.floor(fixedLimit) === +fixedLimit)) {
                    fixedLimit = 0;
                }
                return fixedLimit * this.options.rowHeight
                        + this.options.visInstanceContentPaddingTop
                        + this.options.visInstanceContentPaddingBottom;
            },


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

            _generateCustomParamsForBasePerspectiveRequestParams: function(viewConfig) {
                var result = {
                        "limit":   this.getConfigParameterValueOrDefaultValue(viewConfig, "limit", true),
                        "offset":  this.getConfigParameterValueOrDefaultValue(viewConfig, "offset", true),
                        "sort_by": this.getConfigParameterValueOrDefaultValue(viewConfig, "sortBy", true),
                    };
                return result;
            },


            __domEventHandlerToSetSelectedRecording: function() {
                var $this = $(this);
                var visInstanceView = $this.data("visInstanceView");
                var recordingURI = $this.data("recordingURI");
                if (visInstanceView.options.entityConfig.getParameterValue("recordingURI") == recordingURI) {
                    //visInstanceView.options.entityConfig.updateParameter("recordingURI", undefined);
                } else {
                    visInstanceView.options.entityConfig.updateParameter("recordingURI", recordingURI);
                }
            },

            __domEventHandlerToPlayAudio: function(event) {
                var $this = $(this);

//                if (!_.isEventAnAttemptToOpenANewTab(event)) {
                    App.play($this.data("recordingURI"));
                    event.preventDefault();
                    return false;
//                }
            },

            __domEventHandlerToAnalyseRecording: function() {
                var $this = $(this);
                var _this = $this.data("master");
                var recordingURI = $this.parent().data("recordingURI");
                var existingRecordingConfigsByRecordingURI = {};
                var recordingConfigs = App.context.get("state").get("musicRecordingGrid").get("entityConfigs");

                recordingConfigs.each(function(recordingConfig) {
                    existingRecordingConfigsByRecordingURI[recordingConfig.getParameterValue("recordingURI")] = recordingConfig;
                });

                var nowAdding = !existingRecordingConfigsByRecordingURI[recordingURI];
                if (nowAdding) {
                    // add
                    recordingConfigs.add(new App.ContextModule.Config({
                        parameters: {
                            recordingURI: recordingURI
                        }
                    }));
                } else {
                    // remove
                    recordingConfigs.remove(existingRecordingConfigsByRecordingURI[recordingURI]);
                }

                // launch the flying circle
                var $flyingCircle = $.bem.generateElement("vic-list", "flying-circle", [nowAdding ? "type_adding" : "type_removing"]);
                if (!_this._cachedMusicRecordingsButtonRight) {
                    var $modeChanger = $(".main-menu-bar__item_action_change-mode");
                    _this._cachedMusicRecordingsButtonRight = $modeChanger.width() / 2;
                    _this._cachedMusicRecordingsButtonTop = $modeChanger.height() / 2;
                }

                $flyingCircle.appendTo(document.body);
                var initialOffset = $($this[0]).offset();
                var targetOffset = {
                        "left": $(window).width() - _this._cachedMusicRecordingsButtonRight,
                        "top": _this._cachedMusicRecordingsButtonTop,
                    };

                // Flip initial and target if the circle is returning
                if (!nowAdding) {
                    var bubble = initialOffset;
                    initialOffset = targetOffset;
                    targetOffset = bubble;
                };

                $flyingCircle.css(initialOffset);

                var flyingDistance = Math.sqrt(
                        Math.pow(targetOffset.left - initialOffset.left, 2) +
                        Math.pow(targetOffset.top  - initialOffset.top,  2)
                    );
                var speed = (_this.options.flyingCircleSpeedMax - _this.options.flyingCircleSpeedMin)
                          * Math.min(1, flyingDistance / _this.options.flyingCircleDistanceForMaxSpeed)
                          + _this.options.flyingCircleSpeedMin;
                $flyingCircle.animate(targetOffset, speed, _this.__removeFlyingCircleAfterAnimation);

                // show a notification if needed
                var notificationHasBeenShown = App.DataModule.Storage.getStrCache(RepresentationModule, "master_view.collection.list_flying-square-notification-shown");
                if (!notificationHasBeenShown) {
                    App.showNotification({
                        "content": $("#notification-content_flying-circle").html(),
                        "id": "flying-circle",
                        "modifiers": ["ttl_20"]
                    });

                    App.context.get("state").once("change:musicRecordingsGridIsShown", function() {
                        App.hideNotification("flying-circle");
                    });
                    App.DataModule.Storage.setStrCache(RepresentationModule, "master_view.collection.list_flying-square-notification-shown", "1");
                }

                // explicitly remove tooltip
                $this.trigger("mouseup");
            },

            __removeFlyingCircleAfterAnimation: function() {
                $(this).remove();
            },

            _doRenderVisInstanceViewBaseWithKnownComparisonMode: function(visInstanceView, comparisonMode) {
                var _this = this;

                var items = visInstanceView.dynamicDerivedVisInstanceDataForBase.attributes.apiResponse.items;

                var bankOf$analyzeByRecordingURI = {};
                var $list = $.bem.generateBlock("vic-list");
                for (var i = 0; i < items.length; i++) {
                    var item = items[i];
                    var $item = $.bem.generateElement("vic-list", "item")
                        .data("recordingURI", item.uri)
                        .data("visInstanceView", visInstanceView);

                    // Label
                    $.bem.generateElement("vic-list", "item-label")
                        .text(item.label)
                        .appendTo($item);

                    // Year
                    if (item.date) {
                        var year = item.date.indexOf("/") > 0 ? item.date.slice(-4) : item.date.slice(0, 4);
                        $.bem.generateElement("vic-list", "item-year")
                            .text(year)
                            .appendTo($item);
                    }
                    // Audio
                    if (item.audio && item.audio.length) {
                        $.bem.generateElement("span", "vic-list", "item-command", ["action_audio"])
                            //.attr("href", item.audio[0])
                            .data("recordingURI", item.uri)
                            .data("master", _this)
                            .click(this.__domEventHandlerToPlayAudio)
                            .attr("title", "play this recording")
                            .append("<i/>")
                            .appendTo($item);
                    }

                    // Analyze
                    var $analyse = $.bem.generateElement("vic-list", "item-command", ["action_analyze"])
                        .click(this.__domEventHandlerToAnalyseRecording)
                        .attr("title", " ")
                        .data("master", _this)
                        .append("<i/>")
                        .appendTo($item);
                    bankOf$analyzeByRecordingURI[item.uri] = $analyse;

                    $item.click(this.__domEventHandlerToSetSelectedRecording);

                    $list.append($item);
                }

                App.TooltipModule.convertTitlesToTooltips($list);
                $list.data("bankOf$analyzeByRecordingURI", bankOf$analyzeByRecordingURI);
                visInstanceView.$content.empty().append($list);
            },


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

            _calculateVisInstanceRenderingHashForOverlay: function(visInstanceView) {
                return visInstanceView._cachedSizeHash
                    //+ visInstanceView.options.viewConfig.getHashForParameters()
                    //+ visInstanceView.dynamicDerivedConfigDataForEntity.getHash()
                    //+ visInstanceView.dynamicDerivedConfigDataForView.getHash()
                      + visInstanceView.dynamicDerivedVisInstanceDataForOverlay.getHash();
//
//
//                return visInstanceView.options.entityConfig.getParameterValue("recordingURI")
//                + App.context
//                    .attributes.state
//                    .attributes.musicRecordingGrid
//                    .attributes.entityConfigs
//                    .length;
            },

            _doRenderVisInstanceViewOverlayWithKnownComparisonMode: function(visInstanceView, comparisonMode) {
                var recordingURI = visInstanceView.options.entityConfig.getParameterValue("recordingURI");
                visInstanceView.$content.children(0).children().each(function() {
                    var $listItem = $(this);
                    var listItemRecordingURI = $listItem.data("recordingURI");
                    $listItem.toggleClass("vic-list__item_status_selected", recordingURI == listItemRecordingURI);
                });

                var existingRecordingConfigsByRecordingURI = {};
                var recordingConfigs = App.context.get("state").get("musicRecordingGrid").get("entityConfigs");

                recordingConfigs.each(function(recordingConfig) {
                    existingRecordingConfigsByRecordingURI[recordingConfig.getParameterValue("recordingURI")] = recordingConfig;
                });

                var bankOf$analyzeByRecordingURI = visInstanceView.$content.children(0).data("bankOf$analyzeByRecordingURI");

                _.each(bankOf$analyzeByRecordingURI, function($analyze, recordingURI) {
                    var exists = !! existingRecordingConfigsByRecordingURI[recordingURI];
                    $analyze.toggleClass("vic-list__item-command_status_toggled", exists);
                    $analyze.attr("tooltip-title", exists ? "remove this recording from the ‘music recordings’ grid" : "add this recording to the ‘music recordings’ grid");

                });
            },
        });
    });
}, Logger);
