/********************************************************************
//
//
// PanoHead Verze 1.03
//
// 16.5.2011 - 15:06
//
// Michal Hruby 2011
//
//
//
********************************************************************/

//-------------------------------------------------------------------
// DEFINICE konstant
//-------------------------------------------------------------------

#define F_CPU 8000000UL		// frekvence hodinového signálu (nutné pro delay.h)

#define MAX_OHNISKO	200		// Maximalni velikost ohniska
#define MAX_OVERLAP	70		// Maximalni velikost presahu snimek
#define MAX_AXIS_X	360		// Maximalni velikost uhlu na osy X
#define MAX_AXIS_Y	50		// Maximalni velikost uhlu na osa Y


//-------------------------------------------------------------------
// INCLUDE souboru
//-------------------------------------------------------------------

#include <avr/pgmspace.h>	// hlavickovy soubor pro praci s FLASH
#include <avr/io.h>			// hlavickovy soubor pro mikrokontroler ATmega
#include <util/delay.h>		// hlavickový soubor pro zpoždění


//-------------------------------------------------------------------
// GLOBALNI PROMENNE
//-------------------------------------------------------------------

char item_menu=1;			// pozice v menu
char can_exit=1; 			// umoznuje opustit while pro zacykleni
char skip_wait=0; 			// umoznuje preskoceni cekani na zmacknuti klavese



//-------------------------------------------------------------------
// FUNKCE
//-------------------------------------------------------------------

// Nutnost umistit mimo knihovnu - vracelo spatny vysledek 
float decodeADC(char adc_value){
	/***************************************************************
	Prepocita ADC hodnotu baterie na volty
	
	Argumenty:
	1)char adc_value : hodnota AD prevodniku

	Navratova hodnota:
	cislo typu float - hodnota ve Voltech

	Priklad vypoctu: ADC=720 ; ACD_REFERENCE=5V ; Delic 1:3
	 (720*5*4/1024)= 14,06 V

	Pozn: bylo nutno pretypovat vsechny prvky 
	****************************************************************/

	return ((float)adc_value/(float)256)*(float)20;

}


void InitMCU(){
	/***************************************************************

	Provede zakladni inicializaci po zapnuti/restartu

	****************************************************************/
	motors_disa();			// Deaktivuje motory
	DDRB=0b11111111; 		// PORTB = vystupni
	PORTB=0b00000000;  	 	// PORTB = vystupy do 0
	initADC();				// inicializace AD prevodniku
	foto_init();			// inicializace komunikace s fotoaparatem		
	lcd_init();				// inicializace LCD

}



//-------------------------------------------------------------------
// MAIN FUNKCE
//-------------------------------------------------------------------



int main(void)
{
	/***************************************************************
	
	Hlavni smycka programu

	****************************************************************/

	InitMCU();				// inicializece procesoru po restartu/zapnuti

							// Nastaveni defaultnich parametru pro panorama
	int ohnisko = 50;	
	int presah = 20;		
	int osaX = 45;			
	int osaY = 10;			

	char key=0;		 		// neni stisnuta klavesa

	// UVITACI OBRAZOVKA
	lcd_lines_print("     PANOHEAD","      v.1.03");
	
	// kontrola baterie + ikona
	lcd_goXY(19, 0);
	lcd_batery_print(batery_check(averageADC(10)));

	_delay_ms(500);			// pauza

	lcd_goXY(14, 1);
	lcd_print_s("Moment");

	//nastaveni motoru do domovske polohy
	motor_startup();
				
	while(1){				// nekonecna smycka programu
	
	int pocetY = 0;			// pocet fotek X
	int pocetX = 0;			// pocet rad Y

	
	switch (item_menu)		// Vykresleni obrazovky podle polohy v menu
		{
			motors_disa();
		  	case 1:			// Hlavni menu
					lcd_lines_print("* -AUTOMATICKY REZIM","  -MANUALNI REZIM");
					break;

	  		case 2:			// Hlavni menu
					lcd_lines_print("  -AUTOMATICKY REZIM","* -MANUALNI REZIM");
					break;

	  		case 3:			// Hlavni menu
					lcd_lines_print("  -MANUALNI REZIM","* -VERZE PANOHEAD");
					break;

			case 4:			// Hlavni menu
					lcd_lines_print("  -VERZE PANOHEAD","* -DEBUG");
					break;

			case 10:		// AUTOMATICKY rezim - obrazovka 1
					ohnisko = input_screen(ohnisko, "Ohnisko:", "mm", MAX_OHNISKO);
					break;

			case 11:		// AUTOMATICKY rezim - obrazovka 2
					presah = input_screen(presah, "Presah:", "procent", MAX_OVERLAP);
					break;

			case 12:		// AUTOMATICKY rezim - obrazovka 3
					osaX = input_screen(osaX, "OsaX:", "stupnu", MAX_AXIS_X);
					break;

			case 13:		// AUTOMATICKY rezim - obrazovka 4
					osaY = input_screen(osaY, "OsaY:", "stupnu", MAX_AXIS_Y);
					break;

			case 14:		// AUTOMATICKY rezim - obrazovka 5
					
					lcd_lines_print("Pocitam...","");		// Pocitani poctu fotek pro zadane parametry

					//osetreni nulovych vstupu
					if(ohnisko==0){	
						ohnisko=1;
					}
					if(presah==0){
						presah=1;
					}
					if(osaX==0){
						osaX=1;
					}
					if(osaY==0){
						osaY=1;
					}

					pocetY = make_pano_XY(1, ohnisko, presah, osaY, osaX);	// Pocet rad Y
					
					pocetX = make_pano_X(1, ohnisko, presah, osaX);			// Pocet fotek X

					lcd_goXY(0, 0);				
					lcd_print_int(pocetY,3);			// Zobrazi pocet rad Y
					lcd_print_s(" x ");	
					lcd_goXY(6, 0);			
					lcd_print_int(pocetX,3);			// Zobrazi pocet fotek X

					set_shots_total(pocetX*pocetY);		// Ulozi celkovy pocet fotek pro pozdejsi pouziti

					lcd_print_s(" = ");					
					lcd_print_int((char)get_shots_total(),4);	// Zobrazi celkovy pocet fotek

					lcd_goXY(0, 1);
					lcd_print_s("(Y  x  X )  SPUSTIT?");
					break;

			case 15:	// AUTOMATICKY rezim - obrazovka 6
					
					lcd_lines_print("Zahajuji foceni...","");
					lcd_goXY(19, 0);
					lcd_batery_print(batery_check(averageADC(10)));	// Kontrola baterie + ikona
					//----------------------------------------------
					make_pano_XY(0, ohnisko, presah, osaY, osaX);	// SPUSTI PANORAMA	//panorama_xhruby00.c
					//----------------------------------------------
					item_menu=menu_forw(item_menu);
					can_exit=1;  		// umozni opustit zacykleni cekajici na stisk klavesy
					skip_wait=1;		// umozni preskoceni zacykleni cekajici na tlacitko
					break;

			case 16:	// AUTOMATICKY rezim - obrazovka 6
					lcd_lines_print("   *** HOTOVO ***","  OPAKOVAT CYKLUS?");
			break;


			case 20:	// AUTOMATICKY rezim - obrazovka 6
					lcd_lines_print("Manualni ovladani", "stisknuto:");
					//---------------------------------------------
					manual_control();								// SPUSTI RUCNI OVLADANI //menu.xhruby00.c
					//---------------------------------------------
	    	break;

			case 30:	// VERZE - obrazovka 1
					lcd_lines_print("Michal Hruby", "verze 1.03");

	    	break;

			case 40:	// DEBUG - obrazovka 1
					lcd_lines_print("Optozavora:", "Baterie:");
	
					// STAV optozavory
					if(opto_check()){			
						lcd_goXY(12,0);
						lcd_print_s("CLOSE");
					}else{
						lcd_goXY(12,0);
						lcd_print_s("FREE ");
					}
					
					// STAV baterie - Volty
					lcd_goXY(9, 1);
					lcd_print_float((float)decodeADC(averageADC(10)), 2); lcd_print_s(" V");

					lcd_goXY(19, 0);
					lcd_batery_print(batery_check(averageADC(10))); // stav baterie + ikona

					skip_wait=1;	// umozni preskoceni zacykleni cekajici na tlacitko

	    			break;

		
			default: // Neexistujici polozka menu - presmerovani do hlavniho menu
					lcd_lines_print("ERROR 404... moment", "presmerovani do menu");
					item_menu=1;
					_delay_ms(2500); 	// casova prodleva
					skip_wait=1;		// umozni preskoceni zacykleni cekani na tlacitko
										// z duvodu potreby znovu prekresleni menu
	    			break;

		}
		
		// Zacykleni - cekani na stisk tlacitka
		if(skip_wait!=1) //pokud je 0 - provede se zacykleni s cekanim na zmacknuti tlacitka
		{
			do{		// dokud neni stiksnuto tlacitko - cekej
				_delay_ms(1);
			}
			while(keypad_read()==0); 	// pokud neni stiknuta klavesa bezi nekonecna smycka
								 		// to z duvodu, aby se zabranilo zbytecnemu 
								 		// prepisovani displeje
		}

			key=keypad_read();			// cti, ktere tlacitko bylo stiknuto
			if(key!=0)					// pokud bzlo opravdu nejake stisknuto
			{
				
				switch(keypad_decode(key)){	// akce podle stiknuteho tlacitka
				case '2':
						item_menu=menu_dec(item_menu);	// Nahoru
						break;
				case '5':
						item_menu=menu_forw(item_menu); // Potvrzeni
						break;
				case '8':
						item_menu=menu_inc(item_menu);	// Dolu
						break;
				case '#':
						item_menu=menu_forw(item_menu); // Potvrzeni
						break;
				case '*':
						item_menu=menu_back(item_menu);	// Zpet
						can_exit=1;  					// umozni opustit zacykleni
						break;
								
				}
				 
			}
		_delay_ms(200); 				// cekej 
		

	}


	while(1);		// nekonecna smycka - posledni zachrany
		
}

	
