/*
 * kbd.c
 *
 *  Created on: Mar 7, 2012
 *      Author: qwer1
 */

#include "kbd.h"
#include "ul_kbd.h"
#include "ind.h"
#include "config.h"
#include "process.h"
#include "sound.h"

void setup_kbd(void) {
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // disable SWD pins
	GPIO_StructInit(&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//start keyboard thread
	ptx_add(pt_kbd, NULL, PTX_FLAG_RUN | PTX_FLAG_SYNC_10MS);
}

U8 kbd_read(void) {
	return (!*BITP(&GPIOA->IDR, 14)) | (!(*BITP(&GPIOA->IDR, 13)) << 1);
}

PT_THREAD( pt_kbd( struct pt *pt, struct ptx *ptx ) ) {
	PT_BEGIN(pt);

	while (1) {
		//read keyboard state
		kbd_buf[1] = kbd_read();

		//update keyboard buffers
		kbd_update();

		//DOWN short press - disable sound
		if ((ind_mode == IND_MO_NORMAL)&&(kbd_press(KBD_CO_DOWN, KBD_PR_SHORT))) {
//			sound_start(SOUND_MO_NONE);
		}

		struct program_step_struct *step = &config.programs[config.current_program][config.current_step];

		//STOP work mode
		if (!process.run) {

			//NORMAL indication mode
			if (ind_mode == IND_MO_NORMAL) {

				//SETUP key press - select next parameter
				if (kbd_press2(KBD_CO_SETUP, KBD_PR_SHORT, KBD_PR_LONG)) {
					if (kbd_cnt == KBD_PR_LONG) edit_param = 0;
					else {
						if (edit_param == EDIT_PARAM_NONE) edit_param = EDIT_PARAM_STEP;//EDIT_PARAM_STEP_TIME;
						else {
							if (++edit_param > EDIT_PARAMS) {
								edit_param = EDIT_PARAM_NONE;
							} else {
								if (config_updates())
									config_update_wait();
							}
						}
					}
				}

				//SETUP long key press - go to parameters edit mode
				else if (kbd_press(KBD_CO_SETUP, KBD_PR_LONGLONG)) {
					edit_param = EDIT_PARAM_NONE;
					ind_mode = IND_MO_CONFIG;
				}

				//UP key press
				else if (kbd_press2(KBD_CO_UP, KBD_PR_SHORT, KBD_PR_LONG)) {
					if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

					//increment program number
//					if (edit_param == EDIT_PARAM_PROGRAM) {
//						if (++config.current_program >= PROGRAMS_NUM)
//							config.current_program = 0;
//						config_update_wait();
//					}

					//increment step number
					if (edit_param == EDIT_PARAM_STEP) {
						INC_ROLL(config.current_step, 0, PROGRAM_STEPS_NUM-1);
					}

					//increment step time
					else if (edit_param == EDIT_PARAM_STEP_TIME) {
						INC_ROLL(step->time, 0, PROGRAM_STEP_TIME_MAX);
						config_update_wait();
					}

					//increment temperature
					else if ((edit_param >= EDIT_PARAM_STEP_T1)&&(edit_param <= EDIT_PARAM_STEP_T4)) {
						INC_ROLL(step->t_set[edit_param - EDIT_PARAM_STEP_T1], 0, PROGRAM_STEP_T_MAX);
						config_update_wait();
					}

					//no parameter selected - select next program
					else if (edit_param == EDIT_PARAM_NONE) {
						INC_ROLL(config.current_program, 0, PROGRAMS_NUM-1);
						config.current_step = 0;
						config_update_wait();
					}

				}

				//DOWN key press
				else if (kbd_press2(KBD_CO_DOWN, KBD_PR_SHORT, KBD_PR_LONG)) {
					if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

					//decrement program
//					if (edit_param == EDIT_PARAM_PROGRAM) {
//						if (config.current_program == 0)
//							config.current_program = PROGRAMS_NUM - 1;
//						else config.current_program--;
//						config_update_wait();
//					}

					//decrement step
					if (edit_param == EDIT_PARAM_STEP) {
						DEC_ROLL(config.current_step, 0, PROGRAM_STEPS_NUM-1);
					}

					//decrement step time
					else if (edit_param == EDIT_PARAM_STEP_TIME) {
						DEC_ROLL(step->time, 0, PROGRAM_STEP_TIME_MAX);
						config_update_wait();
					}

					//decrement temperature
					else if ((edit_param >= EDIT_PARAM_STEP_T1)&&(edit_param <= EDIT_PARAM_STEP_T4)) {
						DEC_ROLL(step->t_set[edit_param - EDIT_PARAM_STEP_T1], 0, PROGRAM_STEP_T_MAX);
						config_update_wait();
					}

					//no parameter selected - select previous program
					else if ((edit_param == EDIT_PARAM_NONE)&&(kbd_cnt == KBD_PR_SHORT)) {
						DEC_ROLL(config.current_program, 0, PROGRAMS_NUM-1);
						config.current_step = 0;
						config_update_wait();
					}
					
					//					//no parameter selected - select next step
					//					else if ((edit_param == EDIT_PARAM_NONE)&&(kbd_cnt == KBD_PR_SHORT)) {
					//						if (++config.current_step >= PROGRAM_STEPS_NUM)
					//							config.current_step = 0;
					//					}

					//no parameter selected, long press - start current profile
					else if ((edit_param == EDIT_PARAM_NONE)&&(kbd_cnt == KBD_PR_LONG - KBD_PR_AUTO)) {
						kbd_cnt = KBD_PR_LONG + 1;
						process.run = 1;
						process.pause = 0;

						//select next program
						INC_ROLL(config.current_program, 0, PROGRAMS_NUM-1);

						//restart regulator task
						process_restart();
					}

				}
			}
		}

		//RUN work mode
		else if (process.run) {

			if (ind_mode == IND_MO_NORMAL) {

				//DOWN key press
				if (kbd_press2(KBD_CO_DOWN, KBD_PR_SHORT, KBD_PR_LONG)) {
					if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

					if (edit_param == EDIT_PARAM_NONE) {

						//short press - pause/unpause
						if (kbd_cnt == KBD_PR_SHORT) {
							if (process.pause) {
								process.pause = 0;
								ptx_start(ptx_process);
								snd_buf_add(SND_STEP_PAUSE);
							} else {
								process.pause = 1;
								ptx_stop(ptx_process);
								snd_buf_add(SND_STEP_PAUSE);
							}
						}

						//LONG press - goto STOP work mode
						else if (kbd_cnt == KBD_PR_LONG - KBD_PR_AUTO) {
							kbd_cnt = KBD_PR_LONG + 1;
							process.run = 0;

							//play stop sound
							snd_buf_add(SND_STEP_STOP);

							//restart regulator thread
							process_restart();
						}
					} else if ((edit_param >= EDIT_PARAM_STEP_T1)&&(edit_param <= EDIT_PARAM_STEP_T4)) {
						U8 i = edit_param - EDIT_PARAM_STEP_T1;
						DEC_ROLL(step->t_set[i], 0, PROGRAM_STEP_T_MAX);
						process.t_set_current[i] = process.t_set_last[i] =
							(step->t_set[i] <= 50) ? step->t_set[i] : step->t_set[i] * 1000UL;
						config_update_wait();
					}
				}

				//UP key press
				else if (kbd_press2(KBD_CO_UP, KBD_PR_SHORT, KBD_PR_LONG)) {
					if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

					if (edit_param == EDIT_PARAM_NONE) {
					} else if ((edit_param >= EDIT_PARAM_STEP_T1)&&(edit_param <= EDIT_PARAM_STEP_T4)) {
						U8 i = edit_param - EDIT_PARAM_STEP_T1;
						INC_ROLL(step->t_set[i], 0, PROGRAM_STEP_T_MAX);
						process.t_set_current[i] = process.t_set_last[i] =
							(step->t_set[i] <= 50) ? step->t_set[i] : step->t_set[i] * 1000UL;
						config_update_wait();
					}
				}

				//SETUP key press
				else if (kbd_press2(KBD_CO_SETUP, KBD_PR_SHORT, KBD_PR_LONG)) {
					if (kbd_cnt == KBD_PR_SHORT) {
						if (step->time == 999) {
							if (edit_param == EDIT_PARAM_NONE)
								edit_param = EDIT_PARAM_STEP_T1;
							else {
								while (++edit_param <= EDIT_PARAM_STEP_T4) {
									if (step->t_set[edit_param - EDIT_PARAM_STEP_T1])
										break;
								}
								if (edit_param > EDIT_PARAM_STEP_T4)
									edit_param = EDIT_PARAM_NONE;
							}
						}
					} else if (kbd_cnt == KBD_PR_LONG) {
						if (edit_param != EDIT_PARAM_NONE) {
							edit_param = EDIT_PARAM_NONE;
						}
					}
				}

				//SETUP long key press - go to parameters edit mode
				else if (kbd_press(KBD_CO_SETUP, KBD_PR_LONGLONG)) {
					edit_param = EDIT_PARAM_NONE;
					ind_mode = IND_MO_CONFIG;
				}
			}
		}

		if (ind_mode == IND_MO_CONFIG) {

			//SETUP key short press - edit value
			if (kbd_press(KBD_CO_SETUP, KBD_PR_SHORT)) {
				ind_mode = IND_MO_CONFIG_ED;
			}

			//SETUP key long press - return to normal mode
			else if (kbd_press(KBD_CO_SETUP, KBD_PR_LONG)) {
				ind_mode = IND_MO_NORMAL;
				config_update_wait();
			}

			//UP key press
			else if (kbd_press2(KBD_CO_UP, KBD_PR_SHORT, KBD_PR_LONG)) {
				if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

				INC_ROLL(param_num, 0, CONFIG_PARAMS_NUM-1);
			}

			//DOWN key press
			else if (kbd_press2(KBD_CO_DOWN, KBD_PR_SHORT, KBD_PR_LONG)) {
				if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

				DEC_ROLL(param_num, 0, CONFIG_PARAMS_NUM-1);
			}

		} else if (ind_mode == IND_MO_CONFIG_ED) {

			//SETUP key short press - select parameter
			if (kbd_press(KBD_CO_SETUP, KBD_PR_SHORT)) {
				ind_mode = IND_MO_CONFIG;
			}

			//SETUP key long press - return to normal mode
			else if (kbd_press(KBD_CO_SETUP, KBD_PR_LONG)) {
				ind_mode = IND_MO_NORMAL;
				config_update_wait();
			}

			//UP key press
			else if (kbd_press2(KBD_CO_UP, KBD_PR_SHORT, KBD_PR_LONG)) {
				if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

				INC_ROLL(config.params[param_num], params_info[param_num].min, params_info[param_num].max);
			}

			//DOWN key press
			else if (kbd_press2(KBD_CO_DOWN, KBD_PR_SHORT, KBD_PR_LONG)) {
				if (kbd_cnt == KBD_PR_LONG) kbd_cnt = KBD_PR_LONG - KBD_PR_AUTO;

				DEC_ROLL(config.params[param_num], params_info[param_num].min, params_info[param_num].max);
			}

		}

		PT_YIELD(pt);
	}
	PT_END(pt);
}
