-- Copyright: 2009 Betty Diegel 
-- License: BSD3 (see LICENSE)
-- Author: Betty Diegel <bdiegel@usa.net> 

import Graphics.UI.WX
import Graphics.UI.WXCore
import Shop.Data.Item

import Data.Map hiding (map, filter, (\\))
import Data.List
import System.Environment
import System.FilePath


addSelections :: MultiListBox a -> MultiListBox a -> IO ()
addSelections w1 w2 = do
   ss <- getSelections w1 
   --  mapM_  logMessage ss
   addItems w2 ss
   removeItems w1 ss
   indices <- getIndices w2 ss
   set w2 [selections := indices ] 
   -- select (ListItemSelected 1) w2

addItems :: MultiListBox a -> [ String ] -> IO ()
addItems w ss = do 
   mapM_ (itemAppend w ) ss
   unsortedItems <- get w items
   set w [ items := sort unsortedItems ]

removeItems :: MultiListBox a -> [ String ] -> IO ()
removeItems w ss = do 
   allItems <- get w items
   let lessItems = allItems \\ ss 
   set w [ items := sort lessItems ]

delSelections :: MultiListBox a -> MultiListBox a -> IO ()
delSelections w1 w2 = putStrLn "test2"

getSelections :: MultiListBox a -> IO [ String ]
getSelections w = do 
   indices <- get w selections
   mapM (\i -> get w (item i)) indices

getIndices :: MultiListBox a -> [ String ] -> IO [ Int ]
getIndices w ss = do
   itemsW <- get w items
   let ts = zip itemsW [0..] 
   let ts' = filter ( \(s, _) -> s `elem` ss ) ts
   return $ map snd ts'

onSave :: [ String ] -> IO ()
onSave ss = do
   let s = unlines ss
   writeFile "/tmp/shoplist-out" s 

onSaveAs :: Window a -> [ String ] -> IO ()
onSaveAs w ss = do
   let s = unlines ss
   homeDir <- getEnv "HOME"
   fp <- fileSaveDialog w True True "Open image" [("Text file",["*.txt"])] homeDir "grocery.txt"
   maybe (return ()) (\filePath -> writeFile filePath s) fp
 
loadShopList :: Window a -> MultiListBox b -> MultiListBox b -> IO ()
loadShopList w mb1 mb2 = do
   homeDir <- getEnv "HOME"
   fp <- fileOpenDialog w True True "Load list" [("Test file",["*.txt"])] homeDir "grocery.txt"
   s <- maybe (return []) readFile fp
   let ss = lines s
   set mb1 [ items := ss ]
   removeItems mb2 ss

--logSelect :: MultiListBox a -> Point b -> IO ()
logSelect w pt = do 
   ss <- getSelections w
   logMessage ("selected items: " ++ show ss )

addNewItem :: MultiListBox a -> IO ()
addNewItem w = do
   s <- textDialog w "Add item" "Enter name of item:" ""
   addItems w [ s ]



main :: IO ()
main = do
   start mainWindow

mainWindow :: IO ()
mainWindow = do
   dataDir <- getEnv "HOME"
   let itemsFile = dataDir </> "shoplist-new"
   itemsList <- loadItemList itemsFile
   let names = keys $ createItemMap itemsList
--   putStr $ show itemsList

   -- application frame --
   f <- frame [ text := "Shopping List" ]

   -- file menu --
   file <- menuPane        [ text := "&File" ]
   load <- menuItem file   [ text := "&Load\tCtrl+L" ]
   menuLine file
   save <- menuItem file   [ text := "&Save\tCtrl+S" ]
   saveAs <- menuItem file [ text := "Save &As..\tCtrl+A" ]
   menuLine file
   quit <- menuQuit file   [ help := "Exit application" ]

   -- set the appliacion menus --
   set f [ menuBar := [ file ] ]

   -- left list --
   --itemsListBox <- multiListBox f [ items := names, on select ::= logSelect, sorted := True ]
   itemsListBox <- multiListBox f [ items := names, sorted := True ]

   -- right list --
   shopListBox <- multiListBox f [ items := [] ]

   -- button controls --
   buttonPanel <- panel f []
   addButton <- button buttonPanel [ text := ">>"
                                   , on command := addSelections itemsListBox shopListBox ] 
   delButton <- button buttonPanel [ text := "<<"
                                   , on command := delSelections shopListBox itemsListBox ]
  
   -- doublClick: moves item from left list to right list -- 
   set itemsListBox [ on doubleClick := (\pt -> addSelections itemsListBox shopListBox) ]
   set shopListBox [on (charKey 'n') ::= addNewItem  ]
   
   -- layout --
   set f [ layout := margin 20 $ 
                     column 10 [ grid 10 10 [ [ fill $ widget itemsListBox 
                                              , container buttonPanel $ 
                                                floatCentre $ 
                                                column 5 [ widget addButton
                                                         , widget delButton ]
                                              , fill $ widget shopListBox
                                              ] 
                                            ] 
                              ] 
         ]

   -- add mneu event handlers --
   set f [ on (menu load) := loadShopList f shopListBox itemsListBox
         , on (menu save) :=  get shopListBox items >>= onSave 
         , on (menu saveAs) :=  get shopListBox items >>= onSaveAs f 
         , on (menu quit) := close f
         ]

   return ()


