module Diagrams.Coordinates
    ( (:&)(..), Coordinates(..)
    )
    where
import           Diagrams.Points
import           Linear          (V2 (..), V3 (..), V4 (..))
class Coordinates c where
  
  type FinalCoord c    :: *
  
  type PrevDim c       :: *
  
  type Decomposition c :: *
    
  
  
  
  
  
  
  
  
  
  
  (^&)    :: PrevDim c -> FinalCoord c -> c
  
  pr      :: PrevDim c -> FinalCoord c -> c
  pr = (^&)
  
  
  coords :: c -> Decomposition c
infixl 7 ^&
data a :& b = a :& b
  deriving (Eq, Ord, Show)
infixl 7 :&
instance Coordinates (a :& b) where
  type FinalCoord (a :& b) = b
  type PrevDim (a :& b) = a
  type Decomposition (a :& b) = a :& b
  x ^& y                    = x :& y
  coords (x :& y)           = x :& y
instance Coordinates (a,b) where
  type FinalCoord (a,b)    = b
  type PrevDim (a,b)       = a
  type Decomposition (a,b) = a :& b
  x ^& y                   = (x,y)
  coords (x,y)             = x :& y
instance Coordinates (a,b,c) where
  type FinalCoord (a,b,c)    = c
  type PrevDim (a,b,c)       = (a,b)
  type Decomposition (a,b,c) = Decomposition (a,b) :& c
  (x,y) ^& z                  = (x,y,z)
  coords (x,y,z)             = coords (x,y) :& z
instance Coordinates (a,b,c,d) where
  type FinalCoord (a,b,c,d)    = d
  type PrevDim (a,b,c,d)       = (a,b,c)
  type Decomposition (a,b,c,d) = Decomposition (a,b,c) :& d
  (w,x,y)  ^& z                = (w,x,y,z)
  coords (w,x,y,z)             = coords (w,x,y) :& z
instance Coordinates (v n) => Coordinates (Point v n) where
  type FinalCoord (Point v n)    = FinalCoord (v n)
  type PrevDim (Point v n)       = PrevDim (v n)
  type Decomposition (Point v n) = Decomposition (v n)
  x ^& y       = P (x ^& y)
  coords (P v) = coords v
instance Coordinates (V2 n) where
  type FinalCoord (V2 n)    = n
  type PrevDim (V2 n)       = n
  type Decomposition (V2 n) = n :& n
  x ^& y          = V2 x y
  coords (V2 x y) = x :& y
instance Coordinates (V3 n) where
  type FinalCoord (V3 n)    = n
  type PrevDim (V3 n)       = V2 n
  type Decomposition (V3 n) = n :& n :& n
  V2 x y ^& z       = V3 x y z
  coords (V3 x y z) = x :& y :& z
instance Coordinates (V4 n) where
  type FinalCoord (V4 n)    = n
  type PrevDim (V4 n)       = V3 n
  type Decomposition (V4 n) = n :& n :& n :& n
  V3 x y z ^& w       = V4 x y z w
  coords (V4 x y z w) = x :& y :& z :& w