/* Function GetClearanceBetweenSegments
 * Get clearance between 2 segments
 * Returns coordinates of the closest point between these 2 segments in x, y
 * If clearance > max_cl, just returns max_cl+1 and doesn't return x,y
 */
int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int w1,
                                 int x2i, int y2i, int x2f, int y2f, int w2,
                                 int max_cl, int* x, int* y )
{
    // check clearance between bounding rectangles
    int min_dist = max_cl + ( (w1 + w2) / 2 );

    if( std::min( x1i, x1f ) - std::max( x2i, x2f ) > min_dist )
        return max_cl+1;

    if( std::min( x2i, x2f ) - std::max( x1i, x1f ) > min_dist )
        return max_cl+1;

    if( std::min( y1i, y1f ) - std::max( y2i, y2f ) > min_dist )
        return max_cl+1;

    if( std::min( y2i, y2f ) - std::max( y1i, y1f ) > min_dist )
        return max_cl+1;

    int     xx, yy;
    double  dist;
    TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
                                               x2i, y2i, x2f, y2f, &xx, &yy, &dist );
    int d = KiROUND( dist ) - ((w1 + w2) / 2);
    if( d < 0 )
        d = 0;

    if( x )
        *x = xx;

    if( y )
        *y = yy;

    return d;
}
/* compare a trapezoids (can be rectangle) and a segment and return true if distance > aDist
 */
bool trapezoid2segmentDRC( wxPoint aTref[4], wxPoint aSegStart, wxPoint aSegEnd, int aDist )
{
    /* Test if the segment is contained in the polygon.
     * This case is not covered by the following check if the segment is
     * completely contained in the polygon (because edges don't intersect)!
     */
    if( TestPointInsidePolygon( aTref, 4, aSegStart ) )
        return false;

    int ii, jj;

    for( ii = 0, jj = 3; ii < 4; jj = ii, ii++ )  // for all edges in aTref
    {
        double d;
        int    intersect = TestForIntersectionOfStraightLineSegments( aTref[ii].x,
                                                                      aTref[ii].y,
                                                                      aTref[jj].x,
                                                                      aTref[jj].y,
                                                                      aSegStart.x,
                                                                      aSegStart.y,
                                                                      aSegEnd.x,
                                                                      aSegEnd.y,
                                                                      NULL, NULL, &d );
        if( intersect || (d< aDist) )
            return false;
    }

    return true;
}
/* compare 2 convex polygons and return true if distance > aDist
 * i.e if for each edge of the first polygon distance from each edge of the other polygon
 * is >= aDist
 */
bool poly2polyDRC( wxPoint* aTref, int aTrefCount,
                       wxPoint* aTcompare, int aTcompareCount, int aDist )
{
    /* Test if one polygon is contained in the other and thus the polygon overlap.
     * This case is not covered by the following check if one polygone is
     * completely contained in the other (because edges don't intersect)!
     */
    if( TestPointInsidePolygon( aTref, aTrefCount, aTcompare[0] ) )
        return false;

    if( TestPointInsidePolygon( aTcompare, aTcompareCount, aTref[0] ) )
        return false;

    for( int ii = 0, jj = aTrefCount - 1; ii < aTrefCount; jj = ii, ii++ )
    {   // for all edges in aTref
        for( int kk = 0, ll = aTcompareCount - 1; kk < aTcompareCount; ll = kk, kk++ )
        {   // for all edges in aTcompare
            double d;
            int    intersect = TestForIntersectionOfStraightLineSegments(
                                aTref[ii].x, aTref[ii].y, aTref[jj].x, aTref[jj].y,
                                aTcompare[kk].x, aTcompare[kk].y, aTcompare[ll].x, aTcompare[ll].y,
                                NULL, NULL, &d );

            if( intersect || ( d< aDist ) )
                return false;
        }
    }

    return true;
}
/* compare 2 trapezoids (can be rectangle) and return true if distance > aDist
 * i.e if for each edge of the first polygon distance from each edge of the other polygon
 * is >= aDist
 */
bool trapezoid2trapezoidDRC( wxPoint aTref[4], wxPoint aTcompare[4], int aDist )
{
    /* Test if one polygon is contained in the other and thus the polygon overlap.
     * This case is not covered by the following check if one polygond is
     * completely contained in the other (because edges don't intersect)!
     */
    if( TestPointInsidePolygon( aTref, 4, aTcompare[0] ) )
        return false;

    if( TestPointInsidePolygon( aTcompare, 4, aTref[0] ) )
        return false;

    int ii, jj, kk, ll;

    for( ii = 0, jj = 3; ii<4; jj = ii, ii++ )          // for all edges in aTref
    {
        for( kk = 0, ll = 3; kk < 4; ll = kk, kk++ )    // for all edges in aTcompare
        {
            double d;
            int    intersect = TestForIntersectionOfStraightLineSegments( aTref[ii].x,
                                                                          aTref[ii].y,
                                                                          aTref[jj].x,
                                                                          aTref[jj].y,
                                                                          aTcompare[kk].x,
                                                                          aTcompare[kk].y,
                                                                          aTcompare[ll].x,
                                                                          aTcompare[ll].y,
                                                                          NULL, NULL, &d );
            if( intersect || (d< aDist) )
                return false;
        }
    }

    return true;
}
/* Function FindSegmentIntersections
 * find intersections between line segment (xi,yi) to (xf,yf)
 * and line segment (xi2,yi2) to (xf2,yf2)
 * returns true if intersection found
 */
bool FindSegmentIntersections( int xi, int yi, int xf, int yf,
                              int xi2, int yi2, int xf2, int yf2  )
{
    if( std::max( xi, xf ) < std::min( xi2, xf2 )
        || std::min( xi, xf ) > std::max( xi2, xf2 )
        || std::max( yi, yf ) < std::min( yi2, yf2 )
        || std::min( yi, yf ) > std::max( yi2, yf2 ) )
        return false;

    return TestForIntersectionOfStraightLineSegments( xi, yi, xf, yf,
                                                      xi2, yi2, xf2, yf2 );
}