    {-# OPTIONS -fno-warn-missing-methods -fno-warn-orphans #-}
    {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
    module Graphics.Gloss.Data.Point
    	( Point
    	, pointInBox)
    where

    -- | A point on the x-y plane.
    --   Points can also be treated as `Vector`s, so "Graphics.Gloss.Data.Vector"
    --   may also be useful.
    type Point	= (Float, Float)

    -- | Pretend a point is a number.
    --	Vectors aren't real numbes according to Haskell, because they don't
    --	support the multiply and divide field operators. We can pretend they
    --	are though, and use the (+) and (-) operators as component-wise
    --	addition and subtraction.
    --
    instance Num Point where
    	(+) (x1, y1) (x2, y2)	= (x1 + x2, y1 + y2)
     	(-) (x1, y1) (x2, y2)	= (x1 - x2, y1 - y2)
            (*) (x1, y1) (x2, y2)   = (x1 * x2, y1 * y2)
            signum (x, y)           = (signum x, signum y)
            abs    (x, y)           = (abs x, abs y)
    	negate (x, y)		= (negate x, negate y)
            fromInteger x           = (fromInteger x, fromInteger x)

    -- | Test whether a point lies within a rectangular box that is oriented
    --   on the x-y plane. The points P1-P2 are opposing points of the box,
    --   but need not be in a particular order.
    --
    -- @
    --    P2 +-------+
    --       |       |
    --       | + P0  |
    --       |       |
    --       +-------+ P1
    -- @
    --
    pointInBox
    	:: Point
    	-> Point
    	-> Point -> Bool

    pointInBox (x0, y0) (x1, y1) (x2, y2)
     	=  x0 >= min x1 x2
     	&& x0 <= max x1 x2
    	&& y0 >= min y1 y2
    	&& y0 <= max y1 y2