/src/Pads.cpp
#include "Pads.h"

Pads::Pads(SDL_Surface* screen) {
	this->screen = screen;

	for (int x = 0; x < 3; x++) {
		for (int y = 0; y < 3; y++) {
			int i = y * 3 + x;
			button[i] = new RButton(x * 100 + (x + 1) * 5, y * 100 + (y + 1) * 5, 100, 100);
		}
	}

	for (int i = 0; i < 9; i++) {
		last_press[i] = 0;
	}

	samples[0] = Mix_LoadWAV("kits/Lunchbox-Detroit/HHt9.wav");
	samples[1] = Mix_LoadWAV("kits/Lunchbox-Detroit/HHo029.wav");
	samples[2] = Mix_LoadWAV("kits/Lunchbox-Detroit/TT019.wav");
	samples[3] = Mix_LoadWAV("kits/Lunchbox-Detroit/TT139.wav");
	samples[4] = Mix_LoadWAV("kits/Lunchbox-Detroit/SD299.wav");
	samples[5] = Mix_LoadWAV("kits/Lunchbox-Detroit/RIM019.wav");
	samples[6] = Mix_LoadWAV("kits/Lunchbox-Detroit/BD179.wav");
	samples[7] = Mix_LoadWAV("kits/Lunchbox-Detroit/SD019.wav");
	samples[8] = Mix_LoadWAV("kits/Lunchbox-Detroit/CLAP029.wav");

	clock = new Clock(128, 4);
	beatChart = new BeatChart(clock);
	beatChart->setPosition(0, screen->h - 10);
	sequencer = new Sequencer(4, 4);
	bpmDisplay = new BPMDisplay();
	bpmDisplay->setPosition(5, 325);

	BPM_change[0] = BPM_change[1] = 0;
}

Pads::~Pads() {
}

void Pads::handleEvents(int t, const SDL_Event& Event) {
    switch (Event.type) {
        // List of keys that have been pressed
        case SDL_KEYDOWN:
            switch (Event.key.keysym.sym) {
                // Escape forces us to quit the app
                // this is also sent when the user makes a back gesture
                case SDLK_ESCAPE:
					sequencer->clearAll();
                    break;
				case SDLK_SPACE:
					clock->start();
					break;
				case SDLK_q:
					clock->setBPM(clock->getBPM() + 1);
					BPM_change[1] = t;
					break;
				case SDLK_a:
					clock->setBPM(clock->getBPM() - 1);
					BPM_change[0] = t;
					break;
				case SDLK_e:
					button[0]->press();
					press_button(0, t);
					break;
				case SDLK_r:
					button[1]->press();
					press_button(1, t);
					break;
				case SDLK_t:
					button[2]->press();
					press_button(2, t);
					break;
				case SDLK_d:
					button[3]->press();
					press_button(3, t);
					break;
				case SDLK_f:
					button[4]->press();
					press_button(4, t);
					break;
				case SDLK_g:
					button[5]->press();
					press_button(5, t);
					break;
				case SDLK_x:
					button[6]->press();
					press_button(6, t);
					break;
				case SDLK_c:
					button[7]->press();
					press_button(7, t);
					break;
				case SDLK_v:
					button[8]->press();
					press_button(8, t);
					break;
            }
            break;

        case SDL_KEYUP:
            switch (Event.key.keysym.sym) {
				case SDLK_q:
					BPM_change[1] = 0;
					break;
				case SDLK_a:
					BPM_change[0] = 0;
					break;
				case SDLK_e:
					last_press[0] = 0;
					break;
				case SDLK_r:
					last_press[1] = 0;
					break;
				case SDLK_t:
					last_press[2] = 0;
					break;
				case SDLK_d:
					last_press[3] = 0;
					break;
				case SDLK_f:
					last_press[4] = 0;
					break;
				case SDLK_g:
					last_press[5] = 0;
					break;
				case SDLK_x:
					last_press[6] = 0;
					break;
				case SDLK_c:
					last_press[7] = 0;
					break;
				case SDLK_v:
					last_press[8] = 0;
					break;
            }
            break;

		case SDL_MOUSEBUTTONDOWN:
			for (int i = 0; i < 9; i++) {
				if (button[i]->testHit(Event.button.x, Event.button.y))
					press_button(i, t);
			}
			break;

		case SDL_MOUSEBUTTONUP:
			for (int i = 0; i < 9; i++)
				last_press[i] = 0;
			break;

        case SDL_QUIT:
            exit(0);
            break;
    }
}

void Pads::update(int t) {
	int tick = clock->tick(t);
	int slice = clock->getSlice();

	for (int i = 0; i < 9; i++) {
		if (last_press[i] != 0 && t - last_press[i] > 500) {
			sequencer->clearChannel(i);
			last_press[i] = 0;
		}
	}

	if (tick > 0) {
		unsigned int c = sequencer->get(slice % 16);
		if (c != 0) {
			for (int i = 0; i < 9; i++) {
				if (c & 1) {
					button[i]->press();
					Mix_PlayChannel(-1, samples[i], 0);
				}
				c >>= 1;
			}
		}
	}
}

void Pads::draw(int t) {
	if (BPM_change[0] != 0 && t - BPM_change[0] > 250) {
		clock->setBPM(clock->getBPM() - 1);
	} else if (BPM_change[1] != 0 && t - BPM_change[1] > 250) {
		clock->setBPM(clock->getBPM() + 1);
	}

	for (int i = 0; i < 9; i++)
		button[i]->update(t);

    glClear (GL_COLOR_BUFFER_BIT);

	for (int i = 0; i < 9; i++)
		button[i]->draw(t);
	beatChart->draw(t);
	bpmDisplay->draw(t, clock->getBPM());
}

void Pads::press_button(int channel, int t) {
	Mix_PlayChannel(-1, samples[channel], 0);
	sequencer->set(clock->getSlice() % 16, channel);
	last_press[channel] = t;
}