{-|
Module      : Graphics.OscPacking.Boundary
Description : Functions for bounding circle coverage
Copyright   : (c) Christopher Howard, 2016
License     : GPL-3
Maintainer  : ch.howard@zoho.com
-}
module Graphics.OscPacking.Boundary where

import Graphics.OscPacking.Geometry
import Prelude ((/), (+), (/), (-), (>), ($), foldr, min, Maybe(..), (<), or, Float)

-- |A 'Boundary' is a function which takes a 'Point' and determines if
-- it is inside some area. If the Point is outside the area, it
-- returns 'Nothing'. Otherwise, it returns the distance to the edge
-- of the area. Any such 'Boundary' need not be a simple, traditional
-- geometric shape. Though, it is often difficult to calculate the
-- distance for more exotic shapes.
type Boundary = Point -> Maybe Float

-- |Provides a 'Boundary' for a circle of given origin and radius.
circleB
  :: Point -- ^ origin
     -> Float -- ^ radius
     -> Boundary
circleB originP r testP =
  if d > r then Nothing else Just (r - d) where d = euclidean originP testP

-- |Provides a 'Boundary' for a rectangle of given origin and dimensions
rectB :: Point -- ^ coordinate of the bottom left corner
         -> Float -- ^ width
         -> Float -- ^ height
         -> Boundary
rectB (bLX, bLY) width height (tPX, tPY) =
  if or [tPX < bLX,
         tPX > bLX + width,
         tPY < bLY,
         tPY > bLY + height]
  then Nothing
  else Just $ foldr min (1/0)
       [tPX - bLX,
        bLX + width - tPX,
        tPY - bLY,
        bLY + height - tPY]