/*

JavaScript Mandolin Chord Chart, V1.5.1, by Howard Knight:
http://howardknight.net/contact.cgi

This manoline chord chart is an enhanced version of:
JavaScript Guitar Chord Chart, version 1.0. By Gordon McComb.
from "The JavaScript Sourcebook," published by Wiley Computer Publishing.

*/

var showstaff = 1;
var smallmando = 0;

// "notes array":  The notes

var notes = new Array(12);
notes[0] = "C"
notes[1] = "Db"
notes[2] = "D"
notes[3] = "Eb"
notes[4] = "E"
notes[5] = "F"
notes[6] = "Gb"
notes[7] = "G"
notes[8] = "Ab"
notes[9] = "A"
notes[10] = "Bb"
notes[11] = "B"

var snotes = new Array(12);
snotes[0] = "C"
snotes[1] = "C#"
snotes[2] = "D"
snotes[3] = "D#"
snotes[4] = "E"
snotes[5] = "F"
snotes[6] = "F#"
snotes[7] = "G"
snotes[8] = "G#"
snotes[9] = "A"
snotes[10] = "A#"
snotes[11] = "B"

// "strings" array:  Note values for each string

var strings = new Array(4);
strings[0] = 7  // G
strings[1] = 2  // D
strings[2] = 9  // A
strings[3] = 4  // E

// "staff" associative array: Notes for the staff positions

var staff = new Object();
staff["G1"] = 0;
staff["A1"] = 1;
staff["B1"] = 2;
staff["C1"] = 3;
staff["D1"] = 4;
staff["E1"] = 5;
staff["F1"] = 6;
staff["G2"] = 7;
staff["A2"] = 8;
staff["B2"] = 9;
staff["C2"] = 10;
staff["D2"] = 11;
staff["E2"] = 12;
staff["F2"] = 13;
staff["G3"] = 14;
staff["A3"] = 15;
staff["B3"] = 16;

// "chords" array: Each chord is a separate element of an associative array,
// and is referenced by the name of the chord. The first four character
// field of the data indicates how the strings are to be played: 0=fingered,
// 1=not played, and 2=open. The rest of the fields are finger positions:
// 0-3 positions on the first fret, 4-7 positions on the second fret, and
// so on.

var chords = new Object();
chords["C"]  = "2000;5;10;11"
chords["Db"] = "0000;0;9;14;15"
chords["D"]  = "0220;4;7"
chords["Eb"] = "0000;1;2;8;11"
chords["E"]  = "0000;0;5;6;15"
chords["F"]  = "0020;3;9;16"
chords["Gb"] = "0000;7;8;13;14"
chords["G"]  = "2200;6;11"
chords["Ab"] = "0000;0;1;10;15"
chords["A"]  = "0000;4;5;14;19"
chords["Bb"] = "0200;2;3;8"
chords["B"]  = "0000;12;13;22;27"

chords["Cm"]  = "2000;1;10;11"
chords["Dbm"] = "0000;0;5;14;15"
chords["Dm"]  = "0220;3;4"
chords["Ebm"] = "0000;1;2;7;8"
chords["Em"]  = "2000;5;6;11"
chords["Fm"]  = "0000;0;9;10;15"
chords["Gbm"] = "0000;4;7;13;14"
chords["Gm"]  = "2200;2;11"
chords["Abm"] = "0000;0;1;6;15"
chords["Am"]  = "0000;4;5;10;19"
chords["Bbm"] = "0000;8;9;14;23"
chords["Bm"]  = "0000;12;13;18;27"

chords["C7"]  = "2000;2;5;11"
chords["Db7"] = "0000;0;6;9;15"
chords["D7"]  = "0200;4;7;10"
chords["Eb7"] = "0000;1;8;11;14"
chords["E7"]  = "0202;0;6"
chords["F7"]  = "0000;1;3;4;10"
chords["Gb7"] = "0000;5;7;8;14"
chords["G7"]  = "2200;3;6"
chords["Ab7"] = "0000;0;1;7;10"
chords["A7"]  = "0000;4;5;11;14"
chords["Bb7"] = "0000;8;9;15;18"
chords["B7"]  = "0001;1;4;6"

chords["Cm7"]  = "0000;1;8;10;11"
chords["Dbm7"] = "0000;5;12;14;15"
chords["Dm7"]  = "0200;3;4;10"
chords["Ebm7"] = "0000;1;7;8;14"
chords["Em7"]  = "2202;6"
chords["Fm7"]  = "0000;0;1;3;10"
chords["Gbm7"] = "0002;4;13;14"
chords["Gm7"]  = "2200;2;3"
chords["Abm7"] = "0000;0;1;6;7"
chords["Am7"]  = "0000;4;5;10;11"
chords["Bbm7"] = "0000;8;9;14;15"
chords["Bm7"]  = "0220;7;12"

chords["Cmaj7"]  = "0000;5;10;11;12"
chords["Dbmaj7"] = "0000;0;9;10;15"
chords["Dmaj7"]  = "0200;4;7;14"
chords["Ebmaj7"] = "0000;1;8;11;18"
chords["Emaj7"]  = "0002;0;1;6"
chords["Fmaj7"]  = "0000;9;16;19;26"
chords["Gbmaj7"] = "0000;3;8;13;14"
chords["Gmaj7"]  = "2200;6;7"
chords["Abmaj7"] = "0000;0;1;10;11"
chords["Amaj7"]  = "0000;4;5;14;15"
chords["Bbmaj7"] = "0000;8;9;18;19"
chords["Bmaj7"]  = "0000;12;13;22;23"

chords["C6"]  = "0000;4;5;10;11"
chords["Db6"] = "0000;8;9;14;15"
chords["D6"]  = "0200;4;6;7"
chords["Eb6"] = "0000;1;8;10;11"
chords["E6"]  = "0000;5;12;14;15"
chords["F6"]  = "0200;3;4;10"
chords["Gb6"] = "0000;1;7;8;14"
chords["G6"]  = "2202;6"
chords["Ab6"] = "0000;0;1;3;10"
chords["A6"]  = "0002;4;13;14"
chords["Bb6"] = "2200;2;3"
chords["B6"]  = "0000;0;1;6;7"

chords["Cm6"]  = "0000;1;4;10;11"
chords["Dbm6"] = "0000;5;8;14;15"
chords["Dm6"]  = "0200;3;4;6"
chords["Ebm6"] = "0000;1;7;8;10"
chords["Em6"]  = "0000;5;11;12;14"
chords["Fm6"]  = "0200;0;3;10"
chords["Gbm6"] = "0000;1;4;7;14"
chords["Gm6"]  = "2202;2"
chords["Abm6"] = "0000;0;1;3;6"
chords["Am6"]  = "0000;4;5;7;10"
chords["Bbm6"] = "0000;8;9;11;14"
chords["Bm6"]  = "0200;0;6;7"

chords["C9"]  = "0000;5;8;11;18"
chords["Db9"] = "0000;9;12;15;22"
chords["D9"]  = "0000;4;5;7;10"
chords["Eb9"] = "0000;8;9;11;14"
chords["E9"]  = "0200;0;6;7"
chords["F9"]  = "0000;1;4;10;11"
chords["Gb9"] = "0000;5;8;14;15"
chords["G9"]  = "2000;6;9;19"
chords["Ab9"] = "0000;8;10;13;15"
chords["A9"]  = "0000;4;5;6;11"
chords["Bb9"] = "0000;8;9;10;15"
chords["B9"]  = "0000;1;4;7;14"

var key, newkey;
for ( key in chords ) {
   if ( key.match("b") ) {
      newkey = key.replace(/b/, "#");
      switch ( newkey.charAt(0) ) {
         case "D":  newkey = newkey.replace(/D/,"C"); break;
         case "E":  newkey = newkey.replace(/E/,"D"); break;
         case "G":  newkey = newkey.replace(/G/,"F"); break;
         case "A":  newkey = newkey.replace(/A/,"G"); break;
         case "B":  newkey = newkey.replace(/B/,"A"); break;
      }
      chords[newkey] = chords[key];
   }
}

var sharps = 0;
function setSharpsFlag() {
   var i;
   resetMando();
   sharps = document.mando.sharps.checked;
   for ( i = 0; i < 12; i++ ) {
      if ( sharps )
         document.mando.chord.options[i].text = snotes[i];
      else
         document.mando.chord.options[i].text = notes[i];
   }
   setMando();
}

function resetMando() {
   var i, imgsuffix;
   if ( smallmando )
      imgsuffix = "-sm";
   else
      imgsuffix = "";
   document.getElementById("chordname").innerHTML = "&nbsp;"
   if ( showstaff ) {
      for (i=0; i<17; i++ ) {
         document["staff"+i].src="images/staff-whitespace.gif";
      }
      for (i=5; i<14; i+=2 ) {
         document["staff"+i].src="images/staff-line.gif";
      }
   }

   for (i=0; i<4; i++ ) {
      document["str"+i].src="images/blank" + imgsuffix + ".gif";
   }
   for (i=0; i<4; i++ ) {
      document.getElementById(i+"string").innerHTML = notes[strings[i]];
   }
   for (i=0; i < 28; i++) {
      document["pos"+i].src="images/string" + imgsuffix + ".gif";
   }
}

function setMando() {

   resetMando();
   var imgsuffix;
   if ( smallmando )
      imgsuffix = "-sm";
   else
      imgsuffix = "";
   var staffposs = new Array(17);
   var Item, Fret, Frets, i, Temp, mstring, mnote, staffkey, notename;
   var staffpos;
   for ( i = 0; i < 17; i++ ) {
      staffposs[i] = 0;
   }
   Item = document.mando.chord.selectedIndex;
   if (Item != -1) {
      Text = document.mando.chord.options[Item].text;
      if ( document.mando.type[1].checked )
         Text += "m";
      else if ( document.mando.type[2].checked )
         Text += "7";
      else if ( document.mando.type[3].checked )
         Text += "m7";
      else if ( document.mando.type[4].checked )
         Text += "maj7";
      else if ( document.mando.type[5].checked )
         Text += "6";
      else if ( document.mando.type[6].checked )
         Text += "m6";
      else if ( document.mando.type[7].checked )
         Text += "9";
      document.getElementById("chordname").innerHTML = Text;
      Frets = parser (chords[Text])
      for (i = 2; i <= Frets[0]; i++) {
         Temp = parseInt(Frets[i]);
         mstring = Temp % 4;
         Fret = (Temp - mstring) / 4 + 1;
         Fret = mstring * 7 + Fret;
         mnote = strings[mstring] + parseInt(Temp/4) + 1;
         if ( mnote > 11 )
            mnote -= 12;
         if ( sharps ) {
            notename = snotes[mnote];
         }
         else {
            notename = notes[mnote];
         }
         document.getElementById(mstring+"string").innerHTML = notename;
         staffkey = notename.substr(0,1);
         var min1, min2;
         if ( sharps ) {
            min1 = 12;
            min2 = 24;
         }
         else {
            min1 = 11;
            min2 = 23;
         }
         if ( Fret < min1 )
            staffkey += "1"
         else if ( Fret < min2 )
            staffkey += "2"
         else
            staffkey += "3"
         staffpos = staff[staffkey];
         if ( notename.substr(1,2) == "b" )
            staffposs[staffpos] = 2;
         else if ( notename.substr(1,2) == "#" )
            staffposs[staffpos] = 3;
         else
            staffposs[staffpos] = 1;
         document["pos"+Temp].src="images/pos" + imgsuffix + ".gif";
      }
      if (Frets[1] != "0000") {
         for(i=0; i<4; i++ ) {
            if ( Frets[1].substring(i,i+1) == "1" ) {
               document.getElementById(i+"string").innerHTML = "&nbsp;";
               document["str"+i].src="images/x" + imgsuffix + ".gif";
            }
            else if ( Frets[1].substring(i,i+1) == "2" ) {
               notename = notes[strings[i]]
               document.getElementById(i+"string").innerHTML = notename;
               if ( i < 2 )
                  staffkey = notename + "1"
               else
                  staffkey = notename + "2"
               staffpos = staff[staffkey];
               staffposs[staffpos] = 1;
               document["str"+i].src="images/o" + imgsuffix + ".gif";
            }
         }
      }

      if ( showstaff ) {
         for ( i = 1; i < 17; i++ )
            document["staff"+i].src="images/staff-blank.gif";
         var minpos = -1;
         var gifname;
         for ( i = 0; i < 17; i+=2 ) {
            if ( staffposs[i] != 0 ) {
               if ( minpos == -1  && i < 4 )
                  minpos = i;
               gifname = "images/staff-space-note";
               if ( staffposs[i] == 2 )
                  gifname += "-flat";
               else if ( staffposs[i] == 3 )
                  gifname += "-sharp";
               gifname += ".gif"
               document["staff"+i].src = gifname;
            }
         }
         for ( i = 1; i < 16; i+=2 ) {
            if ( staffposs[i] != 0 ) {
               if ( minpos == -1 )
                  minpos = i;
               gifname = "images/staff-";
               if ( i > 4 && i < 14 )
                  gifname += "line-note";
               else
                  gifname += "lineout-note";
               if ( staffposs[i] == 2 )
                  gifname += "-flat";
               else if ( staffposs[i] == 3 )
                  gifname += "-sharp";
               gifname += ".gif"
               document["staff"+i].src = gifname;
            }
            else {
               if ( i > 4 && i < 14 )
                  document["staff"+i].src="images/staff-line.gif";
               else if ( minpos != -1 && ( ( i < 5 && i > minpos ) || ( i == 15 && staffposs[16] > 0 ) ) )
                  document["staff"+i].src="images/staff-lineout.gif";
            }
         }
      }
   }
}

// general function for parsing strings using a specified parse character; result is values in 
// separate elements of an array
function parser (InString)  {
        var Sep = ";", NumSeps=1, i, Start, ParseMark, parse; 
        for (i=1; i < InString.length; i++)  {
                if (InString.charAt(i)==Sep)
                        NumSeps++;
        }
        parse = new Array ();
        var Start=0, i=1, ParseMark=0, LoopCtrl=1;
        while (LoopCtrl==1)  {
                ParseMark = InString.indexOf(Sep, ParseMark);
                TestMark=ParseMark+0;
                if ((TestMark==0) || (TestMark==-1)){
                        parse[i]= InString.substring (Start, InString.length);
                        LoopCtrl=0;
                        break;
                }
                parse[i] = InString.substring (Start, ParseMark);
                Start=ParseMark+1, ParseMark=Start, i++;
        }
        parse[0]=i;
        return (parse);
}

function popupallchords() {
   var outtxt, i, j, k, key, ctext, ctype, fpos, nfrets, fnum, findex, npos;
   newwindow = window.open ("", "_blank");
   outtxt = "<html><head><title>Mandolin Chord Chart</title></head><body>";
   outtxt += "<table border=0><tr><td>&nbsp;</td>";
//   for ( i = 0; i < 12; i++ ) {
//      outtxt += "<td>&nbsp</td>";
//      if ( sharps )
//         outtxt += "<th>" + snotes[i] + "</th>";
//      else
//         outtxt += "<th>" + notes[i] + "</th>";
//   }
   outtxt += "</tr>";
   for ( i = 0; i < 8; i++ ) {
      outtxt += "<tr>";
      switch ( i ) {
         case 0: ctext="maj"; ctype=""; break;
         case 1: ctext="m"; ctype="m"; break;
         case 2: ctext="7th"; ctype="7"; break;
         case 3: ctext="m7"; ctype="m7"; break;
         case 4: ctext="maj7"; ctype="maj7"; break;
         case 5: ctext="6th"; ctype="6"; break;
         case 6: ctext="m6"; ctype="m6"; break;
         case 7: ctext="9th"; ctype="9"; break;
      }
//      outtxt += "<th>" + ctext + "</th>";
      for ( j = 0; j < 12; j++ ) {
         if ( sharps )
            key = snotes[j] + ctype;
         else
            key = notes[j] + ctype;
         fpos = parser (chords[key])
         fnum = fpos[0];
         nfrets = parseInt(fpos[fnum] / 4);
         if ( nfrets < 2 )
            nfrets = 3;
         else if ( nfrets < 5 )
            nfrets ++;
         outtxt += "<td>&nbsp</td><td valign=\"top\"><table width=\"48\" border=0 cellpadding=\"0\" cellspacing=\"0\">";
         outtxt += "<tr><td colspan=\"4\" align=\"center\"><font size=\"-1\">" + key + "</font></td></tr>";
         outtxt += "<tr>";
         for( k = 0; k < 4; k++ ) {
            switch ( fpos[1].substring(k,k+1) ) {
               case "0": outtxt += "<td><img src=\"images/blank-sm.gif\"></td>"; break;
               case "1": outtxt += "<td><img src=\"images/x-sm.gif\"></td>"; break;
               case "2": outtxt += "<td><img src=\"images/o-sm.gif\"></td>"; break;
            }
         }
         outtxt += "</tr><tr><td colspan=4><img src=\"images/nut-sm.gif\"></td></tr>";
         npos = ( nfrets + 1 ) * 4;
         findex = 2;
         for ( k = 0; k < npos; k++ ) {
            if ( (k%4) == 0 ) {
               if ( k > 0 )
                  outtxt += "</tr>";
               outtxt += "<tr><td colspan=\"4\"><img src=\"images/fret-sm.gif\"></td></tr><tr>";
            }
            if ( findex <= fnum && fpos[findex] == k ) {
               outtxt += "<td><img src=\"images/pos-sm.gif\"></td>";
               findex++;
            }
            else
               outtxt += "<td><img src=\"images/string-sm.gif\"></td>";
         }
         outtxt += "</tr></table></td>";
      }
      outtxt += "</tr>";
   }
   outtxt += "</table></body></html>";
   newwindow.document.open("text/html");
   newwindow.document.write (outtxt);
   newwindow.document.close();
   return false;
}

