#include "main.h"
#include "generic_macros.h"
#include "lcd.h"
#include "DNI.h"

static uint32_t DNI_read(void)
{
	HAL_ADC_Start(&hadc1);
	if (HAL_ADC_PollForConversion(&hadc1, 100) != HAL_OK)
		PANIC(0x4000);

	return HAL_ADC_GetValue(&hadc1);
}

static int DNI_convert_to_celsius(uint32_t value)
{
	return (2512 - value) << 2;
}

static int DNI_convert_to_fahrenheit(uint32_t value)
{
	return (2953 - value) * 50 / 7;
}

static void DNI_print(int temperature)
{
	int add_sign = temperature < 0;
	if (add_sign)
		temperature = ~(temperature - 1); // if value is not positive, the string conversion will break

	int temp1 = temperature;

	for (int i = 0; i < 2; i++) {
		temperature /= 10;
		display_write_data_byte('0' + (char) (temp1 - temperature * 10));
		temp1 = temperature;
	}

	display_write_data_byte('.');

	for (int i = 0; i < 3; i++) {
		temperature /= 10;
		display_write_data_byte('0' + (char) (temp1 - temperature * 10));
		temp1 = temperature;

		if (temp1 == 0) {
			display_write_data_seq("  ");
			break;
		}
	}

	if (add_sign) {
		DISPLAY_SET_CURSOR(1, 0);
		display_write_data_byte('-');
	}
}

static void DNI_print_celsius(int temperature)
{
	DISPLAY_SET_CURSOR(1, 7);
	DISPLAY_SET_DECREMENT;
	display_write_data_seq("C ");

	DNI_print(temperature);
}

static void DNI_print_fahrenheit(int temperature)
{
	DISPLAY_SET_CURSOR(1, 7);
	DISPLAY_SET_DECREMENT;
	display_write_data_seq("F ");

	DNI_print(temperature);
}

int DNI_show_celsius(void)
{
	DISPLAY_CLEAR;
	DISPLAY_SET_INCREMENT;

	display_write_data_seq("DNI Temperature");

	uint32_t value = DNI_read();
	int temp = DNI_convert_to_celsius(value);
	DNI_print_celsius(temp);

	return 0;
}

int DNI_show_fahrenheit(void)
{
	DISPLAY_CLEAR;
	DISPLAY_SET_INCREMENT;

	display_write_data_seq("DNI Temperature");

	uint32_t value = DNI_read();
	int temp = DNI_convert_to_fahrenheit(value);
	DNI_print_fahrenheit(temp);

	return 0;
}
