{-|
    Module containing functions for working with 'ListStore'\'s, and
    for refreshing the 'FileBrowser'.
-}

module TreeFunctions 
    (
        getMultipleSelection,
        getSingleSelection,
        refreshBrowser,
        refreshView
    )
where

import qualified Control.Exception as E
import Buttons
import Graphics.UI.Gtk
import System.FilePath ( splitFileName, takeExtension )
import System.Directory ( setCurrentDirectory, getCurrentDirectory, doesDirectoryExist, getModificationTime )
import Util
import Popup
import Types
import Components
import DirectoryTree ( expandPath )
import Control.Monad ( forM )
import System.Time

{-|
    Gets a single selection from a 'ListStore'. If this
    has been erroneously triggered, then it will return
    'Nothing', but apart from that it will return the
    first selection selected by the user.
-}

getSingleSelection :: TreeView -- ^ The 'TreeView' containing the selection.
                   -> ListStore StoreRow  -- ^ The 'ListStore' containing the selected element.
                   -> IO ( Maybe String ) -- ^ The selected element.
getSingleSelection tree store = treeViewGetSelection tree >>= treeSelectionGetSelectedRows >>= ( \s ->
    case ( length s ) of
        0 -> return ( Nothing )
        _ -> getListSelection ( head s ) store >>= (\r -> return ( Just r ) ) )

{-|
    Gets a list of selected items from a list store. If this
    has been erroneously triggered it returns 'Nothing', but
    apart from that it will iterate through the selected items, and
    add them to a list that it will return.
-}

getMultipleSelection :: TreeView -- ^ The 'TreeView' containing the selections.
                     -> ListStore StoreRow -- ^ The 'ListStore' containing the actual elements.
                     -> IO ( Maybe [String] ) -- ^ Nothing or the list of selected elements.
getMultipleSelection tree store = treeViewGetSelection tree >>= treeSelectionGetSelectedRows >>= ( \s ->
    case ( length s ) of
            0 -> return ( Nothing )
            _ -> (\r -> return ( Just r ) ) =<< ( forM s $ \path -> getListSelection path store ) )
               
{-|
    Refreshes the 'FileBrowser' to display the contents
    of a supplied direectory. It sets the directory to 
    be the supplied directory, if there is a problem it
    stays in the current directory and refreshes that, 
    if there is no problem, it updates with the supplied
    directories contents.
-}
                                 
refreshBrowser :: FilePath -- ^ The path to the directory to be displayed.
               -> FileBrowser -- ^ The 'FileBrowser' to be refreshed.
               -> IO ()
refreshBrowser directory b = do
    setCurrentDirectory directory `E.catch` (\_ -> errorWindow ("Invalid Location\n" ++ directory ) )
    ( folders, files ) <- getCurrentDirectory >>= (\dir -> do
                                                            entrySetText ( location b ) dir
                                                            expandPath ( treeTree b ) ( treeStore b ) dir
                                                            viewDirectory dir )
    refreshPane folders ( dirStore b )
    refreshPane files ( fileStore b )

{-|
    Refreshes the view of the current directory. If there is
    a problem with accessing the current directory, it will default
    to the users home directory.
-}

refreshView :: FileBrowser -- ^ The 'FileBrowser' to be refreshed.
            -> IO ( )
refreshView browse = ( getCurrentDirectory `E.catch` (\_ -> getHomeFolder ) ) >>= 
    ( \c -> refreshBrowser c browse )

{-|
    Gets an individual string from a ListStore, based upon
    a supplied 'TreePath'.
-}

getListSelection :: TreePath -> ListStore StoreRow -> IO String
getListSelection path store = listStoreGetValue store ( head path ) >>= (\r -> return ( name r ) )
