-----------------------------------------------------------------------------
-- |
-- Module      :  Graphics.UI.SDL.TTF.Render
-- Copyright   :  (c) David Himmelstrup 2005
-- License     :  BSD-like
--
-- Maintainer  :  lemmih@gmail.com
-- Stability   :  provisional
-- Portability :  portable
--
-----------------------------------------------------------------------------

{-# CFILES Graphics/UI/SDL/TTF/Wrapper.c #-}

module Graphics.UI.SDL.TTF.Render
    ( tryRenderTextSolid
    , renderTextSolid
    , tryRenderUTF8Solid
    , renderUTF8Solid
    , tryRenderGlyphSolid
    , renderGlyphSolid

    , tryRenderTextShaded
    , renderTextShaded
    , tryRenderUTF8Shaded
    , renderUTF8Shaded
    , tryRenderGlyphShaded
    , renderGlyphShaded

    , tryRenderTextBlended
    , renderTextBlended
    , tryRenderUTF8Blended
    , renderUTF8Blended
    , tryRenderGlyphBlended
    , renderGlyphBlended

    ) where

import Graphics.UI.SDL.TTF.Types
import Graphics.UI.SDL.General
import Graphics.UI.SDL.Video
import Graphics.UI.SDL.Color
import Graphics.UI.SDL.Types
import Foreign
import Foreign.C

import Data.Char

renderOneColor :: (Ptr FontStruct -> CString -> Ptr Color -> IO (Ptr SurfaceStruct))
            -> Font -> String -> Color -> IO (Maybe Surface)
renderOneColor render font text color
    = withForeignPtr font $ \fontPtr ->
      withCString text $ \cString ->
      with color $ \colorPtr ->
      do image <- render fontPtr cString colorPtr
         if image == nullPtr
            then return Nothing
            else fmap Just (mkFinalizedSurface image)

renderTwoColor :: (Ptr FontStruct -> CString -> Ptr Color -> Ptr Color -> IO (Ptr SurfaceStruct))
            -> Font -> String -> Color -> Color -> IO (Maybe Surface)
renderTwoColor render font text color1 color2
    = withForeignPtr font $ \fontPtr ->
      withCString text $ \cString ->
      with color1 $ \colorPtr1 ->
      with color2 $ \colorPtr2 -> 
      do image <- render fontPtr cString colorPtr1 colorPtr2
         if image == nullPtr
            then return Nothing
            else fmap Just (mkFinalizedSurface image)

--------------------------------------------------------------
-- Solid
--------------------------------------------------------------


-- SDL_Surface *TTF_RenderText_Solid(TTF_Font *font, const char *text, SDL_Color fg)
foreign import ccall unsafe "renderTextSolid" ttfRenderTextSolid
    :: Ptr FontStruct -> CString -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderTextSolid :: Font -> String -> Color -> IO (Maybe Surface)
tryRenderTextSolid = renderOneColor ttfRenderTextSolid

renderTextSolid :: Font -> String -> Color -> IO Surface
renderTextSolid font text color
    = unwrapMaybe "TTF_RenderText_Solid" (tryRenderTextSolid font text color)

-- SDL_Surface * SDLCALL TTF_RenderUTF8_Solid(TTF_Font *font, const char *text, SDL_Color fg);
foreign import ccall unsafe "renderUTF8Solid" ttfRenderUTF8Solid
    :: Ptr FontStruct -> CString -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderUTF8Solid :: Font -> String -> Color -> IO (Maybe Surface)
tryRenderUTF8Solid = renderOneColor ttfRenderUTF8Solid

renderUTF8Solid :: Font -> String -> Color -> IO Surface
renderUTF8Solid font text color
    = unwrapMaybe "TTF_RenderUTF8_Solid" (tryRenderUTF8Solid font text color)

-- SDL_Surface * renderGlyphSolid(TTF_Font *font, Uint16 ch, SDL_Color *fg);
foreign import ccall unsafe "renderGlyphSolid" renderGlyphSolid
    :: Ptr FontStruct -> Word16 -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderGlyphSolid :: Font -> Char -> Color -> IO (Maybe Surface)
tryRenderGlyphSolid font ch fg
    = withForeignPtr font $ \fontPtr ->
      with fg $ \color ->
      do image <- renderGlyphSolid fontPtr (fromIntegral (ord ch)) color
         if image == nullPtr
            then return Nothing
            else fmap Just (mkFinalizedSurface image)

--------------------------------------------------------------
-- Shaded
--------------------------------------------------------------


-- SDL_Surface *TTF_RenderText_Shaded(TTF_Font *font, const char *text, SDL_Color fg)
foreign import ccall unsafe "renderTextShaded" ttfRenderTextShaded
    :: Ptr FontStruct -> CString -> Ptr Color -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderTextShaded :: Font -> String -> Color -> Color -> IO (Maybe Surface)
tryRenderTextShaded = renderTwoColor ttfRenderTextShaded

renderTextShaded :: Font -> String -> Color -> Color -> IO Surface
renderTextShaded font text fg bg
    = unwrapMaybe "TTF_RenderText_Shaded" (tryRenderTextShaded font text fg bg)

-- SDL_Surface * SDLCALL TTF_RenderUTF8_Shaded(TTF_Font *font, const char *text, SDL_Color fg);
foreign import ccall unsafe "renderUTF8Shaded" ttfRenderUTF8Shaded
    :: Ptr FontStruct -> CString -> Ptr Color -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderUTF8Shaded :: Font -> String -> Color -> Color -> IO (Maybe Surface)
tryRenderUTF8Shaded = renderTwoColor ttfRenderUTF8Shaded

renderUTF8Shaded :: Font -> String -> Color -> Color -> IO Surface
renderUTF8Shaded font text fg bg
    = unwrapMaybe "TTF_RenderUTF8_Shaded" (tryRenderUTF8Shaded font text fg bg)

-- SDL_Surface * renderGlyphShaded(TTF_Font *font, Uint16 ch, SDL_Color *fg);
foreign import ccall unsafe "renderGlyphShaded" renderGlyphShaded
    :: Ptr FontStruct -> Word16 -> Ptr Color -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderGlyphShaded :: Font -> Char -> Color -> Color -> IO (Maybe Surface)
tryRenderGlyphShaded font ch fg bg
    = withForeignPtr font $ \fontPtr ->
      with fg $ \fgPtr ->
      with bg $ \bgPtr ->
      do image <- renderGlyphShaded fontPtr (fromIntegral (ord ch)) fgPtr bgPtr
         if image == nullPtr
            then return Nothing
            else fmap Just (mkFinalizedSurface image)

--------------------------------------------------------------
-- Blended
--------------------------------------------------------------


-- SDL_Surface *TTF_RenderText_Blended(TTF_Font *font, const char *text, SDL_Color fg)
foreign import ccall unsafe "renderTextBlended" ttfRenderTextBlended
    :: Ptr FontStruct -> CString -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderTextBlended :: Font -> String -> Color -> IO (Maybe Surface)
tryRenderTextBlended = renderOneColor ttfRenderTextBlended

renderTextBlended :: Font -> String -> Color -> IO Surface
renderTextBlended font text color
    = unwrapMaybe "TTF_RenderText_Blended" (tryRenderTextBlended font text color)

-- SDL_Surface * SDLCALL TTF_RenderUTF8_Blended(TTF_Font *font, const char *text, SDL_Color fg);
foreign import ccall unsafe "renderUTF8Blended" ttfRenderUTF8Blended
    :: Ptr FontStruct -> CString -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderUTF8Blended :: Font -> String -> Color -> IO (Maybe Surface)
tryRenderUTF8Blended = renderOneColor ttfRenderUTF8Blended

renderUTF8Blended :: Font -> String -> Color -> IO Surface
renderUTF8Blended font text color
    = unwrapMaybe "TTF_RenderUTF8_Blended" (tryRenderUTF8Blended font text color)

-- SDL_Surface * renderGlyphBlended(TTF_Font *font, Uint16 ch, SDL_Color *fg);
foreign import ccall unsafe "renderGlyphBlended" renderGlyphBlended
    :: Ptr FontStruct -> Word16 -> Ptr Color -> IO (Ptr SurfaceStruct)
tryRenderGlyphBlended :: Font -> Char -> Color -> IO (Maybe Surface)
tryRenderGlyphBlended font ch fg
    = withForeignPtr font $ \fontPtr ->
      with fg $ \color ->
      do image <- renderGlyphBlended fontPtr (fromIntegral (ord ch)) color
         if image == nullPtr
            then return Nothing
            else fmap Just (mkFinalizedSurface image)