/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkPathOpsCubic.h"

static bool rotate(const SkDCubic& cubic, int zero, int index, SkDCubic& rotPath) {
    double dy = cubic[index].fY - cubic[zero].fY;
    double dx = cubic[index].fX - cubic[zero].fX;
    if (approximately_zero(dy)) {
        if (approximately_zero(dx)) {
            return false;
        }
        rotPath = cubic;
        if (dy) {
            rotPath[index].fY = cubic[zero].fY;
            int mask = other_two(index, zero);
            int side1 = index ^ mask;
            int side2 = zero ^ mask;
            if (approximately_equal(cubic[side1].fY, cubic[zero].fY)) {
                rotPath[side1].fY = cubic[zero].fY;
            }
            if (approximately_equal(cubic[side2].fY, cubic[zero].fY)) {
                rotPath[side2].fY = cubic[zero].fY;
            }
        }
        return true;
    }
    for (int index = 0; index < 4; ++index) {
        rotPath[index].fX = cubic[index].fX * dx + cubic[index].fY * dy;
        rotPath[index].fY = cubic[index].fY * dx - cubic[index].fX * dy;
    }
    return true;
}


// Returns 0 if negative, 1 if zero, 2 if positive
static int side(double x) {
    return (x > 0) + (x >= 0);
}

/* Given a cubic, find the convex hull described by the end and control points.
   The hull may have 3 or 4 points. Cubics that degenerate into a point or line
   are not considered.

   The hull is computed by assuming that three points, if unique and non-linear,
   form a triangle. The fourth point may replace one of the first three, may be
   discarded if in the triangle or on an edge, or may be inserted between any of
   the three to form a convex quadralateral.

   The indices returned in order describe the convex hull.
*/
int SkDCubic::convexHull(char order[4]) const {
    size_t index;
    // find top point
    size_t yMin = 0;
    for (index = 1; index < 4; ++index) {
        if (fPts[yMin].fY > fPts[index].fY || (fPts[yMin].fY == fPts[index].fY
                && fPts[yMin].fX > fPts[index].fX)) {
            yMin = index;
        }
    }
    order[0] = yMin;
    int midX = -1;
    int backupYMin = -1;
    for (int pass = 0; pass < 2; ++pass) {
        for (index = 0; index < 4; ++index) {
            if (index == yMin) {
                continue;
            }
            // rotate line from (yMin, index) to axis
            // see if remaining two points are both above or below
            // use this to find mid
            int mask = other_two(yMin, index);
            int side1 = yMin ^ mask;
            int side2 = index ^ mask;
            SkDCubic rotPath;
            if (!rotate(*this, yMin, index, rotPath)) { // ! if cbc[yMin]==cbc[idx]
                order[1] = side1;
                order[2] = side2;
                return 3;
            }
            int sides = side(rotPath[side1].fY - rotPath[yMin].fY);
            sides ^= side(rotPath[side2].fY - rotPath[yMin].fY);
            if (sides == 2) { // '2' means one remaining point <0, one >0
                if (midX >= 0) {
                    // one of the control points is equal to an end point
                    order[0] = 0;
                    order[1] = 3;
                    if (fPts[1] == fPts[0] || fPts[1] == fPts[3]) {
                        order[2] = 2;
                        return 3;
                    }
                    if (fPts[2] == fPts[0] || fPts[2] == fPts[3]) {
                        order[2] = 1;
                        return 3;
                    }
                    // one of the control points may be very nearly but not exactly equal --
                    double dist1_0 = fPts[1].distanceSquared(fPts[0]);
                    double dist1_3 = fPts[1].distanceSquared(fPts[3]);
                    double dist2_0 = fPts[2].distanceSquared(fPts[0]);
                    double dist2_3 = fPts[2].distanceSquared(fPts[3]);
                    double smallest1distSq = SkTMin(dist1_0, dist1_3);
                    double smallest2distSq = SkTMin(dist2_0, dist2_3);
                    if (approximately_zero(SkTMin(smallest1distSq, smallest2distSq))) {
                        order[2] = smallest1distSq < smallest2distSq ? 2 : 1;
                        return 3;
                    }
                }
                midX = index;
            } else if (sides == 0) { // '0' means both to one side or the other
                backupYMin = index;
            }
        }
        if (midX >= 0) {
            break;
        }
        if (backupYMin < 0) {
            break;
        }
        yMin = backupYMin;
        backupYMin = -1;
    }
    if (midX < 0) {
        midX = yMin ^ 3; // choose any other point
    }
    int mask = other_two(yMin, midX);
    int least = yMin ^ mask;
    int most = midX ^ mask;
    order[0] = yMin;
    order[1] = least;

    // see if mid value is on same side of line (least, most) as yMin
    SkDCubic midPath;
    if (!rotate(*this, least, most, midPath)) { // ! if cbc[least]==cbc[most]
        order[2] = midX;
        return 3;
    }
    int midSides = side(midPath[yMin].fY - midPath[least].fY);
    midSides ^= side(midPath[midX].fY - midPath[least].fY);
    if (midSides != 2) {  // if mid point is not between
        order[2] = most;
        return 3; // result is a triangle
    }
    order[2] = midX;
    order[3] = most;
    return 4; // result is a quadralateral
}
