var toPoint = function(p) {
  if(p instanceof Point)
    return p.clone();
  return new Point(p.x, p.y)
};

var FaceMarks = function(landmarks) {
  var jaw = landmarks.getJawOutline(),
    nose = landmarks.getNose(),
    mouth = landmarks.getMouth(),
    leftBrow = landmarks.getLeftEyeBrow(),
    rightBrow = landmarks.getRightEyeBrow(),

    leftEye = landmarks.getLeftEye(),
    rightEye = landmarks.getRightEye();


  var marks = this.marks = {
    cheek: {
      left: {

      },
      right: {

      }
    },
    lips: {
      top: {

      },
      bottom: {

      }
    },
    brows: {
      left: {}, right: {}
    },
    eyes: {
      left: {}, right: {}
    }
  };
  // CHEEKS

  marks.cheek.left = this.cheek(nose[3], toPoint(jaw[0]).middle(toPoint(jaw[1])), mouth[0]);
  marks.cheek.right = this.cheek(nose[3], toPoint(jaw[15]).middle(toPoint(jaw[16])), mouth[6]);

  marks.lips.top = this.lip(mouth[2], mouth[4], mouth[13], mouth[15], true);
  marks.lips.bottom = this.lip(mouth[10], mouth[8], mouth[19], mouth[17], true);

  marks.eyes.left = this.eye(leftBrow[0], leftBrow[3], leftEye[0], leftEye[2], leftEye[3], leftEye[4]);
  marks.eyes.right = this.eye(rightBrow[4], rightBrow[1], rightEye[3], rightEye[1], rightEye[0], rightEye[5]);
};

FaceMarks.prototype = {
  eye: function(b1,b2, e1,e2,e3,e4) {
    b1 = toPoint(b1),
    b2 = toPoint(b2),
    e1 = toPoint(e1),
    e2 = toPoint(e2),
    e3 = toPoint(e3),
    e4 = toPoint(e4);

    return {
      t1: [
        b2.lerp(e2, 2/3),
        b1.lerp(e1, 2/3),
        b1.lerp(e1, 1/3)
      ],
      t2: [
        b1.lerp(e1, 0.95/3),
        b1.lerp(b2, 0.5).lerp(e1, 1/3),
        b1.lerp(b2, 0.5).lerp(e1, 1.4/3)
      ],
      t3: [
        e2.lerp(e3, 2),
        e2.lerp(e4, 1.65),
        e2.lerp(e4, 2.35)
      ],
      t4: [
        e2.lerp(e4, 1.65),
        e2.lerp(e4, 2.35),
        b2.lerp(e1, 1.5)
      ]
    }

  },
  cheek: function(nose, jaw, mouthSide) {
    var p1 = toPoint(nose),
      p2 = toPoint(jaw),
      p3 = toPoint(mouthSide), originP3 = p3.clone();

    p3.add(p2.subClone(p3).mul(1/2));
    var v1 = p2.subClone(p1);
    p1.add(v1.mulClone(1/2));
    p2.sub(v1.mul(1/3));

    var cheek = [p1,p2,p3];

    var vx = cheek[0].subClone(cheek[1]),
      vy = cheek[1].subClone(cheek[2]);

    var bonusArea = [
      cheek[1].subClone(vx.mulClone(1/2)),
      cheek[1].subClone(vx.normalize().mul(3))
    ];
    bonusArea.push(bonusArea[1].subClone(vy.mul(1.4)));

    bonusArea[0].sub(vy.mulClone(1/2));
    bonusArea[1].sub(vy.mulClone(1/5));


    var bonusArea2 = [
      bonusArea[2].clone(),
      cheek[0].clone()
    ];
    var middle = bonusArea2[0].middle(bonusArea2[1]),
      toMouthVector = originP3.subClone(middle);

    bonusArea2.push(middle.add(toMouthVector.mul(1/3)));

    toMouthVector.normalize().mul(2);

    bonusArea2[0].add(toMouthVector);
    bonusArea2[1].add(toMouthVector);

    return {base: cheek, bonus1: bonusArea, bonus2: bonusArea2};
  },
  lip: function(p1,p2,p3,p4, isTop) { // rectangular zone
    p1 = toPoint(p1); p2 = toPoint(p2); p3 = toPoint(p3); p4 = toPoint(p4);
    
    var lipVertical = p3.middle(p4).sub(p1.middle(p2)),
      lipHorizontal = toPoint(p2).sub(toPoint(p1)),
      lipDeltaX = lipHorizontal.clone().normalize().mul(3);

    var lips = [];
    lips.push([
      toPoint(p1).add(lipVertical.mulClone(1/3)),
      toPoint(p2).add(lipVertical.mulClone(1/3)),
      toPoint(p3).sub(lipVertical.mulClone(1/5))
    ]);
    lips.push([
      toPoint(p2).add(lipVertical.mulClone(1/3)).add(lipDeltaX),
      toPoint(p4).sub(lipVertical.mulClone(1/5)).add(lipDeltaX),
      toPoint(p3).sub(lipVertical.mulClone(1/5)).add(lipDeltaX)
    ]);


    lips.push( [
      lips[ 0 ][ isTop?2:0 ].subClone( lipHorizontal.mulClone( 1 / 2 ) ),
      lips[ 0 ][ 0 ].subClone( lipDeltaX ),
      lips[ 0 ][ 2 ].subClone( lipDeltaX ),
    ] );

    lips.push( [
      lips[ 1 ][ isTop?1:0 ].addClone( lipHorizontal.mulClone( 1 / 2 ) ),
      lips[ 1 ][ 1 ].addClone( lipDeltaX ),
      lips[ 1 ][ 0 ].addClone( lipDeltaX ),
    ] );

    return lips;
  }
};