/*
 * Kangaroo Punch MultiPlayer Game Server Mark II
 * Copyright (C) 2020-2021  Scott Duensing
 *
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */


#include "timer.h"
#include "task.h"
#include "gui.h"


#define SECONDS_IN_DAY    86400
#define TICKS_PER_SECOND  18.2
#define TICKS_PER_DAY     (SECONDS_IN_DAY * TICKS_PER_SECOND)


uint8_t __timerQuarterSecondTick = 0;
uint8_t __timerHalfSecondTick    = 0;
uint8_t __timerSecondTick        = 0;

uint8_t __timerQuarterSecondOn = 0;
uint8_t __timerHalfSecondOn    = 0;
uint8_t __timerSecondOn        = 0;


static long    _timerLast       = 0;
static uint8_t _timerHalfSecond = 2;
static uint8_t _timerSecond     = 2;


void timerShutdown(void) {
	// Nothing yet.
}


void timerStartup(void) {
	_timerLast = biostime(0, 0);
}


void timerUpdate(void) {
	long now;
	long delta;

	now = biostime(0, 0);

	// Reset ticks.
	__timerQuarterSecondTick = 0;
	__timerHalfSecondTick    = 0;
	__timerSecondTick        = 0;

	// Ensure we haven't rolled past midnight between calls.
	if (now >= _timerLast) {
		delta = now - _timerLast;
	} else {
		// Compensate for midnight rollover.
		delta = (now + TICKS_PER_DAY) - _timerLast;
	}

	// Everything ticks off the quarter second.
	if (delta > TICKS_PER_SECOND * 0.25) {
		_timerLast = now;

		// Quarter Second timer.
		__timerQuarterSecondOn = !__timerQuarterSecondOn;
		__timerQuarterSecondTick = 1;

		// Half Second timer.
		if (--_timerHalfSecond == 0) {
			_timerHalfSecond = 2;
			__timerHalfSecondOn = !__timerHalfSecondOn;
			__timerHalfSecondTick = 1;

			// Second timer
			if (--_timerSecond == 0) {
				_timerSecond = 2;
				__timerSecondOn = !__timerSecondOn;
				__timerSecondTick = 1;
			} // Second.

		} // Half Second.

	} // Quarter Second.
}


void timerQuarterSecondsWait(uint8_t quarterSeconds) {
	uint8_t counter = 0;

	while (counter <= quarterSeconds && !guiHasStopped()) {
		if (__timerQuarterSecondTick) {
			counter++;
		}
		taskYield();
	}
}
