module Colada.Features 
       ( features 
       , featureSeq
       )
where       
import Data.List.Zipper 
import qualified Data.IntMap as IntMap 

-- |  @featureSeq  f  z@  extracts  features at  each  position  of  z
-- following current position, using f to combine features into bigrams.
featureSeq:: (Maybe a -> Maybe a -> Maybe a)
             -> Zipper a 
             -> [IntMap.IntMap a]
featureSeq (+++) = foldrz (\zi z -> features (+++) zi : z) []

-- | @features f z@ extracts features at the current position of z,
-- using f to combine features into bigrams.
features :: (Maybe a -> Maybe a -> Maybe a) -> Zipper a -> IntMap.IntMap a
features (+++) z = 
    let fs = [ 
               (0 , at 0 z )
             , (-2, at (-2) z )
             , (-1, at (-1) z )
             , (-12, at (-2) z +++ at (-1) z)
             , (12,  at 1 z    +++ at 2 z)
             , (1,  at 1 z)
             , (2,  at 2 z)
             ]
    in IntMap.fromList [ (k, v) | (k,Just v) <- fs ] 

at :: Int -> Zipper a -> Maybe a
at i (Zip ls _) | i < 0  = index (negate i) ls
at i (Zip _ rs) | i > 0  = index (i+1) rs
at _ z = safeCursor z    -- i == 0

index :: (Eq a, Num a) => a -> [b] -> Maybe b
index 1 (x:_)  = Just x
index _ []  = Nothing
index i (_:xs) = index (i-1) xs