-- Compile this with 'ghc -o Game Game.hs' and run it with './Game'.
{-# LANGUAGE RecordWildCards #-}

import Graphics.Gloss.Game
import QuadTree
import Tiles
import Debug.Trace
import Control.Exception.Base (assert)

-- A sprite representing our character
slimeSprite :: Picture
slimeSprite = bmp "Slime.bmp"

grassSprite :: Picture
grassSprite = bmp "Grass.bmp"

waterSprite :: Picture
waterSprite = bmp "Water.bmp"
-- Our game world consists purely of the location of our character.
-- data World = World Point

data World = World  {
    playerPos :: Point, 
    tiles :: QuadTree TileContent
}

data TileContent = Grass | Rock | Water | Empty deriving Show

tileSprite Grass = grassSprite
tileSprite Rock = error "No rock sprite"
tileSprite Water = waterSprite
tileSprite Empty = error "No empty sprite"

-- This starts our gamein a window with a give size, running at 30 frames per second.
--
-- The argument 'World (0, 0)' is the initial state of our game world, where our character is at the centre of the
-- window. 
--

initWorld = let playerPos = (0,0)
                maxtile = (2 ^ 32) `div` 2
                mintile = - maxtile
                worldRegion = fromTiles (mintile,mintile) (maxtile,maxtile)
                tiles = setRegion (newQuadTree worldRegion Grass) Water (fromTiles (0,0) (1,1))
            in  trace (show tiles) $ World {..}

main = play (InWindow "Fun game!" (600, 400) (50, 50)) white 60 initWorld draw handle [slide]

-- To draw a frame, we position the character sprite at the location as determined by the current state of the world.
-- We shrink the sprite by 50%.
drawOld (World (x, y) _) = translate x y (scale 0.5 0.5 grassSprite)

draw :: World -> Picture
draw (World (playerx, playery) tiles) = pictures $ 
    [translate ((fromIntegral x)*64) ((fromIntegral y)*64) (scale 0.5 0.5 (tileSprite (fst (tiles `getElemAt` (x,y))))) | x <- [-20..20], y <- [-12..12]] ++ [translate playerx playery (scale 0.5 0.5 slimeSprite)]

slide time (World (x,y) tiles) = World (x,y + time*10) tiles

-- Whenever any of the keys 'a', 'd', 'w', or 's' have been pushed down, move our character in the corresponding
-- direction.
handle (EventKey (Char 'a') Down _ _) (World (x, y) tiles) = World (x - 10, y) tiles
handle (EventKey (Char 'd') Down _ _) (World (x, y) tiles) = World (x + 10, y) tiles
handle (EventKey (Char 'w') Down _ _) (World (x, y) tiles) = World (x, y + 10) tiles
handle (EventKey (Char 's') Down _ _) (World (x, y) tiles) = World (x, y - 10) tiles
handle event world = world        -- don't change the world in case of any other events