/***************************************************************************
 * midi.h: implementation of Midi class
 *
* This file is part of KTabEdit, a KDE tabulature editor
 *
 * copyright (C) 2003-2006 the KTabEdit development team <mrgwen@gmail.com>
 * copyright (C) 2002-2003 the KGuitar development team <mrgwen@gmail.com>
 ***************************************************************************/

/***************************************************************************
 * 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.
 *
 * See the file COPYING for more information.
 ***************************************************************************/

#ifndef MIDI_H
#define MIDI_H

#include <QDataStream>
#include <QFile>
#include <QList>
#include <QVector>

#include "fileimport.h"
#include "fileexport.h"

class TabSong;
class TabTrack;

class Midi : public FileImport, public FileExport
{
public:
	Midi();
	virtual ~Midi();
	
	bool loadFile(const QString& fileName);
	bool saveFile(const QString& fileName, const TabSong& tabSong);
private:
	class MidiEvent {
		public:
			MidiEvent() : mMetaEvent(false)
			{};
			
		enum Event {
			SequenceNumber, Text, Copyright, TrackName, Instrument, Lyric, Marker, CuePoint, MidiPort, EndOfTrack, Tempo,
			SMPTE, TimeSignature, NoteOff, NoteOn, PolyAfterTouch, ControlerChange, PitchBend, ProgramChange, ChannelPressure,
			Unknown
		};
		
		bool mMetaEvent;
		Event mEvent;
		unsigned long mDeltaTime;
		QVector<Q_UINT8> mArrayByte;
	};
	
	QString vectorToQString(const QVector<Q_UINT8>& array);
	
	uint readTrackChunk();
	uint readChunk();
	
	unsigned long readMidiNumber();
	QVector<Q_UINT8> readString();
	QVector<Q_UINT8> readByte(uint numberOfByte);
	
	void readMidiHeader();
	QVector<Midi::MidiEvent> readMidiTrack();
	
	uint findNoteOff(Q_UINT8 noteOn, uint start, const QVector<Midi::MidiEvent>& midiEvent);
	void addTime(TabTrack* tabTrack, Q_UINT8 note, unsigned long duration);
	TabTrack* parseMidiTrack(const QVector<Midi::MidiEvent>& midiEvent, TabSong* tabSong);
	
	QFile mFile;
	QDataStream mStream;
	Q_UINT16 mMidiFormat;
	Q_UINT16 mTrackNum;
	Q_UINT16 mDivisions;
	QList<QVector< Midi::MidiEvent> > mMidiSong;
};

#endif
