{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}  -- Vertex2
----------------------------------------------------------------------
-- |
-- Module      :  Point3
-- Copyright   :  (c) Conal Elliott and Andy J Gill 2008
-- License     :  BSD3
-- 
-- Maintainer  :  conal@conal.net, andygill@ku.edu
-- Stability   :  experimental
-- 
-- Points in 3D
----------------------------------------------------------------------

module Graphics.FieldTrip.Point2
  (
    Point2, point2, origin2, Vertex2(..)
  , point2Polar
  , point2PolarCoords
  ) where

import Graphics.Rendering.OpenGL (Vertex2(..))

import Data.VectorSpace
import Data.AffineSpace
import Graphics.FieldTrip.Vector2

-- | Synonym for Vertex2, a 2D point, parameterized over coordinate type.
type Point2 = Vertex2

-- | Construct a 2D point in rectangular coordinates.
point2 :: s -> s -> Vertex2 s
point2 = Vertex2

origin2 :: Num s => Point2 s
origin2 = point2 0 0

-- or substitute zeroV for 0 above to relax Num s to VectorSpace s s

-- -- | 2D point, parameterized over coordinate type.
-- data Point2 s = Point2 !s !s deriving (Eq, Show)

-- UndecidableInstances because "the Coverage Condition fails" below

instance VectorSpace u s => AffineSpace (Vertex2 u) (Vector2 u) s where
  Vertex2 u v .-. Vertex2 u' v' = Vector2 (u ^-^ u') (v ^-^ v')
  Vertex2 u v .+^ Vector2 dx dy = Vertex2 (u ^+^ dx) (v ^+^ dy)

vToP :: Vector2 s -> Point2 s
vToP (Vector2 u v) = Vertex2 u v

pToV :: Point2 s -> Vector2 s
pToV (Vertex2 u v) = Vector2 u v

-- | Vector from polar coordinates.  See also 'vectorPolarCoords'.
point2Polar :: Floating s => s -> s -> Point2 s
point2Polar = (fmap.fmap) vToP vector2Polar

-- | Polar coordinates of a point.  See also 'point2Polar'.
point2PolarCoords :: (InnerSpace s s, Floating s) => Point2 s -> (s,s)
point2PolarCoords = vector2PolarCoords . pToV