
/*
**  jazz - a midi sequencer for Linux
**
**  Copyright (C) 1994-1996 Andreas Voss (andreas@avix.rhein-neckar.de)
**
**  Copyright (C) 1995-1996 Per Sigmond (Per.Sigmond@hia.no)
**
**  This program is free software; you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation; either version 2 of the License, or
**  (at your option) any later version.
**
**  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.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software
**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#ifndef command_h
#define command_h

class tFilter;
class tEvent;
class tTrack;
class tSong;
class tEventArray;

// 0..11 = C..B major keys
#define ScaleChromatic 12
#define ScaleSelected 13

class tScale
{
  public:
    void Init(int ScaleNr, tFilter *f = 0);	
    int ScaleKeys[12];

    int Member(int Key)
    {
      return ScaleKeys[Key % 12]; 
    }

    int Next(int Key);
    int Prev(int Key);
    int Transpose(int Key, int Steps);
    int FitInto(int Key);
    static int Analyze(tFilter *f);	// returns ScaleNr
};


class tCommand
{
  public:
    tFilter *Filter;
    tSong   *Song;
    int      Reverse;

    tCommand(tFilter *f);
    virtual void Execute(int NewUndo = 1);
    virtual void ExecuteTrack(tTrack *t);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
    long Interpolate(long clk, long vmin, long vmax);
};


class tCmdShift : public tCommand
{
  long DeltaClock;
  public:
    tCmdShift(tFilter *f, long DeltaClock);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};


class tCmdErase : public tCommand
{
  public:
    int LeaveSpace;
    tCmdErase(tFilter *f, int LeaveSpace = 1);
    virtual void Execute(int NewUndo = 1);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};

class tCmdVelocity : public tCommand
{
  public:
    int FromValue, ToValue, Mode;
    tCmdVelocity(tFilter *f, int From, int To, int Mode);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};


class tCmdLength : public tCommand
{
  public:
    int FromValue, ToValue, Mode;
    tCmdLength(tFilter *f, int From, int To, int Mode);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};

class tCmdCleanup : public tCommand
{
    long lengthLimit;
  public:
    tCmdCleanup(tFilter *f, long limitClocks);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};


class tCmdSearchReplace : public tCommand
{
  short fr, to;
  public:
    tCmdSearchReplace(tFilter *f, short fr, short to);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};


class tCmdQuantize : public tCommand
{
    long Quantize(long Clock);
  public:
    long QntClocks;
    int NoteStart;	// yes
    int NoteLength;	// no
    tCmdQuantize(tFilter *f, long QntClocks);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};


class tCmdTranspose : public tCommand
{
  public:
    int Notes;
    int FitIntoScale;
    tScale Scale;
    tCmdTranspose(tFilter *f, int Notes, int ScaleNr = 0, int FitIntoScale = 0);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};


class tCmdSetChannel : public tCommand
{
  public:
    int NewChannel;	// 0
    tCmdSetChannel(tFilter *f, int NewChannel);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};


class tCmdCopyToBuffer : public tCommand
{
  tEventArray *Buffer;
  public:
    tCmdCopyToBuffer(tFilter *f, tEventArray *Buffer);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};



class tCmdCopy : public tCommand
{
  public:
    int  DestTrack;
    long DestClock;

    int EraseSource;	// no
    int EraseDestin;	// yes
    int InsertSpace;	// no
    long RepeatClock;	// -1L

    tCmdCopy(tFilter *f, long DestTrack, long DestClock);
    virtual void ExecuteTrack(tTrack *t);
};    



class tCmdExchLeftRight : public tCommand
{
  public:
    tCmdExchLeftRight(tFilter *f);
    virtual void ExecuteEvent(tTrack *t, tEvent *e);
};

class tCmdExchUpDown : public tCommand
{
  public:
    tCmdExchUpDown(tFilter *f);
    virtual void ExecuteTrack(tTrack *t);
};

#endif
