{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE InstanceSigs          #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables   #-}

module HaskellWorks.Data.Json.Simple.Cursor
  ( JsonCursor(..)
  , jsonCursorPos
  ) where

import Data.String
import Data.Word
import HaskellWorks.Data.FromByteString
import HaskellWorks.Data.FromForeignRegion
import HaskellWorks.Data.Positioning
import HaskellWorks.Data.RankSelect.Base.Rank0
import HaskellWorks.Data.RankSelect.Base.Rank1
import HaskellWorks.Data.RankSelect.Base.Select1
import HaskellWorks.Data.RankSelect.CsPoppy
import HaskellWorks.Data.TreeCursor
import Prelude                                   hiding (drop)

import qualified Data.ByteString                                as BS
import qualified Data.ByteString.Char8                          as BSC
import qualified Data.ByteString.Internal                       as BSI
import qualified Data.Vector.Storable                           as DVS
import qualified Foreign.ForeignPtr                             as F
import qualified HaskellWorks.Data.BalancedParens               as BP
import qualified HaskellWorks.Data.BalancedParens.RangeMin      as RM
import qualified HaskellWorks.Data.Json.Simple.Cursor.SemiIndex as SI

data JsonCursor t v w = JsonCursor
  { JsonCursor t v w -> t
cursorText     :: !t
  , JsonCursor t v w -> v
interests      :: !v
  , JsonCursor t v w -> w
balancedParens :: !w
  , JsonCursor t v w -> Count
cursorRank     :: !Count
  }
  deriving (JsonCursor t v w -> JsonCursor t v w -> Bool
(JsonCursor t v w -> JsonCursor t v w -> Bool)
-> (JsonCursor t v w -> JsonCursor t v w -> Bool)
-> Eq (JsonCursor t v w)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall t v w.
(Eq t, Eq v, Eq w) =>
JsonCursor t v w -> JsonCursor t v w -> Bool
/= :: JsonCursor t v w -> JsonCursor t v w -> Bool
$c/= :: forall t v w.
(Eq t, Eq v, Eq w) =>
JsonCursor t v w -> JsonCursor t v w -> Bool
== :: JsonCursor t v w -> JsonCursor t v w -> Bool
$c== :: forall t v w.
(Eq t, Eq v, Eq w) =>
JsonCursor t v w -> JsonCursor t v w -> Bool
Eq, Int -> JsonCursor t v w -> ShowS
[JsonCursor t v w] -> ShowS
JsonCursor t v w -> String
(Int -> JsonCursor t v w -> ShowS)
-> (JsonCursor t v w -> String)
-> ([JsonCursor t v w] -> ShowS)
-> Show (JsonCursor t v w)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall t v w.
(Show t, Show v, Show w) =>
Int -> JsonCursor t v w -> ShowS
forall t v w.
(Show t, Show v, Show w) =>
[JsonCursor t v w] -> ShowS
forall t v w.
(Show t, Show v, Show w) =>
JsonCursor t v w -> String
showList :: [JsonCursor t v w] -> ShowS
$cshowList :: forall t v w.
(Show t, Show v, Show w) =>
[JsonCursor t v w] -> ShowS
show :: JsonCursor t v w -> String
$cshow :: forall t v w.
(Show t, Show v, Show w) =>
JsonCursor t v w -> String
showsPrec :: Int -> JsonCursor t v w -> ShowS
$cshowsPrec :: forall t v w.
(Show t, Show v, Show w) =>
Int -> JsonCursor t v w -> ShowS
Show)

instance FromByteString (JsonCursor BS.ByteString (DVS.Vector Word64) (BP.SimpleBalancedParens (DVS.Vector Word64))) where
  fromByteString :: ByteString
-> JsonCursor
     ByteString (Vector Count) (SimpleBalancedParens (Vector Count))
fromByteString ByteString
bs = JsonCursor :: forall t v w. t -> v -> w -> Count -> JsonCursor t v w
JsonCursor
    { cursorText :: ByteString
cursorText      = ByteString
bs
    , interests :: Vector Count
interests       = Vector Count
ib
    , balancedParens :: SimpleBalancedParens (Vector Count)
balancedParens  = Vector Count -> SimpleBalancedParens (Vector Count)
forall a. a -> SimpleBalancedParens a
BP.SimpleBalancedParens Vector Count
bp
    , cursorRank :: Count
cursorRank      = Count
1
    }
    where SI.SemiIndex Context
_ Vector Count
ib Vector Count
bp = ByteString -> SemiIndex (Vector Count)
SI.buildSemiIndex ByteString
bs

instance FromByteString (JsonCursor BS.ByteString CsPoppy (RM.RangeMin CsPoppy)) where
  fromByteString :: ByteString -> JsonCursor ByteString CsPoppy (RangeMin CsPoppy)
fromByteString ByteString
bs = JsonCursor :: forall t v w. t -> v -> w -> Count -> JsonCursor t v w
JsonCursor
    { cursorText :: ByteString
cursorText      = ByteString
bs
    , interests :: CsPoppy
interests       = Vector Count -> CsPoppy
makeCsPoppy Vector Count
ib
    , balancedParens :: RangeMin CsPoppy
balancedParens  = CsPoppy -> RangeMin CsPoppy
forall a. AsVector64 a => a -> RangeMin a
RM.mkRangeMin (Vector Count -> CsPoppy
makeCsPoppy Vector Count
bp)
    , cursorRank :: Count
cursorRank      = Count
1
    }
    where SI.SemiIndex Context
_ Vector Count
ib Vector Count
bp = ByteString -> SemiIndex (Vector Count)
SI.buildSemiIndex ByteString
bs

instance FromForeignRegion (JsonCursor BS.ByteString (DVS.Vector Word64) (BP.SimpleBalancedParens (DVS.Vector Word64))) where
  fromForeignRegion :: ForeignRegion
-> JsonCursor
     ByteString (Vector Count) (SimpleBalancedParens (Vector Count))
fromForeignRegion (ForeignPtr Word8
fptr, Int
offset, Int
size) = ByteString
-> JsonCursor
     ByteString (Vector Count) (SimpleBalancedParens (Vector Count))
forall a. FromByteString a => ByteString -> a
fromByteString (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
F.castForeignPtr ForeignPtr Word8
fptr) Int
offset Int
size)

instance FromForeignRegion (JsonCursor BS.ByteString CsPoppy (RM.RangeMin CsPoppy)) where
  fromForeignRegion :: ForeignRegion -> JsonCursor ByteString CsPoppy (RangeMin CsPoppy)
fromForeignRegion (ForeignPtr Word8
fptr, Int
offset, Int
size) = ByteString -> JsonCursor ByteString CsPoppy (RangeMin CsPoppy)
forall a. FromByteString a => ByteString -> a
fromByteString (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
F.castForeignPtr ForeignPtr Word8
fptr) Int
offset Int
size)

instance IsString (JsonCursor BS.ByteString (DVS.Vector Word64) (BP.SimpleBalancedParens (DVS.Vector Word64))) where
  fromString :: String
-> JsonCursor
     ByteString (Vector Count) (SimpleBalancedParens (Vector Count))
fromString = ByteString
-> JsonCursor
     ByteString (Vector Count) (SimpleBalancedParens (Vector Count))
forall a. FromByteString a => ByteString -> a
fromByteString (ByteString
 -> JsonCursor
      ByteString (Vector Count) (SimpleBalancedParens (Vector Count)))
-> (String -> ByteString)
-> String
-> JsonCursor
     ByteString (Vector Count) (SimpleBalancedParens (Vector Count))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

instance IsString (JsonCursor BS.ByteString CsPoppy (RM.RangeMin CsPoppy)) where
  fromString :: String -> JsonCursor ByteString CsPoppy (RangeMin CsPoppy)
fromString = ByteString -> JsonCursor ByteString CsPoppy (RangeMin CsPoppy)
forall a. FromByteString a => ByteString -> a
fromByteString (ByteString -> JsonCursor ByteString CsPoppy (RangeMin CsPoppy))
-> (String -> ByteString)
-> String
-> JsonCursor ByteString CsPoppy (RangeMin CsPoppy)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

instance (BP.BalancedParens u, Rank1 u, Rank0 u) => TreeCursor (JsonCursor t v u) where
  firstChild :: JsonCursor t v u -> Maybe (JsonCursor t v u)
  firstChild :: JsonCursor t v u -> Maybe (JsonCursor t v u)
firstChild JsonCursor t v u
k = let mq :: Maybe Count
mq = u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.firstChild (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k) in (\Count
q -> JsonCursor t v u
k { cursorRank :: Count
cursorRank = Count
q }) (Count -> JsonCursor t v u)
-> Maybe Count -> Maybe (JsonCursor t v u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Count
mq

  nextSibling :: JsonCursor t v u -> Maybe (JsonCursor t v u)
  nextSibling :: JsonCursor t v u -> Maybe (JsonCursor t v u)
nextSibling JsonCursor t v u
k = (\Count
q -> JsonCursor t v u
k { cursorRank :: Count
cursorRank = Count
q }) (Count -> JsonCursor t v u)
-> Maybe Count -> Maybe (JsonCursor t v u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.nextSibling (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k)

  parent :: JsonCursor t v u -> Maybe (JsonCursor t v u)
  parent :: JsonCursor t v u -> Maybe (JsonCursor t v u)
parent JsonCursor t v u
k = let mq :: Maybe Count
mq = u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.parent (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k) in (\Count
q -> JsonCursor t v u
k { cursorRank :: Count
cursorRank = Count
q }) (Count -> JsonCursor t v u)
-> Maybe Count -> Maybe (JsonCursor t v u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Count
mq

  depth :: JsonCursor t v u -> Maybe Count
  depth :: JsonCursor t v u -> Maybe Count
depth JsonCursor t v u
k = u -> Count -> Maybe Count
forall v.
(BalancedParens v, Rank0 v, Rank1 v) =>
v -> Count -> Maybe Count
BP.depth (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k)

  subtreeSize :: JsonCursor t v u -> Maybe Count
  subtreeSize :: JsonCursor t v u -> Maybe Count
subtreeSize JsonCursor t v u
k = u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.subtreeSize (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k)

jsonCursorPos :: (Rank1 w, Select1 v) => JsonCursor s v w -> Position
jsonCursorPos :: JsonCursor s v w -> Position
jsonCursorPos JsonCursor s v w
k = Count -> Position
forall a. ToPosition a => a -> Position
toPosition (v -> Count -> Count
forall v. Select1 v => v -> Count -> Count
select1 v
ik (w -> Count -> Count
forall v. Rank1 v => v -> Count -> Count
rank1 w
bpk (JsonCursor s v w -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor s v w
k)) Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  where ik :: v
ik  = JsonCursor s v w -> v
forall t v w. JsonCursor t v w -> v
interests JsonCursor s v w
k
        bpk :: w
bpk = JsonCursor s v w -> w
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor s v w
k