#include "binary.hpp"
#include "packet.hpp"
#include "scheduler.hpp"
#include "../midifile/include/MidiFile.h"
#include <ostream>
#include <sstream>

unsigned binary::process(std::ostream& dst, const char* path) {
	smf::MidiFile midifile;
	midifile.read(path);
	midifile.doTimeAnalysis();
	midifile.joinTracks();

	Scheduler scheduler(midifile.getTimeInSeconds(1));
	auto& track = midifile[0];
	unsigned ticks_last = 0;
	unsigned notes_added = 0;

	for(int i = 0; i < track.size(); i++) {
		smf::MidiEvent& note = track[i];

		if(!note.isNote()) {
			continue;
		}

		smf::MidiEvent& note_end = *note.getLinkedEvent();
		scheduler.add_note(note.getKeyNumber(), note.tick, note.isNoteOn());
		notes_added++;
	}
	
	scheduler.finalise(dst);
	return notes_added;
}

bool binary::process_all(std::string& dst, int argc, char **argv) {
	if(argc > 2) {
		std::stringstream ss;
		for(int i = 2; i < argc; i++) {
			binary::process(ss, argv[i]);
		}
		binary::finalize(ss);
		dst = std::move(ss.str());
		return true;
	}

	else if(argc == 2) {
		dst = std::string(std::istreambuf_iterator<char>(std::cin), std::istreambuf_iterator<char>());
		return true;
	}

	else {
		return false;
	}
}

void binary::finalize(std::ostream &dst) {
	packet::Generic(packet::Type::stop).finalise(dst);
}