// ---------------------------------------------------------------------------
// - Cursor.hpp                                                              -
// - standard object library - character buffer class definition             -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2001 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef  ALEPH_CURSOR_HPP
#define  ALEPH_CURSOR_HPP

#ifndef  ALEPH_OUTPUT_HPP
#include "Output.hpp"
#endif

namespace aleph {
  /// The Cursor class is a character buffer which can be used to accumulate
  /// character. The class is built as a circular buffer. The class maintains
  /// a set of indexes which can be used for editing purpose. The Cursor class
  /// is used by the terminal class to support editing operation. Note that
  /// the class is self-resizable.
  /// @author amaury darsch

  class Cursor : public virtual Object {
  private:
    /// the character buffer
    char* p_buffer;
    /// the buffer allocated size
    long d_size;
    /// the insert flag
    bool d_insert;
    /// the start index
    long d_start;
    /// the end index
    long d_end;
    /// the cursor position in this buffer
    long d_cursor;

  public:
    /// create a new buffer class. The buffer is created with a default
    /// size of 1024 characters.
    Cursor (void);

    /// create a new buffer class with a default size.
    /// @param size the buffer default size
    Cursor (const long size);
    
    /// create a new buffer and initialize it with a c string
    /// @param value the c string to initialize
    Cursor (const char* value);

    /// create a new buffer and initialize it with a string
    /// @param value the string to initialize
    Cursor (const String& value);

    /// destroy this buffer
    ~Cursor (void);

    /// @return the class name
    String repr (void) const;

    /// add a character to this buffer
    /// @param value the character to add to this buffer
    void add (const char value);

    /// add a character buffer in this buffer
    /// @param buffer the buffer to add
    /// @param size   the buffer size
    void add (const char* buffer, const long size);

    /// add a string to this buffer
    /// @param value the string to add to this buffer
    void add (const String& value);

    /// @return the next character but do not remove it
    char get (void) const;

    /// @return the character at the current index position
    char read (void);

    /// pushback a character in this buffer
    /// @param value the character to push back
    void pushback (const char value);

    /// pushback a character buffer in this buffer
    /// @param buffer the buffer to push back
    /// @param size   the buffer size
    void pushback (const char* buffer, const long size);

    /// pushback a string in this buffer
    /// @param value the string to push back
    void pushback (const String& value);

    /// remove a character before the cursor (backspace mode)
    /// @return true if the backspace succeded
    bool erase (void);

    /// remove a character at the cursor (delete mode)
    /// @return true if the delete succeded
    bool del (void);

    /// kill one or several characters
    void kill (const long num);

    /// @return true if the cursor was moved one character left
    bool movel (void);

    /// @return true if the cursor was moved one character right
    bool mover (void);

    /// move cursor to the begining of the buffer and return the amount
    /// of move done by the cursor
    /// @return the number of cursor move
    long setcb (void);

    /// move cursor to the end of the buffer and return the amount
    /// of move done by the cursor
    /// @return the number of cursor move
    long setce (void);

    /// set the buffer insert flag
    /// @param mode the insert mode
    void setimode (const bool mode);

    /// @return the length of this cursor
    long length (void) const;

    /// @return the buffer contents as a string
    String tostring (void) const;

    /// extract a substring from a previous cursor position
    /// @param start the start cursor position
    String substr (const long start) const;

    /// @return the cursor position
    long getcursor (void) const;

    /// reset this buffer 
    void reset (void);

    /// resize this cursor
    void resize (const long size);

  private:
    // make the copy constructor private
    Cursor (const Cursor&);
    // make the assignment operator private
    Cursor& operator =  (const Cursor&);
  };
}

#endif
