#include <applications/dialog/HomeDialog.h>
#include <applications/dialog/SettingDialog.h>
#include <hal/devices.h>
#include <cstdio>
#include <hal/drivers/adc.h>
#include <cmath>
#include <hal/drivers/buzzer.h>

CHomeDialog HomeDialog;

using namespace std;

void CHomeDialog::OnCreat(void)
{
	conductivity = 0;
	temperature = 25;
	rtd_wire = -1;
	rtd_type = -1;

	OnDraw();
}

void CHomeDialog::OnButtonDown(void)
{
	p_dialog = &SettingDialog;
	p_dialog->OnCreat();
}

void CHomeDialog::OnConductivity(void)
{
	adc_file adc;
	decltype(flash_file::cell_const) k;
	decltype(flash_file::temp_coef) conf;

	fseek(p_flash, (int) (&p_flash_file->cell_const) - (int) (p_flash_file), SEEK_SET);
	fread(&k, sizeof(flash_file::cell_const), 1, p_flash);

	fseek(p_flash, (int) (&p_flash_file->temp_coef) - (int) (p_flash_file), SEEK_SET);
	fread(&conf, sizeof(flash_file::temp_coef), 1, p_flash);

	rewind(p_adc);
	fread(&adc, sizeof(adc_file), 1, p_adc);

	conductivity = (k * (adc.p_curt - adc.n_curt) / (adc.p_volt - adc.n_volt))
	    * (100 / (100 + conf * (temperature - 25)));

	if (!(isfinite(conductivity) && conductivity >= 1e-24 && conductivity < 1e27))
	{
		beep(100);
	}

	OnDraw();
}

void CHomeDialog::OnRTD(void)
{
	adc_file adc;
	decltype(flash_file::cell_const) k;
	decltype(flash_file::temp_coef) conf;

	fseek(p_flash, (int) (&p_flash_file->cell_const) - (int) (p_flash_file), SEEK_SET);
	fread(&k, sizeof(flash_file::cell_const), 1, p_flash);

	fseek(p_flash, (int) (&p_flash_file->temp_coef) - (int) (p_flash_file), SEEK_SET);
	fread(&conf, sizeof(flash_file::temp_coef), 1, p_flash);

	rewind(p_adc);
	fread(&adc, sizeof(adc_file), 1, p_adc);

	temperature = adc.temp;
	rtd_wire = adc.wire_mode;
	rtd_type = adc.rtd_type;

	conductivity = (k * (adc.p_curt - adc.n_curt) / (adc.p_volt - adc.n_volt))
	    * (100 / (100 + conf * (temperature - 25)));

	if (rtd_wire == -1)
	{
		beep(10);
	}

	OnDraw();
}

void CHomeDialog::OnDraw(void)
{
	rewind(p_lcd);
	fwrite(zeros, 128, 1, p_lcd);
	rewind(p_lcd);

	if (rtd_wire == -1)
	{
		fputs("   RTD Error    ", p_lcd);
		fputs("    use 25\xf8" "C", p_lcd);
	}
	else
	{
		fprintf(p_lcd, " RTD: %iW PT%i", rtd_wire, rtd_type);
		fseek(p_lcd, 20, SEEK_SET);
		fprintf(p_lcd, "%6.2f\xf8" "C", temperature);
	}

	fseek(p_lcd, 32, SEEK_SET);
	fputs("Conductivity:", p_lcd);

	fseek(p_lcd, 51, SEEK_SET);

	if (isfinite(conductivity) && conductivity >= 1e-24 && conductivity < 1e27)
	{
		char prefix[] = "y\0z\0\a\0\f\0p\0n\0u\0m\0\0\0k\0M\0G\0T\0P\0E\0Z\0Y";
		int index = floor(log10(conductivity) / 3);

		float f = conductivity / pow(1000, index);

		if (f < 10)
		{
			fprintf(p_lcd, "%6.4f%sS/cm", f, &prefix[index * 2 + 16]);
		}
		else
		{
			if (f < 100)
			{
				fprintf(p_lcd, "%6.3f%sS/cm", f, &prefix[index * 2 + 16]);
			}
			else
			{
				fprintf(p_lcd, "%6.2f%sS/cm", f, &prefix[index * 2 + 16]);
			}
		}
	}
	else
	{
		fputs("sensor error", p_lcd);
	}

	fflush(p_lcd);
}
