
/*
**  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 maction_h
#define maction_h


#ifndef wx_wxh
#include "wx.h"
#endif

#ifndef wx_timerh
#include <wx_timer.h>
#endif

#ifndef util_h
#include "util.h"
#endif


class tMouseMapper
{
  public:
    // actions 
    // 0..2 = left/middle/right down
    // 3..5 = left/middle/right down + shift
    // 6..8 = left/middle/right down + ctrl
    // 9..11 = left/middle/right down + ctrl + shift

    tMouseMapper(const int actions[12]);
    tMouseMapper();

    enum Button { Left, Middle, Right };
    void SetAction(int code, Button but = Left, Bool shift = FALSE, Bool ctrl = FALSE);
    int Action(wxMouseEvent &);

  private:
    int actions[12];
};


class tMouseAction
{
  public:
    virtual int Dragging(wxMouseEvent &) 	{ return 0; };
    virtual int LeftDown(wxMouseEvent &) 	{ return 0; };
    virtual int LeftUp(wxMouseEvent &) 	{ return 0; };
    virtual int RightDown(wxMouseEvent &) 	{ return 0; };
    virtual int RightUp(wxMouseEvent &) 	{ return 0; };
    virtual int MiddleDown(wxMouseEvent &) 	{ return 0; };
    virtual int MiddleUp(wxMouseEvent &) 	{ return 0; };
    virtual int Event(wxMouseEvent &e) 
    {
      if (e.Dragging())		return Dragging(e);
      else if (e.LeftDown())	return LeftDown(e);
      else if (e.LeftUp())	return LeftUp(e);
      else if (e.MiddleDown())	return MiddleDown(e);
      else if (e.MiddleUp())	return MiddleUp(e);
      else if (e.RightDown())	return RightDown(e);
      else if (e.RightUp())	return RightUp(e);
      return 0;
    }
};


// -----------------------------------------------------------------
// Selection - Rechteck mit Maus aufziehen
// -----------------------------------------------------------------


class tSelection : public tMouseAction
{
  wxDC *dc;
  wxCanvas *Canvas;
public:
  int Active;
  virtual void Snap(float &x, float &y, int drag) {}
  tRect r;
  int Selected;		// r is valid
  virtual int Dragging(wxMouseEvent &);
  virtual int LeftDown(wxMouseEvent &);
  virtual int LeftUp(wxMouseEvent &);
  virtual void Draw();
  virtual void Draw(long x, long y, long w, long h); // clipping
  tSelection(wxCanvas *canvas);
  // may not be called while dragging
  void Select(tRect &rr, long x, long y, long w, long h);
};

class tSnapSelection : public tSelection
{
protected:
  long  *xCoords, nxCoords;
  long  *yCoords, nyCoords;
  long  xMin, xMax, xStep, yMin, yMax, yStep;

public:
  tSnapSelection(wxCanvas *c);
  virtual void Snap(float &x, float &y, int up);
  void SetXSnap(long ny, long *cx);
  void SetYSnap(long ny, long *cy);
  void SetXSnap(long xMin, long xMax, long xStep);
  void SetYSnap(long yMin, long yMax, long yStep);
};

// -----------------------------------------------------------------
// MouseCounter - Zahl mit linker/rechter Maustaste eingeben
// -----------------------------------------------------------------


class tMouseCounter : public wxTimer, public tMouseAction
{
    int Min, Max, Delta;
    int Timeout;
    int Wait;	// don't inc/dec at Init
    wxDC *dc;

    virtual int LeftDown(wxMouseEvent &);
    virtual int LeftUp(wxMouseEvent &);
    virtual int RightDown(wxMouseEvent &);
    virtual int RightUp(wxMouseEvent &);
    virtual void Notify();
    virtual void ShowValue();
  public:
    tRect r;
    int Value;
    tMouseCounter(wxDC *dc, tRect *rec, int val, int min, int max, int wait = 0);
};

// -------------------------------------------------------------------------
// tMarkDestin - Zieltrack/Takt anklicken
// -------------------------------------------------------------------------

class tMarkDestin : public tMouseAction
{
  wxCanvas *Canvas;
  wxFrame  *Frame;
  ButtonDown(wxMouseEvent &);

public:
  int Aborted;
  float x, y;

  virtual int LeftDown(wxMouseEvent &);
  virtual int RightDown(wxMouseEvent &);
  tMarkDestin(wxCanvas *canvas, wxFrame *frame, int left);
};

#endif

