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

#include "lmaster.h"
#include "seq.h"
#include "xml.h"
#include "song.h"
#include "globals.h"

#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qtooltip.h>
#include <qlayout.h>
#include <qsizegrip.h>
#include <qpopupmenu.h>
#include <qmenubar.h>
#include <qlistview.h>

//---------------------------------------------------------
//   closeEvent
//---------------------------------------------------------

void LMaster::closeEvent(QCloseEvent* e)
      {
      emit deleted((int)this);
      e->accept();
      }

//---------------------------------------------------------
//   songChanged
//---------------------------------------------------------

void LMaster::songChanged(int type)
      {
      if (type & (SC_SIG | SC_TEMPO))
            updateList();
      }

//---------------------------------------------------------
//   LMaster
//---------------------------------------------------------

LMaster::LMaster()
   : MidiEditor(0, 0, 0)
      {
      setCaption(tr("MusE: Mastertrack"));
      setMinimumHeight(100);
      setFixedWidth(400);

      //---------Pulldown Menu----------------------------
//      QPopupMenu* file = new QPopupMenu(this);
//      menuBar()->insertItem("&File", file);

      //---------ToolBar----------------------------------
      tools = new QToolBar(this, "list-tools");
      undoRedo->addTo(tools);

      QToolBar* edit = new QToolBar(this, "edit tools");
      QToolButton* tempo = new QToolButton(edit);
      QToolButton* time = new QToolButton(edit);
      tempo->setText(tr("Tempo"));
      time->setText(tr("Timesig"));
      QToolTip::add(tempo, tr("new tempo"));
      QToolTip::add(time, tr("new signature"));

      //---------------------------------------------------
      //    master
      //---------------------------------------------------

      view = new QListView(mainw);
      view->setAllColumnsShowFocus(true);
      view->setSelectionMode(QListView::Single);
      view->addColumn(tr("Meter"), 100);
      view->addColumn(tr("Time"),  100);
      view->addColumn(tr("Type"),  100);
      view->addColumn(tr("Value"), 100);
      view->setSorting(-1);

      //---------------------------------------------------
      //    Rest
      //---------------------------------------------------

//      QSizeGrip* corner = new QSizeGrip(mainw);

      mainGrid->setRowStretch(0, 100);
      mainGrid->setColStretch(0, 100);

      mainGrid->addWidget(view,  0, 0);
//      mainGrid->addWidget(corner,  1, 1, AlignBottom | AlignRight);
      updateList();

      connect(view, SIGNAL(selectionChanged(QListViewItem*)), SLOT(select(QListViewItem*)));
      connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
      }

//---------------------------------------------------------
//   ~LMaster
//---------------------------------------------------------

LMaster::~LMaster()
      {
      undoRedo->removeFrom(tools);
      }

//---------------------------------------------------------
//   insertSig
//---------------------------------------------------------

void LMaster::insertSig(const SigEvent* ev)
      {
      int t = ev->tick;
      QString s1, s2, s3, s4;
      int bar, beat, tick;
      sigmap.tickValues(t, &bar, &beat, &tick);
      s1.sprintf("%04d.%02d.%03d", bar+1, beat+1, tick);

      double time = tempomap.tick2time(t);
      int min = int(time) / 60;
      int sec = int(time) % 60;
      int msec = int((time - (min*60 + sec)) * 1000.0);
      s2.sprintf("%03d:%02d:%03d", min, sec, msec);
      s3 = "Timesig";
      s4.sprintf("%d/%d", ev->z, ev->n);
      // view->insertItem(new QListViewItem(view, s1, s2, s3, s4));
      new QListViewItem(view, s1, s2, s3, s4);
      }

//---------------------------------------------------------
//   insertTempo
//---------------------------------------------------------

void LMaster::insertTempo(const TEvent* ev)
      {
      int t = ev->tick;
      QString s1, s2, s3, s4;
      int bar, beat, tick;
      sigmap.tickValues(t, &bar, &beat, &tick);
      s1.sprintf("%04d.%02d.%03d", bar+1, beat+1, tick);

      double time = ev->time;
      int min = int(time) / 60;
      int sec = int(time) % 60;
      int msec = int((time - (min*60 + sec)) * 1000.0);
      s2.sprintf("%03d:%02d:%03d", min, sec, msec);
      s3 = "Tempo";
      double dt = (1000000.0 * 60.0)/ev->tempo;
      s4.setNum(dt, 'f', 3);
      // view->insertItem(new QListViewItem(view, s1, s2, s3, s4));
      new QListViewItem(view, s1, s2, s3, s4);
      }

//---------------------------------------------------------
//   updateList
//---------------------------------------------------------

void LMaster::updateList()
      {
      view->clear();
      const TempoList* t   = &tempomap;
      const SigList* s   = &sigmap;

      criTEvent it   = t->rbegin();
      criSigEvent is = s->rbegin();
      for (;;) {
            if (it == t->rend()) {
                  while(is != s->rend()) {
                        insertSig(is->second);
                        ++is;
                        }
                  break;
                  }
            if (is == s->rend()) {
                  while (it != t->rend()) {
                        insertTempo(it->second);
                        ++it;
                        }
                  break;
                  }
            if (is->second->tick > it->second->tick) {
                  insertSig(is->second);
                  ++is;
                  }
            else {
                  insertTempo(it->second);
                  ++it;
                  }
            }
      }

//---------------------------------------------------------
//   readStatus
//---------------------------------------------------------

void LMaster::readStatus(Xml& xml)
      {
      for (;;) {
            Xml::Token token = xml.parse();
            const QString& tag = xml.s1();
            if (token == Xml::Error || token == Xml::End)
                  break;
            switch (token) {
                  case Xml::TagStart:
                        if (tag == "midieditor")
                              MidiEditor::readStatus(xml);
                        else
                              xml.unknown("LMaster");
                        break;
                  case Xml::TagEnd:
                        if (tag == "lmaster")
                              return;
                  default:
                        break;
                  }
            }
      }

//---------------------------------------------------------
//   writeStatus
//---------------------------------------------------------

void LMaster::writeStatus(int level, Xml& xml) const
      {
      xml.tag(level++, "lmaster");
      MidiEditor::writeStatus(level, xml);
      xml.tag(level, "/lmaster");
      }

void LMaster::select(QListViewItem* item)
      {
//      printf("select %x\n", unsigned(item));
      }


