
jQuery.fn.makeDrawable = function(options) {

  return this.each(function() {
    this.oCtx = this.getContext("2d");
    this.oCtx['fillStyle'] = 'white';
    this.oCtx.fillRect(0,0,this.width, this.height);
    this.undoStack = [];
    this.bMouseIsDown = false;
    this.iLastX = -1;
    this.iLastY = -1;
    this.settings = jQuery.extend({
      lineWidth : 5,
      lineCap : 'round',
      lineJoin : 'round'
    }, options);

    /************
     *
     *  HERE LIE THE FILTERS
     *
     *
     * THEY SHOULD BE DOCUMENTED TOO
     *
     */
    function setFilter(filterstr) {
    };

    this.addUndo = function() {

      this.lastState = this.oCtx.getImageData(0,0,this.width, this.height);
      this.undoStack.push(this.lastState);
    };
    /*************
     * HERE LIE THE DRAWSTYLES
     *
     *
     * I SHOULD DOCUMENT THEM
     */

    function DrawStyle(canvas) {
      this.ctx = canvas.oCtx;
      this.canvas = canvas;
      this.lastState = undefined;
      this.drawMethod = function(ctx, x1,y1,x2,y2) {
      };
      this.startDrawing =  function(x,y) {
        ctx.save();
        ctx.beginPath();
        this.initX = x;
        this.initY = y;
        this.lastX = x;
        this.lastY = y;
        this.lastState = this.ctx.getImageData(0,0,this.canvas.width, this.canvas.height);
        this.canvas.undoStack.push(this.lastState);
      };
      this.moveDrawing =  function(x,y) {
        if (this.lastState) {
          // this.ctx.putImageData(this.lastState,0,0,this.initX, this.initY, this.initX-x, this.initY-y);
          this.ctx.putImageData(this.lastState,0,0);

        }

        this.drawMethod(this.ctx, this.initX,this.initY,x,y, this.lastX, this.lastY);
        this.lastX = x;
        this.lastY = y;
        //        console.log("ds move");

      };
      this.endDrawing =  function(x,y) {
        //      console.log('d-end');

        this.drawMethod(this.ctx, this.initX, this.initY, this.lastX, this.lastY);
        ctx.closePath();
        ctx.restore();

      };
    };

    var BoxStyle = function() {};
    BoxStyle.prototype = new DrawStyle(this);
    BoxStyle.prototype.drawMethod = function (ctx,x1,y1,x2,y2) {
      ctx.strokeRect(x1,y1,x2-x1,y2-y1);
    };

    var ScribbleStyle = function() {};
    ScribbleStyle.prototype = new DrawStyle(this);
    ScribbleStyle.prototype.drawMethod = function (ctx,x1,y1,x2,y2,lastx,lasty) {
      ctx.lineCap = 'round';
      ctx.moveTo(lastx,lasty);
      ctx.lineTo(x2,y2);
      ctx.stroke();

    };

    var LineStyle = function() {};
    LineStyle.prototype = new DrawStyle(this);
    LineStyle.prototype.drawMethod = function (ctx,x1,y1,x2,y2,lastx,lasty) {
      ctx.closePath();
      ctx.lineCap = 'round';
      ctx.moveTo(x1,y1);
      ctx.lineTo(x2,y2);
      ctx.stroke();

    };

    var TextStyle = function() {
      this.font = '48px impact,sans-serif';
    };
    TextStyle.prototype = new DrawStyle(this);
    TextStyle.prototype.drawMethod = function (ctx,x1,y1,x2,y2,lastx,lasty) {
      ctx.font = this.font;
      ctx.save();
      ctx.fillText(this.textToDraw, x2,y2);
      ctx.strokeText(this.textToDraw, x2,y2);
      ctx.restore ();
    };

    this.setDrawStyle = function (ds, text) {
      this.drawStyle = this.drawingStyles[ds];
      if (ds == 'text')
        this.drawStyle.textToDraw = text;
    };

    this.undo = function() {
      if (this.undoStack.length > 0)
        this.oCtx.putImageData(this.undoStack.pop(), 0 ,0);
    };


    this.drawingStyles = {
      'text' : new TextStyle(),
      'scribble' : new ScribbleStyle(),
      'line' : new LineStyle(),
      'box' : new BoxStyle()
    };

    this.drawStyle = new ScribbleStyle();

    this.onmousedown = function(e) {
      this.bMouseIsDown = true;
      this.iLastX = e.clientX - this.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
      this.iLastY = e.clientY - this.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
      this.drawStyle.startDrawing(this.iLastX, this.iLastY);
    };

    this.onmouseup = function(e) {
      this.bMouseIsDown = false;
      this.iLastX = e.clientX - this.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
      this.iLastY = e.clientY - this.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
      this.drawStyle.endDrawing(this.iLastX, this.iLastY);
    };

    this.onmousemove = function(e) {
      if (this.bMouseIsDown) {
	var iX = e.clientX - this.offsetLeft + (window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft);
	var iY = e.clientY - this.offsetTop + (window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop);
        this.drawStyle.moveDrawing(iX, iY);
      }

    };
  });
};


jQuery.fn.addUndoPoint = function() {
  return this.each(function() {
    this.addUndo();
  });
}
jQuery.fn.undoDrawing = function() {
  return this.each(function() {
    this.undo();
  });
}

jQuery.fn.changeDrawingStyle = function(newstyle, text) {
  return this.each(function() {
    this.drawingStyle = this.setDrawStyle(newstyle, text);
  });
}

jQuery.fn.changeDrawingSettings = function(options) {
  return this.each(function() {
    var that = this;
    jQuery.each(options, function(key, val) {
      that.oCtx[key] = val;
      jQuery.extend(that.settings,options);
    });

  });
}

