// reference:
// http://cs1.bradley.edu/public/jcm/weileratherton.html
// http://en.wikipedia.org/wiki/Weiler%E2%80%93Atherton_clipping_algorithm
var inside = require('turf-inside');
var polygon = require('turf-polygon');
var point = require('turf-point');

module.exports = function (subject, clip) {
    var subjectPolygon = subject;
    subjectPolygon.push([subjectPolygon[0], subjectPolygon[1]]);
    //var clipPolygon = polygon([clip])
    var subjectList = new Polygon();
    var clipList = new Polygon();

    for(var i = 0; i < subject.length; i++){
        subjectList.add(new Point(subject[i][0], subject[i][1]));
    }
    for(var i = 0; i < clip.length; i++){
        clipList.add(new Point(clip[i][0], clip[i][1]));
    }

    var currentSubject = subjectList.first;
    var clipList = clipList.first;
    for(var i = 0; i < subject.length; i++) {
        for(var k = 0; k < clip.length; k++) {
            console.log(k)
            var intersection = lineIntersects(
                currentSubject.point.x,
                currentSubject.point.y,
                currentSubject.next.point.x,
                currentSubject.next.point.y,
                currentClip.point.x,
                currentClip.point.y,
                currentClip.next.point.x,
                currentClip.next.point.y);

            if(intersection) {
                var isEntering = !isInside([currentClip.point.x, currentClip.point.y], subjectPolygon);
                subjectList.insertBefore(new Point(intersection[0], intersection[1], isEntering), currentSubject.next);
                console.log(currentClip)
                clipList.insertBefore(new Point(intersection[0], intersection[1], isEntering), currentClip.next);
            }
            currentClip = currentClip.next;
        }
        currentSubject = currentSubject.next;
    }
}

// modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/
function lineIntersects(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
    // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
    var denominator, a, b, numerator1, numerator2, result = {
        x: null,
        y: null,
        onLine1: false,
        onLine2: false
    };
    denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY));
    if (denominator == 0) {
        if(result.x != null && result.y != null) {
            return result;
        } else {
            return false;
        }
    }
    a = line1StartY - line2StartY;
    b = line1StartX - line2StartX;
    numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b);
    numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b);
    a = numerator1 / denominator;
    b = numerator2 / denominator;

    // if we cast these lines infinitely in both directions, they intersect here:
    result.x = line1StartX + (a * (line1EndX - line1StartX));
    result.y = line1StartY + (a * (line1EndY - line1StartY));

    // if line1 is a segment and line2 is infinite, they intersect if:
    if (a > 0 && a < 1) {
        result.onLine1 = true;
    }
    // if line2 is a segment and line1 is infinite, they intersect if:
    if (b > 0 && b < 1) {
        result.onLine2 = true;
    }
    // if line1 and line2 are segments, they intersect if both of the above are true
    if(result.onLine1 && result.onLine2){
        return [result.x, result.y];
    }
    else {
        return false;
    }
}

// polygon contour as a doubly linked list
// https://github.com/mapbox/seidel/blob/master/src/polygon.js
function Polygon() {
    this.length = 0;
    this.first = null;
    this.last = null;
}

function PolygonNode(point) {
    this.point = point;
    this.next = null;
    this.prev = null;
    this.ear = false;
}

Polygon.prototype = {
    add: function (point) {
        var node = new PolygonNode(point);

        if (!this.length) {
            this.first = this.last = node;

        } else {
            this.last.next = node;
            node.prev = this.last;
            this.last = node;
        }

        this.length++;
    },

    remove: function (node) {
        if (!this.length) return;

        if (node === this.first) {
            this.first = this.first.next;

            if (!this.first) this.last = null;
            else this.first.prev = null;

        } else if (node === this.last) {
            this.last = this.last.prev;
            this.last.next = null;

        } else {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }

        node.prev = null;
        node.next = null;

        this.length--;
    },

    insertBefore: function (point, node) {
        //console.log(node)
        var newNode = new PolygonNode(point);
        newNode.prev = node.prev;
        newNode.next = node;

        if (!node.prev) this.first = newNode;
        else node.prev.next = newNode;

        node.prev = newNode;

        this.length++;
    }
};

//modified from https://github.com/mapbox/seidel/blob/master/src/point.js
function Point(x, y, entering) {
    this.x = x;
    this.y = y;
    this.entering = entering;
}

//modified from https://github.com/Turfjs/turf-inside/blob/master/index.js
function isInside(point, polygon){
  var x = point[0];
  var y = point[1];
  var vs = polygon;

  var isInside = false;
  for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
    var xi = vs[i][0], yi = vs[i][1];
    var xj = vs[j][0], yj = vs[j][1];
    
    var intersect = ((yi > y) != (yj > y))
        && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
    if (intersect) isInside = !isInside;
  }
  return isInside;
}
@@ -142,119 +142,8 @@
 ithm
-%0Avar inside = require('turf-inside');%0Avar polygon = require('turf-polygon');%0Avar point = require('turf-point');
 %0A%0Amo

remove dead require statements