content: {-|
  Module      : Monomer.Widgets.Util.Text
  Copyright   : (c) 2018 Francisco Vallarino
  License     : BSD-3-Clause (see the LICENSE file)
  Maintainer  : fjvallarino@gmail.com
  Stability   : experimental
  Portability : non-portable
  
  Helper functions to text related operations in widgets.
  -}
  {-# LANGUAGE Strict #-}
  
  module Monomer.Widgets.Util.Text (
    getTextMetrics,
    getTextSize,
    getTextSize_,
    getSingleTextLineRect,
    getTextGlyphs
  ) where
  
  import Control.Lens ((^.))
  import Data.Sequence (Seq(..))
  import Data.Text (Text)
  
  import Monomer.Core
  import Monomer.Graphics
  
  import qualified Monomer.Core.Lens as L
  
  -- | Returns the text metrics of the active style.
  getTextMetrics :: WidgetEnv s e -> StyleState -> TextMetrics
  getTextMetrics wenv style = textMetrics where
    fontMgr = wenv ^. L.fontManager
    textMetrics = computeTextMetrics fontMgr font fontSize
    font = styleFont style
    fontSize = styleFontSize style
  
  -- | Returns the size of the text using the active style and default options.
  getTextSize :: WidgetEnv s e -> StyleState -> Text -> Size
  getTextSize wenv style text = size where
    fontMgr = wenv ^. L.fontManager
    size = calcTextSize_ fontMgr style SingleLine KeepSpaces Nothing Nothing text
  
  -- | Returns the size of the text using the active style.
  getTextSize_
    :: WidgetEnv s e  -- ^ The widget environment.
    -> StyleState     -- ^ The active style.
    -> TextMode       -- ^ Whether to use single or multi line.
    -> TextTrim       -- ^ Whether to trim spacers or keep them.
    -> Maybe Double   -- ^ Maximum width (required for multi line).
    -> Maybe Int      -- ^ Max lines.
    -> Text           -- ^ Text to measure.
    -> Size           -- ^ The calculated size.
  getTextSize_ wenv style mode trim mwidth mlines text = newSize where
    fontMgr = wenv ^. L.fontManager
    newSize = calcTextSize_ fontMgr style mode trim mwidth mlines text
  
  -- | Returns the rect a single line of text needs to be displayed completely.
  getSingleTextLineRect
    :: WidgetEnv s e  -- ^ The widget environment.
    -> StyleState     -- ^ The active style.
    -> Rect           -- ^ The bounding rect.
    -> AlignTH        -- ^ The horizontal alignment.
    -> AlignTV        -- ^ The vertical alignment.
    -> Text           -- ^ The text to measure.
    -> Rect           -- ^ The used rect. May be larger than the bounding rect.
  getSingleTextLineRect wenv style rect alignH alignV text = textRect where
    fontMgr = wenv ^. L.fontManager
    font = styleFont style
    fSize = styleFontSize style
    fSpcH = styleFontSpaceH style
  
    Rect x y w h = rect
    Size tw _ = computeTextSize fontMgr font fSize fSpcH text
    TextMetrics asc desc lineh lowerX = computeTextMetrics fontMgr font fSize
  
    tx | alignH == ATLeft = x
       | alignH == ATCenter = x + (w - tw) / 2
       | otherwise = x + (w - tw)
    ty | alignV == ATTop = y + asc
       | alignV == ATMiddle = y + h + desc - (h - lineh) / 2
       | alignV == ATAscender = y + h - (h - asc) / 2
       | alignV == ATLowerX = y + h - (h - lowerX) / 2
       | otherwise = y + h + desc
  
    textRect = Rect {
      _rX = tx,
      _rY = ty - lineh,
      _rW = tw,
      _rH = lineh
    }
  
  -- | Returns the glyphs of a single line of text.
  getTextGlyphs :: WidgetEnv s e -> StyleState -> Text -> Seq GlyphPos
  getTextGlyphs wenv style text = glyphs where
    fontMgr = wenv ^. L.fontManager
    font = styleFont style
    fSize = styleFontSize style
    fSpcH = styleFontSpaceH style
    glyphs = computeGlyphsPos fontMgr font fSize fSpcH text
  