/src/Clock.cpp
#include "Clock.h"
#include <SDL.h>

Clock::Clock() {
	this->bpm = 128;
	this->slices_per_beat = 4;
	this->beats_per_measure = 4;
	this->recalculate();
	this->start();
}

Clock::Clock(float bpm) {
	this->bpm = bpm;
	this->slices_per_beat = 4;
	this->beats_per_measure = 4;
	this->recalculate();
	this->start();
}

Clock::Clock(float bpm, int slices_per_beat) {
	this->bpm = bpm;
	this->slices_per_beat = slices_per_beat;
	this->beats_per_measure = 4;
	this->recalculate();
	this->start();
}

Clock::Clock(float bpm, int slices_per_beat, int beats_per_measure) {
	this->bpm = bpm;
	this->slices_per_beat = slices_per_beat;
	this->beats_per_measure = beats_per_measure;
	this->recalculate();
	this->start();
}

Clock::~Clock(void) {
}

void Clock::start() {
	this->t_next = this->t_start = SDL_GetTicks();
	this->slice = 0;
	this->tick(this->t_start);
}

int Clock::tick(int t) {
	int start_slice = this->slice;

	while (t >= this->t_next) {
		this->slice++;
		this->t_next = this->t_start + this->ms_per_slice * this->slice;
	}

	return (this->slice - start_slice);
}

void Clock::setBPM(float bpm) {
	if (bpm < 20)
		return;
	this->t_start -= this->slice * (((60000.0 / bpm) - (60000.0 / this->bpm)) / this->slices_per_beat);
	this->bpm = bpm;
	this->recalculate();
}

float Clock::getBPM() {
	return this->bpm;
}

void Clock::setSlicesPerBeat(int slices_per_beat) {
	this->slices_per_beat = slices_per_beat;
	this->recalculate();
}

int Clock::getMeasure() {
	return this->getBeat() / this->beats_per_measure;
}

int Clock::getBeat() {
	return this->slice / this->slices_per_beat;
}

int Clock::getSlice() {
	return this->slice;
}

void Clock::recalculate() {
	this->ms_per_slice = 60000.0 / (this->bpm * this->slices_per_beat);
}