-- GENERATED by C->Haskell Compiler, version 0.26.1 Budburst, 4 April 2015 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "src/Data/Grib/Raw/Index.chs" #-}
{- |
Module      : Data.Grib.Raw.Index
Copyright   : (c) Mattias Jakobsson 2015
License     : GPL-3

Maintainer  : mjakob422@gmail.com
Stability   : unstable
Portability : portable

The grib_index is the structure giving indexed access to messages in a
file.

Most of the documentation herein was copied from the official
documentation of
<https://software.ecmwf.int/wiki/display/GRIB/Module+Index grib_api>.
-}

module Data.Grib.Raw.Index
       ( -- *The GRIB Index
         GribIndex(..)
       , gribIndexNewFromFile
       , gribIndexNew
       , gribIndexAddFile
       , gribIndexWrite
       , gribIndexRead
       , withGribIndex

         -- **Get values from the index
       , gribIndexGetSize
       , gribIndexGetLong
       , gribIndexGetDouble
       , gribIndexGetString

         -- **Select values from the index
       , gribIndexSelectLong
       , gribIndexSelectDouble
       , gribIndexSelectString

         -- **Other functions
       , gribHandleNewFromIndex
       ) where
import qualified Foreign.C.String as C2HSImp
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.ForeignPtr as C2HSImp
import qualified Foreign.Ptr as C2HSImp



import Foreign   ( Ptr, alloca )
import Foreign.C ( CDouble, CLong, CSize, CString, peekCString, withCString )

import Data.Grib.Raw.Context
{-# LINE 46 "src/Data/Grib/Raw/Index.chs" #-}

import Data.Grib.Raw.Handle
{-# LINE 47 "src/Data/Grib/Raw/Index.chs" #-}

import Data.Grib.Raw.Marshal





{-# LINE 53 "src/Data/Grib/Raw/Index.chs" #-}


-- typedef struct grib_index grib_index;
--
-- |Index structure to access messages in a file.
newtype GribIndex = GribIndex (C2HSImp.ForeignPtr (GribIndex))
withGribIndex :: GribIndex -> (C2HSImp.Ptr GribIndex -> IO b) -> IO b
withGribIndex (GribIndex fptr) = C2HSImp.withForeignPtr fptr
{-# LINE 60 "src/Data/Grib/Raw/Index.chs" #-}


-- grib_index* grib_index_new_from_file(grib_context* c, char* filename,
--                                      const char* keys, int *err);
--
-- |Create a new index from a file.
--
-- The file is indexed with the keys in argument.
gribIndexNewFromFile :: (GribContext) -- ^context
 -> (FilePath) -- ^name of the file of messages to be indexed
 -> ([Key]) -- ^a list of keys for the index. The type of the key can be  explicitly declared appending :l for long, :d for double, :s  for string to the key name. If the type is not declared  explicitly, the native type is assumed
 -> IO ((GribIndex)) -- ^an IO action that will return the new index

gribIndexNewFromFile a1 a2 a3 =
  let {a1' = id a1} in 
  withCString a2 $ \a2' -> 
  withJoinedCString a3 $ \a3' -> 
  alloca $ \a4' -> 
  gribIndexNewFromFile'_ a1' a2' a3' a4' >>= \res ->
  (\x -> C2HSImp.newForeignPtr gribIndexFinalizer x >>= (return . GribIndex)) res >>= \res' ->
  checkStatusPtr  a4'>>
  return (res')

{-# LINE 81 "src/Data/Grib/Raw/Index.chs" #-}


-- grib_index* grib_index_new(grib_context* c, const char* keys, int *err);
--
-- |Create a new index based on a set of keys.
gribIndexNew :: (GribContext) -- ^context
 -> ([Key]) -- ^a list of keys for the index. The type of the key can be  explicitly declared appending :l for long, :d for double, :s  for string to the key name. If the type is not declared  explicitly, the native type is assumed
 -> IO ((GribIndex)) -- ^an IO action that will return the new index

gribIndexNew a1 a2 =
  let {a1' = id a1} in 
  withJoinedCString a2 $ \a2' -> 
  alloca $ \a3' -> 
  gribIndexNew'_ a1' a2' a3' >>= \res ->
  (\x -> C2HSImp.newForeignPtr gribIndexFinalizer x >>= (return . GribIndex)) res >>= \res' ->
  checkStatusPtr  a3'>>
  return (res')

{-# LINE 97 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_add_file(grib_index *index, const char *filename);
--
-- |Indexes the file given in argument in the index given in argument.
gribIndexAddFile :: (GribIndex) -> (FilePath) -> IO ()
gribIndexAddFile a1 a2 =
  (withGribIndex) a1 $ \a1' -> 
  withCString a2 $ \a2' -> 
  gribIndexAddFile'_ a1' a2' >>= \res ->
  checkStatus res >> 
  return ()

{-# LINE 105 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_write(grib_index *index, const char *filename);
--
-- |Write the index and its messages to file.
gribIndexWrite :: (GribIndex) -> (FilePath) -> IO ()
gribIndexWrite a1 a2 =
  (withGribIndex) a1 $ \a1' -> 
  withCString a2 $ \a2' -> 
  gribIndexWrite'_ a1' a2' >>= \res ->
  checkStatus res >> 
  return ()

{-# LINE 113 "src/Data/Grib/Raw/Index.chs" #-}


-- grib_index* grib_index_read(grib_context* c, const char* filename, int *err);
--
-- |Read messages and their index from a file.
gribIndexRead :: (GribContext) -> (FilePath) -> IO ((GribIndex))
gribIndexRead a1 a2 =
  let {a1' = id a1} in 
  withCString a2 $ \a2' -> 
  alloca $ \a3' -> 
  gribIndexRead'_ a1' a2' a3' >>= \res ->
  (\x -> C2HSImp.newForeignPtr gribIndexFinalizer x >>= (return . GribIndex)) res >>= \res' ->
  checkStatusPtr  a3'>>
  return (res')

{-# LINE 122 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_get_size(grib_index* index, const char* key, size_t* size);
--
-- |Get the number of distinct values of the key in argument contained
-- in the index.
--
-- The key must belong to the index.
gribIndexGetSize :: (GribIndex) -> (Key) -> IO ((Int))
gribIndexGetSize a1 a2 =
  (withGribIndex) a1 $ \a1' -> 
  withCString a2 $ \a2' -> 
  alloca $ \a3' -> 
  gribIndexGetSize'_ a1' a2' a3' >>= \res ->
  checkStatus res >> 
  peekIntegral  a3'>>= \a3'' -> 
  return (a3'')

{-# LINE 134 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_get_long(grib_index* index, const char* key, long* values,
--                         size_t *size);
--
-- This function is not macro expanded since an output marshaller
-- would want to return another data type than the corresponding input
-- marshaller accepts.
--
-- |Get the distinct values of the key in argument contained in the index.
--
-- This function is used when the type of the key was explicitly
-- defined as long or when the native type of the key is long.
--
-- This function takes the address of an array that is used to
-- retrieve the values. It could potentially be re-used between
-- multiple calls.
gribIndexGetLong :: GribIndex  -- ^an index created from a file. The
                               -- index must have been created with
                               -- the key in argument.
                 -> Key        -- ^key for which the values are
                               -- returned
                 -> Ptr CLong  -- ^array of values. The array must be
                               -- allocated before entering this
                               -- function and its size must be enough
                               -- to contain all the values.
                 -> Int        -- ^size of the values array
                 -> IO [Int]   -- ^an IO action that will return the
                               -- data in a list
gribIndexGetLong idx key ls n = withGribIndex idx $ \idx' ->
  fmap (map fromIntegral) $ getArray (cCall idx') key ls n
  where cCall = grib_index_get_long
{-# LINE 165 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_get_double(grib_index* index, const char* key,
--                           double* values, size_t *size);
--
-- This function is not macro expanded since an output marshaller
-- would want to return another data type than the corresponding input
-- marshaller accepts.
--
-- |Get the distinct values of the key in argument contained in the index.
--
-- This function is used when the type of the key was explicitly
-- defined as double or when the native type of the key is double.
--
-- This function takes the address of an array that is used to
-- retrieve the values. It could potentially be re-used between
-- multiple calls.
gribIndexGetDouble :: GribIndex    -- ^an index created from a
                                   -- file. The index must have been
                                   -- created with the key in
                                   -- argument.
                   -> Key          -- ^key for which the values are
                                   -- returned
                   -> Ptr CDouble  -- ^array of values. The array must
                                   -- be allocated before entering
                                   -- this function and its size must
                                   -- be enough to contain all the
                                   -- values.
                   -> Int          -- ^size of the values array
                   -> IO [Double]  -- ^an IO action that will return
                                   -- the data in a list
gribIndexGetDouble idx key ds n = withGribIndex idx $ \idx' ->
  fmap (map realToFrac) $ getArray (cCall idx') key ds n
  where cCall = grib_index_get_double
{-# LINE 198 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_get_string(grib_index* index, const char* key, char** values,
--                           size_t *size);
--
-- This function is not macro expanded since an output marshaller
-- would want to return another data type than the corresponding input
-- marshaller accepts.
--
-- |Get the distinct values of the key in argument contained in the
-- index.
--
-- This function is used when the type of the key was explicitly
-- defined as string or when the native type of the key is string.
--
-- This function takes the address of an array that is used to
-- retrieve the values. It could potentially be re-used between
-- multiple calls.
--
-- __WARNING!__ This function seem to leak memory unless the returned
-- strings in values are eventually freed with the grib context's
-- free_mem function.
gribIndexGetString :: GribIndex    -- ^an index created from a
                                   -- file. The index must have been
                                   -- created with the key in
                                   -- argument.
                   -> Key          -- ^key for which the values are
                                   -- returned
                   -> Ptr CString  -- ^array of values. The array must
                                   -- be allocated before entering
                                   -- this function and its size must
                                   -- be enough to contain all the
                                   -- values.
                   -> Int          -- ^size of the values array
                   -> IO [String]  -- ^an IO action that will return
                                   -- the data in a list
gribIndexGetString idx key ss n = withGribIndex idx $ \idx' ->
  getArray (cCall idx') key ss n >>= mapM peekCString
  where cCall = grib_index_get_string
{-# LINE 236 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_select_long(grib_index* index, const char* key, long value);
--
-- |Select the message subset with key==value.
--
-- The index must have been created with the key in argument. The
-- value is a long. The key must have been created with long type or
-- have long as native type if the type was not explicitly defined in
-- the index creation.
gribIndexSelectLong :: (GribIndex) -> (Key) -> (Int) -> IO ()
gribIndexSelectLong a1 a2 a3 =
  (withGribIndex) a1 $ \a1' -> 
  withCString a2 $ \a2' -> 
  let {a3' = fromIntegral a3} in 
  gribIndexSelectLong'_ a1' a2' a3' >>= \res ->
  checkStatus res >> 
  return ()

{-# LINE 250 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_select_double(grib_index* index, const char* key,
--                              double value);
--
-- |Select the message subset with key==value.
--
-- The index must have been created with the key in argument. The
-- value is a double. The key must have been created with double type
-- or have double as native type if the type was not explicitly
-- defined in the index creation.
gribIndexSelectDouble :: (GribIndex) -> (Key) -> (Double) -> IO ()
gribIndexSelectDouble a1 a2 a3 =
  (withGribIndex) a1 $ \a1' -> 
  withCString a2 $ \a2' -> 
  let {a3' = realToFrac a3} in 
  gribIndexSelectDouble'_ a1' a2' a3' >>= \res ->
  checkStatus res >> 
  return ()

{-# LINE 265 "src/Data/Grib/Raw/Index.chs" #-}


-- int grib_index_select_string(grib_index* index, const char* key,
--                              char* value);
--
-- |Select the message subset with key==value.
--
-- The index must have been created with the key in argument. The
-- value is a string. The key must have been created with string type
-- or have string as native type if the type was not explicitly
-- defined in the index creation.
gribIndexSelectString :: (GribIndex) -> (Key) -> (String) -> IO ()
gribIndexSelectString a1 a2 a3 =
  (withGribIndex) a1 $ \a1' -> 
  withCString a2 $ \a2' -> 
  C2HSImp.withCString a3 $ \a3' -> 
  gribIndexSelectString'_ a1' a2' a3' >>= \res ->
  checkStatus res >> 
  return ()

{-# LINE 280 "src/Data/Grib/Raw/Index.chs" #-}


-- grib_handle* grib_handle_new_from_index(grib_index* index,int *err);
--
-- |Create a new handle from an index after having selected the key values.
--
-- All the keys belonging to the index must be selected before calling
-- this function. Successive calls to this function will return all
-- the handles compatible with the constraints defined selecting the
-- values of the index keys.
--
-- This operation may fail with:
--
--   * @isGribException GribEndOfIndex@ when no more handles are
--   available from the index.
gribHandleNewFromIndex :: (GribIndex) -> IO ((GribHandle))
gribHandleNewFromIndex a1 =
  (withGribIndex) a1 $ \a1' -> 
  alloca $ \a2' -> 
  gribHandleNewFromIndex'_ a1' a2' >>= \res ->
  (\x -> C2HSImp.newForeignPtr_ x >>=  (return . GribHandle)) res >>= \res' ->
  checkStatusPtr  a2'>>
  return (res')

{-# LINE 298 "src/Data/Grib/Raw/Index.chs" #-}


foreign import ccall "Data/Grib/Raw/Index.chs.h &grib_index_delete"
  gribIndexFinalizer :: C2HSImp.FinalizerPtr GribIndex

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_new_from_file"
  gribIndexNewFromFile'_ :: ((GribContext) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CInt) -> (IO (C2HSImp.Ptr (GribIndex)))))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_new"
  gribIndexNew'_ :: ((GribContext) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CInt) -> (IO (C2HSImp.Ptr (GribIndex))))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_add_file"
  gribIndexAddFile'_ :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (IO C2HSImp.CInt)))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_write"
  gribIndexWrite'_ :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (IO C2HSImp.CInt)))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_read"
  gribIndexRead'_ :: ((GribContext) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CInt) -> (IO (C2HSImp.Ptr (GribIndex))))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_get_size"
  gribIndexGetSize'_ :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr CSize) -> (IO C2HSImp.CInt))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_get_long"
  grib_index_get_long :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CLong) -> ((C2HSImp.Ptr CSize) -> (IO C2HSImp.CInt)))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_get_double"
  grib_index_get_double :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr CSize) -> (IO C2HSImp.CInt)))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_get_string"
  grib_index_get_string :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> ((C2HSImp.Ptr CSize) -> (IO C2HSImp.CInt)))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_select_long"
  gribIndexSelectLong'_ :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (C2HSImp.CLong -> (IO C2HSImp.CInt))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_select_double"
  gribIndexSelectDouble'_ :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (C2HSImp.CDouble -> (IO C2HSImp.CInt))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_index_select_string"
  gribIndexSelectString'_ :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (IO C2HSImp.CInt))))

foreign import ccall unsafe "Data/Grib/Raw/Index.chs.h grib_handle_new_from_index"
  gribHandleNewFromIndex'_ :: ((C2HSImp.Ptr (GribIndex)) -> ((C2HSImp.Ptr C2HSImp.CInt) -> (IO (C2HSImp.Ptr (GribHandle)))))