
function overscan(iw,ih,sw,sh) {
  var wr=iw/sw;
  var hr=ih/sh;
//alert(wr+" "+hr);
  var x=0;
  var y=0;
  var width;
  var height;
  
  if(wr<hr)
  {
    x="0px";
    y=Math.floor((sh-((1.0/wr)*ih))/2)+"px";
    width="100%";
    height=(1.0/wr)*ih+"px";
  } else
  {
    y="0px";
    x=Math.floor((sw-((1.0/hr)*iw))/2)+"px";
    height="100%";
    width=(1.0/hr)*iw+"px";
  }
  return {x:x,y:y,width:width,height:height};  
}

function splitSong(text)
{
  text="  \n"+text.replace(/\r/g,"");
  var b1=text.split(/\n\w+:/gm);
  var b2=text.match(/\n\w+:/gm);
  var block=new Array();
  var out={};
  out['song']=new Array();
  var b=0;
  if(b2)
  {
  b2.each(function (ln, i){block[i]={"name":b2[i].replace(/\n/,"").slice(0,-1).toLowerCase(),"data":b1[i+1]}});
  block.each(function (ln, i)
  {
//    alert(block[i].name+" "+block[i].data);
     
    switch(block[i].name)
    {
//      case "intro":
//        out['intro']=block[i].data;
//        break;
      case "copy":
        out['copy']=block[i].data;
        break;
      case "title":
        out['title']=block[i].data;
        break;
      case "author":
        out['author']=block[i].data;
        break;
      case "capo":
        out['capo']=block[i].data;
      break; 
      default:
        if(block[i].data)
        {
          out['song'][b]={'name':block[i].name,'data':lineSplit(block[i].data)};
          b++;
        }
    }
  });
 // alert(JSON.encode(out));
 }
  return out;
}

function lineSplit(block)
{
  block=rtrim(block);
  block=block.replace(/\r/g,"");
//  alert(block);
 block=block.replace(/^\n/,"");
//  block=block.replace(/$\n*/,"");
  block=block.replace(/\n\n/g,"\n \n");
  block=block.replace(/\n\n/g,"\n \n");
  var line=block.split(/\n/g);
	line.each(function (ln, i){line[i]=ln.replace(/\n/,"")});
  if(line.length%2==1)
	  line[line.length]=" ";
  out=new Array();
  for (var i=0;i<line.length-1;i+=2)
  {
    out[i/2]={"chords":line[i],"words":line[i+1]};
  }
  return out;
}

function getSongHTML(song)
{
//  alert(song.title);
  var out={};
  if(song.title)
    out.title=new Element('div',{'html':song.title,'class':'songtitle'});
  if(song.author)
    out.author=new Element('div',{'html':song.author,'class':'author'});
  if(song.capo)
    out.capo=new Element('div',{'html':'Capo: '+song.capo,'class':'capo'});
  if(song.song)
  {
    var sout=new Element('div',{'class':'song'});
    song.song.each(function (verse){(verseHTML(verse)).inject(sout)});
    
    if(sout.getLast())
      sout.getLast().setStyle('margin-bottom',"0");
      
    if(sout.getFirst())
    {
      sout.getFirst().setStyle('margin-top',"0");
      sout.getChildren().each(function(verse)
      {
        var prv;
        if ((prv=verse.getPrevious())&&(prv=prv.get('class'))&&(prv=='nowords'))
          verse.setStyle('margin-top',"0");
        if ((prv=verse.getNext())&&(prv=prv.get('class'))&&(prv=='nowords'))
          verse.setStyle('margin-bottom',"0");
      });
    }
    out.song=sout;
  }
  if(song.copy)
    out.copy=new Element('div',{'html':song.copy,'class':'copy'});
 // alert(out.innetHTML)
  return out;
}

function verseHTML(verse)
{
 // alert(JSON.encode(verse));
  var out=new Element('div',{'class':'verse'});
  var nowords=true;
  var nowordslastline=true;
  if(verse.name)
    (new Element('div',{'html':verse.name,'class':'versename','style':'display: none'})).inject(out);
  if(verse.data)
  {
    verse.data.each(function (line)
    {
      chords=trim(line.chords).split(/\s+/);
      var indx=0;
      var offset=0;
	    var offset2=new Array();
      nowordslastline=true;
      if(line.words.search(/^\s*$/))
      {
        nowords=false;
        nowordslastline=false;
      }
	    words=lpad(line.words);
	    while(words.length<line.chords.length)
        words+="\u2002";
		  
      for (var j=0;j<chords.length;j++)
      {
        offset2[j]=line.chords.indexOf(chords[j])+indx;
        offset=line.chords.indexOf(chords[j])+chords[j].length;
        line.chords=line.chords.substring(offset,line.chords.length);
        indx+=offset;
  	  }
      mat=words.match(/  +/g);
      if(mat)
      {
        mat.each(function(m){
          var tp=m.replace(/ /g,'\u2002');
          words=words.replace(new RegExp(m)," "+tp.substr(1));
        });
      }

  	  for (var j=chords.length-1;j>=0;j--)
      {     
  		  words=words.substr(0,offset2[j])+"<span class='cwrap'><div class='chord'>"+chords[j]+"</div></span>"+words.substr(offset2[j]);
      }
      
      words=words.replace(/(\u2002+)/g,"<span class='padding'>$1</span>");
      (new Element('div',{'html':words.substr(0,words.length),'class':line.words!=' '?'line':'line'})).inject(out);
//  	  html+="  <div class='line'>"+words.substr(0,words.length)+"</div>\n";
    });
  }
  if(nowordslastline)
  { 
    var newele=new Element('div',{'class':'nowordslastline'});
    out.inject(newele);
    out=newele;
  }
  if(nowords)
  { 
    var newele=new Element('div',{'class':'nowords'});
    out.inject(newele);
    out=newele;
  }
//  if(nowords)
//    out=new Element('div',{'class':'nowords'});
  return out;
}

function renderSong(id,text)
{
  var html="<div class='song'>";
  text=text.replace(/\n\s*\n\s*\n\s*\n/g,"\n\n\n{_blank}");
  verse=text.split(/\n\s*\n\s*\n/);
  
  for (var h=0;h<verse.length;h++)
  {   
    html+="<div class='verse'>\n";
	  verse[h]=verse[h].replace(/{_blank}/,'\n');
    line=verse[h].split(/^/m);
	  line.each(function (ln, i){line[i]=ln.replace(/\n/,"");});
	  if(line.length%2==1)
	  line[line.length]=" ";
    for (var i=0;i<line.length-1;i+=2)
    {
      chords=trim(line[i]).split(/\s+/);
      var indx=0;
      var offset=0;
	    var offset2=new Array();
	    line[i+1]=lpad(line[i+1]);
	    while(line[i+1].length<line[i].length)
        line[i+1]+="\u2002";
		  
      for (var j=0;j<chords.length;j++)
      {
        offset2[j]=line[i].indexOf(chords[j])+indx;
        offset=line[i].indexOf(chords[j])+chords[j].length;
        line[i]=line[i].substring(offset,line[i].length);
        indx+=offset;
  	  }
      mat=line[i+1].match(/  +/g);
      if(mat)
      {
        mat.each(function(m){
          var tp=m.replace(/ /g,'\u2002');
          line[i+1]=line[i+1].replace(new RegExp(m)," "+tp.substr(1));
        });
      }
 //       $each(mat,function(m){line[i+1]=line[i+1].replace(new RegExp(m),m.replace(/ /,"b"))});
  	  for (var j=chords.length-1;j>=0;j--)
      {     
  		  line[i+1]=line[i+1].substr(0,offset2[j])+"<span class='cwrap'><div class='chord'>"+chords[j]+"</div></span>"+line[i+1].substr(offset2[j]);
      }
      
      line[i+1]=line[i+1].replace(/(\u2002+)/g,"<span class='padding'>$1</span>");
  	  html+="  <div class='line'>"+line[i+1].substr(0,line[i+1].length)+"</div>\n";
  	}
    html+="</div>\n\n";
  }
  html+="</div>\n\n";
  $(id).set('html',html);
  return html;
}


function redraw()
{
//  $("html").value=renderSong("render",$("songwords").value);
  var html=getSongHTML(splitSong($("songwords").value));
  $("render").set('html','');
  html.song.inject($("render"));
}


function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}
 
function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
 
function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function lpad(str){
  var len=str.length-ltrim(str).length;
  str=ltrim(str);
  for (var i=0;i<len;i++)
    str="\u2002"+str;
  return str;
}

function createStyle(style)
{
  style['verse']=style['verse']?style['verse']:0; // 0 is display whole song
  style['verse-size']=style['verse-size']?style['verse-size']:'constant';
  style['chords']=style['chords']?style['chords']:'visible';
  style['width']=style['width']?style['width']:1;
  style['height']=style['height']?style['height']:1; //these are as a fraction of screen dimensions
  style['xoffset']=style['xoffset']?style['xoffset']:0;
  style['yoffset']=style['yoffset']?style['yoffset']:0;
  style['valign']=style['valign']?style['valign']:'middle';
  style['verse-css']=style['verse-css']?style['verse-css']:{};
  style['line-css']=style['line-css']?style['line-css']:{};
  style['chord-css']=style['chord-css']?style['chord-css']:{};
  style['screen-css']=style['screen-css']?style['screen-css']:{};
  return style;
}

function overscanresize(im,css)
{
  var over=overscan(im.width,im.height,$('body').getSize().x,$('body').getSize().y);
      im.setStyles({'position':'absolute'
                   ,'left':over.x
                   ,'top':over.y
                   ,'width':over.width
                   ,'height':over.height
                   });                
  im.inject($("overscan").empty());
  if(css)
  im.setStyles(css);
}

function overscanvideoresize(im,css)
{ 
  var over=overscan(im.videoWidth,im.videoHeight,$('body').getSize().x,$('body').getSize().y);
      im.setStyles({'position':'absolute'
                   ,'left':over.x
                   ,'top':over.y
                   ,'width':over.width
                   ,'height':over.height
                   });
  if(css)
  im.setStyles(css);
}

function fitSongToScreen(style)
{
  var out=0;
  var wholesong=(style['verse']==0);
  var verses;
  var verse=style['verse'];
  var hasvideo=false;
  $("frontbuffer").setStyles({"top":0,"left":0});
  $("fullscreen").removeEvent('mousemove');
  if(!wholesong)
  {
    verses=$("backbuffer").getFirst().getChildren();
    verse=Math.max(1,Math.min(verses.length,verse))-1;
  }
//  if (style['overscan-css'])
 //   $('overscan').getChild().setStyles(style['overscan-css']);
  
  if(style['overscan-video'])
  {
    var test;
    if((test=$('overscan').getElement('video'))&&(test=test.get('src'))&&(test==style['overscan-video']))
    {
      hasvideo=true;
      overscanvideoresize($('overscan').getElement('video'),style['overscan-css']);
    }
    else
    {
      var im=new Element('video',{'src':style['overscan-video'],'autoplay':' '});
      if(hasVideo())
      {
        im.addEventListener("loadedmetadata", function() { overscanvideoresize(im,style['overscan-css']);},true);
        im.addEventListener("ended", function() {im.currentTime=0}, true);
        overscanvideoresize(im,style['overscan-css']);
        im.inject($("overscan").empty());
        hasvideo=true;
      }
    }
  }
  if((style['overscan-image'])&&(!hasvideo))
  {
    
    var im=new Element('img',{'src':style['overscan-image']});
    if(im.width)
    {
      overscanresize(im,style['overscan-css']);
    }
    else
    {
      im.addEvent('load',function(){overscanresize(im,style['overscan-css']);});;
    }
      
  }

  if(style['chords']=='visible')
  {
    $("frontbuffer").set('class','ss_display_chords');
    $("backbuffer").set('class','ss_display_chords');
    $$('.padding').each(function(bx){bx.setStyle('display','inline')});
  } else
  {
    $("frontbuffer").set('class','');
    $("backbuffer").set('class','');
    $$('.padding').each(function(bx){bx.setStyle('display','none')});
  }
  var screenw=$("fullscreen").getSize().x;
  
  var screenh=$("fullscreen").getSize().y;
  var songmaxw=$("backbuffer").getSize().x;

  var songmaxh;
  if(wholesong)
    songmaxh=$("backbuffer").getSize().y
  else if(style['verse-size']=='constant')
  {
    $("backbuffer").getElements('.verse, .verseoneline').each(function (node,i){out=Math.max(out,node.getSize().y)});
    songmaxh=out;
  } else
  {
    var v=$("backbuffer").getElements('.verse, .verseoneline');
    songmaxh=v[style['verse']-1].getSize().y;
    var ele = new Element('div',{'class':'song'});
    ele.set('html',"<div id='tempmeasure' class='song' style='float: left;'>"+verses[verse].get('html')+"</div>").inject($('backbuffer'));
    songmaxw=$("tempmeasure").getSize().x;
    ele.destroy();
  }
  
  var fontsize=parseInt($("backbuffer").getFirst().getFirst().getStyle('font-size'));
  var scale=(Math.floor(((screenw*0.9*style['width'])/(screenh*style['height']))>(songmaxw/songmaxh))&&(style['verse-size']!='scroll')?(fontsize*screenh*style['height'])/songmaxh:(fontsize*(screenw*0.9*style['width']))/songmaxw);
  if(wholesong)
  {
    $("frontbuffer").set('html',$("backbuffer").get('html'));
  } else
  {
    var ele = new Element('div',{'class':'song'});
//  $("frontbuffer").setStyle('visibility','hidden');
    verses[verse].clone().inject(ele).inject($('frontbuffer').empty());
  }
  $("frontbuffer").getElements('.verse, .verseoneline').each(function (ele){ele.setStyle('font-size',scale)});
  $("frontbuffer").setStyle("left",(style['xoffset']*screenw)+(screenw-$("frontbuffer").getSize().x)/2);
  switch(style['valign'])
  {
  case 'middle':
    $("frontbuffer").setStyle("top",(style['yoffset']*screenh)+(screenh-$("frontbuffer").getSize().y)/2);
    break;
  case 'top':
    $("frontbuffer").setStyle("top",style['yoffset']*screenh);
    break;
  case 'bottom':
    $("frontbuffer").setStyle("bottom",style['yoffset']*screenh);
    break;  
  }
  if (style['verse-size']=='scroll')
  {
    $("frontbuffer").setStyle("top",screenh-(style['height']*screenh));
    $("fullscreen").addEvent('mousemove', function (evt)
    {
      var tmp=screenh-(style['height']*screenh);
      var tmp2=tmp-(evt.client.y/screenh)*($('frontbuffer').getSize().y+tmp+tmp-screenh);
      $("frontbuffer").setStyle("top",tmp2);
    });
  }
  $("frontbuffer").getElements(".song").each(function (ele){ele.setStyles(style['song-css'])});
  $("frontbuffer").getElements(".verse, .verseoneline").each(function (ele){ele.setStyles(style['verse-css'])});
  $("frontbuffer").getElements(".line").each(function (ele){ele.setStyles(style['line-css'])});
  $("frontbuffer").getElements(".chord").each(function (ele){ele.setStyles(style['chord-css'])});
  $("frontbuffer").getParent("").setStyles(style['screen-css']);
  if(style['chords']=='visible')
  {
     $("frontbuffer").getElements(".song").each(function (ele){ele.setStyle('text-align','left')});
  }
  if (style['verse-size']!='scroll')
    addOnClicksToVerses(style);
}

function addOnClicksToVerses(style)
{
//  alert('run');
  $("frontbuffer").getElements(".verse, .verseoneline").each(function (ele,i){ele.removeEvents('click');ele.addEvent('click',function(event)
  {
    style['verse']=style['verse']==0?i+1:0;
    event.stop();
    fitSongToScreen(style);
  })});
}

function hasVideo()
{
  var vid = document.createElement('video');
	return (hasattr(vid, 'currentTime') && hasattr(vid, 'play') && hasattr(vid, 'pause') &&
	       hasattr(vid, 'duration') && hasattr(vid, 'volume'));
}

function hasattr(elem,attr) {
	var isset;
	try {
	    eval("isset=typeof elem."+attr+"!='undefined';");
	} catch (e) {
	    isset=false;
	}
	return isset;
}

//
// Rendering
//




function getSongWidth(id)
{
  return $(id).getSize().x;
}

function getMaxVerseHeight(id)
{
  $(id).getChildren().each(function (node,i){var out=0;out=Math.max(out,node.getSize().y)});
}
//
// Editing
//

