/* Knihovna planovace */

/* Standard includes. */
#include <stdint.h>

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

// Include FW knihovny -------------------------------------
#include "stm32f10x_flash.h"	// Kníhovna pro praci s FLASH - pomocne funkce pro knihovnu EEPROM

#include "planovac.h"
#include "eeprom.h"				// Knihovna pro emulaci EEPROM v interni FLASH mikrokontroleru (posledni 2 kb ze 128kb)
#include "My_PWM.h"
#include "My_usart.h"
#include "My_rtc.h"
#include "PIN_config.h"

//#define DEBUG

// Globalni promenne
extern FLASH_Status FlashStatus;
extern const uint16_t EEPROM_VirtAdd[3];

extern volatile uint32_t Planovac_Timestamp;			// Format: [0-16] ... cas ve vternach (17 bitu)
														// 		   [17-21] .. den			  (5 bitu)
														//		   [22-25] .. mesic			  (4 bity)
														//    	   [26-31] .. rok			  (6 bitu)
														// 31       24       16              0
														// RRRRRRMM MMDDDDDC CCCCCCCC CCCCCCCC
extern uint8_t Planovac_Kanal[5];						// [0-6] ... Kanal 1 (0-100%)
														// [0-6] ... Kanal 2 (0-100%)
														// [0-6] ... Kanal 3 (0-100%)
														// [0-6] ... Kanal 4 (0-100%)
														// [0-6] ... Kanal 5 (0-100%)
														// [7] ..... Kanal 6 (0-OFF/1-ON)
extern uint8_t PlanovacStav;
extern uint8_t AutomatickyRezim;
extern uint16_t PWM_max[5];

// Hodiny a datum
extern uint8_t Time_Hodiny;
extern uint8_t Time_Minuty;
extern uint8_t Time_Vteriny;
extern uint8_t Time_Den;
extern uint8_t Time_Mesic;
extern uint16_t Time_Rok;
extern uint8_t Time_DenVTydnu;

/* -------------------------------------------------
 Funkce zkontroluje jestli je jiz cas na provedeni 
 naplanovane zmeny
 ------------------------------------------------ */
void Planovac_CheckPlan(void)
{
	volatile uint32_t AktualniTimestamp;

	if((Planovac_Timestamp==0) | (Planovac_Timestamp==0xFFFFFFFF))		// Neni nic naplanovano
	{
		goto PLANOVAC_CHECKPLAN_KONEC;
	}
	AktualniTimestamp = ((uint32_t)((Time_Rok-2010))<<26);
	AktualniTimestamp |=((uint32_t)(Time_Mesic)<<22);
	AktualniTimestamp |=(((uint32_t)Time_Den)<<17);
	AktualniTimestamp |=((((uint32_t)Time_Hodiny*3600+(uint32_t)Time_Minuty*60+(uint32_t)Time_Vteriny)));

	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > AktualniT: ",0);
		USART1_SendInt32(AktualniTimestamp);		
		USART1_Send("  PlanovacT: ",0);
		USART1_SendInt32(Planovac_Timestamp);
		USART1_Send_Enter();
		USART1_FreeMUTEX();
	#endif

	// Kontrola pro plan zadany bez opakovani v presne datum a cas
	if(AktualniTimestamp>=Planovac_Timestamp )
	{
		if((PlanovacStav&(1<<PLANOVAC_PROVEDENO))==0)
		{													// Nastal cas pro provedeni planu ktery jeste nebyl proveden
			if((Planovac_Kanal[0]<=100)&((AutomatickyRezim&(1<<0))!=0))				// Overeni jestli ma LED1 povoleno měnit nastaveni pomoci planovace
			{				
				PWM_Set_LED_1((PWM_max[0] * (uint16_t)Planovac_Kanal[0])/100);
			}
			if((Planovac_Kanal[1]<=100)&((AutomatickyRezim&(1<<1))!=0))				// Overeni jestli ma LED2 povoleno měnit nastaveni pomoci planovace
			{				
				PWM_Set_LED_2((PWM_max[1] * (uint16_t)Planovac_Kanal[1])/100);
			}
			if((Planovac_Kanal[2]<=100)&((AutomatickyRezim&(1<<2))!=0))				// Overeni jestli ma LED3 povoleno měnit nastaveni pomoci planovace
			{				
				PWM_Set_LED_3((PWM_max[2] * (uint16_t)Planovac_Kanal[2])/100);
			}
			if((Planovac_Kanal[3]<=100)&((AutomatickyRezim&(1<<3))!=0))				// Overeni jestli ma LED4 povoleno měnit nastaveni pomoci planovace
			{				
				PWM_Set_LED_4((PWM_max[3] * (uint16_t)Planovac_Kanal[3])/100);
			}
			if((Planovac_Kanal[4]!=127)&((AutomatickyRezim&(1<<4))!=0))				// Overeni jestli ma LED5 povoleno měnit nastaveni pomoci planovace
			{				
				PWM_Set_LED_5((PWM_max[4] * (uint16_t)(Planovac_Kanal[4]&0x7F))/100);
			}
			if(AutomatickyRezim&(1<<5))											// Overeni jestli ma LED6 povoleno měnit nastaveni pomoci planovace
			{				
				if(Planovac_Kanal[4]&0x80)
				{
					PWM_Set_LED_6_ON();
				}
				else
				{
					PWM_Set_LED_6_OFF();
				}
			}			
			PlanovacStav|=(1<<PLANOVAC_PROVEDENO);								// Nastaveni planu jako provedeneho
			PlanovacStav&=~(1<<PLANOVAC_RESTART);								// Nastaveni po restartu provedeno
		}
	}

PLANOVAC_CHECKPLAN_KONEC:
	if((PlanovacStav&(1<<PLANOVAC_PROVEDENO))|(PlanovacStav&(1<<PLANOVAC_RESTART)))
	{
		Planovac_SearchPlan();
	}
}

/* -------------------------------------------------
 Vyhleda ve FLASH nejblizsi dalsi planovane prepnuti
 a nahraje ho do RAM
 ------------------------------------------------ */
void Planovac_SearchPlan(void)
{
	uint8_t i=0;
	uint16_t temp;
	uint32_t TimeStamp_Nalezen1 = 0xFFFFFFFF;	// Format: [0-16] ... cas ve vternach (17 bitu)
	uint32_t TimeStamp_Nalezen2 = 0xFFFFFFFF;	// 		   [17-21] .. den			  (5 bitu)
	uint32_t TimeStamp_Aktualni = 0;			//		   [22-25] .. mesic			  (4 bity)
												//    	   [26-31] .. rok			  (6 bitu)
												// 31       24       16              0
												// RRRRRRMM MMDDDDDC CCCCCCCC CCCCCCCC		
	uint32_t temp1_32;
	uint32_t temp2_32;
	uint8_t temp_Opak;
	uint32_t temp_Cas=0;
	uint8_t temp_Den=0;
	uint8_t temp_Mesic=0;
	uint16_t temp_Rok=0;
	uint8_t temp_DenVTydnu=0;
	uint8_t temp_ID=0;

	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > Start search",1);							
		USART1_FreeMUTEX();
	#endif

	TimeStamp_Aktualni = ((uint32_t)(Time_Rok-2010))<<26;
	TimeStamp_Aktualni |=((uint32_t)Time_Mesic&0x0F)<<22;
	TimeStamp_Aktualni |=((uint32_t)Time_Den&0x1F)<<17;
	TimeStamp_Aktualni |=((uint32_t)Time_Hodiny*3600+(uint32_t)Time_Minuty*60+(uint32_t)Time_Vteriny)&0x1FFFF;

	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > Aktual TimeStamp: ",0);
		USART1_SendInt32(TimeStamp_Aktualni);
		USART1_Send_Enter();
		USART1_FreeMUTEX();
	#endif
	
	// Prochazeni zaznamu s nastavenym opakovanim
	for(i=0;i<PLANOVAC_MAXZAZNAMU;i++)
	{
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		temp&=0x00FF;
		if(((temp & (1<<PLANOVAC_DENNE))==0) &
		   ((temp & (1<<PLANOVAC_TYDNE))==0) &
		   ((temp & (1<<PLANOVAC_MESICNE))==0) &
		   ((temp & (1<<PLANOVAC_ROCNE))==0) |
		   (temp & (1<<PLANOVAC_DEAKTIVOVAT)))		// Overeni jestli je zaznam opakujici se
		{
			continue;
		}
		temp_Opak=temp;

		// Nacteni dat z FLASH do docasnych promennych		
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		temp1_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		temp1_32|=temp;
		if(temp1_32==0xFFFFFFFF)				// Kontrola jestli neni zaznam smazany (neplatny)
		{
			continue;
		}
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+0), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		temp2_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+1), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		temp2_32|=temp;

		// Overeni jestli neni zaznam jiz prosly		
		if(TimeStamp_Aktualni>temp2_32)
		{
			continue;
		}

		// Vypocet nasledujiciho datumu z opakovani
		if(temp_Opak&(1<<PLANOVAC_DENNE))
		{
			if(TimeStamp_Aktualni<temp1_32)		 
			{									// Pocatecni datum a cas jeste neprobehly -> datum = polozka start
				temp_Rok = ((temp1_32>>26)&0x3F)+2010;
				temp_Mesic = (temp1_32>>22)&0x0F;
				temp_Den = (temp1_32>>17)&0x1F;
			}
			else
			{									// Pocatecni datum a cas jiz probehly -> datum = aktualni datum + dny do stejneho dne v tydnu
				TimeStamp_Nalezen2 = temp1_32;
				Planovac_CompareCandidate(&temp_ID,&i,&TimeStamp_Nalezen1,&TimeStamp_Nalezen2,&TimeStamp_Aktualni);	// Vlozeni starsiho zaznamu (pro obnovu predchoziho stavu po zapnuti, restartu, ...)
				
				temp_Rok = Time_Rok;
				temp_Mesic = Time_Mesic;
				temp_Den = Time_Den;
				temp_Cas = temp1_32 & 0x1FFFF;
				if(GetTimeRAW()>temp_Cas)		// Kontrola jestli jiz neuplynul cas planu
				{
					temp_Den++;					// Posun na nasledujici den
				}
				Planovac_CorectDate(&temp_Rok,&temp_Mesic,&temp_Den);								
			}
			temp_Cas = temp1_32&0x1FFFF;
		}
		else if(temp_Opak&(1<<PLANOVAC_TYDNE))
		{
			if(TimeStamp_Aktualni<temp1_32)		 
			{									// Pocatecni datum a cas jeste neprobehly -> datum = polozka start
				temp_Rok = ((temp1_32>>26)&0x3F)+2010;
				temp_Mesic = (temp1_32>>22)&0x0F;
				temp_Den = (temp1_32>>17)&0x1F;
			}
			else
			{									// Pocatecni datum a cas jiz probehly -> datum = aktualni datum + dny do stejneho dne v tydnu
				TimeStamp_Nalezen2 = temp1_32;
				Planovac_CompareCandidate(&temp_ID,&i,&TimeStamp_Nalezen1,&TimeStamp_Nalezen2,&TimeStamp_Aktualni);	// Vlozeni starsiho zaznamu (pro obnovu predchoziho stavu po zapnuti, restartu, ...)
				
				temp_Rok = Time_Rok;
				temp_Mesic = Time_Mesic;
				temp_Den = Time_Den;
				temp_DenVTydnu = WeekDayEurope(((temp1_32>>26)&0x3F)+2010,(temp1_32>>22)&0x0F,(temp1_32>>17)&0x1F);

				if(temp_DenVTydnu!=Time_DenVTydnu)	// Plan se ma provest v pristich dnech -> vypocitat datum nasledujiciho dne se stejnym dnem v tydnu jako je zacatek ve FLASH
				{
					if(temp_DenVTydnu>WeekDayEurope(Time_Rok,Time_Mesic,Time_Den))		// Osetreni absolutni hodnoty rozdilu aktualniho a pozadovaneho dne v tydnu
					{
						temp_Den+=temp_DenVTydnu-WeekDayEurope(Time_Rok,Time_Mesic,Time_Den);
					} 
					else
					{
						temp_Den+=WeekDayEurope(Time_Rok,Time_Mesic,Time_Den)-temp_DenVTydnu;
					}
					
					Planovac_CorectDate(&temp_Rok,&temp_Mesic,&temp_Den);
				}							
			}
			temp_Cas = temp1_32&0x1FFFF;
		}
		else if(temp_Opak&(1<<PLANOVAC_MESICNE))
		{
			if(TimeStamp_Aktualni<temp1_32)		 
			{									// Pocatecni datum a cas jeste neprobehly -> datum = polozka start
				temp_Rok = ((temp1_32>>26)&0x3F)+2010;
				temp_Mesic = (temp1_32>>22)&0x0F;
				temp_Den = (temp1_32>>17)&0x1F;
			}
			else
			{									// Pocatecni datum a cas jiz probehly -> datum = aktualni datum + dny do stejneho dne v tydnu
				TimeStamp_Nalezen2 = temp1_32;
				Planovac_CompareCandidate(&temp_ID,&i,&TimeStamp_Nalezen1,&TimeStamp_Nalezen2,&TimeStamp_Aktualni);	// Vlozeni starsiho zaznamu (pro obnovu predchoziho stavu po zapnuti, restartu, ...)
				
				temp_Rok = Time_Rok;
				temp_Mesic = Time_Mesic;
				temp_Den = (temp1_32>>17)&0x1F;
				if(Time_Den>temp_Den)			// Kontrola jestli se plan tento mesic uz provedl nebo jeste ne
				{				
					temp_Mesic++;				// Tento mesic se uz provedl -> naplanovat na pristi mesic
				}
				Planovac_CorectDate(&temp_Rok,&temp_Mesic,&temp_Den);
			}
			temp_Cas = temp1_32&0x1FFFF;
		}
		else if(temp_Opak&(1<<PLANOVAC_ROCNE))
		{
			if(TimeStamp_Aktualni<temp1_32)		 
			{									// Pocatecni datum a cas jeste neprobehly -> datum = polozka start
				temp_Rok = ((temp1_32>>26)&0x3F)+2010;
				temp_Mesic = (temp1_32>>22)&0x0F;
				temp_Den = (temp1_32>>17)&0x1F;
			}
			else
			{									// Pocatecni datum a cas jiz probehly -> datum = aktualni datum + dny do stejneho dne v tydnu
				TimeStamp_Nalezen2 = temp1_32;
				Planovac_CompareCandidate(&temp_ID,&i,&TimeStamp_Nalezen1,&TimeStamp_Nalezen2,&TimeStamp_Aktualni);	// Vlozeni starsiho zaznamu (pro obnovu predchoziho stavu po zapnuti, restartu, ...)
				
				temp_Rok = Time_Rok;
				temp_Mesic = (temp1_32>>22)&0x0F;
				temp_Den = (temp1_32>>17)&0x1F;
				if((Time_Mesic>temp_Mesic)|((Time_Mesic==temp_Mesic)&(Time_Den>temp_Den)))
				{
					temp_Rok++;
				}				
				Planovac_CorectDate(&temp_Rok,&temp_Mesic,&temp_Den);
			}
			temp_Cas = temp1_32&0x1FFFF;
		}
		TimeStamp_Nalezen2 = ((((uint32_t)temp_Rok-2010)&0x3F)<<26)| 
							 (((uint32_t)temp_Mesic&0x0F)<<22) | 
						     (((uint32_t)temp_Den&0x1F)<<17) | 
						     ((uint32_t)temp_Cas&0x1FFFF);
		Planovac_CompareCandidate(&temp_ID,&i,&TimeStamp_Nalezen1,&TimeStamp_Nalezen2,&TimeStamp_Aktualni);		
	}	
	
	// Prochazeni jednorazovych zaznamu
	for(i=0;i<PLANOVAC_MAXZAZNAMU;i++)
	{
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		if((temp&(1<<PLANOVAC_DENNE))|(temp&(1<<PLANOVAC_TYDNE))|
		   (temp&(1<<PLANOVAC_MESICNE))|(temp&(1<<PLANOVAC_ROCNE))|
		   (temp&(1<<PLANOVAC_DEAKTIVOVAT)))	// Overeni jestli je zaznam jednorazovy
		{
			continue;
		}
		temp_Opak=temp;
		
		// Nacteni dat z FLASH do docasnych promennych		
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		temp1_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		temp1_32|=temp;
		if(temp1_32==0xFFFFFFFF)				// Kontrola jestli neni zaznam smazany (neplatny)
		{
			continue;
		}

		TimeStamp_Nalezen2 = temp1_32;
		if(((PlanovacStav&(1<<PLANOVAC_RESTART))&(TimeStamp_Nalezen2>=TimeStamp_Aktualni))|
		   ((PlanovacStav&(1<<PLANOVAC_RESTART))==0))
		{
			Planovac_CompareCandidate(&temp_ID,&i,&TimeStamp_Nalezen1,&TimeStamp_Nalezen2,&TimeStamp_Aktualni);
		}
	}

	// Vlozeni vybraneho zaznamu do RAM	
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN SEARCH > Vkladam zaznam do RAM", 1);
		USART1_FreeMUTEX();
	#endif
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(temp_ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL1_2), &temp)!=0)
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN SEARCH > Chyba cteni: 1", 1);
			USART1_FreeMUTEX();
		#endif
		return;									// Promenna ve FLASH neexistuje -> konec bez ulozeni do RAM
	}
	Planovac_Kanal[0]=(temp&0xFF00)>>8;
	Planovac_Kanal[1]=(temp&0x00FF);
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(temp_ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL3_4), &temp)!=0)
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN SEARCH > Chyba cteni: 1", 1);
			USART1_FreeMUTEX();
		#endif
		return;									// Promenna ve FLASH neexistuje -> konec bez ulozeni do RAM
	}
	Planovac_Kanal[2]=(temp&0xFF00)>>8;
	Planovac_Kanal[3]=(temp&0x00FF);
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(temp_ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK), &temp)!=0)
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN SEARCH > Chyba cteni: 1", 1);
			USART1_FreeMUTEX();
		#endif
		return;									// Promenna ve FLASH neexistuje -> konec bez ulozeni do RAM
	}
	Planovac_Kanal[4]=(temp&0xFF00)>>8;
	Planovac_Timestamp = TimeStamp_Nalezen1;
	PlanovacStav&=~(1<<PLANOVAC_PROVEDENO);		// Nastaveni planu na neprovedeno => pri dalsim pruchodu se aktivuje

	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN SEARCH > Naplanovany TimeStamp=", 0);
		USART1_SendInt32(Planovac_Timestamp);
		USART1_Send_Enter();
		USART1_FreeMUTEX();
	#endif

//PLANOVAC_SEARCHPLAN_KONEC:
}

/* -------------------------------------------------
 Funkce porovnava kandidaty na plan ktery se 
 aktivuje a provede se podle nej nastaveni LED
 ------------------------------------------------ */
void Planovac_CompareCandidate(uint8_t *ID_vybraneho,uint8_t *ID_kandidat, uint32_t *TimeStamp_Nalezen1, uint32_t *TimeStamp_Nalezen2, uint32_t *TimeStamp_Aktualni)
{
	// Hledani nejmladsiho zaznamu z minulosti - pouze po restartu kvuli navzani na preruseny plan. 
	// Resi pouze zaznamy starsi nez aktualni datum
	if((*TimeStamp_Nalezen2&0xFFFE0000)<(*TimeStamp_Aktualni&0xFFFE0000))
	{
		if((PlanovacStav&(1<<PLANOVAC_RESTART))!=0)
		{
			if((*TimeStamp_Nalezen1&0xFFFE0000)<(*TimeStamp_Aktualni&0xFFFE0000))
			{
				if(*TimeStamp_Nalezen2>*TimeStamp_Nalezen1)
				{
					*TimeStamp_Nalezen1=*TimeStamp_Nalezen2;
					*ID_vybraneho=*ID_kandidat;
				}
			}
			else
			{
				*TimeStamp_Nalezen1=*TimeStamp_Nalezen2;
				*ID_vybraneho=*ID_kandidat;
			}
		}
	}

	// Porovnani jestli je aktualne nalezeny zaznam blize aktualnimu datu nez byl doposud nejlepsi nalezeny zaznam
	// Resi i obnovovaci zaznamy, ale pouze s aktualnim datem
	else if ((*TimeStamp_Nalezen2&0xFFFE0000)<(*TimeStamp_Nalezen1&0xFFFE0000))
	{
		*TimeStamp_Nalezen1=*TimeStamp_Nalezen2;
		*ID_vybraneho=*ID_kandidat;
	}
	// Porovnani jestli aktualne nalezeny zaznam neni blize aktualnimu casu nez byl doposud nejlepsi nalezeny zaznam ve stejnem dni
	else if((*TimeStamp_Nalezen2&0xFFFE0000)==(*TimeStamp_Aktualni&0xFFFE0000))	// Kontrola dne planu shodneho s aktualnim datem
	{			
		if((PlanovacStav&(1<<PLANOVAC_RESTART))==0)							// Zajisti, aby se uprednostnovali zaznamy
		{																	//  z minulosti pouze jednou po zapnuti napajeni
			if((*TimeStamp_Nalezen2&0x1FFFF)<(*TimeStamp_Aktualni&0x1FFFF))	// Nalezeny zaznam je vlevo od aktualniho casu
			{
				if(*TimeStamp_Nalezen2>*TimeStamp_Nalezen1)					// Nejblizsi zaznam k aktualnimu casu zleva
				{
					*TimeStamp_Nalezen1=*TimeStamp_Nalezen2;
					*ID_vybraneho=*ID_kandidat;
				}
				else if((*TimeStamp_Nalezen1&0x1FFFF)>(*TimeStamp_Aktualni&0x1FFFF))	// Prepis minuleho zaznamu pokud je minuly 
				{																		// vpravo od aktualniho casu a zaroven 
					*TimeStamp_Nalezen1=*TimeStamp_Nalezen2;							// nove najity je vlevo od aktualniho casu
					*ID_vybraneho=*ID_kandidat;
				} 
			}
		}
		else																// Nalezeny zaznam je vpravo od aktualniho casu
		{
			if(*TimeStamp_Nalezen2<*TimeStamp_Nalezen1)						// Nejblizsi zaznam k aktualnimu casu zprava
			{
				*TimeStamp_Nalezen1=*TimeStamp_Nalezen2;
				*ID_vybraneho=*ID_kandidat;
			}				
		}
	}
	// Porovnani jestli aktualne nalezeny zaznam neni blize aktualnimu datu a casu nez byl predchozi
	else if(*TimeStamp_Nalezen2<*TimeStamp_Nalezen1)
	{
		*TimeStamp_Nalezen1=*TimeStamp_Nalezen2;
		*ID_vybraneho=*ID_kandidat;
	}	
}

/* -------------------------------------------------
 Funkce opravi preteceni datumu se zachovanim 
 puvodniho posunu
 ------------------------------------------------ */
void Planovac_CorectDate(uint16_t *temp_Rok,uint8_t *temp_Mesic,uint8_t *temp_Den)
{
	if(*temp_Mesic==2)								// Kontrola jestli je mesic Unor
	{
		if((*temp_Den>29)&(*temp_Rok%4==0))		// Kontrola prekroceni poctu dni pro Unor v prestupnem roce 
		{			
			*temp_Mesic++;
			*temp_Den = *temp_Den-29;				// Posun na den odpovidjici poctu dni o ktere presahuje prestupny unor sve maximum	
		}
		else if((*temp_Den>28)&(*temp_Rok%4!=0))	// Kontrola prekroceni poctu dni pro Unor v neprestupnem roce 
		{
			*temp_Mesic++;
			*temp_Den = *temp_Den-28;				// Posun na den odpovidjici poctu dni o ktere presahuje neprestupny unor sve maximum	
		}
	}
	else if((*temp_Mesic==1)|(*temp_Mesic==3)|
			(*temp_Mesic==5)|(*temp_Mesic==7)|
			(*temp_Mesic==8)|(*temp_Mesic==10)|
			(*temp_Mesic==12))
	{
		if(*temp_Den>31)							// Kontrola prekroceni poctu dni pro mesice s 31 dny
		{			
			*temp_Mesic++;
			*temp_Den = *temp_Den-31;				// Posun na den odpovidjici poctu dni o ktere presahuje mesic s 31 dny
		}
	}
	else
	{
		if(*temp_Den>30)							// Kontrola prekroceni poctu dni pro mesice s 30 dny
		{			
			*temp_Mesic++;
			*temp_Den = *temp_Den-30;				// Posun na den odpovidjici poctu dni o ktere presahuje mesic s 30 dny
		}
	}
	if(*temp_Mesic>12)								// Kontrola prekroceni poctu mesicu v roce
	{
		*temp_Mesic=1;
	}
}

/* -------------------------------------------------
 Funkce vrati udaje o zaznamu ve FLASH urcenem ID
 ------------------------------------------------ */
uint8_t Planovac_GetZaznam(uint8_t ID,uint8_t *Zacatek,uint8_t *Konec,uint8_t *Opakovani,uint8_t *NastaveniKanalu)
{
	uint16_t temp;
	uint32_t temp_32;

	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), &temp)!=0)
	{
		return(0);							// Promenna ve FLASH neexistuje
	}
	temp_32=(uint32_t)temp<<16;
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), &temp)!=0)
	{
		return(0);							// Promenna ve FLASH neexistuje
	}
	temp_32|=temp;
	Zacatek[2] = (temp_32>>26)&0x3F;					// Rok
	Zacatek[1] = (temp_32>>22)&0x0F;					// Mesic
	Zacatek[0] = (temp_32>>17)&0x1F;					// Den
	Zacatek[3] = (temp_32&0x1FFFF)/(60*60);				// Hodiny
	Zacatek[4] = ((temp_32&0x1FFFF)%(60*60))/60;		// Minuty
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+0), &temp)!=0)
	{
		return(0);							// Promenna ve FLASH neexistuje
	}
	temp_32=(uint32_t)temp<<16;
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+1), &temp)!=0)
	{
		return(0);							// Promenna ve FLASH neexistuje
	}
	temp_32|=temp;
	Konec[2] = (temp_32>>26)&0x3F;						// Rok
	Konec[1] = (temp_32>>22)&0x0F;						// Mesic
	Konec[0] = (temp_32>>17)&0x1F;						// Den
	Konec[3] = (temp_32&0x1FFFF)/(60*60);				// Hodiny
	Konec[4] = ((temp_32&0x1FFFF)%(60*60))/60;			// Minuty
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL1_2), &temp)!=0)
	{
		return(0);									// Promenna ve FLASH neexistuje -> konec bez ulozeni do RAM
	}
	NastaveniKanalu[0] = (temp&0xFF00)>>8;
	NastaveniKanalu[1] = (temp&0x00FF);
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL3_4), &temp)!=0)
	{
		return(0);									// Promenna ve FLASH neexistuje -> konec bez ulozeni do RAM
	}
	NastaveniKanalu[2] = (temp&0xFF00)>>8;
	NastaveniKanalu[3] = (temp&0x00FF);
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK), &temp)!=0)
	{
		return(0);									// Promenna ve FLASH neexistuje -> konec bez ulozeni do RAM
	}
	NastaveniKanalu[4] = (temp&0x7F00)>>8;
	NastaveniKanalu[5] = (temp&0x8000)>>(8+7);
		
	temp&=0x00FF;
	if(temp&(1<<PLANOVAC_DEAKTIVOVAT))
	{
		*Opakovani = 0;
	}
	else if(temp==0)
	{
		*Opakovani = 1;
	}
	else if(temp&(1<<PLANOVAC_DENNE))
	{
		*Opakovani = 2;
	}
	else if(temp&(1<<PLANOVAC_TYDNE))
	{
		*Opakovani = 3;
	}
	else if(temp&(1<<PLANOVAC_MESICNE))
	{
		*Opakovani = 4;
	}
	else if(temp&(1<<PLANOVAC_ROCNE))
	{
		*Opakovani = 5;
	}
	return(1);
}

/* -------------------------------------------------
 Funkce vrati celkovy pocet zaznamu a pocet 
 aktivnich zaznamu v planovaci
 ------------------------------------------------ */
void Planovac_PocetZaznamu(uint8_t *PocetZaznamu, uint8_t *PocetAktivnich)
{
	uint8_t i;
	uint16_t temp;
	uint32_t Start_32;
	uint32_t End_32;
	uint32_t TimeStamp_Aktualni;
	
	*PocetZaznamu=0;
	*PocetAktivnich=0;	
	
	TimeStamp_Aktualni = ((uint32_t)(Time_Rok-2010))<<26;
	TimeStamp_Aktualni |=((uint32_t)Time_Mesic&0x0F)<<22;
	TimeStamp_Aktualni |=((uint32_t)Time_Den&0x1F)<<17;
	TimeStamp_Aktualni |=((uint32_t)Time_Hodiny*3600+(uint32_t)Time_Minuty*60+(uint32_t)Time_Vteriny)&0x1FFFF;	

	for(i=0;i<PLANOVAC_MAXZAZNAMU;i++)
	{
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		Start_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		Start_32|=temp;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+0), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		End_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+1), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		End_32|=temp;
		if(Start_32==0xFFFFFFFF)				// Kontrola jestli neni zaznam smazany (neplatny)
		{
			continue;
		}
		if(End_32==0xFFFFFFFF)					// Kontrola jestli neni zaznam smazany (neplatny)
		{
			continue;
		}
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK), &temp)!=0)
		{
			continue;							// Promenna ve FLASH neexistuje -> skok na dalsi
		}
		if((temp&(1<<PLANOVAC_DEAKTIVOVAT))==0)
		{
			if(TimeStamp_Aktualni>=Start_32)
			{
				if(TimeStamp_Aktualni<=End_32)
				{
					*PocetAktivnich=*PocetAktivnich+1;
				}				
			}
		}
		*PocetZaznamu=*PocetZaznamu+1;
	}
}

/* -------------------------------------------------
 Funkce smaze zvoleny zaznam
 ------------------------------------------------ */
uint8_t Planovac_SmazatZaznam(uint8_t ID)
{
	uint8_t status=0;
	
	if(ID>=PLANOVAC_MAXZAZNAMU)	
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN > Neplatne ID zaznamu",1);
			USART1_FreeMUTEX();
		#endif
		return(0);
	}

	FLASH_Unlock();
	status|=EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), 0xFFFF);
	status|=EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), 0xFFFF);
	FLASH_Lock();
	
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > Zaznam smazan z pameti",1);
		USART1_FreeMUTEX();
	#endif	

	return(status);
}

/* -------------------------------------------------
 Funkce prida zaznam do planovace
 ------------------------------------------------ */
uint8_t Planovac_PridatZaznam(uint8_t ZacatekDen,uint8_t ZacatekMesic,uint8_t ZacatekRok,uint8_t ZacatekHodina,
							  uint8_t ZacatekMinuta,uint8_t KonecDen,uint8_t KonecMesic,uint8_t KonecRok,
							  uint8_t KonecHodina,uint8_t KonecMinuta,uint8_t Opakovani,uint8_t *NastaveniKanalu)
{
	uint8_t i;
	uint16_t temp;
	uint32_t temp_32;

	// Nalezeni volne pozice
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > Hledam volne misto v pameti",1);
		USART1_FreeMUTEX();
	#endif
	for(i=0;i<PLANOVAC_MAXZAZNAMU;i++)
	{
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), &temp)!=0)
		{
			break;								// Promenna ve FLASH neexistuje
		}
		temp_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), &temp)!=0)
		{
			break;								// Promenna ve FLASH neexistuje
		}
		temp_32|=temp;
		if(temp_32==0xFFFFFFFF)					// Kontrola jestli je zaznam smazany (neplatny)
		{
			break;
		}
	}
	if(i>=PLANOVAC_MAXZAZNAMU)					// Nebyla nalezena zadna volna pozice pro zaznam
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN > Pamet na plany je plna",1);
			USART1_FreeMUTEX();
		#endif
		return(0);
	}
	else
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN > Nalezena volna pozice ID=",0);
			USART1_SendInteger(i);
			USART1_Send_Enter();
			USART1_FreeMUTEX();
		#endif
	}
	
	// Vlozeni zaznamu na volnou pozici
	FLASH_Unlock();
	temp_32 = (((uint32_t)ZacatekRok&0x3F)<<26)| 
	 		  (((uint32_t)ZacatekMesic&0x0F)<<22) | 
			  (((uint32_t)ZacatekDen&0x1F)<<17) | 
			  ((((uint32_t)ZacatekHodina*3600+(uint32_t)ZacatekMinuta*60+0)&0x1FFFF));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0,(temp_32&0xFFFF0000)>>16);
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1,(temp_32&0x0000FFFF));
	temp_32 = (((uint32_t)KonecRok&0x3F)<<26)| 
	 		  (((uint32_t)KonecMesic&0x0F)<<22) | 
			  (((uint32_t)KonecDen&0x1F)<<17) | 
			  ((((uint32_t)KonecHodina*3600+(uint32_t)KonecMinuta*60+0)&0x1FFFF));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+0,(temp_32&0xFFFF0000)>>16);
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+1,(temp_32&0x0000FFFF));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL1_2,(NastaveniKanalu[0]<<8)|(NastaveniKanalu[1]));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL3_4,(NastaveniKanalu[2]<<8)|(NastaveniKanalu[3]));
	if(NastaveniKanalu[5]>1)
	{
		NastaveniKanalu[5]=1;
	}
	NastaveniKanalu[5]=NastaveniKanalu[5]<<7;
	switch(Opakovani)
	{
		case 0:
		{
			Opakovani=(1<<PLANOVAC_DEAKTIVOVAT);
			break;
		}
		case 1:
		{
			Opakovani=0;
			break;
		}
		case 2:
		{
			Opakovani=(1<<PLANOVAC_DENNE);
			break;
		}
		case 3:
		{
			Opakovani=(1<<PLANOVAC_TYDNE);
			break;
		}
		case 4:
		{
			Opakovani=(1<<PLANOVAC_MESICNE);
			break;
		}
		case 5:
		{
			Opakovani=(1<<PLANOVAC_ROCNE);
			break;
		}
	}
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK,(NastaveniKanalu[4]<<8)|(NastaveniKanalu[5]<<8)|Opakovani);	
	FLASH_Lock();
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > Novy zaznam ulozen",1);
		USART1_FreeMUTEX();
	#endif
	return(1);
}

/* -------------------------------------------------
 Funkce prida zaznam do planovace
 ------------------------------------------------ */
uint8_t Planovac_EditovatZaznam(uint8_t ID,uint8_t ZacatekDen,uint8_t ZacatekMesic,uint8_t ZacatekRok,
								uint8_t ZacatekHodina,uint8_t ZacatekMinuta,uint8_t KonecDen,uint8_t KonecMesic,
								uint8_t KonecRok,uint8_t KonecHodina,uint8_t KonecMinuta,uint8_t Opakovani,
							    uint8_t *NastaveniKanalu)
{
	uint32_t temp_32;

	// Nalezeni volne pozice
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > Zcatek editace zaznamu",1);
		USART1_FreeMUTEX();
	#endif	
	
	if(ID>=PLANOVAC_MAXZAZNAMU)	
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN > Neplatne ID zaznamu",1);
			USART1_FreeMUTEX();
		#endif
		return(0);
	}
	
	// Vlozeni zaznamu na volnou pozici
	FLASH_Unlock();
	temp_32 = (((uint32_t)ZacatekRok&0x3F)<<26)| 
	 		  (((uint32_t)ZacatekMesic&0x0F)<<22) | 
			  (((uint32_t)ZacatekDen&0x1F)<<17) | 
			  ((((uint32_t)ZacatekHodina*3600+(uint32_t)ZacatekMinuta*60+0)&0x1FFFF));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0,(temp_32&0xFFFF0000)>>16);
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1,(temp_32&0x0000FFFF));
	temp_32 = (((uint32_t)KonecRok&0x3F)<<26)| 
	 		  (((uint32_t)KonecMesic&0x0F)<<22) | 
			  (((uint32_t)KonecDen&0x1F)<<17) | 
			  ((((uint32_t)KonecHodina*3600+(uint32_t)KonecMinuta*60+0)&0x1FFFF));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+0,(temp_32&0xFFFF0000)>>16);
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+1,(temp_32&0x0000FFFF));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL1_2,(NastaveniKanalu[0]<<8)|(NastaveniKanalu[1]));
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL3_4,(NastaveniKanalu[2]<<8)|(NastaveniKanalu[3]));
	if(NastaveniKanalu[5]>1)
	{
		NastaveniKanalu[5]=1;
	}
	NastaveniKanalu[5]=NastaveniKanalu[5]<<7;
	switch(Opakovani)
	{
		case 0:
		{
			Opakovani=(1<<PLANOVAC_DEAKTIVOVAT);
			break;
		}
		case 1:
		{
			Opakovani=0;
			break;
		}
		case 2:
		{
			Opakovani=(1<<PLANOVAC_DENNE);
			break;
		}
		case 3:
		{
			Opakovani=(1<<PLANOVAC_TYDNE);
			break;
		}
		case 4:
		{
			Opakovani=(1<<PLANOVAC_MESICNE);
			break;
		}
		case 5:
		{
			Opakovani=(1<<PLANOVAC_ROCNE);
			break;
		}
	}
	EE_WriteVariable(EEPROM_VirtAdd[AddrPlanovac]+ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK,(NastaveniKanalu[4]<<8)|(NastaveniKanalu[5]<<8)|Opakovani);	
	FLASH_Lock();
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("PLAN > Novy zaznam ulozen",1);
		USART1_FreeMUTEX();
	#endif
	return(1);
}

/* -------------------------------------------------
 Funkce overi jestli zaznam s danym ID existuje
 ------------------------------------------------ */
uint8_t Planovac_ExistujiciZaznam(uint8_t ID)
{
	uint16_t temp;
	uint32_t temp_32;
	
	if(ID>=PLANOVAC_MAXZAZNAMU)					// Nebyla nalezena zadna volna pozice pro zaznam
	{
		#ifdef DEBUG
			USART1_WaitForMUTEX();
			USART1_SetMUTEX();
			USART1_Send("PLAN > Neexistujici zaznam ID=",0);
			USART1_SendNumber(ID);
			USART1_Send_Enter();
			USART1_FreeMUTEX();
		#endif
		return(0);
	}

	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), &temp)!=0)
	{
		return(0);								// Promenna ve FLASH neexistuje
	}
	temp_32=(uint32_t)temp<<16;
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(ID*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), &temp)!=0)
	{
		return(0);								// Promenna ve FLASH neexistuje
	}
	temp_32|=temp;
	if(temp_32==0xFFFFFFFF)						// Kontrola jestli je zaznam smazany (neplatny)
	{
		return(0);
	}
	return(1);	
}

/* -------------------------------------------------
 Funkce prida zaznam do planovace
 ------------------------------------------------ */
uint8_t Planovac_Existuje(uint8_t ZacatekDen,uint8_t ZacatekMesic,uint8_t ZacatekRok,uint8_t ZacatekHodina,
						  uint8_t ZacatekMinuta,uint8_t KonecDen,uint8_t KonecMesic,uint8_t KonecRok,
						  uint8_t KonecHodina,uint8_t KonecMinuta,uint8_t Opakovani,uint8_t *NastaveniKanalu)
{
	uint16_t temp;
	uint32_t temp_32;
	uint8_t i;
	uint8_t rZacatek[5]={0xFF,0xFF,0xFF,0xFF,0xFF};
	uint8_t rKonec[5]={0xFF,0xFF,0xFF,0xFF,0xFF};
	uint8_t rNastaveniKanalu[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
	uint8_t rOpakovani=0xFF;

	for(i=0;i<PLANOVAC_MAXZAZNAMU;i++)
	{	
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+0), &temp)!=0)
		{
			continue;										// Promenna ve FLASH neexistuje
		}
		temp_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_STARTTIME+1), &temp)!=0)
		{
			continue;										// Promenna ve FLASH neexistuje
		}
		temp_32|=temp;
		rZacatek[2] = (temp_32>>26)&0x3F;					// Rok
		rZacatek[1] = (temp_32>>22)&0x0F;					// Mesic
		rZacatek[0] = (temp_32>>17)&0x1F;					// Den
		rZacatek[3] = (temp_32&0x1FFFF)/(60*60);			// Hodiny
		rZacatek[4] = ((temp_32&0x1FFFF)%(60*60))/60;		// Minuty
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+0), &temp)!=0)
		{
			continue;										// Promenna ve FLASH neexistuje
		}
		temp_32=(uint32_t)temp<<16;
		if(EE_ReadVariable(AddrPlanovac+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_ENDTIME+1), &temp)!=0)
		{
			continue;										// Promenna ve FLASH neexistuje
		}
		temp_32|=temp;
		rKonec[2] = (temp_32>>26)&0x3F;						// Rok
		rKonec[1] = (temp_32>>22)&0x0F;						// Mesic
		rKonec[0] = (temp_32>>17)&0x1F;						// Den
		rKonec[3] = (temp_32&0x1FFFF)/(60*60);				// Hodiny
		rKonec[4] = ((temp_32&0x1FFFF)%(60*60))/60;			// Minuty
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL1_2), &temp)!=0)
		{
			continue;										// Promenna ve FLASH neexistuje
		}
		rNastaveniKanalu[0] = (temp&0xFF00)>>8;
		rNastaveniKanalu[1] = (temp&0x00FF);
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL3_4), &temp)!=0)
		{
			continue;										// Promenna ve FLASH neexistuje
		}
		rNastaveniKanalu[2] = (temp&0xFF00)>>8;
		rNastaveniKanalu[3] = (temp&0x00FF);
		if(EE_ReadVariable(EEPROM_VirtAdd[AddrPlanovac]+(i*PLANOVAC_DELKAZAZNAMU+PLANOVAC_OFFSET_KANAL56_OPAK), &temp)!=0)
		{
			continue;										// Promenna ve FLASH neexistuje
		}
		rNastaveniKanalu[4] = (temp&0x7F00)>>8;
		rNastaveniKanalu[5] = (temp&0x8000)>>(8+7);
			
		temp&=0x00FF;
		if(temp&(1<<PLANOVAC_DEAKTIVOVAT))
		{
			rOpakovani = 0;
		}
		else if(temp&(1<<PLANOVAC_DENNE))
		{
			rOpakovani = 1;
		}
		else if(temp&(1<<PLANOVAC_TYDNE))
		{
			rOpakovani = 2;
		}
		else if(temp&(1<<PLANOVAC_MESICNE))
		{
			rOpakovani = 3;
		}
		else if(temp&(1<<PLANOVAC_ROCNE))
		{
			rOpakovani = 4;
		}
		// Porovnani
		if((ZacatekDen==rZacatek[0])&(ZacatekMesic==rZacatek[1])&((ZacatekRok-2010)==rZacatek[2])&
		   (ZacatekHodina==rZacatek[3])&(ZacatekMinuta==rZacatek[4])&(KonecDen==rKonec[0])&(KonecMesic==rKonec[1])&
		   ((KonecRok-2010)==rKonec[2])&(KonecHodina==rKonec[3])&(KonecMinuta==rKonec[4])&
		   (rNastaveniKanalu[0]==NastaveniKanalu[0])&(rNastaveniKanalu[1]==NastaveniKanalu[1])&
		   (rNastaveniKanalu[2]==NastaveniKanalu[2])&(rNastaveniKanalu[3]==NastaveniKanalu[3])&
		   (rNastaveniKanalu[4]==NastaveniKanalu[4])&(rNastaveniKanalu[5]==NastaveniKanalu[5])&(rOpakovani==Opakovani))
		{
			#ifdef DEBUG
				USART1_WaitForMUTEX();
				USART1_SetMUTEX();
				USART1_Send(" > Jiz existujici zaznam s ID=",0);
				USART1_SendNumber(i);
				USART1_Send_Enter();
				USART1_FreeMUTEX();
			#endif
			return(1);
		}
	}
	return(0);
}
/* Konec souboru */
