content: {-# LANGUAGE ScopedTypeVariables #-}
  {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE LambdaCase #-}
  -----------------------------------------------------------------------------
  --
  -- Module      :  IDE.PaneGroups
  -- Copyright   :  2007-2011 Juergen Nicklisch-Franken, Hamish Mackenzie
  -- License     :  GPL
  --
  -- Maintainer  :  maintainer@leksah.org
  -- Stability   :  provisional
  -- Portability :
  --
  -- |
  --
  -----------------------------------------------------------------------------
  
  module IDE.PaneGroups (
  
      showBrowser
  ,   setSensitivityDebugger
  ,   showDebugger
  
  ) where
  
  import Prelude ()
  import Prelude.Compat
  import IDE.Core.State (IDEM, readIDE, IDEAction, ideGtk)
  import Graphics.UI.Frame.Panes
         (RecoverablePane, PanePath, getTopWidget, getPane, getOrBuildPane,
          PaneDirection(..), PanePathElement(..), layout, panePathForGroup)
  import Graphics.UI.Frame.ViewFrame
         (viewMoveTo, getBestPanePath, getNotebook, viewSplit',
          newGroupOrBringToFront)
  import Control.Monad (unless, void)
  import Control.Lens (pre, _Just)
  import IDE.Gtk.State (frameState)
  import IDE.Pane.Modules (IDEModules(..))
  import IDE.Pane.Info (IDEInfo)
  import IDE.Pane.SourceBuffer
      (newTextBuffer, bufferName, allBuffers)
  import IDE.Pane.Breakpoints (IDEBreakpoints)
  import IDE.Pane.Variables (IDEVariables)
  import IDE.Pane.Trace (IDETrace)
  import IDE.Pane.Workspace (WorkspacePane(..))
  import IDE.Pane.WebKit.Output (IDEOutput(..))
  import GI.Gtk.Objects.Notebook
         (notebookSetShowTabs, notebookSetTabPos)
  import GI.Gtk.Enums (Orientation(..), PositionType(..))
  import GI.Gtk.Objects.Widget (widgetSetSensitive)
  
  moveOrBuildPane :: RecoverablePane alpha beta delta => PanePath -> delta (Maybe alpha)
  moveOrBuildPane path = do
      mbPane <- getOrBuildPane (Left path)
      case mbPane of
          Just pane -> viewMoveTo path pane
          Nothing   -> return ()
      return mbPane
  
  showBrowser :: IDEAction
  showBrowser = do
      pp   <- panePathForGroup "*Browser"
      ret  <- newGroupOrBringToFront "Browser" pp
      readIDE (pre $ ideGtk . _Just . frameState) >>= mapM_ (\state -> do
          let layout' = layout state
          case ret of
              (Just rpp, True) -> do
                  viewSplit' rpp OrientationHorizontal
                  viewSplit' (rpp ++ [SplitP BottomP]) OrientationHorizontal
                  let lowerP =  rpp ++ [SplitP BottomP, SplitP BottomP]
                  let upperP =  rpp ++ [SplitP BottomP, SplitP TopP]
                  let topP = rpp ++ [SplitP TopP]
                  lower <- getNotebook lowerP
                  upper <- getNotebook upperP
                  top   <- getNotebook topP
                  notebookSetTabPos lower PositionTypeBottom
                  notebookSetTabPos upper PositionTypeTop
                  notebookSetTabPos top PositionTypeTop
                  notebookSetShowTabs upper False
                  notebookSetShowTabs lower False
                  notebookSetShowTabs top False
                  getOrBuildBrowserPanes upperP lowerP topP
              (Just rpp, False) -> do
                  let lowerP  =  getBestPanePath (rpp ++  [SplitP BottomP, SplitP BottomP]) layout'
                  let upperP  =  getBestPanePath (rpp ++ [SplitP BottomP, SplitP TopP]) layout'
                  let topP    =  getBestPanePath (rpp ++ [SplitP TopP]) layout'
                  getOrBuildBrowserPanes upperP lowerP topP
              _ -> return ())
    where
      getOrBuildBrowserPanes upperP lowerP topP = do
          void (moveOrBuildPane upperP :: IDEM (Maybe IDEModules))
          void (moveOrBuildPane lowerP :: IDEM (Maybe IDEInfo))
          void (moveOrBuildPane topP :: IDEM (Maybe WorkspacePane))
  
  setSensitivityDebugger :: Bool -> IDEAction
  setSensitivityDebugger sens = do
      mbBreakpoints :: Maybe IDEBreakpoints <- getPane
      mbVariables   :: Maybe IDEVariables   <- getPane
      mbTrace       :: Maybe IDETrace       <- getPane
      case mbBreakpoints of
          Nothing -> return ()
          Just idePane -> getTopWidget idePane >>= (`widgetSetSensitive` sens)
      case mbVariables of
          Nothing -> return ()
          Just idePane -> getTopWidget idePane >>= (`widgetSetSensitive` sens)
      case mbTrace of
          Nothing -> return ()
          Just idePane -> getTopWidget idePane >>= (`widgetSetSensitive` sens)
  
  showDebugger :: IDEAction
  showDebugger = do
      pp   <- panePathForGroup "*Debug"
      ret  <- newGroupOrBringToFront "Debug" pp
      readIDE (pre $ ideGtk . _Just . frameState) >>= mapM_ (\state -> do
          let layout' = layout state
          bufs <- allBuffers
          case ret of
              (Just rpp, True) -> do
                  viewSplit' rpp OrientationHorizontal
                  let lowerP =  rpp ++ [SplitP BottomP]
                  let upperP =  rpp ++ [SplitP TopP]
                  lower <- getNotebook lowerP
                  upper <- getNotebook upperP
                  notebookSetTabPos lower PositionTypeTop
                  notebookSetTabPos upper PositionTypeTop
                  notebookSetShowTabs upper False
                  getOrBuildDebugPanes upperP lowerP bufs
              (Just rpp, False) -> do
                  let lowerP  =  getBestPanePath (rpp ++ [SplitP BottomP]) layout'
                  let upperP =  getBestPanePath (rpp ++ [SplitP TopP]) layout'
                  getOrBuildDebugPanes upperP lowerP bufs
              _ -> return ())
    where
      getOrBuildDebugPanes upperP lowerP bufs = do
          _ <- moveOrBuildPane lowerP :: IDEM (Maybe IDEBreakpoints)
          _ <- moveOrBuildPane lowerP :: IDEM (Maybe IDEVariables)
          _ <- moveOrBuildPane lowerP :: IDEM (Maybe IDETrace)
          _ <- moveOrBuildPane lowerP :: IDEM (Maybe IDEOutput)
          unless (any (\ b -> bufferName b == "_Eval.hs") bufs) $
              newTextBuffer upperP "_Eval.hs" Nothing >>= \case
                  Nothing   -> return ()
                  Just pane -> viewMoveTo upperP pane
  
  