#ifndef _ADDON_H_
#define _ADDON_H_

#include "operation.h"


class Table;
class Part;
class Track;
class Song;

/**
 * This is the base class for all addons. If you want to write an own addon, derive from this class. Before you start, you have to decide on the following topics:
 * 
 * 1. Shall the user of your operation be able to undo that operation?
 * This only makes sense if your operation modifies the song. If your operation writes output to disk (like tex or pdf, etc), or plays the song in a sophisticated way,
 * there is nothing to be undone after the operation. But if your operation changes e.g. the note pitches or velocities, you want to provide a possibility to
 * undo that operation. In this case you have to make sure to set the TO_BE_UNDONE flag (see below) and to implement the undo() and redo() methods.
 * Beware: If your addon is of the type TO_BE_UNDONE, don't use other operations within your addon!
 *
 * 2. Which scope shall your operation operate on. The following constants are defined to specify the scope:
 * <pre>
 * TREAT_SELECTION - lets the operation act on the selection
 * TREAT_PART      - lets the operation act on a part
 * TREAT_TRACK     - lets the operation act on a track
 * TREAT_SONG      - lets the operation act on the song
 * TREAT_GLOBAL    - lets the operation act without a song context
 * </pre>
 * You can add these constants, or use:
 * <pre>
 * TREAT_ALL       = TREAT_SELECTION + TREAT_PART + TREAT_TRACK + TREAT_SONG + TREAT_GLOBAL;
 * </pre>
 * to indicate that your addon acts on all scopes.
 **/
class Addon : public Operation
{

 protected:
  Element * _target;
  int _context;

 public:
  
  static const bool TO_BE_UNDONE = true;
  static const int TREAT_SELECTION =  1;
  static const int TREAT_PART      =  2;
  static const int TREAT_TRACK     =  4;
  static const int TREAT_SONG      =  8;
  static const int TREAT_GLOBAL    = 16;
  static const int TREAT_ALL       = TREAT_SELECTION + TREAT_PART + TREAT_TRACK + TREAT_SONG + TREAT_GLOBAL;

  /**
   * Default Constructor
   **/
  Addon(char*,Element*,bool,int);
  
  /**
   * Make sure to implement the destructor to free memory and avoid memory leaks!
   **/
  virtual ~Addon();
  
  /**
   * You need to implement this method only if your operation is of the type TO_BE_UNDONE
   **/
  virtual void undo();
  
  /**
   * You need to implement this method only if your operation is of the type TO_BE_UNDONE
   **/
  virtual void redo();
  
  /**
   * Implement this method if your operation acts on selections
   **/
  virtual void selection(Table * selection);

  /**
   * Implement this method if your operation acts on parts
   **/
  virtual void part(Part * part);

  /**
   * Implement this method if your operation acts on tracks
   **/
  virtual void track(Track * track);

  /**
   * Implement this method if your operation acts on the song
   **/
  virtual void song(Song * song);

  /**
   * Implement this method if your operation acts without song context
   **/
  virtual void global();
  
  /**
   * This method is already implemented. You have to call it from your constructor
   **/
  void run();

  /**
   * This method returns the context
   **/
  int context();

  /**
   * This method returns true if the operation supports the context given as a parameter
   **/
  bool context(int context);
  
  
  /**
   * Implementation of the print method
  **/
  virtual ostream & print(int,ostream&) const;

  /**
   * Implementation of the flush method
  **/
  virtual void flush(const char*) const;

  /**
   * Implementation of the copy method
  **/
  virtual Element * copy() const;
  
};

#endif

