module Sifflet.UI.RPanel
    (
     RPanel, newRPanel, rpanelId, rpanelRoot, rpanelContent
    , rpanelAddWidget, rpanelAddWidgets, rpanelNewRow
    , rpanelAddRows
    )
where
import Control.Monad
import Sifflet.UI.LittleGtk
import Sifflet.Util
debugTracing :: Bool
debugTracing = False
data RPanel 
    = RPanel {
        
        rpId :: String   
      , rpRoot :: GtkFrame 
      , rpContent :: [[String]] 
      
      , rpFrame :: GtkFrame 
      , rpExpander :: Expander 
      , rpVBox :: VBox         
      , rpCurrentRow :: HBox   
      
      , rpCurrentRowFreeWidth :: Int 
      , rpMaxWidth :: Int            
      , rpHPad :: Int 
      }
rpanelId :: RPanel -> String
rpanelId = rpId
rpanelRoot :: RPanel -> GtkFrame
rpanelRoot = rpRoot
rpanelContent :: RPanel -> [[String]]
rpanelContent = rpContent
newRPanel :: String -> Int -> Int -> Int -> IO RPanel
newRPanel cid hpad vpad maxWidth = do
  {
    frame <- frameNew 
             
  ; expander <- expanderNew cid
  ; expanderSetExpanded expander True
  ; set frame [containerChild := expander]
  ; vbox <- vBoxNew False vpad  
  ; widgetSetSizeRequest vbox maxWidth (1) 
  ; set expander [containerChild := vbox]
  ; hbox <- hBoxNew False hpad  
  ; boxPackStart vbox hbox PackNatural 0
  ; return $ RPanel {rpId = cid
                    , rpRoot = frame
                    , rpFrame = frame
                    , rpExpander = expander
                    , rpVBox = vbox
                    , rpCurrentRow = hbox
                    , rpContent = [[]]
                    , rpCurrentRowFreeWidth = maxWidth  hpad
                    , rpMaxWidth = maxWidth  hpad
                    , rpHPad = hpad
                    }
              }
rpanelAddWidgets :: (WidgetClass widget) =>
                    RPanel -> [(String, widget)] -> IO RPanel
rpanelAddWidgets rp pairs = 
    let addPair rp' (widgetId, widget) = rpanelAddWidget rp' widgetId widget
    in foldM addPair rp pairs
rpanelAddWidget :: (WidgetClass widget) =>
                   RPanel -> String -> widget -> IO RPanel
rpanelAddWidget rp widgetId widget = do
  {
    Requisition widgetWidth _ <- widgetSizeRequest widget
  ; let freeWidth = rpCurrentRowFreeWidth rp
        freeWidth' = freeWidth  widgetWidth  rpHPad rp
  ; if freeWidth' >= 0 || freeWidth == rpMaxWidth rp
       
       
       
    then do
      {
        let content' = insertLastLast (rpContent rp) widgetId
            packMode = 
                       PackGrow 
                       
      ; boxPackStart (rpCurrentRow rp) widget packMode 0
      
      ; when debugTracing $
             putStr (unlines ["Adding " ++ widgetId ++ 
                              " width " ++ show widgetWidth
                             , "Free width = " ++ show freeWidth ++
                              " -> " ++ show freeWidth'
                             , "Content -> " ++ show content'])
      ; return $ rp {rpContent = content'
                     , rpCurrentRowFreeWidth = freeWidth'}
      }
    else 
        
        
        do
      {
        rp' <- rpanelNewRow rp
      ; rpanelAddWidget rp' widgetId widget
      }
    }
rpanelNewRow :: RPanel -> IO RPanel
rpanelNewRow rp = do
  {
    hbox <- hBoxNew False (rpHPad rp)
  ; boxPackStart (rpVBox rp) hbox PackNatural 0
  ; return $ rp {rpCurrentRow = hbox
                , rpContent = insertLast (rpContent rp) []
                , rpCurrentRowFreeWidth = rpMaxWidth rp}
  }
rpanelAddRows :: (WidgetClass widget) =>
                 RPanel -> [[(String, widget)]] -> IO RPanel
rpanelAddRows rp rows = foldM rpanelAddRow rp rows
rpanelAddRow :: (WidgetClass widget) =>
                RPanel -> [(String, widget)] -> IO RPanel
rpanelAddRow rp row = 
    rpanelAddWidgets rp row >>= rpanelNewRow