    -----------------------------------------------------------------------------
    --
    -- Module      :  Graphics.UI.Editor.Parameters
    -- Copyright   :  (c) Juergen Nicklisch-Franken, Hamish Mackenzie
    -- License     :  GNU-GPL
    --
    -- Maintainer  :  <maintainer at leksah.org>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- | Module for parameters for editors
    --
    -----------------------------------------------------------------------------------

    module Graphics.UI.Editor.Parameters (
        Parameters
    ,   Parameter(..)
    ,   paraName
    ,   paraSynopsis
    ,   paraDirection
    ,   paraShowLabel
    ,   paraShadow
    ,   paraOuterAlignment
    ,   paraInnerAlignment
    ,   paraOuterPadding
    ,   paraInnerPadding
    ,   paraMinSize
    ,   paraHorizontal
    ,   paraStockId
    ,   paraMultiSel
    ,   paraPack

    ,   getParameter
    ,   getParameterPrim
    ,   (<<<-)
    ,   emptyParams
    ,   Direction(..)
    ,   HorizontalAlign(..)
    ) where

    import Graphics.UI.Gtk
    import Data.Maybe
    import qualified Data.List as List

    --
    -- | The direction of a split
    --
    data Direction      =   Horizontal | Vertical
        deriving (Eq,Show)

    data HorizontalAlign =   StartHorizontal | StopHorizontal | Keep
        deriving (Eq,Show)
    --
    -- | A type for parameters for editors
    --
    type Parameters     =   [Parameter]

    data Parameter      =   ParaName String
                        |   ParaSynopsis String
                        |   ParaDirection Direction
                        |   ParaShadow ShadowType
                        |   ParaShowLabel Bool
                        |   ParaOuterAlignment  (Float,Float,Float,Float)
                                                   -- | xalign yalign xscale yscale
                        |   ParaOuterPadding    (Int,Int,Int,Int)
                                                    --  | paddingTop paddingBottom paddingLeft paddingRight
                        |   ParaInnerAlignment  (Float,Float,Float,Float)
                                                    -- | xalign yalign xscale yscale
                        |   ParaInnerPadding   (Int,Int,Int,Int)
                                                    --  | paddingTop paddingBottom paddingLeft paddingRight
                        |   ParaMinSize         (Int, Int)
                        |   ParaHorizontal      HorizontalAlign
                        |   ParaStockId String
                        |   ParaMultiSel Bool
                        |   ParaPack Packing
        deriving (Eq,Show)

    {--        #if MIN_VERSION_gtk(0,9,13)
                -- now defined in gtk
            #else
            instance Show ShadowType
                where show _    =   "Any Shadow"
            #endif
    --}

    emptyParams         ::   [Parameter]
    emptyParams         =   []

    paraName                        ::   (Parameter -> (Maybe String))
    paraName (ParaName str)         =   Just str
    paraName _                      =   Nothing

    paraSynopsis                    ::   (Parameter -> (Maybe String))
    paraSynopsis (ParaSynopsis str) =   Just str
    paraSynopsis _                  =   Nothing

    paraShowLabel                    ::   (Parameter -> (Maybe Bool))
    paraShowLabel (ParaShowLabel b)  =   Just b
    paraShowLabel _                  =   Nothing

    paraDirection                   ::   (Parameter -> (Maybe Direction))
    paraDirection (ParaDirection d) =   Just d
    paraDirection _                 =   Nothing

    paraShadow                      ::   (Parameter -> (Maybe ShadowType))
    paraShadow (ParaShadow d)       =   Just d
    paraShadow _                    =   Nothing

    paraOuterAlignment              ::   (Parameter -> (Maybe (Float,Float,Float,Float)))
    paraOuterAlignment (ParaOuterAlignment d) = Just d
    paraOuterAlignment _            =   Nothing

    paraInnerAlignment              ::   (Parameter -> (Maybe (Float,Float,Float,Float)))
    paraInnerAlignment (ParaInnerAlignment d) = Just d
    paraInnerAlignment _            =   Nothing

    paraOuterPadding                ::   (Parameter -> (Maybe (Int,Int,Int,Int)))
    paraOuterPadding (ParaOuterPadding d) = Just d
    paraOuterPadding _              =   Nothing

    paraInnerPadding                ::   (Parameter -> (Maybe (Int,Int,Int,Int)))
    paraInnerPadding (ParaInnerPadding d) = Just d
    paraInnerPadding _              =   Nothing

    paraMinSize                     ::   (Parameter -> (Maybe (Int, Int)))
    paraMinSize (ParaMinSize d)     =   Just d
    paraMinSize _                   =   Nothing

    paraHorizontal                  ::   (Parameter -> (Maybe (HorizontalAlign)))
    paraHorizontal (ParaHorizontal d) =   Just d
    paraHorizontal _                =   Nothing

    paraStockId                     ::   (Parameter -> (Maybe String))
    paraStockId (ParaStockId str)   =   Just str
    paraStockId _                   =   Nothing

    paraMultiSel                    ::   (Parameter -> (Maybe Bool))
    paraMultiSel (ParaMultiSel b)   =   Just b
    paraMultiSel _                  =   Nothing

    paraPack                        ::   (Parameter -> (Maybe Packing))
    paraPack (ParaPack b)           =   Just b
    paraPack _                      =   Nothing

    --
    -- | Convenience method to get a parameter, or if not set the default parameter
    --
    getParameter :: (Parameter -> (Maybe beta)) -> Parameters -> beta
    getParameter selector parameter =
        case getParameterPrim selector parameter of
            Just ele       -> ele
            _              -> case getParameterPrim selector defaultParameters of
                                Just ele       -> ele
                                _              -> error "default parameter not defined"

    getParameterPrim :: (Parameter -> (Maybe beta)) -> Parameters -> Maybe beta
    getParameterPrim selector parameter =
        case filter isJust $ map selector parameter of
            (Just ele) : _ -> Just ele
            _              -> Nothing

    (<<<-) :: (Parameter -> (Maybe beta)) -> Parameter -> Parameters -> Parameters
    (<<<-) selector para  params = para : filter (isNothing . selector) params

    defaultParameters :: Parameters
    defaultParameters =
        [   ParaName ""
        ,   ParaStockId ""
        ,   ParaSynopsis ""
        ,   ParaDirection Horizontal
        ,   ParaShadow ShadowNone
        ,   ParaOuterAlignment  (0.4, 0.5, 1.0, 0.7)
        ,   ParaOuterPadding    (5, 5, 5, 5)
        ,   ParaInnerAlignment  (0.4, 0.5, 1.0, 0.7)
        ,   ParaInnerPadding    (5, 5, 5, 5)
        ,   ParaMinSize         (-1,-1)
        ,   ParaHorizontal      Keep
        ,   ParaMultiSel True
        ,   ParaPack PackNatural
        ,   ParaShowLabel True
        ]