-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Zipper
-- Copyright   :  (C) 2012-13 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  experimental
-- Portability :  non-portable
--
-- This module provides a 'Zipper' with fairly strong type checking guarantees.
--
-- The code here is inspired by Brandon Simmons' @zippo@ package, but uses
-- a different approach to represent the 'Zipper' that makes the whole thing
-- look like his breadcrumb trail, and can move side-to-side through
-- traversals.
--
-- Some examples types:
--
-- [@'Top' ':>>' a@] represents a trivial 'Zipper' with its focus at the root.
--
-- [@'Top' ':>>' 'Data.Tree.Tree' a ':>>' a@] represents a 'Zipper' that starts with a
--   'Data.Tree.Tree' and descends in a single step to values of type @a@.
--
-- [@'Top' ':>>' 'Data.Tree.Tree' a ':>>' 'Data.Tree.Tree' a ':>>' 'Data.Tree.Tree' a@] represents a 'Zipper' into a
--   'Data.Tree.Tree' with an intermediate bookmarked 'Data.Tree.Tree',
--   focusing in yet another 'Data.Tree.Tree'.
--
-- Since individual levels of a 'Zipper' are managed by an arbitrary
-- 'Control.Lens.Type.IndexedTraversal', you can move left and right through
-- the 'Control.Lens.Type.IndexedTraversal' selecting neighboring elements.
--
-- >>> zipper ("hello","world") & downward _1 & fromWithin traverse & focus .~ 'J' & rightmost & focus .~ 'y' & rezip
-- ("Jelly","world")
--
-- This is particularly powerful when compiled with 'Control.Lens.Plated.plate',
-- 'Data.Data.Lens.uniplate' or 'Data.Data.Lens.biplate' for walking down into
-- self-similar children in syntax trees and other structures.
--
-- Given keys in ascending order you can jump directly to a given key with
-- 'moveTo'. When used with traversals for balanced
-- tree-like structures such as an 'Data.IntMap.IntMap' or 'Data.Map.Map',
-- searching for a key with 'moveTo' can be done in logarithmic time.
-----------------------------------------------------------------------------
module Control.Zipper
  (
  -- * Zippers
    Top()
  , (:>)()
  , (:>>)()
  , (:@)()
  , Zipper
  , zipper
  -- ** Focusing
  , focus
  , focusedContext
  -- ** Vertical Movement
  , upward
  , downward, idownward
  , within, iwithin
  , withins, iwithins
  -- ** Lateral Movement
  , leftward, rightward
  , leftmost, rightmost
  -- ** Movement Combinators
  , tug
  , tugs
  , jerks
  , farthest
  -- ** Absolute Positioning
  , tooth
  , teeth
  , jerkTo
  , tugTo
  , moveTo
  , moveToward
  -- ** Closing the zipper
  , rezip
  , Zipped
  , Zipping()
  -- ** Recording
  , Tape()
  , saveTape
  , restoreTape
  , restoreNearTape
  -- ** Unsafe Movement
  , fromWithin
  , ifromWithin
  , unsafelyRestoreTape
  ) where

import Control.Zipper.Internal

-- $setup
-- >>> :set -XNoOverloadedStrings
-- >>> import Control.Lens