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

#include "cliplist.h"
#include "song.h"
#include "globals.h"
#include "wave.h"
#include "xml.h"
#include "posedit.h"
#include "cliplisteditorbase.h"

#include <qlistview.h>
#include <qlayout.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qstyle.h>

extern int mtcType;
enum { COL_NAME=0, COL_REFS, COL_POS, COL_LEN };

//---------------------------------------------------------
//   ClipItem
//---------------------------------------------------------

class ClipItem : public QListViewItem {
      SndFile* _wf;
      Clip* _clip;

      virtual QString text(int) const;

   public:
      ClipItem(QListView*, SndFile*);
      ClipItem(QListViewItem*, Clip*);
      SndFile* wf() const { return _wf; }
      Clip* clip() const  { return _clip; }
      };

ClipItem::ClipItem(QListView* parent, SndFile* w)
   : QListViewItem(parent)
      {
      _wf   = w;
      _clip = 0;
      }

ClipItem::ClipItem(QListViewItem* parent, Clip* c)
   : QListViewItem(parent)
      {
      _clip = c;
      _wf   = 0;
      }

//---------------------------------------------------------
//   samples2smpte
//---------------------------------------------------------

static QString samples2smpte(int samples)
      {
      double time = double(samples) / double(sampleRate);
      int min  = int(time) / 60;
      int sec  = int(time) % 60;
      double rest = time - (min * 60 + sec);
      switch(mtcType) {
            case 0:     // 24 frames sec
                  rest *= 24;
                  break;
            case 1:     // 25
                  rest *= 25;
                  break;
            case 2:     // 30 drop frame
                  rest *= 30;
                  break;
            case 3:     // 30 non drop frame
                  rest *= 30;
                  break;
                  }
      int frame = int(rest);
      int subframe = int((rest-frame)*100);
      QString s;
      s.sprintf("%03d:%02d:%02d:%02d", min, sec, frame, subframe);
      return s;
      }

//---------------------------------------------------------
//   text
//---------------------------------------------------------

QString ClipItem::text(int col) const
      {
      QString s("");
      if (_wf) {
            switch(col) {
                  case COL_NAME:
                        s = _wf->name();
                        break;
                  case COL_POS:
                  case COL_LEN:
                        break;
                  case COL_REFS:
                        s.setNum(_wf->references());
                        break;
                  }
            }
      else if (_clip) {
            switch(col) {
                  case COL_NAME:
                        s = _clip->name();
                        break;
                  case COL_REFS:
                        s.setNum(_clip->references());
                        break;
                  case COL_POS:
                        s = samples2smpte(_clip->spos());
                        break;
                  case COL_LEN:
                        s = samples2smpte(_clip->samples());
                        break;
                  }
            }
      return s;
      }

//---------------------------------------------------------
//   ClipListEdit
//---------------------------------------------------------

ClipListEdit::ClipListEdit()
   : TopWin(0, "cliplist", WType_TopLevel /*|WDestructiveClose*/)
      {
      setCaption(tr("MusE: Clip List Editor"));
      curClip = 0;

      editor = new ClipListEditorBase(this, "edit");
      setCentralWidget(editor);

      editor->view->setColumnAlignment(COL_REFS, AlignRight);

      QFontMetrics fm(editor->view->font());
      int fw = style().pixelMetric(QStyle::PM_DefaultFrameWidth, this);
      int w  = 2 + fm.width('9') * 9 + fm.width(':') * 3 + fw * 4;
      editor->view->setColumnAlignment(COL_POS, AlignRight);
      editor->view->setColumnWidth(COL_POS, w);
      editor->view->setColumnAlignment(COL_LEN, AlignRight);
      editor->view->setColumnWidth(COL_LEN, w);

      connect(editor->view, SIGNAL(selectionChanged()), SLOT(clipSelectionChanged()));
      connect(editor->view, SIGNAL(clicked(QListViewItem*)), SLOT(clicked(QListViewItem*)));

      connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
      connect(editor->start, SIGNAL(valueChanged(const Pos&)), SLOT(startChanged(const Pos&)));
      connect(editor->len, SIGNAL(valueChanged(const Pos&)), SLOT(lenChanged(const Pos&)));

      updateList();
      }

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

void ClipListEdit::updateList()
      {
      editor->view->clear();

      for (iSndFile f = SndFile::sndFiles.begin(); f != SndFile::sndFiles.end(); ++f) {
            SndFile* wf = *f;
            ClipItem* fi = new ClipItem(editor->view, wf);
            fi->setOpen(true);
            for (iClip c = waveClips->begin(); c != waveClips->end(); ++c) {
                  Clip* clip = *c;
                  if (clip->file1() == wf) {
                        new ClipItem(fi, clip);
                        }
                  }
            }
      }

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

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

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

void ClipListEdit::songChanged(int)
      {
      updateList();
      }

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

void ClipListEdit::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 == "topwin")
                              TopWin::readStatus(xml);
                        else
                              xml.unknown("CliplistEdit");
                        break;
                  case Xml::TagEnd:
                        if (tag == "cliplist")
                              return;
                  default:
                        break;
                  }
            }
      }

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

void ClipListEdit::writeStatus(int level, Xml& xml) const
      {
      xml.tag(level++, "cliplist");
      TopWin::writeStatus(level, xml);
      xml.etag(level, "cliplist");
      }

//---------------------------------------------------------
//   startChanged
//---------------------------------------------------------

void ClipListEdit::startChanged(const Pos& pos)
      {
      if (curClip == 0)
            return;
      curClip->setSpos(pos.posSample());
      editor->view->triggerUpdate();
      }

//---------------------------------------------------------
//   lenChanged
//---------------------------------------------------------

void ClipListEdit::lenChanged(const Pos& pos)
      {
      if (curClip == 0)
            return;
      curClip->setSamples(pos.posSample());
      editor->view->triggerUpdate();
      }

//---------------------------------------------------------
//   clipSelectionChanged
//---------------------------------------------------------

void ClipListEdit::clipSelectionChanged()
      {
      ClipItem* item = (ClipItem*)(editor->view->selectedItem());
      curClip = item->clip();
      if (item == 0 || curClip == 0) {
            curClip = 0;
            editor->start->setEnabled(false);
            editor->len->setEnabled(false);
            return;
            }
      editor->start->setEnabled(true);
      editor->len->setEnabled(true);
      Pos pos, len;
      pos.setType(Pos::SAMPLES);
      len.setType(Pos::SAMPLES);
      pos.setPosSample(curClip->spos());
      len.setPosSample(curClip->samples());
      editor->start->setValue(pos);
      editor->len->setValue(len);
      }

//---------------------------------------------------------
//   clicked
//---------------------------------------------------------

void ClipListEdit::clicked(QListViewItem*)
      {
//      printf("clicked\n");
      }

