-- GENERATED by C->Haskell Compiler, version 0.28.1 Switcheroo, 1 April 2016 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "./BioInf/ViennaRNA/Bindings/FFI/CoFold.chs" #-}

module BioInf.ViennaRNA.Bindings.FFI.CoFold
  ( ffiCoFold
  , ffiCoEnergyOfStructure
  , ffiCoPartitionFunction
  , ffiCoPartitionConstrained
  , CofoldF (..)
  ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified Foreign.Storable as C2HSImp



import           Control.Applicative
import           Control.Monad
import           Foreign.C.String
import           Foreign.C.Types
import           Foreign.Marshal.Alloc
import           Foreign.Marshal.Array
import           Foreign.Ptr
import           Foreign.Storable
import           GHC.Float
import qualified Data.Array.IArray as A
import           Unsafe.Coerce

import           BioInf.ViennaRNA.Bindings.FFI.Utils








type CofoldFPtr = C2HSImp.Ptr (CofoldF)
{-# LINE 31 "./BioInf/ViennaRNA/Bindings/FFI/CoFold.chs" #-}


data CofoldF = CofoldF
  { f0ab :: {-# UNPACK #-} !Double
  , fab  :: {-# UNPACK #-} !Double
  , fcab :: {-# UNPACK #-} !Double
  , fa   :: {-# UNPACK #-} !Double
  , fb   :: {-# UNPACK #-} !Double
  }
  deriving (Show)

instance Storable CofoldF where
  sizeOf _ = 40
{-# LINE 43 "./BioInf/ViennaRNA/Bindings/FFI/CoFold.chs" #-}

  alignment _ = sizeOf (undefined :: CDouble)
  peek p = CofoldF <$> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CDouble}) p)
                   <*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 8 :: IO C2HSImp.CDouble}) p)
                   <*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 16 :: IO C2HSImp.CDouble}) p)
                   <*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 24 :: IO C2HSImp.CDouble}) p)
                   <*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 32 :: IO C2HSImp.CDouble}) p)

-- |

ffiCoFold :: Int -> String -> IO (Double,String)
ffiCoFold cp inp = withCAString inp $ \cinp ->
                   withCAString inp $ \struc -> do
  setCutPoint cp
  e <- cofold cinp struc
  s <- peekCAString struc
  return (cf2d e, s)

-- |

ffiCoEnergyOfStructure :: Int -> String -> String -> Int -> IO Double
ffiCoEnergyOfStructure cp inp struc verb =
  withCAString inp   $ \i ->
  withCAString struc $ \s ->
    setCutPoint cp
    >>  energy_of_structure i s (fromIntegral verb :: CInt)
    >>= (return . cf2d)

-- |

ffiCoPartitionFunction :: Int -> String -> IO (CofoldF,String,A.Array (Int,Int) Double)
ffiCoPartitionFunction cutpoint i =
  withCAString i $ \ci ->
  withCAString i $ \cs ->
  alloca         $ \ptr -> do
  setCutPoint cutpoint
  let n = length i
  let z = n * (n+1) `div` 2 +1
  eF <- co_pf_fold_p ptr ci cs >> peek ptr
  s  <- peekCAString cs
  bp <- export_co_bppm
{-# LINE 83 "./BioInf/ViennaRNA/Bindings/FFI/CoFold.chs" #-}

  xs <- peekArray z (bp :: Ptr CDouble)
  let ar = A.accumArray (const id) 0 ((1,1),(n,n)) $ zip [ (ii,jj) | ii <- [n,n-1..1], jj <- [n,n-1..ii]] (drop 1 $ map unsafeCoerce xs)
  return (eF, s, ar)

-- | Constrained partition function

ffiCoPartitionConstrained :: Int -> String -> String -> IO (CofoldF,String,A.Array (Int,Int) Double)
ffiCoPartitionConstrained cutpoint sq st =
  withCAString sq $ \csq ->
  withCAString st $ \cst ->
  alloca          $ \ptr -> do
  setCutPoint cutpoint
  let n = length sq
  let z = n * (n+1) `div` 2 +1
  eF <- co_pf_fold_constrained_p ptr csq cst 1 >> peek ptr
  s  <- peekCAString cst
  bp <- export_co_bppm
{-# LINE 100 "./BioInf/ViennaRNA/Bindings/FFI/CoFold.chs" #-}

  xs <- peekArray z (bp :: Ptr CDouble)
  let ar = A.accumArray (const id) 0 ((1,1),(n,n)) $ zip [ (ii,jj) | ii <- [n,n-1..1], jj <- [n,n-1..ii]] (drop 1 $ map unsafeCoerce xs)
  return (eF, s, ar)



foreign import ccall "ffiwrap_co_pf_fold" co_pf_fold_p :: CofoldFPtr -> CString -> CString -> IO ()

foreign import ccall "ffiwrap_co_pf_fold_constrained" co_pf_fold_constrained_p :: CofoldFPtr -> CString -> CString -> Int -> IO ()


foreign import ccall safe "BioInf/ViennaRNA/Bindings/FFI/CoFold.chs.h cofold"
  cofold :: ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (IO C2HSImp.CFloat)))

foreign import ccall safe "BioInf/ViennaRNA/Bindings/FFI/CoFold.chs.h energy_of_structure"
  energy_of_structure :: ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (C2HSImp.CInt -> (IO C2HSImp.CFloat))))

foreign import ccall safe "BioInf/ViennaRNA/Bindings/FFI/CoFold.chs.h export_co_bppm"
  export_co_bppm :: (IO (C2HSImp.Ptr C2HSImp.CDouble))