/* ====================================================================
 * Copyright (c) 2003-2006, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

#ifndef _SC_CURSOR_H
#define _SC_CURSOR_H


class Cursor
{
public:
  Cursor() : _line(0), _column(0), _on(false)
  {
  }

  Cursor( int line, int column )
  : _line(line), _column(column), _on(true)
  {
  }

  Cursor( int line, int column, bool on )
  : _line(line), _column(column), _on(on)
  {
  }

  Cursor( const Cursor& src )
  {
    *this = src;
  }

  bool equalPos( const Cursor& src ) const
  {
    return (_line == src._line) && (_column == src._column);
  }

  void operator=( const Cursor& src )
  {
    _on     = src._on;
    _line   = src._line;
    _column = src._column;
  }

  bool operator<( const Cursor& src )
  {
    if( _line < src._line )
    {
      return true;
    }
    else if( _line > src._line )
    {
      return false;
    }
    else // if( _line == src._line )
    {
      return _column < src._column;
    }
  }

  int line() const
  {
    return _line;
  }

  void setLine( int line )
  {
    _line = line;
  }

  int column() const
  {
    return _column;
  }

  void setColumn( int col )
  {
    _column = col;
  }

  void maxColumn( int maxCol )
  {
    if( _column > maxCol )
    {
      _column = maxCol;
    }
  }

  void minColumn( int minCol )
  {
    if( _column < minCol )
    {
      _column = minCol;
    }
  }

  bool isOn() const
  {
    return _on;
  }

  void setOn()
  {
    _on = true;
  }

  bool isOff() const
  {
    return ! _on;
  }

  void setOff()
  {
    _on = false;
  }

  void toggle()
  {
    _on = ! _on;
  }

  void up( int cnt = 1 )
  {
    _line -= cnt;
    _on = true;
  }

  void down( int cnt = 1 )
  {
    _line += cnt;
    _on = true;
  }

  void left( int cnt = 1 )
  {
    _column -= cnt;
    _on = true;
  }

  void right( int cnt = 1 )
  {
    _column += cnt;
    _on = true;
  }

private:
  int  _line;
  int  _column;
  bool _on;
};



class CursorPair
{
public:
  CursorPair( const Cursor& one, const Cursor& two )
    : _1(one), _2(two)
  {
  }

  void order()
  {
    if( _1 < _2 )
    {
      return;
    }
    if( _1.equalPos(_2) )
    {
      return;
    }

    swap();
  }

  void swap()
  {
    Cursor tmp(_1);
    _1 = _2;
    _2 = tmp;
  }

  const Cursor& getOne() const
  {
    return _1;
  }

  const Cursor& getTwo() const
  {
    return _2;
  }

private:
  Cursor _1;
  Cursor _2;
};


#endif // _SC_CURSOR_H

