#include "common/stdafx.h"
#include "common/util.h"

#include "sound/midiparser.h"
#include "sound/mididrv.h"

#include "tinsel/midi.h"

namespace Tinsel {

Midi::Midi(Audio::Mixer *mixer) {
	MidiFile mf;
	uint32 len;
	uint8 b4[4];

	if(_file.open("midi.dat") == false)
	{
		warning("failed to open midi.dat");
		return;
	}

	_xmidiparser = MidiParser::createParser_XMIDI();

	_file.seek(4); // unknown

	while(_file.read(b4, 4)) {
		len = b4[0] + (b4[1] << 8) + (b4[2] << 16) + (b4[3] << 24);

		mf.file_offset = _file.pos();
		mf.offset = mf.file_offset - 4;
		mf.length = len;

		_mfiles.push_back(mf);

		//debug("midi len: %d\n", len);

		_file.seek(len, SEEK_CUR);
	}

	_mididrv = MidiDriver_ADLIB_create(mixer);
	_mididrv->open();

	_xmidiparser->setMidiDriver(_mididrv);

	_xmidiparser->setTrack(0);
	_xmidiparser->jumpToTick(0);
	_xmidiparser->setTimerRate(_mididrv->getBaseTempo());

	_mididrv->setTimerCallback(_xmidiparser, MidiParser::timerCallback);
}

Midi::~Midi() {
	if(_file.isOpen()) _file.close();
}

bool Midi::loadFile(uint32 offset) {
	byte *buf;
	uint32 len;

	for(Common::Array<MidiFile>::const_iterator mf = _mfiles.begin();
		mf != _mfiles.end();
		mf ++) {

		if(offset == mf->offset) {
			len = mf->length;

			_file.seek(mf->file_offset);

			buf = (byte *)calloc(len, sizeof(byte));
			_file.read(buf, len);

			if(!_xmidiparser->loadMusic(buf, len)) {
				warning("error reading XMIDI track\n");
			}
		}
	}

	return true;
}

}
