/*

JavaScript Ukulele Chord Chart, V1.0.0, by Howard Knight:
http://howardknight.net/contact.cgi

This ukulele 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 smalluke = 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] = 0  // C
strings[2] = 4  // A
strings[3] = 9  // E

// "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"]  = "2220;11"
chords["Db"] = "0000;0;1;2;15"
chords["D"]  = "0000;4;5;6;19"
chords["Eb"] = "0000;3;8;9;10"
chords["E"]  = "0000;7;12;13;14"
chords["F"]  = "0202;2;4"
chords["Gb"] = "0000;8;1;6;3"
chords["G"]  = "2000;5;10;7"
chords["Ab"] = "0000;16;9;14;11"
chords["A"]  = "0022;1;4"
chords["Bb"] = "0000;8;5;2;3"
chords["B"]  = "0000;12;9;6;7"

chords["Cm"]  = "2000;9;10;11"
chords["Dbm"] = "0020;0;1;15"
chords["Dm"]  = "0002;2;4;5"
chords["Ebm"] = "0000;8;9;6;3"
chords["Em"]  = "2000;13;10;7"
chords["Fm"]  = "0200;0;2;11"
chords["Gbm"] = "0002;1;4;6"
chords["Gm"]  = "2000;5;10;3"
chords["Abm"] = "0000;0;9;14;7"
chords["Am"]  = "0222;4"
chords["Bbm"] = "0000;8;1;2;3"
chords["Bm"]  = "0000;12;5;6;7"

chords["C7"]  = "2220;3"
chords["Db7"] = "0000;0;1;2;7"
chords["D7"]  = "0000;4;5;6;11"
chords["Eb7"] = "0000;8;9;10;15"
chords["E7"]  = "0020;0;5;7"
chords["F7"]  = "0000;4;9;2;11"
chords["Gb7"] = "0000;8;13;6;15"
chords["G7"]  = "2000;5;2;7"
chords["Ab7"] = "0000;0;9;6;11"
chords["A7"]  = "2022;1"
chords["Bb7"] = "0000;0;5;2;3"
chords["B7"]  = "0000;4;9;6;7"

chords["Cm7"]  = "0000;8;9;10;11"
chords["Dbm7"] = "0000;12;13;14;15"
chords["Dm7"]  = "0000;4;5;2;11"
chords["Ebm7"] = "0000;8;9;6;15"
chords["Em7"]  = "2020;5;7"
chords["Fm7"]  = "0000;0;9;2;11"
chords["Gbm7"] = "0000;4;13;6;15"
chords["Gm7"]  = "2000;5;2;3"
chords["Abm7"] = "0000;0;9;6;7"
chords["Am7"]  = "0000;4;13;10;11"
chords["Bbm7"] = "0000;0;1;2;3"
chords["Bm7"]  = "0000;4;5;6;7"

chords["Cmaj7"]  = "2220;7"
chords["Dbmaj7"] = "0000;0;1;2;11"
chords["Dmaj7"]  = "0000;4;5;6;15"
chords["Ebmaj7"] = "0000;8;9;10;19"
chords["Emaj7"]  = "0020;0;9;7"
chords["Fmaj7"]  = "0000;4;13;2;11"
chords["Gbmaj7"] = "0000;8;17;6;15"
chords["Gmaj7"]  = "2000;5;6;7"
chords["Abmaj7"] = "0000;0;9;10;11"
chords["Amaj7"]  = "0000;4;13;14;15"
chords["Bbmaj7"] = "0002;8;5;2"
chords["Bmaj7"]  = "0000;12;9;6;3"

chords["C6"]  = "2222"
chords["Db6"] = "0000;0;1;2;3"
chords["D6"]  = "0000;4;5;6;7"
chords["Eb6"] = "0000;8;9;10;11"
chords["E6"]  = "0000;12;13;14;15"
chords["F6"]  = "0000;4;5;2;11"
chords["Gb6"] = "0000;8;9;6;15"
chords["G6"]  = "2020;5;7"
chords["Ab6"] = "0000;0;9;2;11"
chords["A6"]  = "0000;4;13;6;15"
chords["Bb6"] = "2000;5;2;3"
chords["B6"]  = "0000;0;9;6;7"

chords["C9"]  = "2020;5;3"
chords["Db9"] = "0000;0;9;2;7"
chords["D9"]  = "0000;4;13;6;11"
chords["Eb9"] = "2000;1;2;3"
chords["E9"]  = "0000;0;5;6;7"
chords["F9"]  = "0000;4;9;10;11"
chords["Gb9"] = "0020;0;1;3"
chords["G9"]  = "0000;4;5;2;7"
chords["Ab9"] = "0000;8;9;6;11"
chords["A9"]  = "2020;1;7"
chords["Bb9"] = "0000;0;5;2;11"
chords["B9"]  = "0000;4;9;6;15"

chords["C dim"]  = "0000;4;9;6;11"
chords["Db dim"] = "2020;1;3"
chords["D dim"]  = "0000;0;5;2;7"
chords["Eb dim"] = "0000;4;9;6;11"
chords["E dim"]  = "2020;1;3"
chords["F dim"]  = "0000;0;5;2;7"
chords["Gb dim"] = "0000;4;9;6;11"
chords["G dim"]  = "2020;1;3"
chords["Ab dim"] = "0000;0;5;2;7"
chords["A dim"]  = "0000;4;9;6;11"
chords["Bb dim"] = "2020;1;3"
chords["B dim"]  = "0000;0;5;2;7"

chords["C aug"]  = "0220;0;11"
chords["Db aug"] = "0002;4;1;2"
chords["D aug"]  = "0000;8;5;6;3"
chords["Eb aug"] = "0000;12;9;10;7"
chords["E aug"]  = "0020;0;13;11"
chords["F aug"]  = "0002;4;1;2"
chords["Gb aug"] = "0000;8;5;6;3"
chords["G aug"]  = "0000;12;9;10;7"
chords["Ab aug"] = "0220;0;11"
chords["A aug"]  = "0000;4;1;2;15"
chords["Bb aug"] = "0000;8;5;6;3"
chords["B aug"]  = "0000;12;9;10;7"

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 ( smalluke )
      imgsuffix = "-sm";
   else
      imgsuffix = "";
   document.getElementById("chordname").innerHTML = "&nbsp;"
   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 ( smalluke )
      imgsuffix = "-sm";
   else
      imgsuffix = "";
   var Item, Fret, Frets, i, Temp, mstring, mnote, notename;
   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 += "9";
      else if ( document.mando.type[7].checked )
         Text += " dim";
      else if ( document.mando.type[8].checked )
         Text += " aug";
      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;
         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;
               document["str"+i].src="images/o" + imgsuffix + ".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, ctype, fpos, nfrets, fnum, findex, npos;
   var hit;
   newwindow = window.open ("", "_blank");
   outtxt = "<html>\n<head>\n<title>Ukulele Chord Chart</title>\n</head>\n<body>\n";
   outtxt += "<table border=0>\n <tr>\n  <td>&nbsp;</td>\n";
   outtxt += " </tr>\n";
   for ( i = 0; i < 9; i++ ) {
      outtxt += " <tr>";
      switch ( i ) {
         case 0: ctype=""; break;
         case 1: ctype="m"; break;
         case 2: ctype="7"; break;
         case 3: ctype="m7"; break;
         case 4: ctype="maj7"; break;
         case 5: ctype="6"; break;
         case 6: ctype="9"; break;
         case 7: ctype=" dim"; break;
         case 8: ctype=" aug"; break;
      }
      for ( j = 0; j < 12; j++ ) {
         if ( sharps )
            key = snotes[j] + ctype;
         else
            key = notes[j] + ctype;
         fpos = parser (chords[key])
         fnum = fpos[0];
         if ( fnum == 1 )
            nfrets = 2;
         else {
            nfrets = parseInt(fpos[fnum] / 4);
            if ( nfrets < 2 )
               nfrets = 3;
            else if ( nfrets < 5 )
               nfrets ++;
         }
         outtxt += "  <td>&nbsp</td>\n  <td valign=\"top\">\n\n   <table width=\"48\" border=0 cellpadding=\"0\" cellspacing=\"0\">\n";
         outtxt += "    <tr>\n     <td colspan=\"4\" align=\"center\"><font size=\"-1\">" + key + "</font></td>\n    </tr>\n";
         outtxt += "    <tr>\n";
         for( k = 0; k < 4; k++ ) {
            switch ( fpos[1].substring(k,k+1) ) {
               case "0": outtxt += "     <td><img src=\"images/blank-sm.gif\"></td>\n"; break;
               case "1": outtxt += "     <td><img src=\"images/x-sm.gif\"></td>\n"; break;
               case "2": outtxt += "     <td><img src=\"images/o-sm.gif\"></td>\n"; break;
            }
         }
         outtxt += "    </tr>\n    <tr>\n     <td colspan=4><img src=\"images/nut-sm.gif\"></td>\n    </tr>";
         npos = ( nfrets + 1 ) * 4;
         findex = 2;
         for ( k = 0; k < npos; k++ ) {
            if ( (k%4) == 0 ) {
               if ( k > 0 )
                  outtxt += "    </tr>\n";
               outtxt += "    <tr>\n     <td colspan=\"4\"><img src=\"images/fret-sm.gif\"></td>\n    </tr>\n    <tr>\n";
            }
            hit = 0;
            for ( findex = 2; findex <= fnum; findex++ ) {
               if ( fpos[findex] == k )
                  hit = 1;
            }
            if ( hit )
               outtxt += "     <td><img src=\"images/pos-sm.gif\"></td>\n"
            else
               outtxt += "     <td><img src=\"images/string-sm.gif\"></td>\n";
         }
         outtxt += "    </tr>\n   </table>\n\n  </td>\n";
      }
      outtxt += " </tr>\n";
   }
   outtxt += "</table>\n</body>\n</html>\n";
   newwindow.document.open("text/html");
   newwindow.document.write (outtxt);
   newwindow.document.close();
   return false;
}
