{--
Author: Nikolaus Huber S1106087
Based on the Tutorial http://www.haskell.org/haskellwiki/OpenGLTutorial2

Changes to the tutorial example for better reviewing:
- moved all modules to one file
- removed the keybindings
- introduced time = animation
- simplified the cube to a square
- moving route is an infinity symbol, squares are largest at the corners, smallest in the middle
- various other small changes

To execute use the MovingInfinity Binary or create your own by using this command in the Terminal:
ghc -package GLUT MovingInfinity.hs -o MovingInfinity

(on Mac OS X thousands of warnings come after the successful compilation. Just press CTRL + C to stop it and execute the binary)
--}

import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
import Data.IORef

main = do
 (progname,_) <- getArgsAndInitialize
 initialDisplayMode $= [DoubleBuffered]
 createWindow "Moving Infinity"
 time  <- newIORef (0.0::GLfloat)
 delta <- newIORef (0.0003::GLfloat)
 idleCallback $= Just (idle time delta)
 displayCallback $= (display time)
 mainLoop

idle time delta = do
  t <- get time
  d <- get delta
  time $= t+d
  postRedisplay Nothing

display time = do 
  clear [ColorBuffer]
  loadIdentity
  preservingMatrix $ do 
    t <- get time
    scale 0.7 0.7 (0.7::GLfloat)
    mapM_ (\(x,y,z) -> preservingMatrix $ do
      color $ Color3 ((x+1.0)/2.0) ((y+1.0)/2.0) (0.5)
      translate $ Vector3 x y z
      square ((abs x + abs y + 1.0)/20.0)
      --square (0.1::GLfloat)
      ) $ points 36 t
    swapBuffers

points :: Int -> GLfloat -> [(GLfloat,GLfloat,GLfloat)]
points n t = [ (cos(i+t),sin(2*(i+t)), 0.0) | i <- [1..n'] ]
       where n' = fromIntegral n

square w = do 
  renderPrimitive Quads $ do
    vertex $ Vertex3 w w 0
    vertex $ Vertex3 w (-w) 0
    vertex $ Vertex3 (-w) (-w) 0
    vertex $ Vertex3 (-w) w 0