{- The menu picture.  -}
module Dodge.Render.MenuScreen
    ( menuScreen
    ) where
import Dodge.Data
import Dodge.WindowLayout
import Dodge.Base.Window
import Picture
import Dodge.Menu
import Padding

import qualified Data.Text as T

menuScreen :: Universe -> ScreenLayer -> Picture
menuScreen w screen = case screen of
    OptionScreen {_scTitle = titf, _scOptions = mos, _scOptionsOffset = off} 
                            -> drawOptions w (titf w) mos off "Use keys to navigate the menu"
    (WaitScreen sf _)       -> drawOptions w (sf w) [] 0 ""
    (InputScreen inputstr help)    -> drawOptions w ('>':T.unpack inputstr) [] 0 help
    (DisplayScreen sd )     -> sd w
    (ColumnsScreen titf pairs) -> drawTwoColumnsScreen (_config w) (titf w) pairs

--displayStringList :: World -> [String] -> Picture
--displayStringList w ss = pictures
--    ( polygon (screenBox w)
--    : zipWith f ys ss
--    )
--  where
--    hw = halfWidth  w
--    ys = [0,22..]
--    f y s = translate (10-hw) y . scale 0.15 0.15 $ text s

drawTwoColumnsScreen :: Configuration -> String -> [(String,String)] -> Picture
drawTwoColumnsScreen cfig title lps = pictures
    [darkenBackground cfig
    ,drawTitle cfig title
    ,drawTwoColumns cfig lps
    ]

drawTwoColumns :: Configuration -> [(String,String)] -> Picture
drawTwoColumns cfig lps = pictures $ zipWith f [hh-100,hh-130..] lps
  where
    f y (s1,s2) = placeString (50-hw) y 0.15 $ rightPad ln '.' s1 ++ s2
    hh = halfHeight cfig
    hw = halfWidth  cfig
    ln = maximum (map (length . fst) lps) + 3
    
drawOptions 
    :: Universe
    -> String       -- ^ Title
    -> [MenuOption] -- ^ Options
    -> Int          -- ^ Options offset
    -> String       -- ^ Help Text
    -> Picture
drawOptions u title ops off footer = pictures $
    [ darkenBackground cfig 
    , drawTitle cfig title
    , drawFooterText cfig red footer
    ] ++
    zipWith (\s vpos -> placeString (-hw + 50) vpos 0.2 s) 
        ops''
        [hh-100,hh-150 ..]
--    ++ [color yellow $ concat [line [V2 (negate hw) (hh-y), V2 hw (hh-y)] | 
--            y <- map (+75) [0,50..hh*2]]
--        ]
  where
    maxOptionLength = 3 + maximum (0 : map (optionValueOffset u) ops')
    ops' = case availableMenuLines cfig of
        x | x < length ops -> take (availableMenuLines cfig) (drop off visibleops)
        _ -> visibleops
    ops'' = case availableMenuLines cfig of
        x | x < length ops -> map (menuOptionToString u maxOptionLength) ops' ++ ["SPACE: MORE OPTIONS"]
        _ -> map (menuOptionToString u maxOptionLength) ops'
    visibleops = filter notInvisible ops
    notInvisible InvisibleToggle {} = False
    notInvisible _ = True
    hh = halfHeight cfig
    hw = halfWidth  cfig
    cfig = _config u

optionValueOffset :: Universe -> MenuOption -> Int
optionValueOffset u mo = case _moString mo u of
    Left _ -> 0
    Right (s,_) -> length s

darkenBackground :: Configuration -> Picture
darkenBackground = color (withAlpha 0.5 black) . polygon . reverse . screenBox

drawTitle :: Configuration -> String -> Picture
drawTitle cfig = placeString (-hw + 30) (hh - 50) 0.4
  where
    hh = halfHeight cfig
    hw = halfWidth  cfig

placeString 
    :: Float -- | x distance from center
    -> Float -- | y distance from center
    -> Float -- | scale
    -> String
    -> Picture
placeString x y sc = color white . translate x y . scale sc sc . text

drawFooterText :: Configuration -> Color -> String -> Picture
drawFooterText cfig col = color col . placeString (-hw + 30) (-hh+10) 0.1
  where
    hh = halfHeight cfig
    hw = halfWidth cfig

menuOptionToString :: Universe -> Int -> MenuOption -> String
menuOptionToString w padAmount mo = theKeys ++ optionText
  where
    optionText = case _moString mo w of
        Left s -> s
        Right (s,t) -> rightPad padAmount '.' s ++ t
    theKeys = case mo of
        Toggle  {_moKey = k} -> stc k : ":"
        Toggle2 {_moKey1 = k1, _moKey2 = k2} -> stc k1 : '/' : stc k2 : ":"
        _ -> undefined
    stc = scodeToChar
