//
//  Lynkeos
//  $Id$
//
//  Created by Jean-Etienne LAMIAUD on Fri Jun 23 2023.
//  Copyright (c) 2023. Jean-Etienne LAMIAUD
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//

#include "geometry.h"

bool pointIsInsideRect(CGPoint point, CGRect rect)
{
   return point.x >= rect.origin.x && point.x < (rect.origin.x + rect.size.width)
          && point.y >= rect.origin.y && point.y < (rect.origin.y + rect.size.height);
}

bool segmentIntersectsHorizontalSegment(CGPoint start, CGPoint end, CGFloat xStart, CGFloat xEnd, CGFloat y)
{
   // Check that the arbitrary segment crosses the horizontal line
   if ((start.y > y && end.y > y) || (start.y < y && end.y < y))
      return false;
   if (start.y != end.y)
   {
      // Then check that it intersect within the segment boundary
      CGFloat ix = (y - start.y)*(end.x - start.x)/(end.y - start.y)+start.x;
      return xStart <= ix && ix < xEnd;
   }
   // Finally check for overlapping horizontal segments
   return (start.y == y)
          && !((start.x < xStart && end.x < xStart) || (start.x >= xEnd && end.x >= xEnd));
}

bool segmentIntersectsVerticalSegment(CGPoint start, CGPoint end, CGFloat yStart, CGFloat yEnd, CGFloat x)
{
   // Check that the arbitrary segment crosses the vertical line
   if ((start.x > x && end.x > x) || (start.x < x && end.x < x))
      return false;
   if (start.x != end.x)
   {
      // Then check that it intersect within the segment boundary
      CGFloat iy = (x - start.x)*(end.y - start.y)/(end.x - start.x)+start.y;
      return yStart <= iy && iy < yEnd;
   }
   // Finally check for overlapping vertical segments
   return (start.x == x)
          && !((start.y < yStart && end.y < yStart) || (start.y >= yEnd && end.y >= yEnd));
}

bool segmentIntersectsRect(CGPoint start, CGPoint end, CGRect rect)
{
   return segmentIntersectsHorizontalSegment(start, end, rect.origin.x, rect.origin.x + rect.size.width,
                                            rect.origin.y)
          || segmentIntersectsHorizontalSegment(start, end, rect.origin.x, rect.origin.x + rect.size.width,
                                               rect.origin.y + rect.size.height)
          || segmentIntersectsVerticalSegment(start, end, rect.origin.y, rect.origin.y + rect.size.height,
                                            rect.origin.x)
          || segmentIntersectsVerticalSegment(start, end, rect.origin.y, rect.origin.y + rect.size.height,
                                            rect.origin.x + rect.size.width);
}
