/*
 * Soubor:  ymsg.c
 * Datum:   06.08.2012
 * Autor:   Stanislav Bárta, xbarta29@stud.fit.vutbr.cz
 * Projekt: IM modul
 * Popis:   soubor obsahujici funkce zpracovavajici protokol YMSG
 */

#include "ymsg.h"

#define ID 0
#define HODNOTU 1

enum STAV
{
	NEPRIPOJEN,
	AUTENTIZACE,
	PRIHLASEN,
	ZAHAJENA_SIFROVANA_KOMUNIKACE,
	SIFROVANA_KOMUNIKACE
};

/*
 * zpracovani zpravy protokolu ymsg
 */
void zpracuj_ymsg(struct data_packetu *zprava, struct sezeni *Sezeni)
{
	int *aktualni_stav = &(Sezeni->aktualni_stav);
	//nastaveni promennych zavisejicich na sezeni
	char **potreba_dokoncit_prichozi = &(Sezeni->potreba_dokoncit_prichozi);
	int *ocekavat_dalsi_prichozi = &(Sezeni->ocekavat_dalsi_prichozi);

	char **potreba_dokoncit_odchozi = &(Sezeni->potreba_dokoncit_odchozi);
	int *ocekavat_dalsi_odchozi = &(Sezeni->ocekavat_dalsi_odchozi);

	int uvolnit = 0;
	char *pomocny_ukazatel;
	
	char *data = zprava->data;

	int zpracovano = 0; // obsahuj udaj o tom kolik jiz bylo zpracovano z aktualni zpravy
	int zpracuj_dalsi = 1;
	int dokonceno = 0; // obsahuje udaj kolik bylo ke zprave pridano dat ulozenych z minula

	if(!porovnani_retezce((char *)(&(((struct ymsg_header*) data)->id)), "YMSG") && !*ocekavat_dalsi_prichozi && !*ocekavat_dalsi_odchozi)
	{
		// prijali jsme neco co nezacina hodnotou "YMSG" a pritom nemusime zpravu dokoncovat -> nejspis chyba
		return;
	}

	if(porovnani_retezce((char *)(&(((struct ymsg_header*) data)->id)), "YMSG") && (*ocekavat_dalsi_prichozi || *ocekavat_dalsi_odchozi))
	{
		// prijali jsme zpravu zacinajici hodnotou "YMSG" a pritom musime zpravu dokoncovat -> asi ztracen paket -> ulozene se zahodi
		if(*ocekavat_dalsi_prichozi && zprava->smer == prichozi)
		{
			*ocekavat_dalsi_prichozi = 0;
			free(*potreba_dokoncit_prichozi);
		}
		else if(*ocekavat_dalsi_odchozi && zprava->smer == odchozi)
		{
			*ocekavat_dalsi_odchozi = 0;
			free(*potreba_dokoncit_odchozi);
		}
	}

	if(*ocekavat_dalsi_prichozi && zprava->smer == prichozi)
	{
		kopie_retezce(data, &pomocny_ukazatel, zprava->velikost_dat);
		data = spoj_retezce(potreba_dokoncit_prichozi, *ocekavat_dalsi_prichozi, &pomocny_ukazatel, zprava->velikost_dat);
		dokonceno = *ocekavat_dalsi_prichozi;
		*ocekavat_dalsi_prichozi = 0;
		uvolnit = 1;
	}
	else if(*ocekavat_dalsi_odchozi && zprava->smer == odchozi)
	{
		kopie_retezce(data, &pomocny_ukazatel, zprava->velikost_dat);
		data = spoj_retezce(potreba_dokoncit_odchozi, *ocekavat_dalsi_odchozi, &pomocny_ukazatel, zprava->velikost_dat);
		dokonceno = *ocekavat_dalsi_odchozi;
		*ocekavat_dalsi_odchozi = 0;
		uvolnit = 1;
	}

	while(zpracuj_dalsi)
	{
		// nemame dostatek dat pro pretypovani na YMSG hlavicku
		if((zprava->velikost_dat + dokonceno) - zpracovano < YMSG_HEADER_LENGTH)
		{
			if(zprava->smer == prichozi)
			{
				kopie_retezce(data + zpracovano, potreba_dokoncit_prichozi, (zprava->velikost_dat + dokonceno) - zpracovano);
				*ocekavat_dalsi_prichozi = (zprava->velikost_dat + dokonceno) - zpracovano;
			}
			else if(zprava->smer == odchozi)
			{
				kopie_retezce(data + zpracovano, potreba_dokoncit_odchozi, (zprava->velikost_dat + dokonceno) - zpracovano);
				*ocekavat_dalsi_odchozi = (zprava->velikost_dat + dokonceno) - zpracovano;
			}
			return;
		}

		struct ymsg_header *ymsg = (struct ymsg_header*) (data + zpracovano);

		// nemame cely ramec takze bude potreba pockat na dokonceni
		if(zpracovano + YMSG_HEADER_LENGTH + ntohs(ymsg->data_length) > zprava->velikost_dat + dokonceno)
		{
			if(zprava->smer == prichozi)
			{
				kopie_retezce(data + zpracovano, potreba_dokoncit_prichozi, (zprava->velikost_dat + dokonceno) - zpracovano);
				*ocekavat_dalsi_prichozi = (zprava->velikost_dat + dokonceno) - zpracovano;
			}
			else if(zprava->smer == odchozi)
			{
				kopie_retezce(data + zpracovano, potreba_dokoncit_odchozi, (zprava->velikost_dat + dokonceno) - zpracovano);
				*ocekavat_dalsi_odchozi = (zprava->velikost_dat + dokonceno) - zpracovano;
			}

			return;
		}

		// analyza obsahu
		struct ymsg_hodnoty *seznam_hodnot = analyzuj_ymsg_obsah((char *)(data + YMSG_HEADER_LENGTH));

//		vypis_hodnoty(seznam_hodnot);

		int service = ntohs(ymsg->service);
		int status = ntohl(ymsg->status);
		// identifikace
		if(service == 0x01) // Logon (1)
		{
		
		}
		else if(service == 0x02) // Logoff (2)
		{
			for(int i = 0 ; i < seznam_hodnot->pocet ; i++)
			{
				if(seznam_hodnot->hodnoty[i]->id == 505)
				{
					char *vytvorena_iri;
					if(Sezeni->aktivni)
					{
						vytvorena_iri = vytvor_iri(IRI_END, YMSG, Sezeni, TYP_ODHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
					}
					else
					{
						vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_ODHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
					}
					odesli_iri(vytvorena_iri);
					free(vytvorena_iri);
				
					*aktualni_stav = NEPRIPOJEN;
					Sezeni->aktivni = 0;
					Sezeni->ukonceno = 1;
				}
			}
		}
		else if(service == 0x06 && zprava->smer == odchozi) // Message (6)
		{
			char *pomocny_prijemce = NULL;

			for(int i = 0 ; i < seznam_hodnot->pocet ; i++)
			{
				if(Sezeni->ID_uzivatele == NULL)
				{
					// kopie ID uzivatele
					if(seznam_hodnot->hodnoty[i]->id == 1 && Sezeni->ID_uzivatele == NULL)
					{
						kopie_retezce(seznam_hodnot->hodnoty[i]->value, &(Sezeni->ID_uzivatele), delka_retezce(seznam_hodnot->hodnoty[i]->value));
					}
				}

				if(seznam_hodnot->hodnoty[i]->id == 5)
				{
					kopie_retezce(seznam_hodnot->hodnoty[i]->value, &(pomocny_prijemce), delka_retezce(seznam_hodnot->hodnoty[i]->value));
				}
			}
			if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
			{
				Sezeni->aktivni = 1;
				char *vytvorena_iri = vytvor_iri(IRI_BEGIN, YMSG, Sezeni, TYP_PRIHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}

			if(*aktualni_stav == PRIHLASEN)
			{
				char *vytvorena_iri;
				if(Sezeni->aktivni)
				{
					vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, pomocny_prijemce, NULL);
				}
				else
				{
					vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, pomocny_prijemce, NULL);
				}
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
			free(pomocny_prijemce);
		}
		else if(service == 0x06 && zprava->smer == prichozi) // Message (6)
		{
			char *pomocny_odesilatel = NULL;

			for(int i = 0 ; i < seznam_hodnot->pocet ; i++)
			{
				if(Sezeni->ID_uzivatele == NULL)
				{
					// kopie ID uzivatele
					if(seznam_hodnot->hodnoty[i]->id == 5 && Sezeni->ID_uzivatele == NULL)
					{
						kopie_retezce(seznam_hodnot->hodnoty[i]->value, &(Sezeni->ID_uzivatele), delka_retezce(seznam_hodnot->hodnoty[i]->value));
					}
				}

				if(seznam_hodnot->hodnoty[i]->id == 4)
				{
					kopie_retezce(seznam_hodnot->hodnoty[i]->value, &(pomocny_odesilatel), delka_retezce(seznam_hodnot->hodnoty[i]->value));
				}
			}
			if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
			{
				*aktualni_stav = PRIHLASEN;
				Sezeni->aktivni = 1;
				char *vytvorena_iri = vytvor_iri(IRI_BEGIN, YMSG, Sezeni, TYP_PRIHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}

			if(*aktualni_stav == PRIHLASEN)
			{
				char *vytvorena_iri;
				if(Sezeni->aktivni)
				{
					vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_PRIJATA_ZPRAVA, USPESNE, &(zprava->cas_zachyceni), NULL, pomocny_odesilatel, NULL, NULL);
				}
				else
				{
					vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_PRIJATA_ZPRAVA, USPESNE, &(zprava->cas_zachyceni), NULL, pomocny_odesilatel, NULL, NULL);
				}
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
			free(pomocny_odesilatel);
		}
		else if(service == 0x4b && status == 22) // Notify (75) // notify (typing)
		{
			if(Sezeni->ID_uzivatele == NULL)
			{
				// kopie ID uzivatele
				for(int i = 0 ; i < seznam_hodnot->pocet ; i++)
				{
					if(seznam_hodnot->hodnoty[i]->id == 1 && Sezeni->ID_uzivatele == NULL)
					{
						kopie_retezce(seznam_hodnot->hodnoty[i]->value, &(Sezeni->ID_uzivatele), delka_retezce(seznam_hodnot->hodnoty[i]->value));
					}
				}
			}

			if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
			{
				*aktualni_stav = PRIHLASEN;
				Sezeni->aktivni = 1;
				char *vytvorena_iri = vytvor_iri(IRI_BEGIN, YMSG, Sezeni, TYP_PRIHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(service == 0x54 && status == 1515563605) // Authentication Response (84) // weblogin
		{

		}
		else if(service == 0x55) // List (85)
		{
			if(*aktualni_stav == AUTENTIZACE)
			{
				*aktualni_stav = PRIHLASEN;
				char *vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_AUTENTIZACE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(service == 0x57 && status != 1) // Authentication (87)
		{
			if(*aktualni_stav == NEPRIPOJEN)
			{
				*aktualni_stav = AUTENTIZACE;

				// kopie ID uzivatele
				for(int i = 0 ; i < seznam_hodnot->pocet ; i++)
				{
					if(seznam_hodnot->hodnoty[i]->id == 1 && Sezeni->ID_uzivatele == NULL)
					{
						kopie_retezce(seznam_hodnot->hodnoty[i]->value, &(Sezeni->ID_uzivatele), delka_retezce(seznam_hodnot->hodnoty[i]->value));
					}
				}
			}
		}
		else if(service == 0x57 && status == 1) // Authentication (87) // server ack
		{
			if(*aktualni_stav == AUTENTIZACE)
			{
				char *vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_PRIPOJENI_K_SERVERU, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(service == 0x83) // YMSG Add Buddy (131)
		{
		
		}
		else if(service == 0x8a) // Keep Alive (138)
		{
		
		}
		else if(service == 0xc6 && status == 0) // Y6 Status update (198) // default
		{
			for(int i = 0 ; i < seznam_hodnot->pocet ; i++)
			{
				if(seznam_hodnot->hodnoty[i]->id == 10)
				{
					int value = atoi(seznam_hodnot->hodnoty[i]->value);
					
					if(value == 0) // available
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_AVAILABLE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_AVAILABLE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 1) // brb
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_BRB, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_BRB, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 2) // busy
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_BUSY, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_BUSY, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 3) // notathome
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_NOTATHOME, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_NOTATHOME, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 4) // notatdesk
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_NOTATDESK, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_NOTATDESK, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 5) // notinoffice
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_NOTINOFFICE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_NOTINOFFICE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 6) // onphone
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_ONPHONE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_ONPHONE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 7) // onvacation
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_ONVACATION, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_ONVACATION, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 8) // outtolunch
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_OUTTOLUNCH, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_OUTTOLUNCH, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 9) // steppedout
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_STEPPEDOUT, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_STEPPEDOUT, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 12) // invisible
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_INVISIBLE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_INVISIBLE, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(value == 99) // custom (away)
					{
						char *vytvorena_iri;
						if(Sezeni->aktivni)
						{
//							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_CUSTOM, USPESNE, &(zprava->cas_zachyceni));
							vytvorena_iri = vytvor_iri(IRI_CONTINUE, YMSG, Sezeni, TYP_AWAY, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						else
						{
//							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_CUSTOM, USPESNE, &(zprava->cas_zachyceni));
							vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_AWAY, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
						}
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
				}
			}
		}
		else if(service == 0xd6) // YMSG Buddy Authentication (216)
		{
		
		}
		else if(service == 0xf0) // YMSG Status v15 (240)
		{
			if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
			{
				Sezeni->aktivni = 1;
				char *vytvorena_iri = vytvor_iri(IRI_BEGIN, YMSG, Sezeni, TYP_PRIHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(service == 0xf1) // YMSG List v15 (241)
		{

		}
		else if(service == 0x2ea) // YMSG SMS Message (746)
		{
		
		}
		else if(service == 0x2ed) // YMSG Mobile IM Setup (749)
		{
		
		}
		/*else if(service == ) //  ()
		{
		
		}*/

		smaz_seznam_hodnot(seznam_hodnot);
		free(seznam_hodnot);

		// zprava kterou zpracovavame jeste nebyla zpracovana cela
		if(zprava->velikost_dat + dokonceno > zpracovano + ntohs(ymsg->data_length)+YMSG_HEADER_LENGTH)
		{
			zpracovano += ntohs(ymsg->data_length)+YMSG_HEADER_LENGTH;
			// dojde k dalsimu pruchodu cyklem
		}
		else
		{
			zpracuj_dalsi = 0;
			// ukonceni cyklu
		}
	}

	if(uvolnit)
	{
		free(data);
	}
}

/*
 * zjisti stav ukonceneho spojeni a v pripade potreby vytvori odpovidajici IRI zpravy
 */
void ukonci_ymsg(struct data_packetu *zprava, struct sezeni *Sezeni)
{
	int *aktualni_stav = &(Sezeni->aktualni_stav);

	if(*aktualni_stav == AUTENTIZACE)
	{
		*aktualni_stav = PRIHLASEN;
		char *vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_AUTENTIZACE, NEUSPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
	}
	else if(*aktualni_stav == PRIHLASEN)
	{
		char *vytvorena_iri;
		if(Sezeni->aktivni)
		{
			vytvorena_iri = vytvor_iri(IRI_END, YMSG, Sezeni, TYP_ODHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
		}
		else
		{
			vytvorena_iri = vytvor_iri(IRI_REPORT, YMSG, Sezeni, TYP_ODHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
		}
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);

		*aktualni_stav = NEPRIPOJEN;
		Sezeni->aktivni = 0;
		Sezeni->ukonceno = 1;
	}
}

/*
 * funkce zpracovavajici obsah datove casti protokolu ymsg
 * dojde k rozdeleni na jednotlive casti a vytvoreni dvojic ID a hodnota.
 */
struct ymsg_hodnoty *analyzuj_ymsg_obsah(char *obsah)
{
	struct ymsg_hodnoty *zpracovano = (struct ymsg_hodnoty *) malloc(sizeof(struct ymsg_hodnoty));
	zpracovano->pocet = 0;
	zpracovano->hodnoty = NULL;

	char *pomocny = NULL;
	int zacatek = 0;
	int ctu = ID;
	int id = 0;
	
	// -2 aby nebyly brany posledni oddelovace a slo tak testovat nasledujici dva znaky
	for(int i = 0 ; i < delka_retezce(obsah) - 2 ; i++)
	{

		if((uint8_t)  obsah[i+1] == 0xc0 && (uint8_t)  obsah[i+2] == 0x80)
		{
			if(ctu == ID)
			{
				ctu = HODNOTU;
				kopie_retezce((char *)(obsah + zacatek), &pomocny, ((i + 1) - zacatek));
				// posun zacatku az za oddelovace
				zacatek = i + 3;
				id = atoi(pomocny);
				free(pomocny);
			}
			else if(ctu == HODNOTU)
			{
				ctu = ID;
				struct ymsg_hodnoty_polozka *nova = pridej_hodnotu_do_seznamu(zpracovano);
				
				nova->id = id;
				kopie_retezce((char *)(obsah + zacatek), &(nova->value), ((i + 1) - zacatek));
				// posun zacatku az za oddelovace
				zacatek = i + 3;
			}
		}
	}

	return zpracovano;
}

/*
 * vytvori misto pro novou polozku v seznamu zpracovanych hodnot a vrati na ni ukazatel
 */
struct ymsg_hodnoty_polozka *pridej_hodnotu_do_seznamu(struct ymsg_hodnoty *seznam)
{
	seznam->pocet++;

	// alokace mista v seznamu
	if(seznam->hodnoty == NULL)
	{
		seznam->hodnoty = (struct ymsg_hodnoty_polozka **) malloc(sizeof(struct ymsg_hodnoty_polozka*));
	}
	else
	{
		seznam->hodnoty = (struct ymsg_hodnoty_polozka **) realloc(seznam->hodnoty ,(seznam->pocet)*sizeof(struct ymsg_hodnoty_polozka*));
	}

	nova_hodnota(&(seznam->hodnoty[seznam->pocet - 1]));
	return seznam->hodnoty[seznam->pocet - 1];
}

/*
 * alokace misat nove polozky a jeji inicializace
 */
void nova_hodnota(struct ymsg_hodnoty_polozka **hodnota)
{
	*hodnota = (struct ymsg_hodnoty_polozka *) malloc(sizeof(struct ymsg_hodnoty_polozka));
	(*hodnota)->id = 0;
	(*hodnota)->value = NULL;
}

/*
 * smazani seznamu hodnot. uvolneni mista v pameti
 */
void smaz_seznam_hodnot(struct ymsg_hodnoty *seznam)
{
	for(int i = 0; i < seznam->pocet ; i++)
	{
		free(seznam->hodnoty[i]->value);
		free(seznam->hodnoty[i]);
	}
	free(seznam->hodnoty);
}

