{-# LANGUAGE DeriveDataTypeable #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  XMonad.Prompt.ProjectGroup
-- Copyright   :  (C) 
-- License     :  BSD3
--
-- Maintainer  :
-- Stability   :  unstable
-- Portability :  unportable
--
-- A project prompt for XMonad
--
-----------------------------------------------------------------------------


module XMonad.Prompt.ProjectGroup (
                             -- * Usage
                             -- $usage
                             projectGroupPrompt,
                             -- addPrompt,
                             -- deletePrompt,

                             -- * For developers
                              ) where

import XMonad hiding ( workspaces )
import XMonad.Prompt
import XMonad.StackSet ( workspaces, tag )
import XMonad.Util.WorkspaceCompare ( getSortByIndex )
import qualified XMonad.Util.ExtensibleState as XS
import qualified XMonad.StackSet as W
import XMonad.Actions.DynamicWorkspaces
import Data.Maybe
import Data.List
import qualified XMonad.Hooks.ProjectHistory as PH
import qualified XMonad.Hooks.ProjectGroupHistory as GH
import System.IO
import qualified XMonad.Prompt.SubWorkspace as SW
import qualified XMonad.Prompt.Project as P

suppressFirstSafe :: [a] -> [a]
suppressFirstSafe l = if null l then l else tail l ++ [head l]

projectGroupPrompt :: XPConfig -> X ()
projectGroupPrompt c = do 
    ts <- XS.get :: X P.ProjectGroups
    pgHistory <- GH.projectGroupHistory
    mkXPrompt (P.Grp "") c (mkComplFunPopWords' $ suppressFirstSafe pgHistory) update

update :: String -> X ()
update selection = do
       ts <- XS.get :: X P.ProjectGroups
       XS.modify (\st -> st { P.groups = (P.groups st) ++ (add selection st), P.currentGroup = selection })
       switchToLastProject selection
       GH.projectGroupHistoryHook selection
 where 
       add selection st = 
           if (inArray selection (P.groups st)) then [] else [P.ProjectGroup { P.groupName = selection }]
       inArray selection st = 
           not (null (filter (\elem -> P.groupName elem == selection) st))

switchToLastProject :: String -> X ()
switchToLastProject grp = do
  ph <- P.groupProjectsHistory grp
  P.update $ if null ph then "main" else head ph

modifyProjectGroup :: String -> (P.ProjectGroup -> P.ProjectGroup) -> X ()
modifyProjectGroup name1 mod = do
    ts <- XS.get :: X P.ProjectGroups
    let (xs, g:ys) = break (\g -> P.groupName g == name1) (P.groups ts)
    XS.modify (\st -> st { P.groups = xs ++ [mod g] ++ ys })

switchTo :: String -> X ()
switchTo w =   
  do s <- gets windowset
     if W.tagMember w s
       then windows $ W.greedyView w
       else addWorkspace w

getByName name1 = do
           ts <- XS.get :: X P.ProjectGroups
           let found = find (\elem -> P.groupName elem == name1) (P.groups ts)
           return found           

deleteProjectGroupPrompt :: XPConfig -> X ()
deleteProjectGroupPrompt c = do 
    ts <- XS.get :: X P.ProjectGroups
    pgHistory <- GH.projectGroupHistory
    mkXPrompt (P.Grp "") c (mkComplFunPopWords' pgHistory) delete_

delete_ :: String -> X ()
delete_ selection = do
       ts <- XS.get :: X P.ProjectGroups
       let (xs, g:ys) = break (\g -> P.groupName g == selection) (P.groups ts)
       XS.modify (\st -> st { P.groups = xs ++ ys, P.currentGroup = P.currentGroup st })
       GH.projectGroupHistoryDeleteHook selection
