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

#include "xmpp.h"

enum STAV
{
	NEPRIPOJEN,
	UVODNI_STREAM,
	POTVRZEN_UVODNI_STREAM,
	PRIJATY_MOZNOSTI,
	SASL,
	SASL_CHALLENGE,
	SASL_RESPONSE,
	SASL_SUCCESS,
	SASL_FAILURE,
	SASL_ABORT,
	BIND,
	PRIHLASEN,
	ZAHAJENA_SIFROVANA_KOMUNIKACE,
	SIFROVANA_KOMUNIKACE
};

/*
 * zpracovani zpravy protokolu xmpp
 */
void zpracuj_xmpp(struct data_packetu *zprava, struct sezeni *Sezeni)
{
	//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);

	char *data = zprava->data;
	// pro vysledny retezec (po spojeni vice nebo ziskany primo z daneho packetu)
	char *stanza = NULL;
	// pokud byl vysledny retezec ziskan spojovanim z predchozim je treba jej pote uvolnit
	int uvolnit = 0;

	// kontrola zacatku zpravy pro pripad ztraty paketu
	if(zprava->data[0] == '<' && (*ocekavat_dalsi_prichozi || *ocekavat_dalsi_odchozi))
	{
		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);
		}
	}

	// kontrola jestli je potreba dokoncit retezec z minula
	if(*ocekavat_dalsi_prichozi && zprava->smer == prichozi)
	{
		kopie_retezce(data, &stanza, delka_retezce(data));
		stanza = spoj_retezce(potreba_dokoncit_prichozi, delka_retezce(*potreba_dokoncit_prichozi), &stanza, delka_retezce(stanza));
		*ocekavat_dalsi_prichozi = 0;
		uvolnit = 1;
	}
	else if(*ocekavat_dalsi_odchozi && zprava->smer == odchozi)
	{
		kopie_retezce(data, &stanza, delka_retezce(data));
		stanza = spoj_retezce(potreba_dokoncit_odchozi, delka_retezce(*potreba_dokoncit_odchozi), &stanza, delka_retezce(stanza) );
		*ocekavat_dalsi_odchozi = 0;
		uvolnit = 1;
	}
	else
	{
		stanza = zprava->data;
	}

	// kontrola jestli bude potreba pripojit dalsi cast retezce.
	// kontrola pouze podle posledniho znaku prijateho retezce
	if(stanza[delka_retezce(stanza)-1] != '>' && stanza[delka_retezce(stanza)-1] != '\n')
	{
/*		if(stanza[0] != '<')
		{
			int *aktualni_stav = &(Sezeni->aktualni_stav);
			if(*aktualni_stav == NEPRIPOJEN)
			{
				*aktualni_stav = SIFROVANA_KOMUNIKACE;
				char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_PROBIHAJICI_SIFROVANA_KOMUNIKACE, NEZNAMO, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}*/

		if(zprava->smer == prichozi)
		{
			kopie_retezce(stanza, potreba_dokoncit_prichozi, delka_retezce(stanza));
			*ocekavat_dalsi_prichozi = 1;
		}
		else
		{
			kopie_retezce(stanza, potreba_dokoncit_odchozi, delka_retezce(stanza));
			*ocekavat_dalsi_odchozi = 1;
		}
		if(uvolnit)
		{
			free(stanza);
		}
	}
	// neni potreba cekat na dokonceni zpravy a muzeme ji rovnou zpracovat
	if(!*ocekavat_dalsi_odchozi && !*ocekavat_dalsi_prichozi)
	{
		struct xml *zpracovane_xml = analyza_stanzy(stanza);

		if(uvolnit)
		{
			free(stanza);
		}

		identifikuj_zpravu(zpracovane_xml, Sezeni, zprava->smer, &(zprava->cas_zachyceni));

		// xml jsme jiz zpracovali a neni treba jej dale ukladat
		uvolneni_xml(zpracovane_xml);
		free(zpracovane_xml);
	}
}

/*
 * identifikace zpravy a pripadne upraveni stavu a vytvoreni zprav IRI
 */
void identifikuj_zpravu(struct xml *zpracovane_xml, struct sezeni *Sezeni, int smer, struct timeval *cas_zachyceni)
{
	int *aktualni_stav = &(Sezeni->aktualni_stav);

	for(int i = 0; i < zpracovane_xml->pocet_potomku; i++)
	{
		// v pripade ze jeste nebyl identifikovan cil, zkusime najit id v atributu prijateho elementu
		if(Sezeni->ID_uzivatele == NULL)
		{
			for(int atr = 0; atr < zpracovane_xml->potomci[i]->pocet_atributu; atr++)
			{
				if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[atr], "from") && smer == odchozi)
				{
					if(Sezeni->ID_uzivatele == NULL)
					{
						char *id = ziskej_hodnotu_atributu(zpracovane_xml->potomci[i]->atributy[atr]);
						if(je_fullJID(id))
						{
							Sezeni->ID_uzivatele = id;
						}
						else
						{
							free(id);
						}
					}
				}
				else if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[atr], "to") && smer == prichozi)
				{
					if(Sezeni->ID_uzivatele == NULL)
					{
						char *id = ziskej_hodnotu_atributu(zpracovane_xml->potomci[i]->atributy[atr]);
						if(je_fullJID(id))
						{
							Sezeni->ID_uzivatele = id;
						}
						else
						{
							free(id);
						}
					}
				}
			}
		}

		// urcime o jakou zpravu se jedna
		if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "stream:stream") && smer == odchozi)
		{
			if(*aktualni_stav == NEPRIPOJEN)
			{
				*aktualni_stav = UVODNI_STREAM;
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "stream:stream") && smer == prichozi)
		{
			if(*aktualni_stav == UVODNI_STREAM)
			{
				*aktualni_stav = POTVRZEN_UVODNI_STREAM;
				char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_PRIPOJENI_K_SERVERU, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "stream:error"))
		{

		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "stream:features"))
		{
			if(*aktualni_stav == POTVRZEN_UVODNI_STREAM)
			{
				*aktualni_stav = PRIJATY_MOZNOSTI;
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "starttls"))
		{
			if(*aktualni_stav == PRIJATY_MOZNOSTI)
			{
				*aktualni_stav = ZAHAJENA_SIFROVANA_KOMUNIKACE;
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "proceed"))
		{
			if(*aktualni_stav == ZAHAJENA_SIFROVANA_KOMUNIKACE)
			{
				*aktualni_stav = SIFROVANA_KOMUNIKACE;
				char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_ZAHAJENA_SIFROVANA_KOMUNIKACE, NEZNAMO, cas_zachyceni, NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "auth"))
		{
			if(*aktualni_stav == PRIJATY_MOZNOSTI)
			{
				*aktualni_stav = SASL;
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "challenge"))
		{
			if(*aktualni_stav == SASL)
			{
				*aktualni_stav = SASL_CHALLENGE;
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "response"))
		{
			if(*aktualni_stav == SASL_CHALLENGE)
			{
				*aktualni_stav = SASL_RESPONSE;
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "success"))
		{
			if(*aktualni_stav == SASL_RESPONSE)
			{
				*aktualni_stav = SASL_SUCCESS;
				char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_AUTENTIZACE, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "failure"))
		{
			if(*aktualni_stav == SASL_RESPONSE || *aktualni_stav == SASL_ABORT)
			{
				*aktualni_stav = NEPRIPOJEN;

				char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_AUTENTIZACE, NEUSPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "abort"))
		{
			if(*aktualni_stav == SASL || *aktualni_stav == SASL_CHALLENGE || *aktualni_stav == SASL_RESPONSE)
			{
				*aktualni_stav = SASL_ABORT;
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "compressed"))
		{
			
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "iq"))
		{
			for(int atr = 0; atr < zpracovane_xml->potomci[i]->pocet_atributu; atr++)
			{
				if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[atr], "type") && porovnani_hodnoty_atributu(zpracovane_xml->potomci[i]->atributy[atr], "set"))
				{
					for(int j = 0; j < zpracovane_xml->potomci[i]->pocet_potomku; j++)
					{
						if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->element, "bind"))
						{
							if(*aktualni_stav == SASL_SUCCESS)
							{
								*aktualni_stav = BIND;
							}
						}
					}
				}
				else if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[atr], "type") && porovnani_hodnoty_atributu(zpracovane_xml->potomci[i]->atributy[atr], "result"))
				{
					for(int j = 0; j < zpracovane_xml->potomci[i]->pocet_potomku; j++)
					{
						if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->element, "bind"))
						{
							for(int k = 0; k < zpracovane_xml->potomci[i]->potomci[j]->pocet_potomku; k++)
							{
								if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->potomci[k]->element, "jid"))
								{
									// jeste neni prirazeno ID nebo jeste neni potvrzeno ze jde o sledovany cil
									if(Sezeni->ID_uzivatele == NULL)
									{
										if(Sezeni->ID_uzivatele == NULL)
										{
											kopie_retezce(zpracovane_xml->potomci[i]->potomci[j]->potomci[k]->obsah, &(Sezeni->ID_uzivatele), delka_retezce(zpracovane_xml->potomci[i]->potomci[j]->potomci[k]->obsah));
										}
									}

									if(*aktualni_stav == BIND)
									{
										*aktualni_stav = PRIHLASEN;
										if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
										{
											Sezeni->aktivni = 1;
											char *vytvorena_iri = vytvor_iri(IRI_BEGIN, XMPP, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
											odesli_iri(vytvorena_iri);
											free(vytvorena_iri);
										}
									}
								}
							}
						}
					}
				}
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "message") && smer == prichozi)
		{
			for(int j = 0; j < zpracovane_xml->potomci[i]->pocet_potomku; j++)
			{
				if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->element, "body"))
				{
					char *pomocny_odesilatel;
					for(int atr = 0; atr < zpracovane_xml->potomci[i]->pocet_atributu; atr++)
					{
						if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[atr], "from"))
						{
							pomocny_odesilatel = ziskej_hodnotu_atributu(zpracovane_xml->potomci[i]->atributy[atr]);
							break;
						}
					}

					if(*aktualni_stav == PRIHLASEN)
					{
						if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
						{
							char *vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_PRIJATA_ZPRAVA, USPESNE, cas_zachyceni, NULL, pomocny_odesilatel, NULL, NULL);
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}
					}

					if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
					{
						*aktualni_stav = PRIHLASEN;
						Sezeni->aktivni = 1;
						char *vytvorena_iri = vytvor_iri(IRI_BEGIN, XMPP, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
						vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_PRIJATA_ZPRAVA, USPESNE, cas_zachyceni, NULL, pomocny_odesilatel, NULL, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(!Sezeni->aktivni)
					{
						char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_PRIJATA_ZPRAVA, USPESNE, cas_zachyceni, NULL, pomocny_odesilatel, NULL, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					
					if(pomocny_odesilatel != NULL)
					{
						free(pomocny_odesilatel);
					}
				}
				else // nejde primo o obsah zpravy -> lze pouzit pro identifikaci pripojeni uzivatele
				{
					if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
					{
						*aktualni_stav = PRIHLASEN;
						Sezeni->aktivni = 1;
						char *vytvorena_iri = vytvor_iri(IRI_BEGIN, XMPP, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
				}
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "message") && smer == odchozi)
		{
			for(int j = 0; j < zpracovane_xml->potomci[i]->pocet_potomku; j++)
			{
				if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->element, "body"))
				{
					char *pomocny_prijemce;
					for(int atr = 0; atr < zpracovane_xml->potomci[i]->pocet_atributu; atr++)
					{
						if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[atr], "to"))
						{
							pomocny_prijemce = ziskej_hodnotu_atributu(zpracovane_xml->potomci[i]->atributy[atr]);
							break;
						}
					}
					
					if(*aktualni_stav == PRIHLASEN)
					{
						if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
						{
							char *vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, cas_zachyceni, NULL, NULL, pomocny_prijemce, NULL);
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}
					}

					if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
					{
						*aktualni_stav = PRIHLASEN;
						Sezeni->aktivni = 1;
						char *vytvorena_iri = vytvor_iri(IRI_BEGIN, XMPP, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
						vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, cas_zachyceni, NULL, NULL, pomocny_prijemce, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
					else if(!Sezeni->aktivni)
					{
						char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, cas_zachyceni, NULL, NULL, pomocny_prijemce, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}

					if(pomocny_prijemce != NULL)
					{
						free(pomocny_prijemce);
					}
				}
				else // nejde primo o obsah zpravy -> lze pouzit pro identifikaci pripojeni uzivatele
				{
					if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
					{
						*aktualni_stav = PRIHLASEN;
						Sezeni->aktivni = 1;
						char *vytvorena_iri = vytvor_iri(IRI_BEGIN, XMPP, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
				}
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "presence") && smer == prichozi)
		{
			if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
			{
				for(int j = 0; j < zpracovane_xml->potomci[i]->pocet_atributu; j++)
				{
					if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[j], "from")
					&& porovnani_hodnoty_atributu(zpracovane_xml->potomci[i]->atributy[j], Sezeni->ID_uzivatele))
					{
						*aktualni_stav = PRIHLASEN;
						Sezeni->aktivni = 1;
						char *vytvorena_iri = vytvor_iri(IRI_BEGIN, XMPP, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
						odesli_iri(vytvorena_iri);
						free(vytvorena_iri);
					}
				}
			}
		}
		else if(porovnani_retezce(zpracovane_xml->potomci[i]->element, "presence") && smer == odchozi)
		{
			if(*aktualni_stav == PRIHLASEN)
			{
				for(int j = 0; j < zpracovane_xml->potomci[i]->pocet_atributu; j++)
				{
					if(porovnani_typu_atributu(zpracovane_xml->potomci[i]->atributy[j], "type")
					&& porovnani_hodnoty_atributu(zpracovane_xml->potomci[i]->atributy[j], "unavailable"))
					{
						if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
						{
							char *vytvorena_iri = vytvor_iri(IRI_END, XMPP, Sezeni, TYP_ODHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}
						else if(!Sezeni->aktivni)
						{
							char *vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_ODHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}

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

			if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
			{
				*aktualni_stav = PRIHLASEN;
				Sezeni->aktivni = 1;
				char *vytvorena_iri = vytvor_iri(IRI_BEGIN, XMPP, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
				odesli_iri(vytvorena_iri);
				free(vytvorena_iri);
			}

			if(*aktualni_stav == PRIHLASEN)
			{
				int show_element_nalezen = 0;
				for(int j = 0; j < zpracovane_xml->potomci[i]->pocet_potomku; j++)
				{
					if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->element, "show"))
					{
						show_element_nalezen = 1;
						if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->obsah, "away"))
						{
							char *vytvorena_iri; 
							if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
							{
								vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_AWAY, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							else
							{
								vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_AWAY, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}
						else if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->obsah, "chat"))
						{
							char *vytvorena_iri; 
							if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
							{
								vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_CHAT, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							else
							{
								vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_CHAT, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}
						else if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->obsah, "dnd"))
						{
							char *vytvorena_iri; 
							if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
							{
								vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_DND, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							else
							{
								vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_DND, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}
						else if(porovnani_retezce(zpracovane_xml->potomci[i]->potomci[j]->obsah, "xa"))
						{
							char *vytvorena_iri; 
							if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
							{
								vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_NA, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							else
							{
								vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_NA, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
							}
							odesli_iri(vytvorena_iri);
							free(vytvorena_iri);
						}
					}
				}
				// show nenalezen a v pripade unavailable by sme se sem ani nedostali takze jde o stav online
				if(!show_element_nalezen)
				{
					char *vytvorena_iri; 
					if((Sezeni->ID_uzivatele != NULL) && Sezeni->aktivni)
					{
						vytvorena_iri = vytvor_iri(IRI_CONTINUE, XMPP, Sezeni, TYP_ONLINE, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
					}
					else
					{
						vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, Sezeni, TYP_ONLINE, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
					}
					odesli_iri(vytvorena_iri);
					free(vytvorena_iri);
				}
			}
		}
	}
}

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

	if(*aktualni_stav != NEPRIPOJEN)
	{
		char *vytvorena_iri;
		if(Sezeni->aktivni)
		{
			vytvorena_iri = vytvor_iri(IRI_END, XMPP, Sezeni, TYP_ODHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
		}
		else
		{
			vytvorena_iri = vytvor_iri(IRI_REPORT, XMPP, 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;
	}
}

/*
 * ze zadaneho ID ziska bare JID
 * pokud jiz je na vstupu bare JID, vraci se NULL, aby nebylo treba alokovat dalsi pamet
 */
char *bareJID(char *ID)
{
	char *pomocny = NULL;
	int i, delka = delka_retezce(ID);

	for(i = 0; i < delka ; i++)
	{
		if(ID[i] == '/')
		{
			break;
		}
	}

	if(i < delka)
	{
		kopie_retezce(ID, &pomocny, i);
	}

	return pomocny;
}

/*
 * ze zadaneho ID ziska cast resources
 */
char *resources(char *ID)
{
	char *pomocny = NULL;
	int i, delka = delka_retezce(ID);

	for(i = 0; i < delka ; i++)
	{
		if(ID[i] == '/')
		{
			break;
		}
	}

	if(i < delka)
	{
		i++; // preskoceni zaku /
		kopie_retezce(ID+i, &pomocny, delka-i);
	}

	return pomocny;
}

/*
 * vraci 1 pokud se jedna u full JID jinak vraci 0
 */
int je_fullJID(char *ID)
{
	for(int i = 0 ; i < delka_retezce(ID) ; i++)
	{
		if(ID[i] == '/' && i < (delka_retezce(ID) - 1))
		{
			return 1;
		}
	}

	return 0;
}

