/********************************************************************************
*                                                                               *
*                  U n d o / R e d o - a b l e   C o m m a n d                  *
*                                                                               *
*********************************************************************************
* Copyright (C) 2000 by Jeroen van der Zijp.   All Rights Reserved.             *
*********************************************************************************
* This library is free software; you can redistribute it and/or                 *
* modify it under the terms of the GNU Library General Public                   *
* License as published by the Free Software Foundation; either                  *
* version 2 of the License, or (at your option) any later version.              *
*                                                                               *
* This library 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.  See the GNU             *
* Library General Public License for more details.                              *
*                                                                               *
* You should have received a copy of the GNU Library General Public             *
* License along with this library; if not, write to the Free                    *
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
*********************************************************************************
* $Id: FXUndoList.h,v 1.8 2000/07/18 06:54:54 jeroen Exp $                      *
********************************************************************************/
#ifndef FXUNDOLIST_H
#define FXUNDOLIST_H


// An undoable command
class FXAPI FXCommand {
  friend class FXUndoList;
private:
  FXCommand *next;
private:
  FXCommand(const FXCommand&);
  FXCommand &operator=(const FXCommand&);
protected:
  FXCommand():next(NULL){}
public:
  virtual void undo() = 0;
  virtual void redo() = 0;
  virtual FXuint size() const = 0;
  virtual FXString undoName() const = 0;
  virtual FXString redoName() const = 0;
  virtual ~FXCommand(){}
  };


// A list of commands
class FXAPI FXUndoList : public FXObject {
  FXDECLARE(FXUndoList)
private:
  FXCommand *redolist;      // List yet to be done from this point
  FXCommand *undolist;      // List which has been done from this point
  FXuint     size;          // Size of undo records
  FXuint     count;         // Number of undo records
public:
  long onCmdUndo(FXObject*,FXSelector,void*);
  long onUpdUndo(FXObject*,FXSelector,void*);
  long onCmdRedo(FXObject*,FXSelector,void*);
  long onUpdRedo(FXObject*,FXSelector,void*);
  long onCmdClear(FXObject*,FXSelector,void*);
  long onUpdClear(FXObject*,FXSelector,void*);
public:
  enum{
    ID_CLEAR=FXWindow::ID_LAST,
    ID_UNDO,
    ID_REDO,
    ID_LAST
    };
public:

  /// Make new empty undo list.
  FXUndoList();

  /// Cut the redo list
  void cut();

  /// Add new command, executing if desired
  FXbool add(FXCommand* command,FXbool doit=FALSE);

  /// Undo last command
  FXbool undo();

  /// Redo next command
  FXbool redo();

  /// Can we undo more commands
  FXbool canUndo() const { return undolist!=NULL; }

  /// Can we redo more commands
  FXbool canRedo() const { return redolist!=NULL; }

  /// Current undo command
  FXCommand* current() const { return undolist; }

  /// Number of undo records
  FXuint undoCount() const { return count; }

  /// Size of undo information
  FXuint undoSize() const { return size; }
  
  /// Clear list
  void clear();

  /// Trim undo list down to at most nc commands
  void trimCount(FXuint nc);
  
  /// Trim undo list down to at most size sz
  void trimSize(FXuint sz);

  /// Clean up
  ~FXUndoList();
  };


#endif
