Index: main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/js/jam-guitar.js
===================================================================
--- main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/js/jam-guitar.js	(revision 29941)
+++ main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/js/jam-guitar.js	(revision 29942)
@@ -1,2 +1,4 @@
+"use strict";
+
 // Script derived from Chrome Jam
 
@@ -236,7 +238,8 @@
     this._strumForce = 5;
     this._strumDuration = 100;
-    MIDI.noteOn(0, this._midiPitch, 40);
-    console.log("*** Setting Jam guitar strumForce = 5");
-
+    if (this._midiPitch>=0) {
+      MIDI.noteOn(0, this._midiPitch, 40);
+      console.log("*** Setting Jam guitar strumForce = 5");
+    }
 };
 
@@ -260,6 +263,8 @@
     else if (this._strumDuration == 0) {
 	this._strumDuration = -1;
-	console.log("*** setting strumDuration = 0");
-	MIDI.noteOff(0, this._midiPitch, 0);
+	if (this._midiPitch>=0) {
+	    console.log("*** setting strumDuration = 0");
+	    MIDI.noteOff(0, this._midiPitch, 0);
+	}
     }
 };
@@ -283,5 +288,8 @@
 
 //var jamMidiStringPitches = [ 60, 64, 67, 72, 76, 79 ];
-var jamMidiStringPitches = [ 48, 52, 55, 60, 64, 67 ];
+//var jamMidiStringPitches = [ 48, 52, 55, 60, 64, 67 ];
+// E   A   D   G   B   E
+// 52, 57, 62, 67, 71, 76
+var jamMidiStringPitches = [ 52, 57, 62, 67, 71, 76 ];
 
 StringInstrument.prototype.create = function() {
@@ -295,4 +303,18 @@
 };
 
+StringInstrument.prototype.setStringFret = function(spos,fbase, fpos) {
+
+    var s = this.strings[spos];
+    if (fpos>=0) {
+      s._midiPitch = jamMidiStringPitches[spos] + fbase + fpos;
+    }
+    else {
+      s._midiPitch = -1;
+    }
+
+};
+
+
+
 var lastTime = 0;
 
@@ -318,5 +340,160 @@
 };
 
+var guitar = null;
 $(document).ready(function() {
-    var guitar = new StringInstrument("jamStage", "jamStrings", 6);
+    console.log("**** creating guitar");
+    guitar = new StringInstrument("jamStage", "jamStrings", 6);
 });
+
+var jamLineupLen = 17;
+
+var jam_chords = { 'maj': [ 'C', 'C#' ,'Db', 'D', 'D#', 'Eb', 'E', 'F', 'F#', 'Gb', 'G', 'G#', 'Ab',' A', 'A#', 'Bb', 'B'],
+		   'min': [ 'Cm','C#m','Dbm','Dm','D#m','Ebm','Em','Fm','F#m','Gbm','Gm','G#m','Abm','Am','A#m','Bbm','Bm'],
+		   'cus': [ 'Dsus4' ],
+		   'cus-skip': {"1":true,"4":true,"8":true,"11":true,"14":true}
+		 };
+
+var cgc_mode = null; // cgc => 'current guitar chord'
+var cgc_id = null;
+
+
+function whitespaceTidyUp(str)
+{
+    if (str) {
+	str = str.replace(/^\s+/,"").replace(/\s+$/,"");
+    }
+
+    return str;
+}
+
+
+function chordChange(bid) {
+        
+    console.log("chordChange(" +bid + ")");
+    if (cgc_id != null) {
+	$('#offscreen-jtab-chord-'+cgc_id).css("background-color","#FFFFFF");
+    }
+    cgc_id = bid;
+    $('#offscreen-jtab-chord-'+cgc_id).css("background-color","rgba(46,82,164,0.50)");
+    
+    var cgc_code = whitespaceTidyUp($('#offscreen-jtab-chord-'+cgc_id+'>div>svg>text>tspan').html());
+    console.log("*** clicked on guitar chord = " + cgc_code);
+    
+    var cgc_data = jtab.Chords[cgc_code][0];
+    var cgc_base_fret = cgc_data[0];
+    //var cgc_string_frets = [];
+    for (var i=1; i<=6; i++) {
+	var cgc_string_fret_pos = cgc_data[i][0]; // pick out the fret position
+	//cgc_string_frets.push(cgc_string_fret_pos); // pick out the fret position
+	guitar.setStringFret(i-1,cgc_base_fret,cgc_string_fret_pos);
+    }
+    
+    //console.log("*** strings = " + JSON.stringify(cgc_string_frets));
+}
+
+
+
+function scaleJTab(pos)
+{
+
+    // ... and scale the newly rendered element down
+    var $tab_svg = $('#offscreen-jtab-chord-'+pos+'>div>svg');
+    $tab_svg.attr("width", "58"); // go thinner than 'natural' width of 69 (for a height of 59)
+    $tab_svg.attr("height","59");
+    // True box is 0 0 138 118, but shaving off values so not so much white-space
+    $tab_svg[0].setAttribute("viewBox","20 0 90 118"); // W3C DOM way to avoid jquery lower-casing 'viewBox' into 'viewbox'
+    $tab_svg.parent().css("height","59px");
+
+}
+
+function setChordLineupMode(mode) {
+    cgc_mode = mode;
+
+    if (mode == "cus") {
+	$('#addCustomChord').show({effect: "fade", duration: 400});
+    }
+    else {
+	$('#addCustomChord').hide({effect: "fade", duration: 300});
+    }
+
+    var lineup = jam_chords[mode];
+    var lineup_len = lineup.length;
+
+    var lineup_skip = jam_chords[mode+"-skip"];
+
+
+    for (var i=0; i<jamLineupLen; i++) {
+
+	var active_div_id = '#offscreen-jtab-chord-'+i;
+	
+	if ((i<lineup_len) && 
+	    (!lineup_skip || (lineup_skip && !lineup_skip[""+i]))) {
+	    console.log("*** lineup_skip = " + lineup_skip);
+	    if (lineup_skip) {
+		console.log("*** lineup_skip lookup = " + lineup_skip[""+i]);
+	    }
+	    jtab.render($(active_div_id),lineup[i]);
+
+	    scaleJTab(i);
+	}
+	else {
+	    // make empty
+	    jtab.render($(active_div_id).empty());
+	}
+
+    }
+
+    if (cgc_id != null) {
+	chordChange(cgc_id);
+    }
+}
+
+
+
+function addCustomChord() {
+
+
+    var custom_lineup = jam_chords['cus'];
+    var custom_lineup_len = custom_lineup.length;
+
+    var custom_lineup_skip = jam_chords['cus-skip'];
+
+
+    var chord_text = whitespaceTidyUp($('#addCustomChordText').val());
+
+    if (chord_text) {	
+	// check the chord exists ...
+	if (jtab.Chords[chord_text]) {
+	    // check there is space to add the chord ...
+
+	    var custom_pos = null;
+	    if (custom_lineup_len < jamLineupLen) {
+		// append (determin append pos) ...
+
+		custom_pos = custom_lineup_len;
+
+		// ... but need to increment one higher, if in a skip position
+		if (custom_lineup_skip["" + custom_pos]) {
+		    custom_pos++;
+		}
+
+		custom_lineup[custom_pos] = chord_text;
+
+	    }
+	    else {
+		//replace the one that is currently highlighted
+		custom_pos = cgc_id;
+		custom_lineup[custom_pos] = chord_text;
+	    }
+	    
+	    jtab.render($('#offscreen-jtab-chord-'+custom_pos),chord_text);
+	    scaleJTab(custom_pos);
+
+	    // update local storage under this doc-id
+	}
+
+
+    }
+
+
+}
Index: main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/transform/pages/document.xsl
===================================================================
--- main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/transform/pages/document.xsl	(revision 29941)
+++ main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/transform/pages/document.xsl	(revision 29942)
@@ -1758,10 +1758,10 @@
 @-webkit-keyframes drumHit {
   0%   { background-size: 100%;}
-  10%  { background-size: 105%; }
-  30%  { background-size: 103%; }
+  10%  { background-size: 95%; }
+  30%  { background-size: 97%; }
   50%  { background-size: 100%;}
-  60%  { background-size: 102%; }
+  60%  { background-size: 98%; }
   70%  { background-size: 100%;}
-  80%  { background-size: 101%; }
+  80%  { background-size: 99%; }
   100% { background-size: 100%;}
 }
@@ -1769,10 +1769,10 @@
 @-moz-keyframes drumHit {
   0%   { background-size: 100%;}
-  10%  { background-size: 105%; }
-  30%  { background-size: 103%; }
+  10%  { background-size: 95%; }
+  30%  { background-size: 97%; }
   50%  { background-size: 100%;}
-  60%  { background-size: 102%; }
+  60%  { background-size: 98%; }
   70%  { background-size: 100%;}
-  80%  { background-size: 101%; }
+  80%  { background-size: 99%; }
   100% { background-size: 100%;}
 }
@@ -1780,10 +1780,10 @@
 @-o-keyframes drumHit {
   0%   { background-size: 100%;}
-  10%  { background-size: 105%; }
-  30%  { background-size: 103%; }
+  10%  { background-size: 95%; }
+  30%  { background-size: 97%; }
   50%  { background-size: 100%;}
-  60%  { background-size: 102%; }
+  60%  { background-size: 98%; }
   70%  { background-size: 100%;}
-  80%  { background-size: 101%; }
+  80%  { background-size: 99%; }
   100% { background-size: 100%;}
 }
@@ -1791,10 +1791,10 @@
 @-ms-keyframes drumHit {
   0%   { background-size: 100%;}
-  10%  { background-size: 105%; }
-  30%  { background-size: 103%; }
+  10%  { background-size: 95%; }
+  30%  { background-size: 97%; }
   50%  { background-size: 100%;}
-  60%  { background-size: 102%; }
+  60%  { background-size: 98%; }
   70%  { background-size: 100%;}
-  80%  { background-size: 101%; }
+  80%  { background-size: 99%; }
   100% { background-size: 100%;}
 }
@@ -1889,6 +1889,6 @@
 
 	  <div style="position: relative; background-color: white;">
-	    <div style="display:inline-block; width: 150px; height: 200px;">
-	      <form style="position: absolute; top: 60px; left: 10px;">
+	    <div style="display:inline-block; width: 150px; height: 130px;">
+	      <form style="position: absolute; top: 10px; leftXX: 10px;">
 
 		<fieldset>
@@ -1899,5 +1899,5 @@
 		    <div class="radio-label-combo">
 		      <span>
-			<input type="radio" id="clm-maj" name="clm-radio" onchange="setChordLineupMode()" value="Maj"
+			<input type="radio" id="clm-maj" name="clm-radio" onchange="setChordLineupMode('maj')" value="Maj"
 			       checked="checked"/>
 		      </span>
@@ -1911,7 +1911,7 @@
 		  <div class="radio-label-combo">
 		    <span>
-		      <input type="radio" id="clm-maj" name="clm-radio" onchange="setChordLineupMode()" value="Maj"/>
+		      <input type="radio" id="clm-min" name="clm-radio" onchange="setChordLineupMode('min')" value="Min"/>
 		    </span>
-		    <label for="clm-maj" class="radio-label">
+		    <label for="clm-min" class="radio-label">
 		      <span>
 			Minor
@@ -1919,4 +1919,16 @@
 		    </label>
 		  </div>
+
+		  <div class="radio-label-combo">
+		    <span>
+		      <input type="radio" id="clm-cus" name="clm-radio" onchange="setChordLineupMode('cus')" value="Cus"/>
+		    </span>
+		    <label for="clm-cus" class="radio-label">
+		      <span>
+			Custom
+		      </span>
+		    </label>
+		  </div>
+
 		  </div>
 	      </fieldset>
@@ -1924,11 +1936,67 @@
 	    </div>
 
+<!--
 	    <div id="mytab" style="display:inline-block; height: 160px; width: 780px;">
 	      <svg class="graph" xmlns = "http://www.w3.org/2000/svg" width="100%" height="100%">
-		<g id="scaled-mytab-group" transform="scale(0.5,0.6)">
+		<g id="scaled-mytab-group" transform="scale(0.45,0.55)">
 		  <foreignobject id="scaled-mytab" width="2000px" height="300px"><xsl:comment>filler</xsl:comment></foreignobject>
 		</g>
 	      </svg>
 	    </div>
+-->
+
+
+	    <gsf:div id="mytab" style="display:inline-block; heightXX: 130px; width: 780px;">
+	      <gsf:div id="scaled-mytab" widthXX="2000px" heightXX="300px">
+		
+
+<!--		
+		<gsf:div id="offscreen-jtab-chord-0" class="chordLineupBlock"/>
+		  
+		<div class="chordLineupBlock">
+		  <gsf:div id="offscreen-jtab-chord-1"/>
+		  <gsf:div id="offscreen-jtab-chord-2"/>
+		</div>
+		
+		<gsf:div id="offscreen-jtab-chord-3" class="chordLineupBlock"/>
+		
+		<div class="chordLineupBlock">
+		  <gsf:div id="offscreen-jtab-chord-4"/>
+		  <gsf:div id="offscreen-jtab-chord-5"/>
+		</div>
+		
+		<gsf:div id="offscreen-jtab-chord-6" class="chordLineupBlock"/>
+		<gsf:div id="offscreen-jtab-chord-7" class="chordLineupBlock"/>
+		
+		<div class="chordLineupBlock">
+		  <gsf:div id="offscreen-jtab-chord-8"/>
+		  <gsf:div id="offscreen-jtab-chord-9"/>
+		</div>
+		
+		<gsf:div id="offscreen-jtab-chord-10" class="chordLineupBlock"/>
+		  
+		<div class="chordLineupBlock">
+		  <gsf:div id="offscreen-jtab-chord-11"/>
+		  <gsf:div id="offscreen-jtab-chord-12"/>
+		</div>
+		
+		<gsf:div id="offscreen-jtab-chord-13" class="chordLineupBlock"/>
+		
+		<div class="chordLineupBlock">
+		  <gsf:div id="offscreen-jtab-chord-14"/>
+		  <gsf:div id="offscreen-jtab-chord-15"/>
+		</div>
+		
+		<gsf:div id="offscreen-jtab-chord-16" class="chordLineupBlock"/>		
+-->
+
+	      </gsf:div>
+	      <gsf:div id="addCustomChord" style="display:none;">
+		<input id="addCustomChordText" type="text" size="10"/>
+		<input type="button" value="add custom chord" onclick="addCustomChord()"/>
+	      </gsf:div>
+
+	    </gsf:div>
+
 	  </div>
 
@@ -1940,5 +2008,5 @@
       <div style="position: absolute; top: -300px; background-color: white;">
 	<style>
-	  .chordLineup {
+	  .chordLineupXX {
   	    -webkit-transform-style: preserve-3d;
 	    -moz-transform-style: preserve-3d;
@@ -1950,5 +2018,5 @@
 	  }
 	  
-	  .chordLineupBlockVerticalCenter {
+	  .chordLineupBlockVerticalCenterXX {
 	    position: relative;
 	    top: 50%;
@@ -1959,106 +2027,105 @@
 
 	</style>
+
+
 	<div id="offscreen-jtab-chord-lineup">
-
-	  <div id="offscreen-jtab-chord-C" class="chordLineupBlock">
-	    <xsl:comment>filler</xsl:comment>
-	  </div>
-
+	  
+	  <gsf:div id="offscreen-jtab-chord-0" class="chordLineupBlock"/>
+	  
 	  <div class="chordLineupBlock">
-	    <div id="offscreen-jtab-chord-Db">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	    <div id="offscreen-jtab-chord-Cs">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
+	    <gsf:div id="offscreen-jtab-chord-1"/>
+	    <gsf:div id="offscreen-jtab-chord-2"/>
 	  </div>
 	  
-	  <div id="offscreen-jtab-chord-D" class="chordLineupBlock">
-	    <xsl:comment>filler</xsl:comment>
-	  </div>
-
+	  <gsf:div id="offscreen-jtab-chord-3" class="chordLineupBlock"/>
+	  
 	  <div class="chordLineupBlock">
-	    <div id="offscreen-jtab-chord-Eb">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	    <div id="offscreen-jtab-chord-Ds">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
+	    <gsf:div id="offscreen-jtab-chord-4"/>
+	    <gsf:div id="offscreen-jtab-chord-5"/>
 	  </div>
 	  
-	  <div id="offscreen-jtab-chord-E" class="chordLineupBlock">
-	    <xsl:comment>filler</xsl:comment>
+	  <gsf:div id="offscreen-jtab-chord-6" class="chordLineupBlock"/>
+	  <gsf:div id="offscreen-jtab-chord-7" class="chordLineupBlock"/>
+	  
+	  <div class="chordLineupBlock">
+	    <gsf:div id="offscreen-jtab-chord-8"/>
+	    <gsf:div id="offscreen-jtab-chord-9"/>
+	  </div>
+
+	  <gsf:div id="offscreen-jtab-chord-10" class="chordLineupBlock"/>
+	  
+	  <div class="chordLineupBlock">
+	    <gsf:div id="offscreen-jtab-chord-11"/>
+	    <gsf:div id="offscreen-jtab-chord-12"/>
 	  </div>
 	  
-	  <div id="offscreen-jtab-chord-F" class="chordLineupBlock">
-	    <xsl:comment>filler</xsl:comment>
+	  <gsf:div id="offscreen-jtab-chord-13" class="chordLineupBlock"/>
+	  
+	  <div class="chordLineupBlock">
+	    <gsf:div id="offscreen-jtab-chord-14"/>
+	    <gsf:div id="offscreen-jtab-chord-15"/>
 	  </div>
 	  
-	  <div class="chordLineupBlock">
-	    <div id="offscreen-jtab-chord-Gb">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	    <div id="offscreen-jtab-chord-Fs">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	  </div>
-
-	  <div id="offscreen-jtab-chord-G" class="chordLineupBlock">
-	    <xsl:comment>filler</xsl:comment>
-	  </div>
-	  
-	  <div class="chordLineupBlock">
-	    <div id="offscreen-jtab-chord-Ab">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	    <div id="offscreen-jtab-chord-Gs">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	  </div>
-
-	  <div id="offscreen-jtab-chord-A" class="chordLineupBlock">
-	    <xsl:comment>filler</xsl:comment>
-	  </div>
-	  
-	  <div class="chordLineupBlock">
-	    <div id="offscreen-jtab-chord-Bb">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	    <div id="offscreen-jtab-chord-As">
-	      <xsl:comment>filler</xsl:comment>
-	    </div>
-	  </div>
-
-	  <div id="offscreen-jtab-chord-B" class="chordLineupBlock">
-	    <xsl:comment>filler</xsl:comment>
-	  </div>
+	  <gsf:div id="offscreen-jtab-chord-16" class="chordLineupBlock"/>
 	  
 	</div>
 
+
+
 	<gsf:script>
+          <![CDATA[
+
 	  $(document).ready(function() {
 
-	    jtab.render($('#offscreen-jtab-chord-C') ,'C');
-	    jtab.render($('#offscreen-jtab-chord-Cs'),'C#');
-	    jtab.render($('#offscreen-jtab-chord-Db'),'Db');
-	    jtab.render($('#offscreen-jtab-chord-D') ,'D');
-	    jtab.render($('#offscreen-jtab-chord-Ds'),'D#');
-	    jtab.render($('#offscreen-jtab-chord-Eb'),'Eb');
-	    jtab.render($('#offscreen-jtab-chord-F') ,'F');
-	    jtab.render($('#offscreen-jtab-chord-Fs'),'F#');
-	    jtab.render($('#offscreen-jtab-chord-Gb'),'Gb');
-	    jtab.render($('#offscreen-jtab-chord-G') ,'G');
-	    jtab.render($('#offscreen-jtab-chord-Gs'),'G#');
-	    jtab.render($('#offscreen-jtab-chord-Ab'),'Ab');
-	    jtab.render($('#offscreen-jtab-chord-A') ,'A');
-	    jtab.render($('#offscreen-jtab-chord-As'),'A#');
-	    jtab.render($('#offscreen-jtab-chord-Bb'),'Bb');
-	    jtab.render($('#offscreen-jtab-chord-B') ,'B');
+
+            setChordLineupMode("maj");
+	    chordChange("0");
+
+            var lineup = jam_chords["maj"];
+    
+            // add click handler and scale down in size: one-time operation
+
+            for (var i=0; i<lineup.length; i++) {
+                $('#offscreen-jtab-chord-'+i).click(function(ii) { return function(e) { chordChange(ii) } }(i) );
+
+                var $tab_svg = $('#offscreen-jtab-chord-'+i+'>div>svg');
+		$tab_svg.attr("width", "58"); // go thinner than 'natural' width of 69 (for a height of 59)
+		$tab_svg.attr("height","59");
+		// True box is 0 0 138 118, but shaving off values so not so much white-space
+		$tab_svg[0].setAttribute("viewBox","20 0 90 118"); // W3C DOM way to avoid jquery lower-casing 'viewBox' into 'viewbox'
+		$tab_svg.parent().css("height","59px");
+		//$tab_svg.parent().attr("height","59");
+		//$tab_svg.parent().parent().attr("width","60");
+		//$tab_svg.parent().parent().attr("height","59");
+		
+	    }
+
+   
+
+/*
+            $('#offscreen-jtab-chord-0').click(function(e) { chordChange('0') });
+            $('#offscreen-jtab-chord-1').click(function(e) { chordChange('1') });
+            $('#offscreen-jtab-chord-2').click(function(e) { chordChange('2') });
+            $('#offscreen-jtab-chord-3').click(function(e) { chordChange('3') });
+            $('#offscreen-jtab-chord-4').click(function(e) { chordChange('4') });
+            $('#offscreen-jtab-chord-5').click(function(e) { chordChange('5') });
+            $('#offscreen-jtab-chord-6').click(function(e) { chordChange('6') });
+            $('#offscreen-jtab-chord-7').click(function(e) { chordChange('7') });
+            $('#offscreen-jtab-chord-8').click(function(e) { chordChange('8') });
+            $('#offscreen-jtab-chord-9').click(function(e) { chordChange('9') });
+            $('#offscreen-jtab-chord-10').click(function(e) { chordChange('10') });
+            $('#offscreen-jtab-chord-11').click(function(e) { chordChange('11') });
+            $('#offscreen-jtab-chord-12').click(function(e) { chordChange('12') });
+            $('#offscreen-jtab-chord-13').click(function(e) { chordChange('13') });
+            $('#offscreen-jtab-chord-14').click(function(e) { chordChange('14') });
+            $('#offscreen-jtab-chord-15').click(function(e) { chordChange('15') });
+            $('#offscreen-jtab-chord-16').click(function(e) { chordChange('16') });
+*/
 
 	    $('#scaled-mytab').append($('#offscreen-jtab-chord-lineup'));
 
-	    console.log("!!!! forced background colour for F major in Guitar Tab area!!!")
-	    $('#builder_6').css("background-color","rgba(46,82,164,0.50)");
+
 	  });
+        ]]>
 	</gsf:script>
       </div>
