#ifndef _CUTSELECTION_CPP_
#define _CUTSELECTION_CPP_

#include <iostream.h>

#include "cutSelection.h"
#include "element.h"
#include "compound.h"

#include "track.h"
#include "event.h"
#include "song.h"
#include "part.h"
#include "table.h"
#include "reference.h"

extern Song * sonG;
extern Table * selectioN;
extern Table * selectionMemory;


CutSelection::CutSelection(Compound * comp) : Operation(), _oldTable(0), _comp(comp) {
  _type = CUTSELECTION;
  _description = "cut selection";
  _to_be_undone = true;
  _oldTable = selectionMemory;
  _delete = _oldTable;

  Element * ev = 0;
  for (Reference * r = (Reference*)selectioN->first(); r != 0; r = (Reference*) Element::next(r)) {
    ev = (Element*) r->getValue();
    if (ev!=0) {
      _comp->remove(ev);
      ev->hide();
    }
  }
  selectionMemory = selectioN;
  selectioN = new Table();

}


CutSelection::CutSelection(const CutSelection& el) : Operation(el) {
  _type = CUTSELECTION;
  _oldTable = el._oldTable;
  _delete = el._delete;
  _comp   = el._comp;
}

CutSelection::~CutSelection() {
  if (_oldTable!=0) {
    ((Compound*)_oldTable)->scratch();
    delete _oldTable;
  }
}

void CutSelection::undo() {
  Table * tmp = selectionMemory;
  selectionMemory = _oldTable;
  _oldTable = tmp;
  _delete = _oldTable;
  // now put events back into the part:
  // Element * ev = 0;
  for (Reference * r = (Reference*)_oldTable->first(); r != 0; r = (Reference*) Element::next(r)) {
    _comp->add((Element*)r->getValue());
    r->getValue()->show();
  }
}

void CutSelection::redo() {
  Table * tmp = _oldTable;
  _oldTable = selectionMemory;
  selectionMemory = tmp;
  _delete = _oldTable;
  // now remove the events from the part again:
  // Element * ev = 0;
  for (Reference * r = (Reference*)selectionMemory->first(); r != 0; r = (Reference*) Element::next(r)) {
    _comp->remove((Element*)r->getValue());
    r->getValue()->hide();
  }

}



// ---------------
// virtuals:
//

ostream & CutSelection::print(int dep, ostream & s) const {
  s << spc(dep) << "<CUTSELECTION />" << endl;
  return s;
}

void CutSelection::flush(const char * c) const {
  cout << c << "CUTSELECTION" << endl;
}

Element * CutSelection::copy() const {
  return new CutSelection(*this);
}




#endif
