{-# LANGUAGE StandaloneDeriving #-}

module BioInf.RNAFold.Energy
  ( FoldFunctions (..)
  , Fold (..)
  ) where

import BioInf.RNAFold
import Biobase.Types.Energy
import Biobase.Types.Ring
import BioInf.RNAFold.Functions



instance FoldFunctions Energy

instance Fold Energy where
  backtrack trnr inp tbls = error "write me"
{-
  backtrack trnr inp (weak,strong,mbr1,mbr,extern) = ext 0 n delta where
    n = VU.length inp -1
    delta = one :: Energy
    overallBest = extern `unsafeIndex` (0,n)
    ext i j d = let bestE = extern `unsafeIndex` (i,j) in
      [ []
      | i==j
      , overallBest == one
      ] ++ -- gives us the unfolded sequence
      [ r
      | i<j
      , r <- ext (i+1) j d
      ] ++
      [ r
      | i<j
      , ((k,l),ce) <- externalLoopIdx trnr inp strong i j
      , let dNew = ce `rmult` d `rmult` neg bestE
      , dNew <= one
      , r <- str k l d
      ] ++
      [ r++s
      | i<j
      , (k,ce) <- externalAddLoopIdx trnr inp strong extern i j
      , let dNew = ce `rmult` d `rmult` neg bestE
      , dNew <= one
      , r <- str i k d
      , s <- ext (k+1) j d ++ [[]] -- not 'd' but what 'str' leaves us with!, the [[]] only if the str-part alone works out
      ]
    str i j d = let bestE = strong `unsafeIndex` (i,j) in
      [ (i,j):r
      | i+2<j
      , ((k,l),ce) <- stackIdx trnr inp strong i j
      , let dNew = ce `rmult` d `rmult` neg bestE
      , dNew <= one
      , r <- str k l d
      ] ++
      [ (i,j):r
      | i+2<j
      , ((k,l),ce) <- stackIdx trnr inp weak   i j
      , let dNew = ce `rmult` d `rmult` neg bestE
      , dNew <= one
      , r <- wea k l d
      ]
    wea :: Int -> Int -> a -> [Pairlist]
    wea i j d = let bestE = weak `unsafeIndex` (i,j) in
      [ [(i,j)]
      | i+3<j
      , (ce :: Energy) <- hairpinIdx trnr inp i j -- needs to be qualified as we give no other table
      ]
-}



-- | (DEBUG) Print an array.

{-
printArr arr = do
  --let (IT.IxTable (0,0) (_,n) _) = arr
  let n = snd $ snd $ bounds arr
  forM_ [0..n] $ \i -> do
    putStrLn ""
    forM [0..n] $ \j -> do
      if j>=i
        then do
          let v = arr `unsafeIndex` (i,j)
          if isZero v
            then printf "%5s" "_i_"
            else printf "%5i" (unEnergy $ arr `unsafeIndex` (i,j))
        else do
          putStr "     "
  putStrLn ""
  return ()
-}