#include <applications/dialog/BaudRateDialog.h>
#include <cstdio>
#include <hal/devices.h>
#include <hal/drivers/buzzer.h>
#include <applications/dialog/SettingDialog.h>
#include <hal/drivers/uart.h>

CBaudRateDialog BaudRateDialog;

#define SIZE(a) (sizeof(a)/sizeof(a[0]))
static const int BAUD_RATE[] = {9600, 19200, 38400, 57600, 115200, 230400, 460800};

void CBaudRateDialog::OnCreat(void)
{
	rewind(p_lcd);
	fwrite(zeros, 128, 1, p_lcd);

	rewind(p_lcd);
	fputs("Baud rate:", p_lcd);

	fseek(p_lcd, 48, SEEK_SET);
	fputs("  Save   Cancel", p_lcd);

	in_edit = false;
	menu_item = br;

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

	OnDraw();
}

void CBaudRateDialog::OnEncoderCW(void)
{
	if (in_edit)
	{
		for (int i = 0; i < SIZE(BAUD_RATE); ++i)
		{
			if (i == SIZE(BAUD_RATE) - 1)
			{
				beep(10);
				return;
			}

			if (baud_rate == BAUD_RATE[i])
			{
				baud_rate = BAUD_RATE[i + 1];
				break;
			}
		}
	}
	else
	{
		switch (menu_item)
		{
		default:
		case br:
			menu_item = save;
			break;
		case save:
			menu_item = cancel;
			break;
		case cancel:
			beep(10);
			return;
			break;
		}
	}

	OnDraw();
}

void CBaudRateDialog::OnEncoderCCW(void)
{
	if (in_edit)
	{
		for (int i = SIZE(BAUD_RATE) - 1; i >= 0; --i)
		{
			if (i == 0)
			{
				beep(10);
				return;
			}

			if (baud_rate == BAUD_RATE[i])
			{
				baud_rate = BAUD_RATE[i - 1];
				break;
			}
		}
	}
	else
	{
		switch (menu_item)
		{
		case br:
			beep(10);
			return;
			break;
		case save:
			menu_item = br;
			break;
		default:
		case cancel:
			menu_item = save;
			break;
		}
	}

	OnDraw();
}

void CBaudRateDialog::OnButtonDown(void)
{
	flash_file * p_flash_file;

	switch (menu_item)
	{
	default:
		menu_item = br;
	case br:
		in_edit = !in_edit;
		break;
	case save:
		fseek(p_flash, (int) (&p_flash_file->baud_rate) - (int) (p_flash_file), SEEK_SET);
		fwrite(&baud_rate, sizeof(flash_file::baud_rate), 1, p_flash);
		fflush(p_flash);
		uart_baud(baud_rate);
	case cancel:
		p_dialog = &SettingDialog;
		p_dialog->OnCreat();
		return;
		break;
	}

	OnDraw();
}

void CBaudRateDialog::OnDraw(void)
{
	fseek(p_lcd, 100, SEEK_SET);
	fwrite(zeros, 6, 1, p_lcd);

	fseek(p_lcd, 112, SEEK_SET);
	fwrite(zeros, 16, 1, p_lcd);

	fseek(p_lcd, 36, SEEK_SET);
	fprintf(p_lcd, "%6ibps", baud_rate);

	switch (menu_item)
	{
	default:
		menu_item = br;
	case br:
		fseek(p_lcd, 100, SEEK_SET);
		if (in_edit)
		{
			fputs("\2\2\2\2\2\2", p_lcd);
		}
		else
		{
			fputs("\1\1\1\1\1\1", p_lcd);
		}
		break;
	case save:
		fseek(p_lcd, 112, SEEK_SET);
		fputs("\1\1\1\1\1\1\1\1", p_lcd);
		break;
	case cancel:
		fseek(p_lcd, 120, SEEK_SET);
		fputs("\1\1\1\1\1\1\1\1", p_lcd);
		break;
	}

	fflush(p_lcd);
}

