/*
 * Soubor:  irc.c
 * Datum:   06.08.2012
 * Autor:   Stanislav Bárta, xbarta29@stud.fit.vutbr.cz
 * Projekt: IM modul
 * Popis:   soubor obsahuji funkce pro zpracovani protokolu IRC
 *          obsahuje funkce pro rozdeleni projate zpravy na jednotlive prikazi
 *          dale obsahuje funkce, ktere zpracuji prikaz a podle nej upravi stav a vytvori zpavy IRI
 */

#include "irc.h"

enum STAV
{
	NEPRIPOJEN,
	ODESLANO_HESLO,
	ODESLANA_PREZDIVKA,
	ODESLANO_JMENO,
	PRIHLASEN,
	NASTAVENI_AWAY,
};


/*
 * zpracuje prijatou zpravu a rozdeli ji na jednotlive prikazi, ktere postupne identifikuje a zpracuje
 */
void zpracuj_irc(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;
	// slouzi k deleni prijate zpravy na jednotlive prikazy
	char *pomocny_ukazatel = data;
	char *prikaz = NULL;

	// kontrola zacatku zpravy pro pripad ztraty paketu. V pripade ze zprava nema prefix chyba neni odhalena -> pripadne spojeni nesouvisejicich casti a vyhodnoceno chybne
	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);
		}
	}

	int i, j = 0;
	// projde celou zpravu a rozdeli ji na jednotlive prikazi
	for(i = 0; i < delka_retezce(data); i++)
	{
		j++;

		// konec prikazu
		if(data[i] == '\n')
		{
			// ze zpravy vykopiruje aktualni prikaz
			kopie_retezce(pomocny_ukazatel, &prikaz, (j-1));

			// pokud je z minuleho packetu ulozena cast prikazu, spoji se aktualne vykopirovanou casti
			if(*ocekavat_dalsi_prichozi && zprava->smer == prichozi)
			{
				prikaz = spoj_retezce(potreba_dokoncit_prichozi, delka_retezce(*potreba_dokoncit_prichozi), &prikaz, delka_retezce(prikaz));
				*ocekavat_dalsi_prichozi = 0;
			}
			else if(*ocekavat_dalsi_odchozi && zprava->smer == odchozi)
			{
				prikaz = spoj_retezce(potreba_dokoncit_odchozi,delka_retezce(*potreba_dokoncit_odchozi), &prikaz, delka_retezce(prikaz));
				*ocekavat_dalsi_odchozi = 0;
			}

			// zpracuje aktualne zuskany prikaz
			zpracuj_prikaz(prikaz, Sezeni, zprava->smer, &(zprava->cas_zachyceni));

			// posunuti ukazatele pro dalsi prikaz
			pomocny_ukazatel = pomocny_ukazatel + j;
			j = 0;
			// uvolneni pameti po zpracovani prikazu
			free(prikaz);
			prikaz = NULL;
		}
	}

	// prikaz neni kompletni a dalsi cast bude v pristim packetu
	if(data[i-1] != '\n')
	{
		// ulozeni prvni casti prikazu pro pozdejsi dokonceni
		if(zprava->smer == prichozi)
		{
			// jeste neni prikaz dokoncen ani ze dvou zprav
			if(*ocekavat_dalsi_prichozi)
			{
				char *dalsi_cast = NULL;
				kopie_retezce(pomocny_ukazatel, &dalsi_cast, delka_retezce(pomocny_ukazatel));
				*potreba_dokoncit_prichozi = spoj_retezce(potreba_dokoncit_prichozi, delka_retezce(*potreba_dokoncit_prichozi), &dalsi_cast, delka_retezce(dalsi_cast));
			}
			else
			{
				kopie_retezce(pomocny_ukazatel, potreba_dokoncit_prichozi, j);
				*ocekavat_dalsi_prichozi = 1;
			}
		}
		else if(zprava->smer == odchozi)
		{
			// jeste neni prikaz dokoncen ani ze dvou zprav
			if(*ocekavat_dalsi_odchozi)
			{
				char *dalsi_cast = NULL;
				kopie_retezce(pomocny_ukazatel, &dalsi_cast, delka_retezce(pomocny_ukazatel));
				*potreba_dokoncit_odchozi = spoj_retezce(potreba_dokoncit_odchozi, delka_retezce(*potreba_dokoncit_odchozi), &dalsi_cast, delka_retezce(dalsi_cast));
			}
			else
			{
				kopie_retezce(pomocny_ukazatel, potreba_dokoncit_odchozi, j);
				*ocekavat_dalsi_odchozi = 1;
			}
		}
	}
}

/*
 * ziskany prikaz rozdeli na jednotlive casti: prefix, prikaz a parametry
 */
void zpracuj_prikaz(char *prikaz, struct sezeni *Sezeni, int smer, struct timeval *cas_zachyceni)
{
	// struktura pro zpracovany vysledek
	struct irc_prikaz pozadavek = {NULL, NULL, NULL};

	int zacatek = 0;

	int ctu_prefix = 0;
	int ctu_prikaz = 0;


	if(prikaz[0] == ':')
	{
		ctu_prefix = 1;
	}
	else
	{
		ctu_prikaz = 1;
	}

	int i;
	for(i = 0 ; i < delka_retezce(prikaz) ; i++)
	{
		if(prikaz[i] == ' ')
		{
			if(ctu_prefix)
			{
				ctu_prefix = 0;
				ctu_prikaz = 1;
				kopie_retezce((prikaz + 1), &(pozadavek.prefix), i-1);
				zacatek = i+1;
			}
			else if(ctu_prikaz)
			{
				ctu_prikaz = 0;
				kopie_retezce((prikaz + zacatek), &(pozadavek.prikaz), i-zacatek);
				zacatek = i+1;
			}
		}
	}
	// prikaz nema parametry
	if(ctu_prikaz)
	{
		kopie_retezce((prikaz + zacatek), &(pozadavek.prikaz), (i-1)-zacatek);
	}
	else // cetli se parametry
	{
		kopie_retezce((prikaz + zacatek), &(pozadavek.parametry), delka_retezce(prikaz)-(zacatek+1)); // +1 kvuli znaku konce radku
	}

	identifikuj_pozadavek(&pozadavek, Sezeni, smer, cas_zachyceni);

	// uvolneni jiz zpracovaneho prikazu
	if(pozadavek.prefix != NULL)
	{
		free(pozadavek.prefix);
	}
	free(pozadavek.prikaz);

	if(pozadavek.parametry != NULL)
	{
		free(pozadavek.parametry);
	}
}

/*
 * identifikuje rozdeleny prikaz a podle neho upravi aktualni stav
 */
void identifikuj_pozadavek(struct irc_prikaz *pozadavek, struct sezeni *Sezeni, int smer, struct timeval *cas_zachyceni)
{
	int *aktualni_stav = &(Sezeni->aktualni_stav);
	if(porovnani_retezce(pozadavek->prikaz, "PASS"))
	{
		if(*aktualni_stav == NEPRIPOJEN)
		{
			*aktualni_stav = ODESLANO_HESLO;
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "NICK"))
	{
		if(Sezeni->ID_uzivatele == NULL)
		{
			char *id = prvni_parametr(pozadavek->parametry);
			Sezeni->ID_uzivatele = id;
		}

		if(*aktualni_stav == NEPRIPOJEN || *aktualni_stav == ODESLANO_HESLO)
		{
			*aktualni_stav = ODESLANA_PREZDIVKA;
		}

	}
	else if(porovnani_retezce(pozadavek->prikaz, "USER"))
	{
		if(*aktualni_stav == ODESLANA_PREZDIVKA)
		{
			*aktualni_stav = ODESLANO_JMENO;
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "LIST"))
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "TOPIC"))
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "JOIN") && smer == odchozi)
	{
//		Sezeni->pocet_kanalu = urci_pocet_kanalu(pozadavek->parametry);

		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			Sezeni->aktivni = 1;
			char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "JOIN") && smer == prichozi)
	{
		char *pomocny = urci_kanal(pozadavek->parametry);

		char *vytvorena_iri;
		if(Sezeni->aktivni)
		{
			vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, USPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		}
		else
		{
			vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, USPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		}
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "PART") && smer == odchozi)
	{
		*aktualni_stav = PRIHLASEN;
		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			Sezeni->aktivni = 1;
			char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}

		if(*aktualni_stav == PRIHLASEN)
		{
			int zacatek = 0;
			int mezera = 0;
			char *pomocny = NULL;

			if(pozadavek->parametry[0]== ':')
			{
				zacatek = 1;
			}

			for(int i = zacatek; i < delka_retezce(pozadavek->parametry) ; i++)
			{
				if(pozadavek->parametry[i] == ' ')
				{
					mezera = i;
				}
			}

			// kopie nazvu kanalu do pomocneho ukazatele
			kopie_retezce((pozadavek->parametry)+zacatek, &pomocny, (mezera-zacatek));

			char *vytvorena_iri;
			if(Sezeni->aktivni)
			{
				vytvorena_iri = vytvor_iri(IRI_END, IRC, Sezeni, TYP_ODPOJEN_OD_KANALU, USPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_ODPOJEN_OD_KANALU, USPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
			free(pomocny);
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "PRIVMSG") && smer == prichozi)
	{
		*aktualni_stav = PRIHLASEN;

		char *pomocny_odesilatel = odesilatel_podle_prefixu(pozadavek->prefix);

		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			Sezeni->aktivni = 1;
			char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, USPESNE, 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, IRC, Sezeni, TYP_PRIJATA_ZPRAVA, USPESNE, cas_zachyceni, NULL, pomocny_odesilatel, NULL, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, 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 if(porovnani_retezce(pozadavek->prikaz, "NOTICE") && smer == prichozi)
	{
		*aktualni_stav = PRIHLASEN;

		char *pomocny_odesilatel = odesilatel_podle_prefixu(pozadavek->prefix);

		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			Sezeni->aktivni = 1;
			char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, USPESNE, 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, IRC, Sezeni, TYP_PRIJATO_OZNAMENI, USPESNE, cas_zachyceni, NULL, pomocny_odesilatel, NULL, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIJATO_OZNAMENI, USPESNE, cas_zachyceni, NULL, pomocny_odesilatel, NULL, NULL);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
		if(pomocny_odesilatel != NULL)
		{
			free(pomocny_odesilatel);
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "PRIVMSG") && smer == odchozi)
	{
		*aktualni_stav = PRIHLASEN;

		char *pomocny_prijemce = prvni_parametr(pozadavek->parametry);

		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			Sezeni->aktivni = 1;
			char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, USPESNE, 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, IRC, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, cas_zachyceni, NULL, NULL, pomocny_prijemce, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, cas_zachyceni, NULL, NULL, pomocny_prijemce, NULL);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
		free(pomocny_prijemce);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "NOTICE") && smer == odchozi)
	{
		*aktualni_stav = PRIHLASEN;

		char *pomocny_prijemce = prvni_parametr(pozadavek->parametry);

		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			Sezeni->aktivni = 1;
			char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, USPESNE, 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, IRC, Sezeni, TYP_ODESLANO_OZNAMENI, USPESNE, cas_zachyceni, NULL, NULL, pomocny_prijemce, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_ODESLANO_OZNAMENI, USPESNE, cas_zachyceni, NULL, NULL, pomocny_prijemce, NULL);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
		free(pomocny_prijemce);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "SQUERY") && smer == odchozi)
	{
		*aktualni_stav = PRIHLASEN;

		char *pomocna_service = prvni_parametr(pozadavek->parametry);

		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			Sezeni->aktivni = 1;
			char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, USPESNE, 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, IRC, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, cas_zachyceni, NULL, NULL, NULL, pomocna_service);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_ODESLANA_ZPRAVA, USPESNE, cas_zachyceni, NULL, NULL, NULL, pomocna_service);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
		free(pomocna_service);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "QUIT") && smer == odchozi)
	{

		if(*aktualni_stav == PRIHLASEN)
		{
			*aktualni_stav = NEPRIPOJEN;
			char *vytvorena_iri;
			if(Sezeni->aktivni)
			{
				vytvorena_iri = vytvor_iri(IRI_END, IRC, Sezeni, TYP_ODHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_ODHLASEN, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);

			Sezeni->aktivni = 0;
			Sezeni->ukonceno = 1;
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "AWAY"))
	{

		if(*aktualni_stav == PRIHLASEN)
		{
			*aktualni_stav = NASTAVENI_AWAY;
		}
	}
	// odpovedi
	else if(porovnani_retezce(pozadavek->prikaz, "ERROR"))
	{
		if(*aktualni_stav != NEPRIPOJEN)
		{
			*aktualni_stav = NEPRIPOJEN;
			Sezeni->ukonceno = 1;
			char *vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIHLASEN, NEUSPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "001")) // RPL_WELCOME
	{

		char *id = prvni_parametr(pozadavek->parametry);
		Sezeni->ID_uzivatele = id;

		if(pozadavek->prefix != NULL)
		{
			kopie_retezce(pozadavek->prefix, &(Sezeni->server), delka_retezce(pozadavek->prefix));
		}

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

	}
	else if(porovnani_retezce(pozadavek->prikaz, "002")) // RPL_YOURHOST
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "003")) // RPL_CREATED
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "004")) // RPL_MYINFO
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "005")) // RPL_BOUNCE (presmerovani na jiny server. vetsinou kdyz je server plny)
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "020"))
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "302")) // RPL_USERHOST
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "305")) // RPL_UNAWAY
	{
		if(*aktualni_stav == NASTAVENI_AWAY)
		{
			*aktualni_stav = PRIHLASEN;
			char *vytvorena_iri;
			if(Sezeni->aktivni)
			{
				vytvorena_iri = vytvor_iri(IRI_CONTINUE, IRC, Sezeni, TYP_ONLINE, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_ONLINE, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "306")) // RPL_NOWAWAY
	{
		if(*aktualni_stav == NASTAVENI_AWAY)
		{
			*aktualni_stav = PRIHLASEN;
			char *vytvorena_iri;
			if(Sezeni->aktivni)
			{
				vytvorena_iri = vytvor_iri(IRI_CONTINUE, IRC, Sezeni, TYP_AWAY, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			}
			else
			{
				vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_AWAY, USPESNE, cas_zachyceni, NULL, NULL, NULL, NULL);
			}
			odesli_iri(vytvorena_iri);
			free(vytvorena_iri);
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "322")) // RPL_LIST
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "323")) // RPL_LISTEND
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "332")) // RPL_TOPIC
	{

	}

	// chybove odpovedi
	else if(porovnani_retezce(pozadavek->prikaz, "403")) // ERR_NOSUCHCHANNEL
	{
		char *pomocny = druhy_parametr(pozadavek->parametry);

		char *vytvorena_iri;
		vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, NEUSPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "405")) // ERR_TOOMANYCHANNELS
	{
		char *pomocny = druhy_parametr(pozadavek->parametry);

		char *vytvorena_iri;
		vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, NEUSPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "407")) //  ERR_TOOMANYTARGETS
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "421")) // ERR_UNKNOWNCOMMAND
	{
		if(*aktualni_stav == NASTAVENI_AWAY)
		{
			*aktualni_stav = PRIHLASEN;
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "437")) // ERR_UNAVAILRESOURCE
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "451")) // 
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "461")) // ERR_NEEDMOREPARAMS
	{

	}
	else if(porovnani_retezce(pozadavek->prikaz, "471")) // ERR_CHANNELISFULL
	{
		char *pomocny = druhy_parametr(pozadavek->parametry);

		char *vytvorena_iri;
		vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, NEUSPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "473")) // ERR_INVITEONLYCHAN
	{
		char *pomocny = druhy_parametr(pozadavek->parametry);

		char *vytvorena_iri;
		vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, NEUSPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "474")) // ERR_BANNEDFROMCHAN
	{
		char *pomocny = druhy_parametr(pozadavek->parametry);

		char *vytvorena_iri;
		vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, NEUSPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "475")) // ERR_BADCHANNELKEY
	{
		char *pomocny = druhy_parametr(pozadavek->parametry);

		char *vytvorena_iri;
		vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, NEUSPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "476")) // ERR_BADCHANMASK
	{
		char *pomocny = druhy_parametr(pozadavek->parametry);

		char *vytvorena_iri;
		vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, Sezeni, TYP_PRIPOJENI_KE_KANALU, NEUSPESNE, cas_zachyceni, pomocny, NULL, NULL, NULL);
		odesli_iri(vytvorena_iri);
		free(vytvorena_iri);
		free(pomocny);
	}
	else if(porovnani_retezce(pozadavek->prikaz, "PONG")) // 
	{
		if(pozadavek->prefix != NULL && Sezeni->server == NULL)
		{
			kopie_retezce(pozadavek->prefix, &(Sezeni->server), delka_retezce(pozadavek->prefix));
		}
	}
	else if(porovnani_retezce(pozadavek->prikaz, "")) // 
	{

	}
	else if(je_cislo(pozadavek->prikaz)) // jedna se o nejakou dalsi odpoved (ciselna hodnota prikazu)
	{
		if(Sezeni->ID_uzivatele == NULL)
		{
			char *id = prvni_parametr(pozadavek->parametry);
			Sezeni->ID_uzivatele = id;
		}

		if(pozadavek->prefix != NULL && Sezeni->server == NULL)
		{
			kopie_retezce(pozadavek->prefix, &(Sezeni->server), delka_retezce(pozadavek->prefix));
		}

		if((Sezeni->ID_uzivatele != NULL) && !Sezeni->aktivni)
		{
			if(*aktualni_stav == NEPRIPOJEN)
			{
				*aktualni_stav = PRIHLASEN;
				Sezeni->aktivni = 1;
				char *vytvorena_iri = vytvor_iri(IRI_BEGIN, IRC, Sezeni, TYP_PRIHLASEN, 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_irc(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, IRC, Sezeni, TYP_ODHLASEN, USPESNE, &(zprava->cas_zachyceni), NULL, NULL, NULL, NULL);
		}
		else
		{
			vytvorena_iri = vytvor_iri(IRI_REPORT, IRC, 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;
	}
}

/*
 * z retezce tvoriciho seznam parametru vrati prvni
 */
char *prvni_parametr(char *parametry)
{
	char *pomocny = NULL;
	int i = 0;
	for(i = 0 ; i < delka_retezce(parametry); i++)
	{
		if(parametry[i] == ' ' || parametry[i] == '\n')
		{
			break;
		}
	}

	if(i > 0)
	{
		kopie_retezce(parametry, &pomocny, i);
	}

	return pomocny;
}

/*
 * z retezce tvoriciho seznam parametru vrati druhy
 */
char *druhy_parametr(char *parametry)
{
	char *pomocny = NULL;
	int zacatek = 0;
	int i = 0;
	for(i = 0 ; i < delka_retezce(parametry); i++)
	{
		if(parametry[i] == ' ' && zacatek == 0)
		{
			zacatek = i+1;
		}
		else if(parametry[i] == ' ')
		{
			break;
		}
	}

	if(i > 0)
	{
		kopie_retezce(parametry+zacatek, &pomocny, i-zacatek);
	}

	return pomocny;
}

/*
 * urci jesli je v retezci ulozeno cislo (pro identifikaci ciselnych odpovedi)
 */
int je_cislo(char *retezec)
{
	char *error;
	errno = 0;

	int cislo = strtoul(retezec, &error, 10);

	if((errno == ERANGE && cislo == INT_MAX) ||(errno != 0 && cislo == 0))
	{
		return 0;
	}
	else if (error == retezec) 
	{
		return 0;
	}
	else
	{
		if (*error != '\0')
		{
			return 0;
		}
	}

	return 1;
}

/*
 * urci odesilatele podle prefixu prikazu
 */
char *odesilatel_podle_prefixu(char *prefix)
{
	if(prefix == NULL)
	{
		return NULL;
	}

	char *pomocny = NULL;
	int i = 0;
	for(i = 0 ; i < delka_retezce(prefix); i++)
	{
		if(prefix[i] == '!')
		{
			break;
		}
	}

	kopie_retezce(prefix, &pomocny, i);

	return pomocny;

}

/*
 * urci podle parametru pocet kanalu ke kterym se pripojuje
 */
int urci_pocet_kanalu(char *parametry)
{
	int pocet = 0;
	int i = 0;
	for(i = 0 ; i < delka_retezce(parametry) ; i++)
	{
		if(parametry[i] == ',' || parametry[i] == ' ')
		{
			pocet++;
		}
		
		if(parametry[i] == ' ')
		{
			break;
		}
	}

	if(i == delka_retezce(parametry))
	{
		pocet++;
	}

	return pocet;
}

/*
 * podle parametru prikazu join urci kanal
 */
char *urci_kanal(char *parametry)
{
	int zacatek = 0;
	if(parametry[0] == ':')
	{
		zacatek = 1;
	}

	char *pomocny = NULL;
	kopie_retezce(parametry+zacatek, &pomocny, delka_retezce(parametry)-zacatek);

	return pomocny;
}

