//=========================================================
//  MusE
//  Linux Music Editor
//  $Id: tempo.h,v 1.1.1.1 2003/10/29 10:05:06 wschweer Exp $
//
//  (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
//=========================================================

#ifndef __TEMPO_H__
#define __TEMPO_H__

#include <map>

#ifndef MAX_TICK
#define MAX_TICK (0x7fffffff/100)
#endif

class Xml;

//---------------------------------------------------------
//   Tempo Event
//---------------------------------------------------------

struct TEvent {
      int tempo;
      int tick;            // new tempo at tick
      double time;         // precomputed time for tick in sec

      int read(Xml&);
      void write(int, Xml&, int) const;

      TEvent() { }
      TEvent(int t, int tk) {
            tempo = t;
            tick = tk;
            time = 0.0;
            }
      };

//---------------------------------------------------------
//   TempoList
//---------------------------------------------------------

typedef std::map<int, TEvent*, std::less<int> >::iterator iTEvent;
typedef std::map<int, TEvent*, std::less<int> >::const_iterator ciTEvent;
typedef std::map<int, TEvent*, std::less<int> >::reverse_iterator riTEvent;
typedef std::map<int, TEvent*, std::less<int> >::const_reverse_iterator criTEvent;

class TempoList : public std::map<int, TEvent*, std::less<int> > {
      int _tempoSN;           // serial no to track tempo changes
      bool useList;
      int _tempo;             // tempo if not using tempo list
      int _globalTempo;       // %percent 50-200%

      void normalize();
      void add(int tick, int tempo);
      void change(int tick, int newTempo);
      void del(iTEvent);
      void del(int tick);

   public:
      TempoList();
      void clear();

      void read(Xml&);
      void write(int, Xml&) const;
      void dump() const;

      int tempo(int tick) const;
      double tick2time(int tick, int* sn = 0) const;
      double tick2time(int tick, double time, int* sn) const;
      int time2tick(double time, int* sn = 0) const;
      int time2tick(double time, int tick, int* sn) const;
      int tempoSN() const { return _tempoSN; }
      void setTempo(int tick, int newTempo);
      void addTempo(int t, int tempo);
      void delTempo(int tick);
      void changeTempo(int tick, int newTempo);
      bool setMasterFlag(int tick, bool val);
      int globalTempo() const           { return _globalTempo; }
      void setGlobalTempo(int val);
      };

extern TempoList tempomap;
#endif
