{-# LANGUAGE FlexibleInstances #-}
module Types.Interior where

import Data.Matrix as M

import Linear.V2

-- internal imports

import Types.Map
import Types.ReachPoint
import Types.ImgId
import Types.Direction

data Cluster
  = ClusterBox1
  | ClusterTableSW
  | ClusterTableNW
  | ClusterTableNE
  | ClusterTableSE
  | ClusterCornerTable
  | ClusterTableGroup
  | ClusterCopier
  | ClusterFlipchart
  | ClusterConferenceTable
  | ClusterPlant1
  | ClusterPlant2
  | ClusterToilet
  | ClusterWatercooler
  | ClusterVending
  | ClusterCabCoffee
  deriving (Enum, Bounded, Show)

-- row -> NS; col -> WE
clusterMat :: Cluster -> (Int, Int) -> Matrix (Maybe ImgId)
clusterMat ClusterBox1 _ =
  M.fromLists
    [ [Just ImgMiscBox1]
    ]
clusterMat ClusterTableSW (h, _) =
  M.fromLists $ replicate h
    [Just ImgEmpty, Just ImgTableSW]
clusterMat ClusterTableSE (_, w) =
  M.fromLists $
    [ replicate w (Just ImgTableSE)
    , replicate w (Just ImgEmpty)
    ]
clusterMat ClusterTableNE (h, _) =
  M.fromLists $ replicate h
    [Just ImgTableNE, Just ImgEmpty]
clusterMat ClusterTableNW (_, w) =
  M.fromLists $
    [ replicate w (Just ImgEmpty)
    , replicate w (Just ImgTableNW)
    ]
clusterMat ClusterCornerTable _ =
  M.fromLists
    [ [Just ImgTableSE, Just ImgTableCorner]
    , [Just ImgEmpty,   Just ImgTableSW]
    ]
clusterMat ClusterTableGroup _ =
 M.fromLists
   [ [ Just ImgEmpty, Just ImgTableSE, Just ImgTableCorner
     , Just ImgEmpty, Just ImgTableSE, Just ImgTableCorner
     ]
   , [ Just ImgEmpty, Just ImgEmpty, Just ImgTableSW
     , Just ImgEmpty, Just ImgEmpty, Just ImgTableSW
     ]
   , [ Just ImgEmpty, Just ImgEmpty, Just ImgEmpty
     , Just ImgEmpty, Just ImgEmpty, Just ImgEmpty
     ]
   , [ Nothing, Nothing, Nothing
     , Just ImgEmpty, Just ImgTableSE, Just ImgTableCorner
     ]
   , [ Nothing, Nothing, Nothing
     , Just ImgEmpty, Just ImgEmpty, Just ImgTableSW
     ]
   ]
clusterMat ClusterCopier _ =
  M.fromLists
    [ [ Just ImgEmptyNoWalk]
    , [ Just ImgEmpty]
    ]
clusterMat ClusterFlipchart _ =
  M.fromLists
    [ [ Just ImgMiscFlipchart]
    , [ Just ImgEmpty]
    ]
clusterMat ClusterConferenceTable (h, w) =
  let mw = max 4 w
      mh = max 4 h
  in M.fromLists $
    [ replicate mw (Just ImgEmpty)
    , [ Just ImgEmpty, Just ImgTableC4] ++ replicate (mw-4) (Just ImgTableNW) ++
      [ Just ImgTableC3, Just ImgEmpty ]
    ] ++
    replicate (mh-4) ([ Just ImgEmpty, Just ImgTableSW] ++ replicate (mw-4) (Just ImgEmpty) ++
      [ Just ImgTableNE, Just ImgEmpty ]) ++
    [ [ Just ImgEmpty, Just ImgTableC1] ++ replicate (mw-4) (Just ImgTableSE) ++
      [ Just ImgTableC2, Just ImgEmpty ]
    , replicate mw (Just ImgEmpty)
    ]
clusterMat ClusterPlant1 _ =
  M.fromLists
    [ [ Just ImgMiscPlant1 ] ]
clusterMat ClusterPlant2 _ =
  M.fromLists
    [ [ Just ImgMiscPlant2 ] ]
clusterMat ClusterToilet _ =
  M.fromLists
    [ [ Just ImgEmpty, Just ImgEmptyNoWalk] ]
clusterMat ClusterWatercooler _ =
  M.fromLists
    [ [ Just ImgMiscWatercooler ]
    , [ Just ImgEmpty ]
    ]
clusterMat ClusterVending _ =
  M.fromLists
    [ [ Just ImgMiscVending ]
    , [ Just ImgEmpty ]
    ]
clusterMat ClusterCabCoffee _ =
  M.fromLists
    [ [ Just ImgEmpty, Just ImgCabinetCoffee ]
    ]

clusterRoom :: Cluster -> [TileState]
clusterRoom ClusterBox1             = [Offi]
clusterRoom ClusterTableSW          = [Offi]
clusterRoom ClusterTableNW          = [Offi]
clusterRoom ClusterTableNE          = [Offi]
clusterRoom ClusterTableSE          = [Offi]
clusterRoom ClusterCornerTable      = [Offi]
clusterRoom ClusterTableGroup       = [Offi]
clusterRoom ClusterCopier           = [Offi]
clusterRoom ClusterFlipchart        = [Offi]
clusterRoom ClusterConferenceTable  = [Offi]
clusterRoom ClusterPlant1           = [Offi]
clusterRoom ClusterPlant2           = [Offi]
clusterRoom ClusterToilet           = [Toil]
clusterRoom ClusterWatercooler      = [Kitc, Offi]
clusterRoom ClusterVending          = [Kitc]
clusterRoom ClusterCabCoffee        = [Kitc]

clusterPoints :: Cluster -> (Int, Int) -> [ReachPoint]
clusterPoints ClusterBox1 _ = []
clusterPoints ClusterTableNE (h, _) =
  [ ReachPoint Table (V2 r 2) SW | r <- [1..h] ]
clusterPoints ClusterTableNW (_, w) =
  [ ReachPoint Table (V2 1 c) SE | c <- [1..w] ]
clusterPoints ClusterTableSW (h, _) =
  [ ReachPoint Table (V2 r 1) NE | r <- [1..h] ]
clusterPoints ClusterTableSE (_, w) =
  [ ReachPoint Table (V2 2 c) NW | c <- [1..w] ]
clusterPoints ClusterCornerTable _ =
  [ ReachPoint Computer (V2 2 1) N
  ]
clusterPoints ClusterTableGroup _ =
  [ ReachPoint Computer (V2 2 2) N
  , ReachPoint Computer (V2 2 5) N
  , ReachPoint Computer (V2 5 5) N
  ]
clusterPoints ClusterCopier _ =
  [ ReachPoint Copier (V2 2 1) NW
  ]
clusterPoints ClusterFlipchart _ =
  [ ReachPoint Table (V2 2 1) NW
  ]
clusterPoints ClusterConferenceTable (h, w) =
  let mw = max 4 w
      mh = max 4 h
  in
    [ ReachPoint Table (V2 1 c)  SE | c <- [2..mw-1] ] ++
    [ ReachPoint Table (V2 r 1)  NE | r <- [2..mh-1] ] ++
    [ ReachPoint Table (V2 r mw) SW | r <- [2..mh-1] ] ++
    [ ReachPoint Table (V2 mh c) NW | c <- [2..mw-1] ]
clusterPoints ClusterToilet _ =
  [ ReachPoint Toilet (V2 1 1) NE
  ]
clusterPoints ClusterWatercooler _ =
  [ ReachPoint Drink (V2 2 1) NW
  ]
clusterPoints ClusterVending _ =
  [ ReachPoint Eat (V2 2 1) NW
  ]
clusterPoints ClusterCabCoffee _ =
  [ ReachPoint Drink (V2 1 1) NE
  ]
clusterPoints _ _ = []

instance Size (Cluster, (Int, Int)) where
  size (c, dim) =
    let mat = clusterMat c dim
    in  fromIntegral ((nrows mat) * (ncols mat))
