module Data.Woot.WChar
    ( WChar(..)
    , wCharBeginning
    , wCharEnding
    , hide
    , ClientId
    , WCharId(..)
    ) where


data WChar = WChar
    { wCharId      :: WCharId
    , wCharVisible :: Bool
    , wCharAlpha   :: Char
    , wCharPrevId  :: WCharId
    , wCharNextId  :: WCharId
    } deriving (Eq, Show)


-- special character to mark the beginning of a wString
-- note: clientId of -1 denotes a special character generated by this library
-- includes a self-referential 'prevId' field
wCharBeginning :: WChar
wCharBeginning = WChar wCharIdBeginning False ' ' wCharIdBeginning wCharIdEnding


-- special character to mark the ending of a wString
-- note: clientId of -1 denotes a special character generated by this library
-- includes a self-referential 'nextId' field
wCharEnding :: WChar
wCharEnding = WChar wCharIdEnding False ' ' wCharIdBeginning wCharIdEnding


hide :: WChar -> WChar
hide wc = wc {wCharVisible = False}


type ClientId = Int


data WCharId = WCharId
    { wCharIdClientId :: ClientId
    , wCharIdClock    :: Int
    } deriving (Eq, Show)


instance Ord WCharId where
    compare = compareCharIds


compareCharIds :: WCharId -> WCharId -> Ordering
compareCharIds (WCharId cA iA) (WCharId cB iB) = compare (cA, iA) (cB, iB)


wCharIdBeginning :: WCharId
wCharIdBeginning = WCharId (-1) 0


wCharIdEnding :: WCharId
wCharIdEnding = WCharId (-1) 1