module Language.Mecha.Types
  ( Vector, Vertex, Normal, Color
  , Moveable  (..)
  , Scaleable (..)
  , Colorable (..)
  , Setable   (..)
  , moveX
  , moveY
  , moveZ
  , rotateX
  , rotateY
  , rotateZ
  , scaleXYZ
  , unions
  , debug
  ) where

import System.IO.Unsafe

type Vector = (Double, Double, Double)
type Vertex = Vector
type Normal = Vector
type Color  = Vector

class Moveable a where
  move   :: Vector -> a -> a
  rotate :: Vector -> Double -> a -> a

moveX :: Moveable a => Double -> a -> a
moveX a = move (a, 0, 0)

moveY :: Moveable a => Double -> a -> a
moveY a = move (0, a, 0)

moveZ :: Moveable a => Double -> a -> a
moveZ a = move (0, 0, a)

rotateX :: Moveable a => Double -> a -> a
rotateX = rotate (1, 0, 0)

rotateY :: Moveable a => Double -> a -> a
rotateY = rotate (0, 1, 0)

rotateZ :: Moveable a => Double -> a -> a
rotateZ = rotate (0, 0, 1)

class Scaleable a where
  scale :: Vector -> a -> a

scaleXYZ :: Scaleable a => Double -> a -> a
scaleXYZ a = scale (a, a, a)

class Colorable a where
  color :: Color -> a -> a

class Setable a where
  union        :: a -> a -> a
  intersection :: a -> a -> a
  difference   :: a -> a -> a

unions :: Setable a => [a] -> a
unions = foldl1 union

debug :: Show a => String -> a -> b -> b
debug m a b = unsafePerformIO (putStrLn (m ++ ": " ++ show a) >> return b)