-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Marking text regions
--   
--   Provides functions to update text region positions according to text
--   edit actions
@package text-region
@version 0.3.1.0

module Data.Text.Region.Types

-- | Point at text: zero-based line and column
data Point
Point :: Int -> Int -> Point
[_pointLine] :: Point -> Int
[_pointColumn] :: Point -> Int
pointLine :: Lens' Point Int
pointColumn :: Lens' Point Int

-- | As empty region
pointRegion :: Iso' Point Region

-- | Distance between <a>Point</a>s is measured in lines and columns. And
--   it is defined, that distance between point at l:c and point (l + 1):0
--   is one line no matter c is because we need to go to new line to reach
--   destination point Columns are taken into account only if points are on
--   the same line
type Size = Point

-- | <tt>pt .-. base</tt> is distance from <tt>base</tt> to <tt>pt</tt>
--   Distance can't be less then zero lines and columns
(.-.) :: Point -> Point -> Point

-- | Opposite to <a>.-.</a>
--   
--   <pre>
--   (pt .-. base) .+. base = pt
--   </pre>
(.+.) :: Point -> Point -> Point

-- | Region from <a>Point</a> to another
data Region
Region :: Point -> Point -> Region
[_regionFrom] :: Region -> Point
[_regionTo] :: Region -> Point
regionFrom :: Lens' Region Point
regionTo :: Lens' Region Point

-- | Main idea is that there are only two basic actions, that changes
--   regions: inserting and cutting When something is cutted out or
--   inserted in, <a>Region</a> positions must be updated All editings can
--   be represented as many cuts and inserts, so we can combine them to get
--   function which maps source regions to regions on updated data Because
--   insert is dual to cut (and therefore composes something like iso), we
--   can also get function to map regions back Combining this functions
--   while edit, we get function, that maps regions from source data to
--   edited one To get back function, we must also combine opposite
--   actions, or we can represent actions as <a>Iso</a> Same idea goes for
--   modifying contents, represent each action as isomorphism and combine
--   them together This works if we don't use overlapped regions
newtype Map
Map :: Iso' Region Region -> Map
[mapIso] :: Map -> Iso' Region Region

-- | Contents is list of lines, list must have at least one (maybe empty)
--   line
type Contents a = [a]

-- | Empty contents are contents with one empty line
emptyContents :: Monoid a => Contents a
concatCts :: Monoid a => Contents a -> Contents a -> Contents a

-- | Split <a>Contents</a> at some <a>Point</a>
splitCts :: Editable a => Point -> Contents a -> (Contents a, Contents a)

-- | Get splitted <a>Contents</a> at some <a>Point</a>
splitted :: Editable a => Point -> Iso' (Contents a) (Contents a, Contents a)

-- | Something editable, string types implements this
class Monoid a => Editable a

-- | Split editable at some position
splitContents :: Editable a => Int -> a -> (a, a)
contentsLength :: Editable a => a -> Int
splitLines :: Editable a => a -> [a]
joinLines :: Editable a => [a] -> a

-- | Get <a>Contents</a> for some <a>Editable</a>, splitting lines
contents :: (Editable a, Editable b) => Iso a b (Contents a) (Contents b)
by :: Editable a => a -> Contents a

-- | Contents <a>Size</a>
measure :: Editable s => Contents s -> Size

-- | Serializable edit action
data Replace s
Replace :: Region -> Contents s -> Replace s

-- | <a>Region</a> to replace
[_replaceRegion] :: Replace s -> Region

-- | <a>Contents</a> to replace with
[_replaceWith] :: Replace s -> Contents s
replaceRegion :: forall s_alAq. Lens' (Replace s_alAq) Region
replaceWith :: forall s_alAq s_anDY. Lens (Replace s_alAq) (Replace s_anDY) (Contents s_alAq) (Contents s_anDY)

-- | Edit is several replace actions, applied simultaneously, must not
--   overlap
newtype Edit s
Edit :: [Replace s] -> Edit s
[_replaces] :: Edit s -> [Replace s]
replaces :: forall s_anEc s_arxO. Iso (Edit s_anEc) (Edit s_arxO) [Replace s_anEc] [Replace s_arxO]
class Regioned a
regions :: Regioned a => Traversal' a Region
instance Data.Text.Region.Types.Regioned Data.Text.Region.Types.Point
instance Data.Text.Region.Types.Regioned Data.Text.Region.Types.Region
instance Data.Text.Region.Types.Regioned (Data.Text.Region.Types.Replace s)
instance Data.Text.Region.Types.Regioned (Data.Text.Region.Types.Edit s)
instance (Data.Text.Region.Types.Editable s, Data.Aeson.Types.ToJSON.ToJSON s) => Data.Aeson.Types.ToJSON.ToJSON (Data.Text.Region.Types.Edit s)
instance (Data.Text.Region.Types.Editable s, Data.Aeson.Types.FromJSON.FromJSON s) => Data.Aeson.Types.FromJSON.FromJSON (Data.Text.Region.Types.Edit s)
instance GHC.Base.Monoid (Data.Text.Region.Types.Edit s)
instance Data.Semigroup.Semigroup (Data.Text.Region.Types.Edit s)
instance (Data.Aeson.Types.ToJSON.ToJSON s, Data.Text.Region.Types.Editable s) => GHC.Show.Show (Data.Text.Region.Types.Edit s)
instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.Text.Region.Types.Edit s)
instance (Data.Text.Region.Types.Editable s, Data.Aeson.Types.ToJSON.ToJSON s) => Data.Aeson.Types.ToJSON.ToJSON (Data.Text.Region.Types.Replace s)
instance (Data.Text.Region.Types.Editable s, Data.Aeson.Types.FromJSON.FromJSON s) => Data.Aeson.Types.FromJSON.FromJSON (Data.Text.Region.Types.Replace s)
instance (Data.Text.Region.Types.Editable s, Data.Aeson.Types.ToJSON.ToJSON s) => GHC.Show.Show (Data.Text.Region.Types.Replace s)
instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.Text.Region.Types.Replace s)
instance Data.Text.Region.Types.Editable GHC.Base.String
instance Data.Text.Region.Types.Editable Data.Text.Internal.Text
instance Data.Semigroup.Semigroup Data.Text.Region.Types.Map
instance GHC.Base.Monoid Data.Text.Region.Types.Map
instance Data.Group.Group Data.Text.Region.Types.Map
instance Data.Aeson.Types.ToJSON.ToJSON Data.Text.Region.Types.Region
instance Data.Aeson.Types.FromJSON.FromJSON Data.Text.Region.Types.Region
instance GHC.Show.Show Data.Text.Region.Types.Region
instance GHC.Read.Read Data.Text.Region.Types.Region
instance GHC.Classes.Ord Data.Text.Region.Types.Region
instance GHC.Classes.Eq Data.Text.Region.Types.Region
instance Data.Aeson.Types.ToJSON.ToJSON Data.Text.Region.Types.Point
instance Data.Aeson.Types.FromJSON.FromJSON Data.Text.Region.Types.Point
instance Data.Semigroup.Semigroup Data.Text.Region.Types.Point
instance GHC.Base.Monoid Data.Text.Region.Types.Point
instance Data.Group.Group Data.Text.Region.Types.Point
instance GHC.Show.Show Data.Text.Region.Types.Point
instance GHC.Read.Read Data.Text.Region.Types.Point
instance GHC.Classes.Ord Data.Text.Region.Types.Point
instance GHC.Classes.Eq Data.Text.Region.Types.Point

module Data.Text.Region

-- | Make <a>Point</a> from line and column
pt :: Int -> Int -> Point

-- | <a>Point</a> at the beginning
start :: Point

-- | <a>Point</a> at the beginning of line
lineStart :: Int -> Point

-- | Regions length
regionLength :: Lens' Region Size

-- | Region from one <a>Point</a> to another
till :: Point -> Point -> Region

-- | Distance of <tt>n</tt> lines
linesSize :: Int -> Size
regionLines :: Lens' Region Int

-- | Is <a>Region</a> empty
emptyRegion :: Region -> Bool

-- | n'th line region, starts at the beginning of line and ends on the next
--   line
line :: Int -> Region

-- | Make <a>Region</a> by start position and <a>Size</a>
regionSize :: Point -> Size -> Region

-- | Expand <a>Region</a> to contain full lines
expandLines :: Region -> Region

-- | Get contents at <a>Region</a>
atRegion :: Editable s => Region -> Lens' (Contents s) (Contents s)

-- | Does regions overlaps
overlaps :: Region -> Region -> Bool
applyMap :: Map -> Region -> Region

-- | Cut <a>Region</a> mapping
cutMap :: Region -> Map

-- | Opposite to <a>cutMap</a>
insertMap :: Region -> Map

-- | Update second <a>Region</a> position as if it was data cutted at first
--   <a>Region</a>
cutRegion :: Region -> Region -> Region

-- | Update second region position as if it was data inserted at first
--   region (region sets insertion point and data size) Region tries not to
--   extend if data inserted at region bound except when region is empty
--   This allows define replace as cut and insert in special case when we
--   replace region itself
insertRegion :: Region -> Region -> Region
class Editable s => EditAction e s

-- | Make replace action over <a>Region</a> and <a>Contents</a>
replaceAction :: EditAction e s => Region -> Contents s -> e s

-- | Make <a>Map</a> from action
actionMap :: EditAction e s => e s -> Map

-- | Perform action, modifying <a>Contents</a>
perform :: EditAction e s => e s -> Contents s -> Contents s

-- | Get action undo
inversed :: EditAction e s => e s -> Contents s -> e s

-- | Replace region with data
replace :: EditAction e s => Region -> s -> e s

-- | Cuts region
cut :: EditAction e s => Region -> e s

-- | Pastes <a>Contents</a> at some <a>Point</a>
paste :: EditAction e s => Point -> s -> e s

-- | Overwrites <a>Contents</a> at some <a>Point</a>
overwrite :: EditAction e s => Point -> s -> e s

-- | <a>perform</a> for <a>Edit</a>
apply :: Editable s => Edit s -> s -> s

-- | Update regions
update :: (Editable s, Regioned r) => Edit s -> r -> r

-- | Get undo
undo :: Editable s => Edit s -> s -> Edit s
instance Data.Text.Region.Types.Editable s => Data.Text.Region.EditAction Data.Text.Region.Types.Replace s
instance Data.Text.Region.Types.Editable s => Data.Text.Region.EditAction Data.Text.Region.Types.Edit s
