/***************************************************************************
                          MIDIIO.cpp  -  description
                             -------------------
    begin                : Die Feb 1 2005
    copyright            : (C) 2005 by klaus frieler
    email                : kgf@omniversum.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
#include "types.h"
#include "FileReader.h"
#include "Melody.h"
#include "MIDITime.h"

#include "jdkmidi/world.h"
#include "jdkmidi/fileread.h"
#include "jdkmidi/fileshow.h"
#include "MIDIMelodyAdapter.h"
#include "MIDIFileAnalyzer.h"
#include "MIDIWriter.h"

using namespace jdkmidi;

bool MIDIIO::analyze(const string& inFile)
{
   MIDIFileReadStreamFile rs( inFile.c_str() );
   MIDIFileAnalyzer analyzer;
   MIDIFileRead reader2( &rs, &analyzer);
   if(!reader2.Parse()){
      setErrorText(analyzer.getErrText());
      return false;
   }
   //cout<<"File: "<<inFile.c_str()<<endl;
   analyzer.dump();
   analyzer.analyze();
   if(!analyzer.isWellFormed()){
      setErrorText("MIDI source not usable.");
      return false;
   }
   m_nTrkNum = analyzer.selectTrack();
   m_nSigTrkNum = analyzer.getSigTrkNum();
   //nTrkNum = 5;
   return m_nTrkNum != -1;   
}

bool MIDIIO::read(const string& inFile, Melody** ppMelody )
{
   MIDIFileReadStreamFile rs( inFile.c_str() );

   if(!ppMelody || !m_pParam) {
      setErrorText("Internal error: Invalid pointer");
      return false;
   }

   *ppMelody = new Melody;
   if(!*ppMelody) return false;
   
   MIDIMelodyAdapter adapter(*ppMelody);
   MIDIFileRead reader( &rs, &adapter );

   if(!analyze(inFile)){
      return false;
   }
   //set data
   adapter.setTrackNum(m_nTrkNum);
   adapter.setSigTrackNum(m_nSigTrkNum);
   adapter.setCut(m_pParam->getCut());
   //use default if no tempo track is present
   adapter.setTempo(m_pParam->getTempo());
   adapter.setQuantization(m_pParam->getQuantization());
   adapter.setIgnoreTempoChanges(m_pParam->getIgnoreTempoChanges());
   cout<<"Extracting track "<<m_nTrkNum<<"..."<<endl;
   if(!reader.Parse()){
      setErrorText(adapter.getErrText());
      return false;
   }
   Melody *pMelody = *ppMelody;
   if(pMelody->empty()) {
      cout<<"Melody empty."<<endl;
      return false;
   }
   pMelody->check(m_pParam->getQuantization());
   //pMelody->dump();
   //pMelody->dumpStatistics();
   
   return true;
}

bool MIDIIO::write(const string& outFile, const Melody* pMelody)
{
   MIDIWriter writer(outFile, pMelody, 0, 1);
   if(!writer.write()){
      setErrorText(writer.getErrText());
      return false;
   }
   return true;
}
