{-# LINE 1 "lib/Numeric/GSL/Special/Internal.hsc" #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
{-# LINE 2 "lib/Numeric/GSL/Special/Internal.hsc" #-}
-----------------------------------------------------------------------------
{- |
Module      :  Numeric.GSL.Special.Internal
Copyright   :  (c) Alberto Ruiz 2007
License     :  GPL-style

Maintainer  :  Alberto Ruiz (aruiz at um dot es)
Stability   :  provisional
Portability :  uses ffi

Support for Special functions.

<http://www.gnu.org/software/gsl/manual/html_node/Special-Functions.html#Special-Functions>
-}
-----------------------------------------------------------------------------


{-# LINE 19 "lib/Numeric/GSL/Special/Internal.hsc" #-}

{-# LINE 20 "lib/Numeric/GSL/Special/Internal.hsc" #-}

module Numeric.GSL.Special.Internal (
    createSFR,
    create2SFR,
    createSFR_E10,
    Precision(..),
    Gsl_mode_t,
    Size_t,
    precCode
)
where

import Foreign.Storable
import Foreign.Ptr
import Foreign.Marshal
import System.IO.Unsafe(unsafePerformIO)
import Data.Packed.Development(check,(//))
import Foreign.C.Types

data Precision = PrecDouble | PrecSingle | PrecApprox

precCode :: Precision -> Int
precCode PrecDouble = 0
precCode PrecSingle = 1
precCode PrecApprox = 2

type Gsl_mode_t = Int

type Size_t = CSize

---------------------------------------------------

data Gsl_sf_result = SF Double Double
  deriving (Show)

instance Storable Gsl_sf_result where
  sizeOf _ = (16)
{-# LINE 57 "lib/Numeric/GSL/Special/Internal.hsc" #-}
  alignment _ = 8
{-# LINE 58 "lib/Numeric/GSL/Special/Internal.hsc" #-}
  peek ptr = do
    val <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
{-# LINE 60 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    err <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) ptr
{-# LINE 61 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    return (SF val err)
  poke ptr (SF val err) = do
    ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr val
{-# LINE 64 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) ptr err
{-# LINE 65 "lib/Numeric/GSL/Special/Internal.hsc" #-}


data Gsl_sf_result_e10 = SFE Double Double CInt
  deriving (Show)

instance Storable Gsl_sf_result_e10 where
  sizeOf _ = (24)
{-# LINE 72 "lib/Numeric/GSL/Special/Internal.hsc" #-}
  alignment _ = 8
{-# LINE 73 "lib/Numeric/GSL/Special/Internal.hsc" #-}
  peek ptr = do
    val <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
{-# LINE 75 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    err <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) ptr
{-# LINE 76 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    e10 <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) ptr
{-# LINE 77 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    return (SFE val err e10)
  poke ptr (SFE val err e10) = do
    ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr val
{-# LINE 80 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) ptr err
{-# LINE 81 "lib/Numeric/GSL/Special/Internal.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 16)) ptr e10
{-# LINE 82 "lib/Numeric/GSL/Special/Internal.hsc" #-}


----------------------------------------------------------------
-- | access to one sf_result
createSFR :: String -> (Ptr a -> IO CInt) -> (Double, Double)
createSFR s f = unsafePerformIO $ do
    p <- malloc :: IO (Ptr Gsl_sf_result)
    f (castPtr p) // check s
    SF val err <- peek p
    free p
    return (val,err)

----------------------------------------------------------------
-- | access to two sf_result's
create2SFR :: String -> (Ptr a -> Ptr a -> IO CInt) -> ((Double, Double),(Double, Double))
create2SFR s f = unsafePerformIO $ do
    p1 <- malloc :: IO (Ptr Gsl_sf_result)
    p2 <- malloc :: IO (Ptr Gsl_sf_result)
    f (castPtr p1) (castPtr p2) // check s
    SF val1 err1 <- peek p1
    SF val2 err2 <- peek p2
    free p1
    free p2
    return ((val1,err1),(val2,err2))

---------------------------------------------------------------------
-- the sf_result_e10 contains two doubles and the exponent

-- | access to sf_result_e10
createSFR_E10 :: String -> (Ptr a -> IO CInt) -> (Double, Int, Double)
createSFR_E10 s f = unsafePerformIO $ do
    p <- malloc :: IO (Ptr Gsl_sf_result_e10)
    f (castPtr p) // check s
    SFE val err expo  <- peek p
    free p
    return (val, fromIntegral expo,err)