"use strict";

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

    GraphicsRenderingModule.addInitializer(function(options) {

        GraphicsRenderingModule.registerRenderer({
            id : "chord-seq._",
            inherit: "_",

            defaultVegaConfig: {
                modesOfPiece: [undefined, "major", "minor"],
                relativeRootNotes: _.range(1, 13),
                relativeRootNotesInMajor: ["I","#I","II","#II","III","IV","#IV","V","#V","VI","#VI","VII"],
                relativeRootNotesInMinor: ['I','#I','II','III','#III','IV','#IV','V','VI','#VI','VII','#VII'],
                chordTypes:      ["", "6", "7", "m", "m6", "m7", "maj7", "m7b5", "dim", "dim7", "aug"],
                chordTypesWithM: ["M", "6", "7", "m", "m6", "m7", "maj7", "m7b5", "dim", "dim7", "aug"],
                //baseLabels: ["1","","2","b3","3","4","","5","","6","b7","7"],

                sequenceOfUsedRootNotes:   _.range(12),
                sequenceOfUsedChordTypes: _.range(11),
                chordGrouppingIsByType: false,
                nIsIncluded: true,
                guidesAreVisible: true,
            },


            /**
             * @return array [mode of piece, root note, type, base label]
             */
            parseEncodedChord: function(encodedChord) {
                if (encodedChord == "0") {
                    // null chord
                    return 0;
                }
                if (_.isString(encodedChord) && encodedChord.length == 7) {
                    return [
                        //   1: mode of piece
                        encodedChord[0] * 1,
                        // 2-3: offset of the chord root (zero-based)
                        encodedChord[1] * 10 + encodedChord[2] * 1 - 1,
                        // 4-5: type of the chord  (zero-based)
                        encodedChord[3] * 10 + encodedChord[4] * 1 - 1,
                        // 6-7: offset of the base note towards the chord root  (zero-based)
                        encodedChord[5] * 10 + encodedChord[6] * 1 - 1,
                    ];
                }

                throw "could not parse chord " + encodedChord;
            },


            parsedEncodedChordToBin: function(vc, parsedEncodedChord /* [mode of piece, root note, type, base label] */) {

                if (!_.isArray(parsedEncodedChord)) {
                    return vc.nIsIncluded ? vc.numberOfChords - 1: null;
                }
                var indexOfRootNote  = _.indexOf(vc.sequenceOfUsedRootNotes,  parsedEncodedChord[1]);
                var indexOfChordType = _.indexOf(vc.sequenceOfUsedChordTypes, parsedEncodedChord[2]);
                if (indexOfRootNote == -1 || indexOfChordType == -1) {
                    return null;
                }

                if (vc.chordGrouppingIsByType) {
                    return vc.numberOfRootNotes * indexOfChordType + indexOfRootNote;
                } else {
                    return vc.numberOfChordTypes * indexOfRootNote + indexOfChordType;
                }
            },


            chordBinToCoordinate: function(vc, chordBin) {
                if (chordBin === null) {
                    throw "cannot convert null bin to a coordinate";
                }
                var nGaps = Math.floor(chordBin / (vc.chordGrouppingIsByType ? vc.numberOfRootNotes : vc.numberOfChordTypes));
                return chordBin * vc.chordSize + nGaps * vc.chordGroupGapSize;
            },

            titleOfParsedEncodedChord: function(vc, parsedEncodedChord) {
                if (parsedEncodedChord === 0) {
                    return "N";
                } else {
                    return vc.titlesForRootNotes[parsedEncodedChord[1]] + " " + vc.titlesForChordTypes[parsedEncodedChord[2]];
                }
            }
        });


    });
}, Logger);
