{-# LANGUAGE OverloadedStrings #-}

import qualified SDL
import Control.Concurrent (threadDelay)
import Linear (V2(..), V4(..))
import Linear.Affine (Point(P))
import Control.Monad (unless)
import Foreign.C.Types
import Data.Foldable (traverse_)
import System.IO (hPutStrLn, stderr)

main :: IO ()
main = do
    SDL.initialize [SDL.InitVideo]
    window <- SDL.createWindow "Mirrors and lasers" $ SDL.defaultWindow { SDL.windowInitialSize = V2 576 511 }
    renderer <- SDL.createRenderer window (-1) SDL.defaultRenderer
    tileset <- SDL.loadBMP "data/tileset.bmp" >>= SDL.createTextureFromSurface renderer
    SDL.showWindow window
    
    mainLoop window renderer tileset
    
    SDL.destroyTexture tileset
    SDL.destroyRenderer renderer
    SDL.destroyWindow window
    SDL.quit

mainLoop :: SDL.Window -> SDL.Renderer -> SDL.Texture -> IO ()
mainLoop window renderer tileset = do
    event <- SDL.waitEvent
    let quit = SDL.eventPayload event == SDL.QuitEvent

    let (cx, cy) = case SDL.eventPayload event of
                    SDL.MouseMotionEvent da -> let P (V2 x y) = SDL.mouseMotionEventPos da in (fromIntegral x, fromIntegral y)
                    otherwise -> (fromIntegral 0, fromIntegral 0)
    
    let posx = fromIntegral cx `div` (tileSize+2)
    let posy = fromIntegral cy `div` (tileSize+2)
    
    debug $ "PosX: " ++ show posx ++ ", PoxY: " ++ show posy

    SDL.rendererDrawColor renderer SDL.$= V4 0 0 0 0
    SDL.clear renderer
    drawGrid window renderer
    SDL.copyEx
        renderer
        tileset
        (Just $ SDL.Rectangle (P $ V2 (CInt $ 32) -- pos x
                                      (CInt $ 0)) -- pos y
                              (V2 tileSize tileSize)) -- dimension
        (Just $ SDL.Rectangle (P $ V2 (CInt $ posx * tileSize + posx * 2 + 1) -- pos x
                                      (CInt $ posy * tileSize + posy * 2 + 1)) -- pos y
                              (V2 tileSize tileSize)) -- dimension
        (CDouble 0)
        Nothing
        (V2 False False)
    SDL.present renderer

    unless quit $ mainLoop window renderer tileset

drawGrid :: SDL.Window -> SDL.Renderer -> IO ()
drawGrid window renderer = do
    V2 width height <- SDL.get $ SDL.windowSize window
    let drawVertical x = SDL.drawLine renderer (P $ V2 x 0) (P $ V2 x height)
    let drawHorizontal y = SDL.drawLine renderer (P $ V2 0 y) (P $ V2 (width - sidebarSize) y)
    
    SDL.rendererDrawColor renderer SDL.$= V4 100 100 100 255
    traverse_ drawVertical [0,34..width - sidebarSize]
    traverse_ drawHorizontal [0,34..height]
    where
        sidebarSize = 2 + (4 * (tileSize + 1))

debug :: String -> IO ()
debug = hPutStrLn stderr -- TODO: Seems to produce an error on windows

tileSize :: Num a => a
tileSize = fromIntegral 32
