{-# LANGUAGE UnicodeSyntax, RecordWildCards #-}
module Data.Tiled.Types where

import Data.Map (Map)
import Data.Word (Word8, Word32)

-- | Orientations.
data MapOrientation = Orthogonal | Isometric deriving (Show, Eq)

-- | Properties.
type Properties = [(String, String)]

-- | A tiled map.
data TiledMap = TiledMap
         { mapPath              FilePath -- ^ The file path of the map file.
         , mapOrientation       MapOrientation
         , mapWidth, mapHeight  Int
         , mapTileWidth         Int
         , mapTileHeight        Int
         , mapProperties        Properties
         , mapTilesets          [Tileset]
         , mapLayers            [Layer]
         } deriving (Show, Eq)

-- | A set of tiles that can be used.
data Tileset = Tileset
             { tsName                     String
             , tsInitialGid               Word32
             , tsTileWidth, tsTileHeight  Int
             , tsSpacing, tsMargin        Int
             , tsImages                   [Image] -- ^ Multiple images not
                                                   -- yet supported in tiled.
             , tsTileProperties           [(Word32, Properties)]
             } deriving (Show, Eq)

-- | An image containing tiles.
data Image = Image
           { iSource          FilePath
           , iTrans           Maybe (Word8, Word8, Word8)
           , iWidth, iHeight  Int
           } deriving (Show, Eq)

-- | An object, usable for stuff not repetitively aligned on a grid.
data Object = Object
            { objectName                 Maybe String
            , objectType                 Maybe String
            , objectProperties           Properties
            , objectX, objectY           Int
            , objectWidth, objectHeight  Maybe Int
            , objectGid                  Maybe Word32
            , objectPolygon              Maybe Polygon
            , objectPolyline             Maybe Polyline
            } deriving (Show, Eq)

-- | A polygon.
data Polygon = Polygon [(Int, Int)] deriving (Show, Eq)

-- | A polyline.
data Polyline = Polyline [(Int, Int)] deriving (Show, Eq)

-- | Either a tile layer or an object layer.
data Layer = Layer
           { layerName        String
           , layerOpacity     Float
           , layerIsVisible   Bool
           , layerProperties  Properties
           , layerData        Map (Int, Int) Tile
           }
           | ObjectLayer
           { layerName        String
           , layerOpacity     Float
           , layerIsVisible   Bool
           , layerProperties  Properties
           , layerObjects     [Object]
           }
           | ImageLayer
           { layerName        String
           , layerOpacity     Float
           , layerIsVisible   Bool
           , layerProperties  Properties
           , layerImage       Image
           } deriving Eq

-- | A single tile as is stored in a layer.
data Tile = Tile { tileGid                         Word32
                 , tileIsVFlipped, tileIsHFlipped, tileIsDiagFlipped  Bool
                 } deriving (Show, Eq, Ord)


instance Show Layer where
    show Layer {..} = "Layer { layerName = " ++ show layerName ++
                            ", layerOpacity = " ++ show layerOpacity ++
                            ", layerIsVisible = " ++ show layerIsVisible ++
                            ", layerProperties = " ++ show layerProperties ++
                            ", layerData = \"...\" }"
    show ObjectLayer {..} = "ObjectLayer { layerName = " ++ show layerName ++
                                        ", layerOpacity = " ++ show layerOpacity ++
                                        ", layerIsVisible = " ++ show layerIsVisible ++
                                        ", layerProperties = " ++ show layerProperties ++
                                        ", layerObjects = " ++ show layerObjects ++ " }"
    show ImageLayer {..} = "ObjectLayer { layerName = " ++ show layerName ++
                                       ", layerOpacity = " ++ show layerOpacity ++
                                       ", layerIsVisible = " ++ show layerIsVisible ++
                                       ", layerProperties = " ++ show layerProperties ++
                                       ", layerImage = " ++ show layerImage ++ " }"