
   var Solfeggio = { "Note": ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "H"],
                     "Notb": ["", "Db", "", "Eb", "", "", "Gb", "", "Ab", "", "Hb", ""],
                     "Mins": ["c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "h", "db", "eb", "gb", "ab", "hb", "bb", "b"],
                     "Notx": ["", "", "", "", "", "", "", "", "", "", "Bb", "B"],
                     "Kind": ["", "m"],
                     "Adds": ["", "7(#5,#9)", "7(#5,b9)", "7(b5,#9)", "7(b5,b9)", "maj13#11", "sus2sus4", "maj9#11", "maj7#5", "maj7b5", "7sus4",
                              "6add9", "13#11", "maj13", "maj11", "maj9", "dim7", "13b9", "sus2", "add9", "sus4",
                              "maj7", "11b9", "aug", "7b5", "7#5", "dim", "7#9", "7b9", "9#5", "9b5",
                              "11", "13", "-5", "7", "6", "9", "5", "add4"]
   };                     


   var rowClasses = ["BLANK", "CHORDS", "VERSE", "LINE", "TEXT"];

   var ytTemplate = '<iframe width="560" height="28" src="https://www.youtube.com/embed/{{YTID}}" frameborder="0" allowfullscreen></iframe>';

   var ytid = false;

   $(document).ready(function() {

      $()._9A_MODAL("INITIALIZE", { });

      attachEvents();

      getSong();

      $("#TuneEditor").delegate("textarea", "click", function(e) {
          console.log($(this).attr("data-type"))
      });

      $("#TuneEditor").delegate("textarea", "input keydown keyup paste", function(e) { // console.log(e.keyCode) // 

          if(e.type == "paste") {
              splitRows($(this), e);
              adjustHeights();
              return false;
          }

          if(e.type == "keyup") {
              setClass($(this), AnalyseLine($(this).val()));
          }

          if(e.type == "keydown") { // console.log($(this).prop("selectionStart"), e.keyCode);

              if(e.keyCode == 8 && $(this).prop("selectionStart") == 0 && $(this).prop("selectionEnd") == 0) { // 8 = Backspace key
                 if($(this).prev().prop("tagName").toUpperCase() == "HR") {
                     $(this).prev().remove();
                     return false;
                 }
                 console.log($(this).prevUntil(".VERSE").val());
                 var selEnd = $(this).prev("textarea").val().length;
                 $(this).prev().val($(this).prev().val() + $(this).val()).focus().prop("selectionEnd", selEnd);
                 setClass($(this).prev(), AnalyseLine($(this).prev().val()));
                 $(this).remove();
                 adjustHeights();
                 return false;
              }

              if(e.keyCode == 38) { // 38 = Arrow up key
                 var caretPos = $(this).prop("selectionStart");
                 $(this).prev("textarea").focus().prop("selectionStart", caretPos);
                 $(this).prev("textarea").focus().prop("selectionEnd", caretPos);
                 return false;
              }

              if(e.keyCode == 40) { // 40 = Arrow down key
                 var caretPos = $(this).prop("selectionStart");
                 $(this).next("textarea").focus().prop("selectionStart", caretPos);
                 $(this).next("textarea").focus().prop("selectionEnd", caretPos);
                 return false;
              }

              if(e.keyCode == 46) { // 46 = Delete key
                 if($(this).prop("selectionEnd") == $(this).val().length) {
                    if($(this).next().prop("tagName").toUpperCase() == "HR") {
                       $(this).next().remove();
                       return false;
                    }
                    var selEnd = $(this).val().length;
                    $(this).val($(this).val() + $(this).next("textarea").val());
                    $(this).next("textarea").remove();
                    $(this).prop("selectionEnd", selEnd);
                    setClass($(this).val(), AnalyseLine($(this).val()));
                    adjustHeights();
                    return false;
                 }
              }

              if(e.keyCode == 13) { // 13 = Enter key
                 var selStart = $(this).prop("selectionStart"),
                     selEnd = $(this).val().length,
                     selText = $(this).val().substring(selStart),
                     remText = $(this).val().substring(0, selStart);
                 $("<textarea>" + selText + "</textarea>").insertAfter($(this));
                 $(this).val(remText).next("textarea").focus();
                 setClass($(this), AnalyseLine($(this).val()));
                 setClass($(this).next(), AnalyseLine($(this).next().val()));
                 noSpellCheck();
                 adjustHeights();
                 return false;
              }

          }

      });

   });

   function saveSong() {
      var JSONSong = "[\n",
          temp, chords,
          coma = "";
      $("textarea, hr").each(function() {
         switch($(this).attr("class")) {
            case "BLANK":
               temp = "[0]";
               break;
            case "CHORDS":
               chords = AnalyseLine($(this).val());
               temp = JSON.stringify(chords);
               // if(chords[0] == 1) temp = JSON.stringify(chords);
               // else temp ='[2,"' + $(this).val()+ '"]';
               break;
            case "VERSE":
               temp = '[2,"' + $(this).val() + '"]';
               break;
            case "LINE":
               temp = "[3]";
               break;
            case "TEXT":
               temp = '[4,"' + $(this).val() + '"]';
               break;
         }
          JSONSong = JSONSong + coma + temp;
          coma = ",\n";
      });
      JSONSong = JSONSong + "\n]";
      $.get("server/get_data.php", { JOB: "SAVE", ID: SongID, Data: JSONSong }, function(data) {
          console.log(data);
      });
   }

   function setClass(obj, arr) {
      $(obj).attr("class", rowClasses[arr[0]]);
      if(arr.length == 0) {
          $(obj).attr("data-type", 0);
          arr.push(0);
          return;
      }
      $(obj).attr("data-type", arr[0]);
   }

   function adjustHeights() {
      $("textarea").each(function() {
         $(this).height("1px");
         var lines = Math.floor($(this).prop("scrollHeight") / parseInt($(this).css("lineHeight")));
         $(this).height(lines * parseInt($(this).css("font-size")));
      });
   }

   function splitRows(obj, e) {
       var clip = e.originalEvent.clipboardData.getData("text");
       clip = clip.replace(/\r\n/g,"{{BREAK}}");
       clip = clip.replace(/\n\r/g,"{{BREAK}}");
       clip = clip.replace(/\n/g,"{{BREAK}}");
       clip = clip.replace(/\r/g,"{{BREAK}}");
       var rows = ($(obj).val() + clip).split("{{BREAK}}");
       for(var i = rows.length - 1; i > 0; i--) {
           $("<textarea class='newLine'>" + rows[i] + "</textarea>").insertAfter(obj);
       }
       $(obj).val(rows[0]);

       setClass($(obj), AnalyseLine($(obj).val()));

       $(".newLine").each(function() {
           setClass($(this), AnalyseLine($(this).val()));
       });

       noSpellCheck();
   }
   
   function CheckRow(RowString) {
       // console.log(RowString);
   }

   function getChords(chordLine) {
       var outChordLine = "",
           chordStr,
           NumSpaces,
           StrSpaces;
       for(var i = 1; i < chordLine.length; i++) {
          NumSpaces = parseInt(chordLine[i][3]) - 1 - outChordLine.length;
          for(StrSpaces = ""; StrSpaces.length < NumSpaces; StrSpaces += " ") {}
          chordStr = Solfeggio.Note[chordLine[i][0]]
                   + Solfeggio.Kind[chordLine[i][1]]
                   // + Solfeggio.Adds[chordLine[i][2]];
                   // + (chordLine[i][1] == -1 ? "" : Solfeggio.Kind[1])
                   + (chordLine[i][2] == -1 ? "" : Solfeggio.Adds[chordLine[i][2]]);
          outChordLine = outChordLine + StrSpaces + chordStr;
       }
       return outChordLine;
   }

   function AnalyseLine(Line) {

      var blocks  = Line.split(" ");
      var IsChord = [];
      var Failed  = false;
      var ChPos   = 0;
      var Out     = [];
      
      if(Line == "") return Out;
      
      for(var b = 0; b < blocks.length; b++) {
         ChPos++;
         if(blocks[b] == "") continue;
         if(blocks[b].indexOf("/") != -1) {
            var DC = blocks[b].split("/");
            IsChord = RecognizeChord(DC[0]);
            if(IsChord[0])
               Out.push([IsChord[1][1], IsChord[2][2], IsChord[3][2]]);
            IsChord = RecognizeChord(DC[1]);
            Out[Out.length - 1].push(IsChord[1][1], IsChord[2][2], IsChord[3][2], ChPos);
            ChPos = ChPos + blocks[b].length;
            continue;
         }
         var IsChord = RecognizeChord(blocks[b]);
         if(IsChord[0]) {
            Out.push([IsChord[1][1], IsChord[2][2], IsChord[3][2], ChPos]);
            ChPos = ChPos + blocks[b].length;
         }
         else {
             Failed = true;
             break;
         }
      }
      if(Failed) Out = [2, Line];
      else Out.unshift(1);
      return Out;
   }

   function RecognizeChord(ChordToRecognize) {

      var Add      = "",
          Minor    = "",
          Chord    = "",
          AddIdx   = 0,
          MinorIdx = 0,
          ChordIdx = 0,
          GA = GetAdd(ChordToRecognize),
          GM = GetMinor(GA[0]),
          MC = MainChord(GM[0]);

      if(MC[1] == -1) return [false];
      else return[true, MC, GM, GA];

      function GetAdd(InChord) {

         var OutChord  = InChord,
             OutAdd    = "",
             OutAddIdx = 0;

         for(var a = 1; a < Solfeggio.Adds.length; a++) {
            var n = InChord.toLowerCase().lastIndexOf(Solfeggio.Adds[a]);
            if(n != -1) {
               OutAddIdx = a;
               OutAdd    = Solfeggio.Adds[a];
               OutChord  = InChord.substring(0, n);
               break;
            }
         }
         return [OutChord, OutAdd, OutAddIdx];
      }

      function GetMinor(InChord) {

         var OutChord    = InChord,
             OutMinor    = "",
             OutMinorIdx = 0;

         var m = InChord.charAt(InChord.length - 1).toLowerCase();

         if(m == "m") {
            OutChord    = InChord.substring(0, InChord.length - 1);
            OutMinorIdx = 1;
         }

         if($.inArray(OutChord, Solfeggio.Mins) != -1) {
            OutChord = OutChord[0].toUpperCase() + OutChord.slice(1);
            OutMinorIdx = 1;
         }
         OutMinor = Solfeggio.Kind[OutMinorIdx];
         return [OutChord, OutMinor, OutMinorIdx];
      }

      function MainChord(InChord) {

         var OutChord    = InChord,
             OutChordIdx = -1;

         for(var c = 0; c < Solfeggio.Note.length; c++) {
            if(Solfeggio.Note[c] == InChord
            || Solfeggio.Notb[c] == InChord
            || Solfeggio.Notx[c] == InChord) {
               OutChordIdx = c;
               OutChord    = Solfeggio.Note[c];
               break;
            }
         }        
         return [OutChord, OutChordIdx];
      }
   }

   function noSpellCheck() {
      $("textarea").attr("autocomplete", "off");
      $("textarea").attr("autocorrect", "off");
      $("textarea").attr("autocapitalize", "off");
      $("textarea").attr("spellcheck", "false");
   }

   function getSong() {

      $.get("server/get_data.php", { JOB: "SONG", ID: SongID }, function(data) {

          var Song = JSON.parse(data);

          if(Song.Status == "ERROR") return;

          $("#TuneToolbar span.label").text(Song.Data[0].Artist + ":");
          $("#TuneToolbar span.value").text(Song.Data[0].Title);

          var Chords = JSON.parse(Song.Data[0].Tune),
              ytid   = Song.Data[0].YTID,
              rows   = "";

          for(var i = 0; i < Chords.length; i++) {
              // console.log(Chords[i]);
              if(Chords[i][0] == 0) rows = rows + "<textarea data-type='0' class=\"BLANK\"></textarea>";
              if(Chords[i][0] == 1) rows = rows + "<textarea data-type='1' class=\"CHORDS\">" + getChords(Chords[i]) + "</textarea>";
              if(Chords[i][0] == 2) rows = rows + "<textarea data-type='2' class=\"VERSE\">" + Chords[i][1] + "</textarea>";
              if(Chords[i][0] == 3) rows = rows + "<hr data-type='3' class=\"LINE\" />";
              if(Chords[i][0] == 4) rows = rows + "<textarea data-type='4' class=\"TEXT\">" + Chords[i][1] + "</textarea>";
          }

          $("#TuneEditor").html(rows);
          noSpellCheck();
          adjustHeights();

      });
   }
