(function($){var labelIndex=0;$.fn.theogram=function(opts){var container=this;var fullWidthIncludingBorders=784;var fullWidth=fullWidthIncludingBorders-10;var drawerWidth=212;var viewportLeftMargin=drawerWidth+8;var viewportRightMargin=8;var usableViewportWidth=fullWidth-viewportLeftMargin-viewportRightMargin;var rowHeight=26;var topMargin=20;var bottomMargin=54;var allRowsHeight=opts.rows.length*rowHeight;var height=allRowsHeight+topMargin+bottomMargin;var timelineWidth=fullWidth;var animationDuration=3000;var drawerVisible=true;var isInteractive=!window.THEOGRAM_STANDALONE;container.addClass('theogram-active').css({'width':fullWidth+'px'});var headingElem=$('<div class="heading"></div>');container.append(headingElem);var captionElem=$('<div class="caption"></div>');headingElem.append(captionElem);captionWidth=Math.min(650,fullWidth-250);captionElem.css({'width':captionWidth+'px'});var titleElem=$('<h2></h2>').text(opts.title);captionElem.append(titleElem);var descriptionElem=$('<p></p>').text(opts.description);captionElem.append(descriptionElem);if(window.THEOGRAM_STANDALONE){var logo=$('<div class="logo">Nuffield Trust</div>');headingElem.append(logo);}
var zoomElem=$('<div class="zoom">Zoom:</div>');var zoomOutElem=$('<a href="javascript:void(0)" class="zoom-out" title="Zoom out">Out</a>');zoomOutElem.click(function(){if(drawerVisible){changeZoom(-1,fullWidth/2+drawerWidth/2);}else{changeZoom(-1,fullWidth/2);}})
zoomElem.append(zoomOutElem);var zoomInElem=$('<a href="javascript:void(0)" class="zoom-in" title="Zoom in">In</a>');zoomInElem.click(function(){if(drawerVisible){changeZoom(+1,fullWidth/2+drawerWidth/2);}else{changeZoom(+1,fullWidth/2);}})
zoomElem.append(zoomInElem);if(isInteractive)headingElem.append(zoomElem);headingElem.append('<div style="clear: both;"></div>');var bodyElem=$('<div class="theogram-body"></div>').css({'height':height+'px'});container.append(bodyElem);var bodyInnerElem=$('<div class="theogram-body-inner"></div>').css({'height':height+'px'});bodyElem.append(bodyInnerElem);var drawerElem=$('<div class="drawer"></div>');bodyInnerElem.append(drawerElem);var drawerControlsElem=$('<div class="controls"></div>');drawerElem.append(drawerControlsElem);var drawerShowHideElem=$('<a href="javascript:void(0)" class="hide" title="Hide labels">Hide</a>');drawerShowHideElem.toggle(function(){drawerElem.animate({'left':-drawerWidth+'px'},function(){drawerShowHideElem.attr({'class':'show','title':'Show labels'}).text('Show');});scrollLeftElem.animate({'left':'8px'});drawerVisible=false;},function(){drawerElem.animate({'left':'0px'},function(){drawerShowHideElem.attr({'class':'hide','title':'Hide labels'}).text('Hide');});scrollLeftElem.animate({'left':'199px'});drawerVisible=true;});if(isInteractive)drawerControlsElem.append(drawerShowHideElem);var rowHeadingsElem=$('<ul class="row-headings"></ul>');drawerElem.append(rowHeadingsElem);var rowsById={};function addRowHeading(row){var rowHeadingElem=$('<li></li>');rowHeadingElem.append($('<label></label>').text(row.name).attr({'for':'theogram-checkbox-'+labelIndex}));rowHeadingElem.addClass(i%2?'odd':'even');var checkbox=$('<input type="checkbox" checked="checked" />').attr({'id':'theogram-checkbox-'+labelIndex});labelIndex++;row.checkbox=checkbox.get(0);checkbox.change(function(){if(this.checked){rowHeadingElem.removeClass('disabled');}else{rowHeadingElem.addClass('disabled');}
plot();});if(isInteractive)rowHeadingElem.append(checkbox);rowHeadingsElem.append(rowHeadingElem);}
for(var i=0;i<opts.rows.length;i++){var row=opts.rows[i];row.index=i;rowsById[row.id]=row;addRowHeading(row);}
var viewportElem=$('<div class="viewport"></div>');bodyInnerElem.append(viewportElem);var raphaelElem=$('<div class="timeline"></div>');viewportElem.append(raphaelElem);var scrollLeftElem=$('<a href="javascript:void(0)" class="scroll-left">Previous</a>');scrollLeftElem.css({'top':(topMargin+allRowsHeight+8)+'px'});if(isInteractive)bodyInnerElem.append(scrollLeftElem);var scrollRightElem=$('<a href="javascript:void(0)" class="scroll-right">Next</a>');scrollRightElem.css({'top':(topMargin+allRowsHeight+8)+'px'});if(isInteractive)bodyInnerElem.append(scrollRightElem);var copyright=$('<div class="copyright">&copy; Nuffield Trust</div>');bodyInnerElem.append(copyright);scrollLeftElem.mousedown(function(e){if(e.which!=1)return;var originalViewportX=viewportX;var keepScrolling=true;var timer=setInterval(function(){setViewportX(viewportX-10);if(!keepScrolling){var distanceScrolled=originalViewportX-viewportX;if(distanceScrolled>120||atStart())clearInterval(timer);}},20)
function mouseup(e){if(e.which!=1)return;keepScrolling=false;$(document).unbind('mouseup',mouseup);}
$(document).mouseup(mouseup);return false;})
scrollRightElem.mousedown(function(e){if(e.which!=1)return;var originalViewportX=viewportX;var keepScrolling=true;var timer=setInterval(function(){setViewportX(viewportX+10);if(!keepScrolling){var distanceScrolled=viewportX-originalViewportX;if(distanceScrolled>120||atEnd())clearInterval(timer);}},20)
function mouseup(e){if(e.which!=1)return;keepScrolling=false;$(document).unbind('mouseup',mouseup);}
$(document).mouseup(mouseup);return false;})
var zoomLevel=0;var minZoom=0;var maxZoom=Math.floor(Math.log(30*opts.days/usableViewportWidth)/Math.log(2));function refreshZoomButtons(){if(zoomLevel<=minZoom){zoomOutElem.addClass('disabled');}else{zoomOutElem.removeClass('disabled');}
if(zoomLevel>=maxZoom){zoomInElem.addClass('disabled');}else{zoomInElem.removeClass('disabled');}}
refreshZoomButtons();opts.events.sort(function(a,b){return(a.day-b.day);});var viewportX=0;var dragStartX;viewportElem.drag(function(){dragStartX=viewportX;},function(e){setViewportX(dragStartX-e.offsetX);}).dblclick(function(e){changeZoom(+1,e.clientX-container.position().left)})
function setViewportX(x){x=Math.max(0,x);x=Math.min(timelineWidth-fullWidth,x);raphaelElem.css({'left':-x+'px'});viewportX=x;refreshScrollButtons();}
function atStart(){return(viewportX<=0);}
function atEnd(){return(viewportX>=timelineWidth-fullWidth);}
function refreshScrollButtons(){if(atStart()){scrollLeftElem.addClass('scroll-disabled');}else{scrollLeftElem.removeClass('scroll-disabled');}
if(atEnd()){scrollRightElem.addClass('scroll-disabled');}else{scrollRightElem.removeClass('scroll-disabled');}}
refreshScrollButtons();var raph=Raphael(raphaelElem.get(0),1,1);function plot(animate){raph.clear();var pixelsPerDay=usableViewportWidth/opts.days*Math.pow(2,zoomLevel);timelineWidth=pixelsPerDay*opts.days+viewportLeftMargin+viewportRightMargin;viewportElem.css({'height':height+'px'});raph.setSize(timelineWidth,height);for(var i=0;i<opts.rows.length;i++){var row=opts.rows[i];raph.rect(0,i*rowHeight+topMargin+0.5,timelineWidth,rowHeight).attr({'fill':i%2?'#eeece8':'#fffffe','stroke':'none'});}
raph.path("M0 "+(allRowsHeight+topMargin+0.5)+"H"+timelineWidth).attr({'stroke':'#a09c98'});raph.rect(0,0,drawerWidth,allRowsHeight+topMargin).attr({'fill':'rgba(192, 192, 192, 0.5)','stroke-width':0});raph.path("M"+(drawerWidth-0.5)+" 0 V"+(allRowsHeight+topMargin)).attr({'stroke':'#a09c98'});if(pixelsPerDay>100){var dateStep=1;var dateLabel='Day ';}else if(pixelsPerDay>50/30){var dateStep=30;var dateLabel='Month ';}else{var dateStep=360;var dateLabel='Year ';}
var stepWidth=dateStep*pixelsPerDay;var counter=1;for(var i=0;i<=opts.days;i+=dateStep){var x=Math.floor(i*pixelsPerDay+viewportLeftMargin)+0.5;if(i>0){raph.path("M"+x+" 0 V"+(topMargin+allRowsHeight+25)).attr({'stroke':'#a09c98'});}
raph.text(x+stepWidth/2,topMargin+allRowsHeight+25,dateLabel+counter).attr({'font-size':12,'font-weight':'bold'});counter++;}
if(opts.periods){for(var i=0;i<opts.periods.length;i++){var period=opts.periods[i];if(!period)continue;var xStart=(period.day-1)*pixelsPerDay+viewportLeftMargin;var xEnd=(period['end-day']||period.day)*pixelsPerDay+viewportLeftMargin;raph.rect(xStart,0,xEnd-xStart,topMargin+allRowsHeight).attr({'opacity':0.1,'fill':period.color,'stroke-width':0});raph.text(xStart+6,topMargin*0.45,period.description).attr({'text-anchor':'start','font-size':11,'fill':period.color})}}
function addInfoBubble(box,title,event,minX,maxX,y){var bubble;box.hover(function(e){var x=e.clientX-bodyElem.position().left;x=Math.max(minX-viewportX,x);x=Math.min(maxX-viewportX,x);if(x<fullWidth/2){bubble=$('<div class="info-bubble bubble-left"></div>');var leftOffset=32;}else{bubble=$('<div class="info-bubble bubble-right"></div>');var leftOffset=301;}
bodyElem.append(bubble);bubble.append('<div class="bubble-top"></div>');var bubbleInner=$('<div class="bubble-inner"></div>');bubble.append(bubbleInner);var dateElem=$('<div class="date"></div>');bubbleInner.append(dateElem);if(event['end-day']&&event['end-day']!=event.day){dateElem.text('Days '+event.day+' - '+event['end-day'])}else{dateElem.text('Day '+event.day)}
bubbleInner.append($('<h3></h3>').text(title));if(event.description)bubbleInner.append($('<p></p>').text(event.description));bubble.append('<div class="bubble-bottom"></div>');bubble.css({'left':x-leftOffset+'px','top':y+12+'px'});},function(){if(bubble){bubble.remove();bubble=null;}})}
var lastX=null;var lastY=null;var eventBoxes=raph.set();function plotEvent(event,row){var cxStart=(event.day-0.5)*pixelsPerDay+viewportLeftMargin;var cxEnd=((event['end-day']||event.day)-0.5)*pixelsPerDay+viewportLeftMargin;var cy=row.index*rowHeight+topMargin+rowHeight/2;var icon=event.icon||row.icon||'box';var color=event.color||row.color||'#000088';var eventBox;if(icon=='box-large'){eventBox=raph.rect(Math.floor(cxStart)-7.5,cy-7.5,Math.floor(cxEnd-cxStart)+16,16,2).attr({'fill':color,'stroke':'#ffffff'});}else if(cxStart!=cxEnd||icon=='box'){eventBox=raph.rect(cxStart-5.5,cy-5.5,(cxEnd-cxStart)+11,11,1).attr({'fill':color,'stroke':'#ffffff'});}else if(icon=='circle'){eventBox=raph.circle(cxStart,cy,5.5).attr({'fill':color,'stroke':'#ffffff'});}else if(icon=='circle-large'){eventBox=raph.circle(cxStart,cy,8).attr({'fill':color,'stroke':'#ffffff'});}else if(icon=='triangle'){eventBox=raph.path('M '+(cxStart-6.351)+' '+(cy+3.667)+' l 6.351 -11 l 6.351 11 z').attr({'fill':color,'stroke':'#ffffff'});}else if(icon=='triangle-large'){eventBox=raph.path('M '+(cxStart-9.238)+' '+(cy+6.333)+' l 9.238 -16 l 9.238 16 z').attr({'fill':color,'stroke':'#ffffff'});}else if(icon=='cross'){eventBox=raph.path('M '+(cxStart-5.5)+' '+(cy-5.5)+' l 11 11 m 0 -11 l -11 11').attr({'stroke':color,'stroke-width':2});}else if(icon=='cross-large'){eventBox=raph.path('M '+(cxStart-8)+' '+(cy-8)+' l 16 16 m 0 -16 l -16 16').attr({'stroke':color,'stroke-width':4});}
eventBoxes.push(eventBox);addInfoBubble(eventBox,row.name,event,cxStart,cxEnd,cy);var line=null;if(lastX!=null&&lastY!=null&&opts.lines){line=raph.path("M"+lastX+" "+lastY+"L"+cxStart+" "+cy).attr({'stroke':'#c3c3c2'});}
if(animate){eventBox.attr({'opacity':0});if(line)line.attr({'opacity':0});setTimeout(function(){eventBox.animate({'opacity':1},300);if(line)line.animate({'opacity':1},300);},animationDuration*(event.day/opts.days))}
lastX=cxEnd;lastY=cy;}
for(var i=0;i<opts.events.length;i++){var event=opts.events[i];var row=rowsById[event.type];if(row.checkbox.checked)plotEvent(event,row);}
eventBoxes.toFront();}
plot(isInteractive);container.append('<div style="clear: both;"></div>');function changeZoom(delta,centreX){if(zoomLevel+delta>maxZoom||zoomLevel+delta<minZoom)return;var pixelsPerDay=usableViewportWidth/opts.days*Math.pow(2,zoomLevel);var centreDay=(centreX+viewportX-viewportLeftMargin)/pixelsPerDay;zoomLevel+=delta;plot();var newPixelsPerDay=usableViewportWidth/opts.days*Math.pow(2,zoomLevel);var newViewportX=centreDay*newPixelsPerDay+viewportLeftMargin-centreX;setViewportX(newViewportX);refreshZoomButtons();}
if(window.THEOGRAM_STANDALONE){$(function(){var elem=container;while(true){elem.siblings().remove();elem=elem.parent();if(elem.is('body'))break;}});}}})(jQuery);
