define(function(require,exports,module){var KeyEvent=brackets.getModule("utils/KeyEvent"),Strings=brackets.getModule("strings"),Mustache=brackets.getModule("thirdparty/mustache/mustache"),TimingFunctionUtils=require("TimingFunctionUtils"),StepEditorTemplate=require("text!StepEditorTemplate.html"),STEP_LINE=1,DASH_LINE=2;function StepParameters(params){if(!params)throw"No parameters were defined";this.count=params.count,this.timing=params.timing}function StepCanvas(canvas,stepParams,padding){this.canvas=canvas,this.stepParams=stepParams,this.padding=this.getPadding(padding);var ctx=this.canvas.getContext("2d"),p=this.padding;ctx.scale(canvas.width*(1-p[1]-p[3]),-canvas.height*(1-p[0]-p[2])),ctx.translate(p[3]/(1-p[1]-p[3]),-1-p[0]/(1-p[0]-p[2]))}function _canvasKeyDown(e){var code=e.keyCode,self,stepEditor=e.target.stepEditor;if(code>=KeyEvent.DOM_VK_LEFT&&code<=KeyEvent.DOM_VK_DOWN){switch(e.preventDefault(),code){case KeyEvent.DOM_VK_LEFT:stepEditor.stepCanvas.stepParams.timing="start";break;case KeyEvent.DOM_VK_UP:stepEditor.stepCanvas.stepParams.count++;break;case KeyEvent.DOM_VK_RIGHT:stepEditor.stepCanvas.stepParams.timing="end";break;case KeyEvent.DOM_VK_DOWN:stepEditor.stepCanvas.stepParams.count>1&&stepEditor.stepCanvas.stepParams.count--}return stepEditor._stepParams=stepEditor.stepCanvas.stepParams,stepEditor._commitTimingFunction(),stepEditor._updateCanvas(),!0}return code===KeyEvent.DOM_VK_ESCAPE}function StepEditor($parent,stepMatch,callback){this.$element=$(Mustache.render(StepEditorTemplate,Strings)),$parent.append(this.$element),this._callback=callback,this._stepParams=this._getStepParams(stepMatch),this.hint={},this.hint.elem=$(".hint",this.$element),stepMatch.originalString?TimingFunctionUtils.showHideHint(this.hint,!0,stepMatch.originalString,"steps("+this._stepParams.count.toString()+", "+this._stepParams.timing+")"):TimingFunctionUtils.showHideHint(this.hint,!1),this.canvas=this.$element.find(".steps")[0],this.canvas.stepEditor=this,this.stepCanvas=new StepCanvas(this.canvas,null,[.1]),this._updateCanvas(),$(this.canvas).on("keydown",_canvasKeyDown)}StepCanvas.prototype={drawBackground:function(){this.ctx.beginPath(),this.ctx.lineWidth=this.settings.borderWidth,this.ctx.strokeStyle=this.settings.borderColor,this.ctx.fillStyle=this.settings.bgColor,this.ctx.moveTo(0,0),this.ctx.lineTo(0,1),this.ctx.lineTo(1,1),this.ctx.lineTo(1,0),this.ctx.lineTo(0,0),this.ctx.stroke(),this.ctx.fill(),this.ctx.closePath()},drawPoint:function(x,y,isFilled){this.ctx.beginPath(),this.ctx.lineWidth=this.settings.pointLineWidth,this.ctx.strokeStyle=this.settings.stepColor,this.ctx.arc(x,y,this.settings.pointRadius,0,2*Math.PI,!1),this.ctx.stroke(),isFilled&&(this.ctx.fillStyle=this.settings.stepColor,this.ctx.fill()),this.ctx.closePath()},drawLine:function(x1,y1,x2,y2,type){this.ctx.beginPath(),1===type?(this.ctx.lineWidth=this.settings.stepLineWidth,this.ctx.strokeStyle=this.settings.stepColor):2===type&&(this.ctx.lineWidth=this.settings.dashLineWidth,this.ctx.strokeStyle=this.settings.dashColor),this.ctx.moveTo(x1,y1),this.ctx.lineTo(x2,y2),this.ctx.stroke(),this.ctx.closePath()},drawStartInterval:function(x1,y1,x2,y2){var pr=this.settings.pointRadius;this.drawPoint(x1,y1,!1),this.drawLine(x1,y1+pr,x1,y2,2),this.drawPoint(x1,y2,!0),this.drawLine(x1,y2,x2-pr,y2,1)},drawEndInterval:function(x1,y1,x2,y2){var pr=this.settings.pointRadius;this.drawPoint(x1,y1,!0),this.drawLine(x1,y1,x2-pr,y1,1),this.drawPoint(x2,y1,!1),this.drawLine(x2,y1+pr,x2,y2,2)},plot:function(settings){var setting,i,j,last,interval,sp=this.stepParams,isStart="start"===sp.timing,p=[],defaultSettings={bgColor:"transparent",borderColor:"#bbb",stepColor:"#2893ef",dashColor:"#b8b8b8",borderWidth:.00667,stepLineWidth:.02,dashLineWidth:.008,pointLineWidth:.008,pointRadius:.015};for(setting in this.settings=settings||{},defaultSettings)defaultSettings.hasOwnProperty(setting)&&(this.settings.hasOwnProperty(setting)||(this.settings[setting]=defaultSettings[setting]));for(this.ctx=this.canvas.getContext("2d"),p[0]={x:0,y:0},i=1;i<=sp.count;i++)interval=i/sp.count,p[i]={x:interval,y:interval};for(this.ctx.clearRect(-.5,-.5,2,2),this.drawBackground(),last=p.length-1,i=0,j=1;i