module GTypes where

type Point = (Double,Double)
type Rect = (Double,Double,Double,Double)
type Radius = Double
type Circle = (Point,Radius)

within ::Point -> Rect -> Bool
within (x,y) (x1,y1,x2,y2) = x >= x1 && x <= x2 && y >= y1 && y <= y2

dist :: Point -> Point -> Double
dist (x1,y1) (x2,y2) = sqrt (x*x + y*y)
  where
    x = x2 - x1
    y = y2 - y1

intersectR ::Rect -> Rect -> Bool
intersectR (x1,y1,x2,y2) (x1',y1',x2',y2') = 
    (x2' > x1 && x2 > x1') && (y2' > y1 && y2 > y1')

qsplit :: Rect -> (Rect,Rect,Rect,Rect)
qsplit r@(x1,y1,x2,y2) = (
    (x1,y1,x3,y3),
    (x3,y1,x2,y3),
    (x1,y3,x3,y2),
    (x3,y3,x2,y2) )
  where
    (x3,y3) = centre r

centre :: Rect -> Point
centre (x1,y1,x2,y2) = ((x1 + x2)/2,(y1 + y2)/2)
    
data IC = NONE | INTERSECT | OVERLAP

intersectsCircle c r = case circRect c r of
    NONE -> False
    _ -> True

circRect :: (Point,Double) -> Rect -> IC
circRect (c@(x0,y0),rad) rect@(x1,y1,x2,y2)
      | i1 && i2 && i3 && i4 = OVERLAP
      | intersect = INTERSECT
      | otherwise = NONE

  where
    intersect | x2' < 0 && y2' < 0 = x2' * x2' + y2' * y2' < rad2
              | x2' < 0 && y1' > 0 = x2' * x2' + y1' * y1' < rad2
              | x2' < 0            = abs x2' < rad

              | x1' > 0 && y2' < 0 = x1' * x1' + y2' * y2' < rad2
              | x1' > 0 && y1' > 0 = x1' * x1' + y1' * y1' < rad2
              | x1' > 0            = x1' < rad

              | y2' < 0            = abs y2' < rad
              | y1' > 0            = y1' < rad
              | otherwise          = True
 
    x1' = x1 - x0
    x2' = x2 - x0
    y1' = y1 - y0
    y2' = y2 - y0

    i1 = insideC (x1',y1')
    i2 = insideC (x1',y2')
    i3 = insideC (x2',y1')
    i4 = insideC (x2',y2')
    rad2 = rad**2
    insideC (x,y) = x**2 + y**2 < rad2



