function Canvas() {}

Canvas.prototype.drawStrokeRect = function(
    ctx, color, x, y, width, height, lineWidth) {
  ctx.strokeStyle = color;
  ctx.lineWidth = lineWidth;
  ctx.strokeRect(x, y, width, height);
}

Canvas.prototype.drawFillRect = function(ctx, color, x, y, width, height) {
  ctx.fillStyle = color;
  ctx.fillRect(x, y, width, height);
}

Canvas.prototype.drawEllipse = function(
    ctx, color, x, y, xAxis, yAxis, lineWidth, type) {
  var startX = x + xAxis;
  var startY = y;
  ctx.beginPath();
  ctx.lineWidth = lineWidth;
  ctx.moveTo(startX, startY);
  for (var i = 0; i <= 360; i++) {
    var degree = i * Math.PI / 180;
    startX = x + (xAxis - 2) * Math.cos(degree);
    startY = y - (yAxis - 2) * Math.sin(degree);
    ctx.lineTo(startX, startY);
  }
  if (type == 'rect') {
    ctx.fillStyle = changeColorToRgba(color, 0.5);
    ctx.fill();
  } else if (type == 'border') {
    ctx.strokeStyle = color;
    ctx.stroke();
  }
  ctx.closePath();
}

// Divide an entire phrase in an array of phrases, all with the max pixel
// length given.
Canvas.prototype.getLines = function(ctx, text, width, font) {
  var words = text.split(" ");
  var lines = [];
  var lastLine = "";
  var measure = 0;
  ctx.font = font;
  for (var i = 0; i < words.length; i++) {
    var word = words[i];
    measure = ctx.measureText(lastLine + word).width;
    if (measure <= width || word == "") {
      lastLine += word + " ";
    } else {
      if (lastLine != "")
        lines.push(lastLine);

      // break the word if necessary 
      measure = ctx.measureText(word).width;
      if (measure <= width) {
        lastLine = word + " ";
      } else {
        lastLine = word[0];
        for (var j = 1; j < word.length; j++) {
          measure = ctx.measureText(lastLine + word[j]).width;
          if (measure <= width) {
            lastLine += word[j];
          } else {
            lines.push(lastLine);
            lastLine = word[j];
          } 
        }
        lastLine += " ";
      }
    }
  }
  if (lastLine != "")
    lines.push(lastLine);
  return lines;
}

Canvas.prototype.setText = function(
    ctx, text, color, fontSize, fontFamily, lineHeight, x, y, width) {
  ctx.textBaseline = 'top';
  ctx.fillStyle = color;
  ctx.font = fontSize + ' ' + fontFamily;
  ctx.lineHeight = lineHeight;
  var lines = Canvas.prototype.getLines(ctx, text, width - 2, ctx.font);
  for (var i = 0; i < lines.length; i++)
    ctx.fillText(lines[i], x, y + lineHeight * i, width);
}

Canvas.prototype.drawLine = function(
    ctx, color, lineCap, lineWidth, startX, startY, endX, endY) {
  ctx.beginPath();
  ctx.moveTo(startX, startY);
  ctx.strokeStyle = color;
  ctx.lineWidth = lineWidth;
  ctx.lineCap = lineCap;
  ctx.lineTo(endX, endY);
  ctx.closePath();
  ctx.stroke();
}

Canvas.prototype.drawArrow = function(
    ctx, color, lineWidth, arrowWidth, arrowHeight, lineCap,
    startX, startY, endX, endY) {
  var arrowCoordinates = calculateArrowCoordinates(
      arrowWidth, arrowHeight,startX, startY, endX, endY);
  ctx.beginPath();
  ctx.strokeStyle = color;
  ctx.lineWidth = lineWidth;
  ctx.lineCap = lineCap;
  ctx.moveTo(startX, startY);
  ctx.lineTo(endX, endY);
  ctx.lineTo(arrowCoordinates.p1.x, arrowCoordinates.p1.y);
  ctx.moveTo(endX, endY);
  ctx.lineTo(arrowCoordinates.p2.x, arrowCoordinates.p2.y);
  ctx.closePath();
  ctx.stroke();
}

Canvas.prototype.drawRoundedRect = function(
    ctx, color, x, y, width, height, radius, type) {
  ctx.beginPath();
  ctx.moveTo(x, y + radius);
  ctx.lineTo(x, y + height - radius);
  ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
  ctx.lineTo(x + width - radius, y + height);
  ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
  ctx.lineTo(x + width, y + radius);
  ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
  ctx.lineTo(x + radius, y);
  ctx.quadraticCurveTo(x, y, x, y + radius);
  if (type == 'rect') {
    ctx.fillStyle = changeColorToRgba(color, 0.5);
    ctx.fill();
  } else if (type == 'border') {
    ctx.strokeStyle = color;
    ctx.lineWidth = 2;
    ctx.stroke();
  }
  ctx.closePath();
}

Canvas.prototype.blurImage = function(
    realCanvas, simulateCanvas, layerId, startX, startY, endX, endY) {
  var x = startX < endX ? startX : endX;
  var y = startY < endY ? startY : endY;
  var width = Math.abs(endX - startX - 1);
  var height = Math.abs(endY - startY - 1);
  simulateCanvas.width = $(layerId).clientWidth + 10;
  simulateCanvas.height = $(layerId).clientHeight + 10;
  var ctx = simulateCanvas.getContext('2d');
  try {
    ctx.drawImage(realCanvas, x, y, width, height, 0, 0, width, height);
  } catch (error) {
    console.log(error + ', width : height = ' + width + ' : ' + height);
  }
  var imageData = ctx.getImageData(0, 0, width, height);
  imageData = this.boxBlur(imageData, width, height, 10);
  ctx.putImageData(imageData, 0, 0);
}

Canvas.prototype.boxBlur = function(image, width, height, count) {
  var j;
  var pix = image.data;
  var inner = 0;
  var outer = 0;
  var step = 0;
  var rowOrColumn;
  var nextPosition;
  var nowPosition;
  for(rowOrColumn = 0; rowOrColumn < 2; rowOrColumn++) {
    if (rowOrColumn) {
      // column blurring
      outer = width;
      inner = height;
      step = width * 4;
    } else {
      // Row blurring
      outer = height;
      inner = width;
      step = 4;
    }
    for (var i = 0; i < outer; i++) {
      // Calculate for r g b a
      nextPosition = (rowOrColumn == 0 ? (i * width * 4) : (4 * i));
      for (var k = 0; k < 4; k++) {
        nowPosition = nextPosition + k;
        var pixSum = 0;
          for(var m = 0; m < count; m++) {
            pixSum += pix[nowPosition + step * m];
          }
          pix[nowPosition] = pix[nowPosition + step] =
              pix[nowPosition + step * 2] = Math.floor(pixSum/count);
          for (j = 3; j < inner-2; j++) {
            pixSum = Math.max(0, pixSum - pix[nowPosition + (j - 2) * step]
                + pix[nowPosition + (j + 2) * step]);
            pix[nowPosition + j * step] = Math.floor(pixSum/count);
          }
          pix[nowPosition + j * step] = pix[nowPosition + (j + 1) * step] =
              Math.floor(pixSum / count);
      }
    }
  }
  return image;
}

function changeColorToRgba(color, opacity) {
  var sColor = color.toLowerCase();
  var sColorChange = [];
  for (var i = 1; i < sColor.length; i += 2) {
    sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
  }
  return "rgba(" + sColorChange.join(",") + "," + opacity + ")";
}

// Calculate coordinates of arrow
function calculateArrowCoordinates(
    arrowWidth, arrowHeight, startX, startY, endX, endY) {
  var p1 = function() {
    var x = startX - endX;
    var y = startY - endY;
    var hypotenuse = Math.sqrt(x * x + y * y);
    hypotenuse = (hypotenuse == 0 ? arrowHeight : hypotenuse);
    var dx = Math.round(x / hypotenuse * arrowHeight);
    var dy = Math.round(y / hypotenuse * arrowHeight);
    return {x: endX + dx, y: endY + dy};
  }

  var p2 = function(p1, direct) {
    var x = p1.x - startX;
    var y = p1.y - startY;
    var hypotenuse = Math.sqrt(x * x + y * y);
    hypotenuse = (hypotenuse == 0 ? arrowHeight : hypotenuse);
    var dx = Math.round((y / hypotenuse * arrowWidth) * direct);
    var dy = Math.round((x / hypotenuse * arrowWidth) * direct);
    return {x: p1.x + dx, y: p1.y - dy }
  }

  return {p1:p2(p1(), 1), p2: p2(p1(), -1) } ;
}
