/*

 VexFlow TabDiv 1.0-pre2
 Copyright 2010 Mohit Muthanna Cheppudira <mohit@muthanna.com>

 A library for embedding editable tablature into HTML5 pages, using
 the VexTab tablature language.

 - Requires jQuery and VexFlow for HTML5 Canvas rendering.
 - Requires Raphael.js for SVG and VML support.

 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.

 This library must only be used in its original form. No tampering,
 modification, distribution, or repackaging is allowed without the
 explicit permission of the copyright holder.

 Build ID: prod-2@3623bb9c4bbcc225b32c691ae473c11df1c7f7f9
 Build date: 2010-07-26 18:01:42.389161

*/
var a;Vex.Flow.VexTab=function(){this.init()};a=Vex.Flow.VexTab.prototype;a.init=function(){this.elements={staves:[],tabnotes:[],notes:[],ties:[],beams:[]};this.state={current_line:0,current_stave:-1,current_duration:"8",has_notation:false,beam_start:null};this.valid=false;this.last_error="";this.height=this.last_error_line=0;this.tuning=new Vex.Flow.Tuning};a.isValid=function(){return this.valid};a.getElements=function(){return this.elements};a.getHeight=function(){return this.height};
a.parse=function(b){this.init();b=b.split("\n");for(var c=0;c<b.length;++c){var g=b[c];this.state.current_line++;g=g.replace(/(^\s*)|(\s*$)/gi,"");g!=""&&this.parseLine(g)}this.valid=true;this.height+=30;return this};a.parseError=function(b){this.valid=false;this.last_error=b;this.last_error_line=this.state.current_line;b=new Vex.RERR("ParseError","Line "+this.state.current_line+": "+b);b.line=this.state.current_line;throw b;};
a.parseLine=function(b){b=b.split(/\s+/);var c=b[0];switch(c){case "tabstave":this.parseTabStave(b);break;case "notes":this.parseNotes(b);break;default:this.parseError("Invalid keyword: "+c)}};a.parseKeyValue=function(b){var c=b.split(/\s*=\s*/);c.length!=2&&this.parseError("Invalid key value pair: "+b);return{key:c[0],value:c[1]}};
a.parseTabStave=function(b){for(var c=false,g=1;g<b.length;++g){var h=this.parseKeyValue(b[g]);if(h.key.toLowerCase()=="notation")switch(h.value.toLowerCase()){case "true":c=true;break;case "false":c=false;break;default:this.parseError('notation must be "true" or "false": '+h.value)}else this.parseError("Invalid parameter for tabstave: "+h.key)}this.genTabStave({notation:c})};
a.parseNotes=function(b){for(var c=1;c<b.length;++c)switch(b[c]){case "|":this.genBar();break;case "[":this.parseOpenBeam();break;case "]":this.parseCloseBeam();break;default:this.parseToken(b[c]);this.genElements()}this.state.beam_start!=null&&this.parseError("Beam not closed")};
a.getNextRegExp=function(b){this.parse_state.done&&this.parseError("Unexpected end of line");if(b=this.parse_state.str.match(b)){this.parse_state.value=b[1];this.parse_state.str=b[2];if(this.parse_state.str=="")this.parse_state.done=true;return true}this.parseError("Error parsing notes at: "+this.parse_state.str);return false};a.getNextToken=function(){return this.getNextRegExp(/^(\d+|[\)\(-tbhpsvV\.\/\|\:])(.*)/)};a.getNextDurationToken=function(){return this.getNextRegExp(/^([0-9a-z]+|:)(.*)/)};
a.parseToken=function(b){this.parse_state={str:b,done:false,expecting_string:false,positions:[],durations:[],position_index:-1,annotations:[],bends:[],vibratos:[],ties:[],chord_ties:[],inside_bend:false,chord_index:-1};for(b=false;!b&&this.getNextToken();){switch(this.parse_state.value){case "(":this.parseOpenChord();break;case "t":this.parseTapAnnotation();break;default:this.parseFret()}b=this.parse_state.done}};
Vex.Flow.VexTab.validDurations={w:"w",h:"h",q:"q","8":"8","8d":"8d","16":"16","16d":"16d","32":"32","32d":"32d"};a=Vex.Flow.VexTab.prototype;
a.parseDuration=function(){this.getNextDurationToken();var b=Vex.Flow.VexTab.validDurations[this.parse_state.value];if(b)this.state.current_duration=b;else this.parseError("Invalid duration: "+this.parse_state.value);if(!this.parse_state.done){this.getNextDurationToken();this.parse_state.value!=":"&&this.parseError("Unexpected token: "+this.parse_state.str);this.parse_state.done||this.parseError("Unexpected token: "+this.parse_state.str)}};
a.parseOpenChord=function(){this.parse_state.positions.push([]);this.parse_state.durations.push(this.state.current_duration);this.parse_state.position_index++;this.parse_state.chord_index=-1;this.getNextToken();this.parseChordFret()};a.parseTapAnnotation=function(){this.parse_state.annotations.push({position:this.parse_state.position_index+1,text:"T"});this.getNextToken();switch(this.parse_state.value){case "(":this.parseOpenChord();break;default:this.parseFret()}};
a.parseChordFret=function(){if(this.parse_state.value==":"){this.parseFretDuration();this.parse_state.durations[this.parse_state.durations.length-1]=this.state.current_duration;if(this.parse_state.done)return;this.getNextToken()}var b=this.parse_state.value;isNaN(parseInt(b))&&this.parseError("Invalid fret number: "+b);this.getNextToken();if(this.parse_state.value=="b")this.parseChordBend();else this.parse_state.value!="/"&&this.parseError("Expecting / for string number: "+this.parse_state.value);
this.getNextToken();var c=parseInt(this.parse_state.value);isNaN(parseInt(c))&&this.parseError("Invalid string number: "+this.parse_state.value);this.parse_state.positions[this.parse_state.position_index].push({fret:b,str:c});this.parse_state.chord_index++;this.getNextToken();switch(this.parse_state.value){case ".":this.getNextToken();this.parseChordFret();break;case ")":this.parseCloseChord();break;default:this.parseError("Unexpected token: "+this.parse_state.value)}};
a.parseCloseChord=function(){this.chord_index=-1;if(!this.parse_state.done){this.getNextToken();switch(this.parse_state.value){case "h":this.parseChordTie();break;case "p":this.parseChordTie();break;case "s":this.parseChordTie();break;case "t":this.parseChordTie();break;case "v":this.parseVibrato();break;case "V":this.parseVibrato();break;default:this.parseError("Unexpected token: "+this.parse_state.value)}}};
a.parseChordBend=function(){this.getNextToken();var b=parseInt(this.parse_state.value);isNaN(b)&&this.parseError("Expecting fret: "+this.parse_state.value);if(this.parse_state.inside_bend)this.parse_state.bends[this.parse_state.bends.length-1].count++;else{this.parse_state.inside_bend=true;this.parse_state.bends.push({position:this.parse_state.position_index,count:1,index:this.parse_state.chord_index+1,to_fret:b})}this.getNextToken();switch(this.parse_state.value){case "b":this.parseChordBend();break;
case "/":break;default:this.parseError("Unexpected token: "+this.parse_state.value)}this.parse_state.inside_bend=false};a.parseFretDuration=function(){this.getNextDurationToken();var b=Vex.Flow.VexTab.validDurations[this.parse_state.value];if(b)this.state.current_duration=b;else this.parseError("Invalid duration: "+this.parse_state.value);if(!this.parse_state.done){this.getNextDurationToken();this.parse_state.value!=":"&&this.parseError("Unexpected token: "+this.parse_state.str)}};
a.parseFret=function(){if(this.parse_state.value==":"){this.parseFretDuration();if(this.parse_state.done)return;this.getNextToken()}var b=this.parse_state.value;isNaN(parseInt(b))&&this.parseError("Invalid fret number: "+b);this.parse_state.positions.push([{fret:b}]);this.parse_state.durations.push(this.state.current_duration);this.parse_state.position_index++;this.getNextToken();switch(this.parse_state.value){case "-":this.parseDash();break;case "/":this.parseSlash();break;case "b":this.parseBend();
break;case "s":this.parseTie();break;case "t":this.parseTie();break;case "h":this.parseTie();break;case "p":this.parseTie();break;case "v":this.parseFretVibrato();break;case "V":this.parseFretVibrato();break;default:this.parseError("Unexpected token: "+this.parse_state.value)}};a.parseDash=function(){this.parse_state.inside_bend=false;this.parse_state.expecting_string&&this.parseError("No dashes on strings: "+this.parse_state.str)};
a.parseVibrato=function(){var b=false;if(this.parse_state.value=="V")b=true;var c=this.parse_state.position_index;if(this.parse_state.inside_bend)c-=this.parse_state.bends[this.parse_state.bends.length-1].count;this.parse_state.vibratos.push({position:c,harsh:b})};
a.parseFretVibrato=function(){this.parseVibrato();this.getNextToken();switch(this.parse_state.value){case "-":this.parseDash();break;case "s":this.parseTie();break;case "h":this.parseTie();break;case "p":this.parseTie();break;case "t":this.parseTie();break;case "/":this.parseSlash();break;default:this.parseError("Unexpected token: "+this.parse_state.value)}};a.parseSlash=function(){this.parse_state.inside_bend=false;this.parse_state.expecting_string=true;this.getNextToken();this.parseString()};
a.parseString=function(){var b=this.parse_state.value;this.parse_state.positions.length==0&&this.parseError("String without frets: "+b);for(var c=0;c<this.parse_state.positions.length;++c)this.parse_state.positions[c][0].str=b};
a.parseTie=function(){this.parse_state.inside_bend=false;this.parse_state.expecting_string&&this.parseError("Unexpected token on string: "+this.parse_state.str);this.parse_state.ties.push({position:this.parse_state.position_index,index:this.parse_state.chord_index+1,effect:this.parse_state.value.toUpperCase()});this.getNextToken();this.parseFret()};
a.parseChordTie=function(){this.parse_state.chord_ties.push({position:this.parse_state.position_index,effect:this.parse_state.value.toUpperCase()});this.getNextToken();this.parse_state.value!="("&&this.parseError("Expecting ( after chord ties/slides");this.parseOpenChord()};
a.parseBend=function(){this.parse_state.expecting_string&&this.parseError("Unexpected token on string: "+this.parse_state.str);if(this.parse_state.inside_bend)this.parse_state.bends[this.parse_state.bends.length-1].count++;else{this.parse_state.inside_bend=true;this.parse_state.bends.push({position:this.parse_state.position_index,count:1,index:0})}this.getNextToken();this.parseFret()};
a.genElements=function(){function b(p){for(var o=p;o>=0;--o)if(h[o].persist==true)return o;throw new Vex.RERR("GenError","Invalid position: "+p);}this.state.current_stave==-1&&this.genTabStave();for(var c=this.parse_state.positions,g=this.parse_state.durations,h=[],m=[],f=0;f<c.length;++f){var d=c[f],i=g[f],e=new Vex.Flow.TabNote({positions:d,duration:i});h.push({note:e,persist:true});if(this.state.has_notation){var k=[],j=[];for(e=0;e<d.length;++e){var l=d[e];l=this.tuning.getNoteForFret(l.fret,
l.str);var n=Vex.Flow.keyProperties(l);j.push(n.accidental);k.push(l)}d=new Vex.Flow.StaveNote({keys:k,duration:i});for(e=0;e<j.length;++e)j[e]&&d.addAccidental(e,new Vex.Flow.Accidental(j[e]));m.push(d)}}e=this.parse_state.bends;for(f=0;f<e.length;++f){d=e[f];g=parseInt(c[d.position][d.index].fret);if(e[f].to_fret)i=e[f].to_fret;else{i=parseInt(c[d.position+1][d.index].fret);for(j=1;j<=d.count;++j)h[d.position+j].persist=false}j=false;if(d.count>1)j=true;k=h[d.position].note;switch(i-g){case 1:k.addModifier(new Vex.Flow.Bend("1/2",
j),d.index);break;case 2:k.addModifier(new Vex.Flow.Bend("Full",j),d.index);break;case 3:k.addModifier(new Vex.Flow.Bend("1 1/2",j),d.index);break;case 4:k.addModifier(new Vex.Flow.Bend("2 Steps",j),d.index);break;default:k.addModifier(new Vex.Flow.Bend("Bend to "+i,j),d.index)}}e=this.parse_state.vibratos;for(f=0;f<e.length;++f){d=e[f];h[d.position].note.addModifier((new Vex.Flow.Vibrato).setHarsh(d.harsh))}e=this.parse_state.annotations;for(f=0;f<e.length;++f){d=e[f];h[d.position].note.addModifier(new Vex.Flow.Annotation(d.text))}d=
this.parse_state.ties;for(f=0;f<d.length;++f){g=d[f];i=b(g.position);e=g.effect=="S"?new Vex.Flow.TabSlide({first_note:h[i].note,last_note:h[g.position+1].note}):new Vex.Flow.TabTie({first_note:h[i].note,last_note:h[g.position+1].note},g.effect);this.state.has_notation&&this.elements.ties[this.state.current_stave].push(new Vex.Flow.StaveTie({first_note:m[i],last_note:m[g.position+1]}));this.elements.ties[this.state.current_stave].push(e)}j=this.parse_state.chord_ties;for(f=0;f<j.length;++f){g=j[f];
i=b(g.position);k=[];for(e=0;e<c[i].length;++e){d=c[i][e];k[d.str]={from:e}}for(e=0;e<c[g.position+1].length;++e){d=c[g.position+1][e];k[d.str]||(k[d.str]={});k[d.str].to=e}d=[];l=[];for(e=0;e<k.length;++e)if(n=k[e])if(!(typeof n.from=="undefined"||typeof n.to=="undefined")){d.push(n.from);l.push(n.to)}e=g.effect=="S"?new Vex.Flow.TabSlide({first_note:h[i].note,last_note:h[g.position+1].note,first_indices:d,last_indices:l}):new Vex.Flow.TabTie({first_note:h[i].note,last_note:h[g.position+1].note,
first_indices:d,last_indices:l},g.effect);this.state.has_notation&&this.elements.ties[this.state.current_stave].push(new Vex.Flow.StaveTie({first_note:m[i],last_note:m[g.position+1],first_indices:d,last_indices:l}));this.elements.ties[this.state.current_stave].push(e)}for(f=0;f<h.length;++f){d=h[f];d.persist?this.elements.tabnotes[this.state.current_stave].push(d.note):this.elements.tabnotes[this.state.current_stave].push(new Vex.Flow.GhostNote(this.state.current_duration))}for(f=0;f<m.length;++f){d=
m[f];this.elements.notes[this.state.current_stave].push(d)}};
a.genTabStave=function(b){var c=false;if(b)c=b.notation;b=c?(new Vex.Flow.Stave(20,this.height,380)).addTrebleGlyph().setNoteStartX(40):null;var g=(new Vex.Flow.TabStave(20,c?b.getHeight()+this.height:this.height,380)).addTabGlyph().setNoteStartX(40);this.elements.staves.push({tab:g,note:b});this.height+=g.getHeight()+(c?b.getHeight():null);this.state.current_stave++;this.state.has_notation=c;this.elements.tabnotes[this.state.current_stave]=[];this.elements.notes[this.state.current_stave]=[];this.elements.ties[this.state.current_stave]=
[]};a.parseOpenBeam=function(){this.state.beam_start!=null&&this.parseError("Beam already open: [");this.state.beam_start=this.elements.notes[this.state.current_stave].length};
a.parseCloseBeam=function(){this.state.beam_start==null&&this.parseError("Can't close beam without openeing: ]");var b=this.elements.notes[this.state.current_stave].length;b-this.state.beam_start<2&&this.parseError("Must have at least two notes in a beam.");for(var c=[],g=this.state.beam_start;g<b;++g)c.push(this.elements.notes[this.state.current_stave][g]);this.elements.beams.push(new Vex.Flow.Beam(c));this.state.beam_start=null};
a.genBar=function(){this.state.current_stave==-1&&this.genTabStave();this.elements.tabnotes[this.state.current_stave].push(new Vex.Flow.BarNote);this.elements.notes[this.state.current_stave].push(new Vex.Flow.BarNote)};Vex.Flow.TabDiv=function(b){arguments.length>0&&this.init(b)};Vex.Flow.TabDiv.SEL=".vex-tabdiv";Vex.Flow.TabDiv.ERROR_NOCANVAS="<b>This browser does not support HTML5 Canvas</b><br/>Please use a modern browser such as <a href='http://google.com/chrome'>Google Chrome</a> or <a href='http://firefox.com'>Firefox</a>.";a=Vex.Flow.TabDiv.prototype;
a.init=function(b){this.sel=b;this.code=$(b).text();$(b).empty();this.width=$(b).attr("width")||600;this.height=$(b).attr("height")||200;this.scale=$(b).attr("scale")||1;if(typeof Raphael=="undefined"){this.canvas=$("<canvas></canvas>").addClass("vex-canvas");$(b).append(this.canvas);this.renderer=new Vex.Flow.Renderer(this.canvas[0],Vex.Flow.Renderer.Backends.CANVAS)}else{this.canvas=$("<div></div>").addClass("vex-canvas");$(b).append(this.canvas);this.renderer=new Vex.Flow.Renderer(this.canvas[0],
Vex.Flow.Renderer.Backends.RAPHAEL)}this.renderer.resize(this.width,this.height);this.ctx=this.renderer.getContext();this.ctx.scale(this.scale,this.scale);this.editor=$(b).attr("editor")||"";this.editor_width=$(b).attr("editor_width")||this.width;this.editor_height=$(b).attr("editor_height")||200;var c=this;if(this.editor=="true"){this.text_area=$("<textarea></textarea>").addClass("editor").val(this.code);this.editor_error=$("<div></div>").addClass("editor-error");$(b).append($("<p/>")).append(this.editor_error);
$(b).append($("<p/>")).append(this.text_area);this.text_area.width(this.editor_width);this.text_area.height(this.editor_height);this.text_area.keyup(function(){c.timeoutID&&window.clearTimeout(c.timeoutID);c.timeoutID=window.setTimeout(function(){if(c.code!=c.text_area.val()){c.code=c.text_area.val();c.redraw()}},100)})}this.parser=new Vex.Flow.VexTab;this.extra_height=(this.message=Vex.Flow.setupCanvasArray())?20:10;this.redraw()};
a.redraw=function(){var b=this;Vex.BM("Total render time: ",function(){b.parse();b.draw()});return this};a.resize=function(){this.renderer.resize(this.width*this.scale,this.height*this.scale);this.ctx=this.renderer.getContext()};
a.drawInternal=function(){if(!this.parser.isValid())return this;this.editor_error&&this.editor_error.empty();var b=this.parser.getElements(),c=b.staves;if(c.length==0){this.resize(this.width,10);this.ctx.clear();return this}var g=b.tabnotes,h=b.notes,m=b.ties;b=b.beams;this.height=this.parser.getHeight()+this.extra_height;this.resize(this.width,this.height);this.ctx.clear();this.ctx.setFont("Arial",8,"Bold");for(var f=0;f<c.length;++f){var d=c[f].tab,i=c[f].note,e=g[f],k=m[f];d.setWidth(this.width-
50);d.setContext(this.ctx).draw();if(i){var j=h[f];i.setWidth(this.width-50);i.setContext(this.ctx).draw();e&&j&&Vex.Flow.Formatter.FormatAndDrawTab(this.ctx,d,i,e,j,this.width-100)}else e&&Vex.Flow.Formatter.FormatAndDraw(this.ctx,d,e,this.width-100);for(d=0;d<k.length;++d)k[d].setContext(this.ctx).draw()}for(d=0;d<b.length;++d)b[d].setContext(this.ctx).draw();if(this.message){this.ctx.setFont("Times",10,"bold italic");this.ctx.fillText(this.message,this.width/2-40,this.height-10)}return this};
a.parseInternal=function(){try{this.parser.parse(this.code)}catch(b){if(this.editor_error){this.editor_error.empty();this.editor_error.append($("<span></span>").addClass("text").html(b.message))}}return this};a.parse=function(){var b=this;Vex.BM("Parse time: ",function(){b.parseInternal()});return this};a.draw=function(){var b=this;Vex.BM("Draw time: ",function(){b.drawInternal()});return this};Vex.Flow.TabDiv.start=function(){$(Vex.Flow.TabDiv.SEL).each(function(){new Vex.Flow.TabDiv(this)})};
$(function(){Vex.Flow.TabDiv.SEL&&Vex.Flow.TabDiv.start()});

