kbs.cs

using System;
using System.Collections;
using System.IO;
using System.Windows.Forms;
//--------------------------------------------------------
namespace KBS
{
	#region Definicie datovych typov v KBS

	public struct Tosobne_udaje
	{
		public string meno;
		public string priezvisko;
		public string c_obc_preuk;
		public string stredisko;
	};
	
 	public struct Tzamestnanec
	{
		public int osobne_cislo;
		public int telefon;

		public Tosobne_udaje osobne_udaje;
	};

	public struct Tlokacia
	{
		public string kod;
		public string nazov;
	};

	public struct Trecent_problem
	{
		public int		zamestnanec_oc;
		public int		riesitel_oc;
		public DateTime datum_a_cas;
	};

	public struct Tporucha
	{
		public bool		je_aktualna;
		public DateTime platnost_od;
		public DateTime platnost_do;
		public string	kod_lokacie;

		public Tproblem	problem;
	};

	public struct Tproblem
	{
		public string	dovod;
		public string	popis;
	};

	public struct Tsolution
	{
		public string skupina;
		public string podskupina;
		
		public int      nSyptomov;
		public Tsymptom []symptom;

		public string postup;
		//-------------------
		public int PocetZobrazeni;
	};

	public struct Tsymptom
	{
		public string popis;
		public bool   hodnota;
	};
	#endregion

	#region Hlavna trieda KSB - samotny KSB
	public class TKBS
	{
		#region Vlastnosti triedy KSB
		public Tzoznam_zamestnancov		zoznam_zamestnancov;
		public Tzoznam_lokacii			zoznam_lokacii;
		public Tzoznam_recent_problemov zoznam_recent_problemov;
		public Tzoznam_poruch			zoznam_poruch;
		public Tzoznam_solutions		zoznam_solutions;

        public int		stav;		// stav, v ktorom sa ZS nachadza
		public int		oper_id;	// osobne cislo HD operatora
		public int		user_id;	// osobne cislo volajuceho uzivatela
		public int		qStav;		// stav dotazovania sa

		public string	skupina;	// skupina a podskupina, v ktorej riesime
		public string	podskupina;

		public Tsymptom[]	SDone;	// zoznam uz odpovedanych symptomov
		public int			nSDone;	// pocet  uz odpovedanych symptomov

		public Tsymptom		currSymptom;	// aktualne dotazovany symptom

		#endregion
		#region Metody triedy KSB
		#region M: konstruktor
		public TKBS()
		{
			zoznam_zamestnancov		= new Tzoznam_zamestnancov();
			zoznam_lokacii			= new Tzoznam_lokacii();
			zoznam_recent_problemov = new Tzoznam_recent_problemov();
            zoznam_poruch			= new Tzoznam_poruch();
			zoznam_solutions		= new Tzoznam_solutions();

			this.SDone				= new Tsymptom[30];
		}
		#endregion
		#region M: nastavenie konkretneho stavu KSB
		public void ChodDoStavu(int stavTo, PZS_proj.Form1 MainForm)
		{
			this.stav = stavTo;
			
			/* Popis stavov po vykonani tychto metod:
			   --------------------------------------
			1 - vybraty operator. Tlacidla su [Novy hovor, Statistika, Pridaj poruchu]
			2 - zacaty novy hovor. Prebiehajuca identifikacia volajuceho.
			3 - volajuci identifikovany. Zistenie recent problemov
			4 - recent problemy vybavene. Cas zistit aktualne poruchy
			5 - vieme, ze aktualne poruchy pre usera su. Cas sa ho popytat.
			6 - uz vieme aky problem ma uzivatel, cas zobrazit vplyv
			7 - je cas na samotne vypytovanie sa ohladom uzivatelovych problemov.
			8 - mame solution, zobrazime ho a cakame na tlacitko
			9 - solution pomohol, cas ukoncit hovor
			*/

			switch(stav)
			{
				case  1: MainForm.SelectOperator(); break;
				case  2: MainForm.NovyHovor(); break;
				case  3: MainForm.IdentifikujVolajuceho(); break;
				case  4: MainForm.AktualnePoruchy(); break;
				case  5: MainForm.AktualnePoruchy2(); break;
				case  6: MainForm.VplyvNaProblem(); break;

				case  7: this.qStav = 0;
						 MainForm.Dotazovanie(); break;
				
				case  8: MainForm.ZobrazSolution(); break;
				case  9: MainForm.UkonciHovor(); break;
				case 10: MainForm.ZaznamenajProblem(); break;
			}
		}
		#endregion
		#region M: overenie recent problemov
		public bool RecentProblemy(PZS_proj.Form1 MainForm)
		{
			int recent_solver;
			string pom, name;

			MainForm.statusBar1.Text = "Overuju sa recent problemy";

			// skusime zistit ci za poslednu hodinu nieco bolo riesene
			recent_solver = this.zoznam_recent_problemov.GetRiesitel(user_id);

			// ak mame nedavneho riesitela
			if(recent_solver!=-1)
			{
				MainForm.TextOut.Clear();

				// ziskame meno posledneho riesitela; present1
				name = this.zoznam_zamestnancov.GetName(recent_solver);
				pom = "Posledny riesitel: " + name;

				MainForm.AddToTextOut("Za poslednu hodinu s uzivatelom bol rieseny problem.", false, true);
				MainForm.AddToTextOut(pom, true, false);
				MainForm.AddToTextOut("Ponuknite uzivatelovi moznost prepojit ho k jeho poslednemu riesitelovi a stlacte prislusne tlacidlo.", true, false);

				MainForm.TextOut.Visible  = true;
				MainForm.label1.Visible   = false;
				MainForm.textBox1.Visible = false;

				MainForm.btn1.Text = "Prepojit";
				MainForm.btn2.Text = "Pokracovat";

				MainForm.btn1.Visible = true;
				MainForm.btn2.Visible = true;
				MainForm.btn3.Visible = false;

				return true;
			}
			else	// ak nedavny riesitel neexistuje
			{
				MainForm.TextOut.Clear();

				MainForm.AddToTextOut("Za poslednu hodinu s uzivatelom NEBOL rieseny problem.", false, true);

				MainForm.TextOut.Visible  = true;
				MainForm.label1.Visible   = false;
				MainForm.textBox1.Visible = false;

				MainForm.btn2.Text = "Pokracovat";

				MainForm.btn1.Visible = false;
				MainForm.btn2.Visible = true;
				MainForm.btn3.Visible = false;

				return false;
			}
		}
		#endregion
		#region M: overenie aktualnych poruch
		public bool AktualnePoruchy(PZS_proj.Form1 MainForm)
		{
			string lokacia, lokacia_full;
			int i, cnt;
			Tporucha pom;

			MainForm.statusBar1.Text = "Overuju sa aktualne poruchy";

			// ziskame lokaciu zamestnanca; ziskaj lokaciu
			lokacia      = this.zoznam_zamestnancov.GetLocation(this.user_id);
			lokacia_full = this.zoznam_lokacii.GetNazov(lokacia);
			
			// preratame ci su poruchy aktualne (meni sa parameter 'je_aktualna'
			this.zoznam_poruch.OverAktualnostPoruch();
			
			// zistime, ci pre danu lokaciu je nejaka aktualna porucha
			cnt = this.zoznam_poruch.GetCount();

			// prejdeme zoznam aktualnych poruch; filter podla lokacie
			for(i=0; i<cnt; i++)
			{ 	// aktualne poruchy
				pom = this.zoznam_poruch.GetPorucha(i); 					
				// ak sme nasli aktualnu poruchu platnu pre danu lokaciu, tak vratime TRUE
				if(pom.je_aktualna==true && pom.kod_lokacie==lokacia)
					return true;
			}

			// inac je to FALSE
			return false;
		}
		#endregion
		#region M: overenie ci aktualna porucha ma vplyv na problem
		public Tporucha OverVplyvAktualnejPoruchy(string popis)  // over vplyv poruchy na problem
		{
			string lokacia, lokacia_full;
			int i, cnt;
			Tporucha pom;

			// ziskame lokaciu zamestnanca
			lokacia      = this.zoznam_zamestnancov.GetLocation(this.user_id);
			lokacia_full = this.zoznam_lokacii.GetNazov(lokacia);

			// zistime, ci pre danu lokaciu je nejaka aktualna porucha
			cnt = this.zoznam_poruch.GetCount();

			// prejdeme zoznam aktualnych poruch
			for(i=0; i<cnt; i++)
			{
				pom = this.zoznam_poruch.GetPorucha(i); // aktualne poruchy v lokacii
					
				// ak sme nasli aktualnu poruchu platnu pre danu lokaciu, tak vratime TRUE
				if(pom.je_aktualna==true && pom.kod_lokacie==lokacia && pom.problem.popis==popis)
					return pom;  //vplyv poruchy na problem
			}

			// inac je to FALSE
			pom = new Tporucha();
			pom.je_aktualna = false;
			return pom;
		}
		#endregion
		#region M: Pripravenie hlavneho okna pred hovorom.
		public void NaZaciatok(PZS_proj.Form1 MainForm)
		{
			MainForm.TextOut.Clear();

			MainForm.AddToTextOut("'Smooth Operator' je pripraveny na dalsi hovor...", false, true);

			MainForm.TextOut.Visible = true;
			//--------------------
			MainForm.btn1.Text = "Novy hovor";
			MainForm.btn2.Text = "Statistika";
			MainForm.btn3.Text = "Pridaj poruchu";

			MainForm.btn1.Visible = true;
			MainForm.btn2.Visible = true;
			MainForm.btn3.Visible = true;

			this.stav = 1;
			this.nSDone = 0;
		}
		#endregion
		#region M: riesenie Queries KBS
		public void GoQuery(PZS_proj.Form1 MainForm)
		{
			switch(this.qStav)
			{
				// ak sme presli vyber skupiny
				case 0:	qStav=1;
						MainForm.Dotazovanie();
						break;

				// ak sme presli vyber podskupiny
				case 1:	qStav=2;
					MainForm.Dotazovanie();
					break;
						
				// ak sme podskupinu ulozili
				case 2:	qStav=3;
					MainForm.Dotazovanie();
					break;

				// ak sme sa uz nieco opytali
				case 3:	qStav=4;
					MainForm.Dotazovanie();
					break;
			}

		}
		#endregion
		#region M: ziskaj dalsi symptom na pytanie sa
		public Tsymptom ZiskajMoznySymptom()
		{
			Tsymptom ret = new Tsymptom();
			Tsolution sol;
			int poc, i, poc2, j;

			// zistime pocet solutions
			poc = this.zoznam_solutions.GetCount();

			// prejdeme vsetky solutions
			for(i=0; i<poc; i++)
			{
				// ziskame solution z pozicie 'i', ak vyhovuje vsetkym trom podmienkam (if)
				// ziskaj mozny solution
				sol = this.zoznam_solutions.GetSolution(i); // solution

				// ak je to solution pre inu skupinu
				if(sol.skupina!=this.skupina)		
					continue;
				
				// ak je to solution pre inu podskupinu
				if(sol.podskupina!=this.podskupina)	
					continue;

				// ak solution nevyhovuje
				if(!this.SolutionVyhovuje(sol)) // pusti solution ak vyhovuje
					continue;

				// zistime kolko obsahuje konkretny solution symptomov
				poc2 = sol.nSyptomov;

				// prejdeme vsetky symptomy; ziskaj mozny symptom
				for(j=0; j<poc2; j++)						// ak sme nasli este nepytany
				if(!this.SymptomDotazovany(sol.symptom[j]))
					return sol.symptom[j];					// tak ho vratime; mozny symptom
			}

			// ak sme nenasli symptom na ktory by sa dalo pytat, tak vratime prazdnotu
			ret.popis   = "";
			ret.hodnota = false;

			return ret;
		}
		#endregion
		#region M: zistenie ci sa na symptom uz pytalo
		public bool SymptomDotazovany(Tsymptom symp)
		{
			int i;

			// prejdeme uz opytane symptomy
			for(i=0; i<this.nSDone; i++)
			if(this.SDone[i].popis == symp.popis)	// ak sa na dany symptom pytalo
				return true;						// vrat true

			return false;							// inac vrat false
		}
		#endregion
		#region M: zistenie ci je solution pouzitelne (ci sa nebije s odpovedanymi symptomami)
		public bool SolutionVyhovuje(Tsolution sol) //over ci je solutions vyhovujuce		{
			int i, j, poc;

			poc = sol.nSyptomov;

			// prejdeme uz opytane symptomy
			for(i=0; i<this.nSDone; i++)
			{
				// opytany symptom porovname so vsetkymi symptomami skumaneho solutionu
				for(j=0; j<poc; j++)
					if(this.SDone[i].popis == sol.symptom[j].popis) 
			// ak sedi popis (teda na symptom uz bolo odpovedane)
						if(this.SDone[i].hodnota != sol.symptom[j].hodnota)	
							return false;									// solution nevyhovuje 			}

			return true;							// inac vrat odpoved true
		}
		#endregion
		#region M: ak nejake solution ma splnene vsetky symptomy, vrati postup
		public string ZiskajPostupZoSolution()
		{
			int i, j, poc, sPoc;
			Tsolution sol;  // mozny solution
			bool SymOpytane, SymSedia;
			Trecent_problem rec = new Trecent_problem();
			
			DateTime dt = new DateTime();
			dt          = DateTime.Now;

			poc = this.zoznam_solutions.GetCount();

			//--------------------------------
			// prejdeme vsetky solution
			for(i=0; i<poc; i++)
			{
				// ziskam solution
				sol = this.zoznam_solutions.GetSolution(i);

				sPoc = sol.nSyptomov;

				// oznacime si, akoze sme sa uz na vsetky symptomy pytali a akoze vsetky sedia
				SymOpytane = true;
				SymSedia   = true;

				// prejdeme vsetky symptomy popisane v solutione; over ci vsetky symptomy potvrdene
				for(j=0; j<sPoc; j++)
				{	
					// ak sa na dany symptom este nepytalo
					if(!this.SymptomDotazovany(sol.symptom[j]))
						SymOpytane = false;						// zmenime priznak pytania sa...

					// ak bol symptom vyvrateny
					if(!this.SymptomPotvrdeny(sol.symptom[j]))
						SymSedia = false;						// zmenime priznak celkoveho overenia
				}

				// ak sme sa na vsetky symptomy uz pytali a vsetky sedia
				if(SymOpytane==true && SymSedia==true) //vysledok overenia
				{
					// inkrementujeme pocet zobrazeni; ziskaj postup solution					this.zoznam_solutions.SetUsageCount(i, (sol.PocetZobrazeni + 1));

					// ulozime si toto do recent problemov
					rec.riesitel_oc    = this.oper_id;
					rec.zamestnanec_oc = this.user_id;
					rec.datum_a_cas    = dt;

					this.zoznam_recent_problemov.Add(rec);

					// a recent problemy ulozime nanovo
					this.zoznam_recent_problemov.SaveToFile();

					// vratime postup
					return sol.postup;	
				}
			}
			//--------------------------------
			return "";							// inac vrat prazdnotu 
		}
		#endregion
		#region M: overenie, ci symptom bol potvrdeny pri dotazovani
		public bool SymptomPotvrdeny(Tsymptom sym)
		{
			int i;

			// prejdeme uz opytane symptomy
			for(i=0; i<this.nSDone; i++)
				if(this.SDone[i].popis == sym.popis)			// ak sa na dany symptom pytalo
				{
					if(this.SDone[i].hodnota == sym.hodnota)	// a pravdivostne hodnoty sedia
						return true;
					else
						return false;
				}

			return false;							// ak sa na symptom nepytalo, jeho pravdivost je 'false'
		}		
	
		#endregion
		#endregion
	};
	#endregion
	#region pomocna trieda 'zoznam_zamestnancov'
	public class Tzoznam_zamestnancov
	{
		#region vlastnosti triedy
		private System.Collections.ArrayList zoznam; 
		private int pocet;
		#endregion

		#region metody triedy
		#region konstruktor
		public Tzoznam_zamestnancov()
		{
			// vytvorenie zatial prazdneho arraylistu
			zoznam = new System.Collections.ArrayList();

			bool res;
			res = this.LoadFromFile();

			if(!res)
				MessageBox.Show("Chyba pri nacitavani zoznamu zamestnancov!", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		#endregion
		#region metoda na prevod Stringu na Int
		public int StrToInt(string s)
		{
			int res=0;
			int i,len;

			if(s==null)
				return 0;

			len=s.Length;

			for(i=0; i<len; i++)
                res = res*10 + (((int)s[i])-48);
 
			return res;
		}
		#endregion
		#region metoda na pridavanie do zoznamu
		public int Add(Tzamestnanec zamestnanec)
		{
			return zoznam.Add(zamestnanec);
		}
	
		#endregion
		#region metoda na odobranie zo zoznamu na pozicii 'index'
		public void Remove(int index)
		{
			zoznam.RemoveAt(index);
		}

		#endregion
		#region metoda na ziskanie poctu zamestnancov
		public int GetCount()
		{
			pocet = zoznam.Count;
			return pocet;
		}
	
		#endregion
		#region metoda na ziskanie zamestnanca z pozicie 'index'
		public Tzamestnanec GetZamestnanec(int index)
		{
			int cnt;
			Tzamestnanec dummy;

			cnt = this.GetCount();
		
			// overim ci index nie je presvihnuty
			if(index<0 || index>=cnt)
			{
				dummy = new Tzamestnanec();

				dummy.osobne_cislo = 0;
				dummy.telefon      = 0;
			
				return (Tzamestnanec) dummy;
			}
			else
				return (Tzamestnanec) zoznam[index];
		}

		#endregion
		#region metoda na nacitanie zoznamu zamestnancov zo suboru
		public bool LoadFromFile()
		{
			string str;
			StreamReader sr;
			FileInfo f;
			Tzamestnanec input;

			f = new FileInfo("zoznam_zamestnancov.txt");
		
			// ak subor neexistuje
			if(!f.Exists)
				return false;
			
			sr = f.OpenText();
        
			// ak bol problem s citanim suboru
			if(sr==null)
				return false;
	
			while(true)
			{
				if((str = sr.ReadLine())==null)
					break;
				
				input.osobne_cislo	= StrToInt(str);

				str = sr.ReadLine();
				input.telefon		= StrToInt(str);

				input.osobne_udaje.meno			= sr.ReadLine();
				input.osobne_udaje.priezvisko	= sr.ReadLine();
				input.osobne_udaje.c_obc_preuk	= sr.ReadLine();
				input.osobne_udaje.stredisko	= sr.ReadLine();

				// este precitame oddelovac riadkov
				str = sr.ReadLine();
				
				// pridame zamestnanca do zoznamu v pamati
				this.Add(input);
			}
			sr.Close();
			return true;
		}
		#endregion
		#region metoda na zistenie mena zamestnanca podla osobneho cisla
		public string GetName(int osobne_cislo)
		{
			int i,cnt;
			string name;
			Tzamestnanec dummy;

			cnt = this.GetCount();

			for(i=0; i<cnt; i++)
			{
				dummy = this.GetZamestnanec(i);

				if(dummy.osobne_cislo==osobne_cislo)
				{
					name = dummy.osobne_udaje.priezvisko + " " + dummy.osobne_udaje.meno;
					return name;
				}
			}

		return "neznamy_zamestnanec";
		}
		#endregion
		#region metoda na zistenie lokacie zamestnanca podla osobneho cisla
		public string GetLocation(int osobne_cislo)
		{
			int i,cnt;
			Tzamestnanec dummy;

			cnt = this.GetCount();

			for(i=0; i<cnt; i++)
			{
				dummy = this.GetZamestnanec(i);

				if(dummy.osobne_cislo==osobne_cislo)
					return dummy.osobne_udaje.stredisko;
			}

			return "neznamy_zamestnanec_-_nezname_stredisko";
		}
		#endregion
		#endregion
	}
	#endregion
	#region pomocna trieda 'zoznam_lokacii'
	public class Tzoznam_lokacii
	{
		#region vlastnosti triedy
		private System.Collections.ArrayList zoznam; 
		private int pocet;
		#endregion
		#region metody triedy
		#region konstruktor
		public Tzoznam_lokacii()
		{
			bool res;

			// vytvorenie zatial prazdneho arraylistu
			zoznam = new System.Collections.ArrayList();
			
			res = this.LoadFromFile();

			if(!res)
				MessageBox.Show("Chyba pri nacitavani lokacii!", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		#endregion
		#region metoda na pridavanie do zoznamu
		public int Add(Tlokacia lokacia)
		{
			return zoznam.Add(lokacia);
		}
		#endregion
		#region metoda na ziskanie poctu prvkov v zozname
		public int GetCount()
		{
			pocet = zoznam.Count;
			return pocet;
		}
	
		#endregion
		#region metoda na ziskanie nazvu lokacie podla kodu
		public string GetNazov(string kod)
		{
			int cnt,i;
			Tlokacia dummy;

			cnt = this.GetCount();

			for(i=0; i<cnt; i++)
			{
				dummy = (Tlokacia) zoznam[i];

				if(dummy.kod==kod)
					return dummy.nazov;
			}

			return ((string)"neznama lokacia");
		}

		#endregion
		#region M: ziskanie celeho nazvu lokacie podla indexu
		public string GetFullNazov(int index)
		{
			int cnt;
			Tlokacia dummy;

			cnt = this.GetCount();

			if(index>=0 && index<cnt)
			{
				dummy = (Tlokacia) zoznam[index];
				return dummy.nazov;
			}

			return ((string)"neznama lokacia");
		}
		#endregion
		#region M: ziskanie kodu lokacie podla indexu
		public string GetKod(int index)
		{
			int cnt;
			Tlokacia dummy;

			cnt = this.GetCount();

			if(index>=0 && index<cnt)
			{
				dummy = (Tlokacia) zoznam[index];
				return dummy.kod;
			}

			return ((string)"neznamy kod");
		}
		#endregion
		#region metoda na nacitanie zoznamu zamestnancov zo suboru
		public bool LoadFromFile()
		{
			string str;
			StreamReader sr;
			FileInfo f;
			Tlokacia input;

			f = new FileInfo("zoznam_lokacii.txt");
		
			// ak subor neexistuje
			if(!f.Exists)
				return false;
			
			sr = f.OpenText();
        
			// ak bol problem s citanim suboru
			if(sr==null)
				return false;
	
			while(true)
			{
				if((str = sr.ReadLine())==null)
					break;
				
				input.kod = str;

				str = sr.ReadLine();
				input.nazov = str;

				// pridame do zoznamu v pamati
				this.Add(input);
			}
			sr.Close();
			return true;
		}
		#endregion
		#endregion
	}

	#endregion
	#region pomocna trieda 'zoznam_recent_problemov'
	public class Tzoznam_recent_problemov
	{
		#region vlastnosti triedy
		private System.Collections.ArrayList zoznam; 
		private int pocet;
		#endregion
		#region metody triedy
		#region M: konstruktor
		public Tzoznam_recent_problemov()
		{
			bool res;

			// vytvorenie zatial prazdneho arraylistu
			zoznam = new System.Collections.ArrayList();
			
			res = this.LoadFromFile();

			if(!res)
				MessageBox.Show("Chyba pri nacitavani recent problemov!", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		#endregion
		#region M: pridavanie do zoznamu
		public int Add(Trecent_problem recent_problem)
		{
			return zoznam.Add(recent_problem);
		}
		#endregion
		#region M: ziskanie poctu prvkov v zozname
		public int GetCount()
		{
			pocet = zoznam.Count;
			return pocet;
		}
	
		#endregion
		#region M: prevod Stringu na Int
		public int StrToInt(string s)
		{
			int res=0;
			int i,len;

			if(s==null)
				return 0;

			len=s.Length;

			for(i=0; i<len; i++)
				res = res*10 + (((int)s[i])-48);
 
			return res;
		}
		#endregion
		#region M: ziskanie osobneho cisla posledneho riesitela recent problemu za posledu hodinu uzivatela 
		public int GetRiesitel(int zamestnanec)
		{
			int cnt,i;
			Trecent_problem dummy;
			DateTime AktDT = DateTime.Now; // aktualny cas a datum
			TimeSpan ts;
			int os_c_min, minMin;

			os_c_min = 0;
			minMin   = 600;

			cnt = this.GetCount();
			//-----------------------
			// prehladame vsetky recent problemy; ziskaj recent problemy
			for(i=0; i<cnt; i++)
			{
				dummy = (Trecent_problem) zoznam[i];

				ts = AktDT - dummy.datum_a_cas;

				// ak sedi cislo zamestnanca a problem bol do hodiny, vrat osobne cislo riesitela
				// ziskaj riesitela recent problemu
				if(dummy.zamestnanec_oc==zamestnanec && ts.TotalMinutes<60 && minMin>ts.TotalMinutes)
				{
					os_c_min = dummy.riesitel_oc;
					minMin   = (int)ts.TotalMinutes;
				}
			}
			//-----------------------
			// ak sme nasli riesitela; riesitel
			if(os_c_min!=0)
					return os_c_min;
			else
					return -1;
		}
		#endregion
		#region M: nacitanie zoznamu recent problemov zo suboru
		public bool LoadFromFile()
		{
			string str;
			StreamReader sr;
			FileInfo f;
			Trecent_problem input;

			f = new FileInfo("zoznam_recent_problemov.txt");
		
			// ak subor neexistuje
			if(!f.Exists)
				return false;
			
			sr = f.OpenText();
        
			// ak bol problem s citanim suboru
			if(sr==null)
				return false;
	
			while(true)
			{
				if((str = sr.ReadLine())==null)
					break;
				
				input.zamestnanec_oc = this.StrToInt(str);

				if((str = sr.ReadLine())==null)
					break;

				input.riesitel_oc = this.StrToInt(str);

				str = sr.ReadLine();
				input.datum_a_cas = DateTime.Parse(str);

				// pridame do zoznamu v pamati
				this.Add(input);
			}
			sr.Close();
			return true;
		}
		#endregion
		#region M: ulozenie zoznamu recent problemov do suboru
		public void SaveToFile()
		{
			string str;
			StreamReader sr;
			int ind=0,cnt,i;
			Trecent_problem rec;

			// otvorime subor
			StreamWriter sw = new StreamWriter("zoznam_recent_problemov.txt");
					
			// ak bol problem s otvorenim
			if(sw==null)
				return;
			
			// prejdeme vsetky solutions
			cnt = this.GetCount();

			for(i=0; i<cnt; i++)
			{
				rec = (Trecent_problem) this.zoznam[i];

				sw.WriteLine("{0}", rec.riesitel_oc);
				sw.WriteLine("{0}", rec.zamestnanec_oc);
				sw.WriteLine("{0}", rec.datum_a_cas.ToString());
			}

			// zavrieme subor
			sw.Close();
		}
		#endregion
		#endregion
	}

	#endregion
	#region pomocna trieda 'zoznam_poruch'
	public class Tzoznam_poruch
	{
		#region vlastnosti triedy
		public System.Collections.ArrayList zoznam; 
		private int pocet;
		#endregion
		#region metody triedy
		#region konstruktor
		public Tzoznam_poruch()
		{
			bool res;

			// vytvorenie zatial prazdneho arraylistu
			zoznam = new System.Collections.ArrayList();
			
			res = this.LoadFromFile();

			if(!res)
				MessageBox.Show("Chyba pri nacitavani poruch!", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		#endregion
		#region metoda na pridavanie do zoznamu
		public int Add(Tporucha porucha)
		{
			return zoznam.Add(porucha);
		}
		#endregion
		#region metoda na ziskanie poctu prvkov v zozname
		public int GetCount()
		{
			pocet = zoznam.Count;
			return pocet;
		}
	
		#endregion
		#region metoda na prevod Stringu na Int
		public int StrToInt(string s)
		{
			int res=0;
			int i,len;

			if(s==null)
				return 0;

			len=s.Length;

			for(i=0; i<len; i++)
				res = res*10 + (((int)s[i])-48);
 
			return res;
		}
		#endregion
		#region metoda na nacitanie zoznamu poruch zo suboru
		public bool LoadFromFile()
		{
			string str;
			StreamReader sr;
			FileInfo f;
			Tporucha input = new Tporucha();

			f = new FileInfo("zoznam_poruch.txt");
		
			// ak subor neexistuje
			if(!f.Exists)
				return false;
			
			sr = f.OpenText();
        
			// ak bol problem s citanim suboru
			if(sr==null)
				return false;
	
			while(true)
			{
				if((str = sr.ReadLine())==null)
					break;

				input.platnost_od = DateTime.Parse(str);

				if((str = sr.ReadLine())==null)
					break;

				input.platnost_do = DateTime.Parse(str);

				input.kod_lokacie	= sr.ReadLine();

				input.problem.dovod = sr.ReadLine();
				input.problem.popis = sr.ReadLine();

				// este nacitame oddelovac
				str = sr.ReadLine();

				// pridame do zoznamu v pamati
				this.Add(input);
			}
			sr.Close();
			return true;
		}
		#endregion
		#region metoda na ulozenie zoznamu poruch do suboru
		public bool SaveToFile()
		{
			Tporucha output = new Tporucha();
			int i,cnt;

			StreamWriter sw = new StreamWriter("zoznam_poruch.txt");
		
			// ak bol problem s citanim suboru
			if(sw==null)
				return false;
	
			cnt = this.GetCount();

			for(i=0; i<cnt; i++)
			{
				output = (Tporucha) this.zoznam[i];

				sw.WriteLine("{0}", output.platnost_od.ToString());
				sw.WriteLine("{0}", output.platnost_do.ToString());

				sw.WriteLine("{0}", output.kod_lokacie);
				sw.WriteLine("{0}", output.problem.dovod);
				sw.WriteLine("{0}", output.problem.popis);

				sw.WriteLine("-----------------------------------");
			}

			sw.Close();

			return true;
		}
		#endregion
		#region metoda na ziskanie poruchy z pozicie 'index'
		public Tporucha GetPorucha(int index)
		{
			int cnt;
			Tporucha dummy;

			dummy.je_aktualna = false;

			cnt = this.GetCount();
		
			// overim ci index nie je presvihnuty
			if(index<0 || index>=cnt)
			{
				dummy = new Tporucha();

				return (Tporucha) dummy;
			}
			else
				return (Tporucha) zoznam[index];
		}
		#endregion
		#region M: nastavenie atributu 'je_aktualna' na pozicii 'index'
		public void SetAktualna(int index, bool val)
		{
			int cnt;
			Tporucha por;
			cnt = this.GetCount();
		
			// pre nepresvihnuty index nastavim parameter
			if(index>=0 || index<cnt)
			{
				por = (Tporucha) zoznam[index];
				por.je_aktualna = val;

				zoznam[index] = por;
			}
		}
		#endregion
		#region M: metoda na zistenie aktualnych poruch v aktualnom case. Nic nevracia, len nastavuje vlastnost je_aktualna
		public void OverAktualnostPoruch() // ziskaj aktualne poruchy
		{
			DateTime AktDT = DateTime.Now; // aktualny cas a datum
			TimeSpan ts1, ts2;
			int Minut1, Minut2, i, cnt;
			Tporucha por;

			cnt = this.GetCount();

			for(i=0; i<cnt; i++)
			{
				por = this.GetPorucha(i);

				// vypocitame, ako dlho porucha trva
				ts1 = por.platnost_do - por.platnost_od;
				Minut1 = (int) ts1.TotalMinutes;

				// vypocitame, ako daleko sme od zaciatku poruchy
				ts2 = AktDT - por.platnost_od;
				Minut2 = (int) ts2.TotalMinutes;

				// ak porucha este nenastala (je planovana, v buducnosti)
				if(Minut2<0)
				{
					this.SetAktualna(i, false);
					return;
				}

				// ak sme v case poruchy, porucha je aktualna
				if(Minut2<=Minut1)
				{
					this.SetAktualna(i, true);
					return;
				}

				// v ostatnych pripadoch je neaktualna
				this.SetAktualna(i, false);
			}
		}
		#endregion

		#endregion
	}
	#endregion
	#region pomocna trieda 'zoznam_solutions'
	public class Tzoznam_solutions
	{
		#region vlastnosti triedy
		public System.Collections.ArrayList zoznam; 
		private int pocet;
		public string[] skupiny;	// skupiny
		public string[] podskupiny;	

		#endregion
		#region metody triedy
		#region konstruktor
		public Tzoznam_solutions()
		{
			bool res;

			// vytvorenie zatial prazdneho arraylistu
			zoznam = new System.Collections.ArrayList();
			
			res = this.LoadFromFile();

			if(!res)
				MessageBox.Show("Chyba pri nacitavani solutions!", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		#endregion
		#region metoda na pridavanie do zoznamu
		public int Add(Tsolution solution)
		{
			return zoznam.Add(solution);
		}
		#endregion
		#region metoda na ziskanie poctu prvkov v zozname
		public int GetCount()
		{
			pocet = zoznam.Count;
			return pocet;
		}
	
		#endregion
		#region M: nacitanie zoznamu poruch zo suboru
		public bool LoadFromFile()
		{
			string str;
			StreamReader sr;
			FileInfo f;
			Tsolution input = new Tsolution();
			int poc;

			f = new FileInfo("zoznam_solutions.txt");
		
			// ak subor neexistuje
			if(!f.Exists)
				return false;
			
			sr = f.OpenText();
        
			// ak bol problem s citanim suboru
			if(sr==null)
				return false;
	
			while(true)
			{
				if((str = sr.ReadLine())==null)
					break;

				poc = 0;

				// nacitame skupinu a podskupinu
				input.skupina    = str;
				input.podskupina = sr.ReadLine();

				input.symptom = new Tsymptom[20];

				// nacitame symptomy
				while(true)
				{
					// nacitame 'hlavicku' bloku
					str = sr.ReadLine();
					
					// ked uz je dalej iba solution, tak skonci cyklus
					if(str=="-> Solution")
						break;

					// ked sa jedna o solution, nacitame to
					if(str=="-> Symptom")
					{
						input.symptom[poc].popis = sr.ReadLine();
						
						// nacitame datovy typ hodnoty. Zatial len bool, takze ignorujeme
						str = sr.ReadLine();

						// nacitame pravdivostnu hodnotu
						str = sr.ReadLine();
                        
						if(str=="true")
							input.symptom[poc].hodnota = true;
						else
							input.symptom[poc].hodnota = false;

						poc++;

						input.nSyptomov = poc;
					}
				}

				// nacitame solution
				input.postup = sr.ReadLine();

				// este nacitame oddelovac
				str = sr.ReadLine();

				// pridame do zoznamu v pamati
				this.Add(input);
			}
			sr.Close();

			// a este nacitame statistiky
			this.LoadStatistics();

			return true;
		}
		#endregion
		#region M: ziskaj solution z pozicie 'index'
		public Tsolution GetSolution(int index)
		{
			int cnt;
			Tsolution dummy;

			dummy = new Tsolution();
			dummy.nSyptomov = 0;

			cnt = this.GetCount();
		
			// overim ci index nie je presvihnuty
			if(index<0 || index>=cnt)
				return (Tsolution) dummy;
			else
				return (Tsolution) zoznam[index];
		}
		#endregion
		#region M: ziskanie nazvov vsetkych skupin
		public string[] GetSkupiny()
		{
			int pocet=0, i, poc;
			string []Skupiny;
			Tsolution sol;

			Skupiny = new string[20];

			// inicializujeme stringy prazdnymi stringami
			for(i=0; i<20; i++)
				Skupiny[i]="";

			// zistime kolko solutions mame
			poc = this.GetCount();

			// prejdeme vsetky solutions; najdi dalsiu solution
			for(i=0; i<poc; i++)
			{
				// ziskame solution z pozicie 'i'
				sol = this.GetSolution(i);

				// ak uz taku skupinu mame ulozenu, tak ideme na dalsie
				if(this.ArrayDoesContain(Skupiny, 20, sol.skupina))
					continue;

				// ulozime si nazov skupiny a zvysime pocitadlo stringov
				Skupiny[pocet] = sol.skupina;
				pocet++;
			}

			return Skupiny;
		}
		#endregion
		#region M: ziskanie nazvov vsetkych podskupin
		public string[] GetPodSkupiny(string InSkupina)
		{
			int pocet=0, i, poc;
			string []PodSkupiny;
			Tsolution sol;

			PodSkupiny = new string[20];

			// inicializujeme stringy prazdnymi stringami
			for(i=0; i<20; i++)
				PodSkupiny[i]="";

			// zistime kolko solutions mame
			poc = this.GetCount();

			// prejdeme vsetky solutions
			for(i=0; i<poc; i++)
			{
				// ziskame solution z pozicie 'i'
				sol = this.GetSolution(i);

				if(sol.skupina!=InSkupina)
					continue;

				// ak uz taku podskupinu mame ulozenu, tak ideme na dalsie
				if(this.ArrayDoesContain(PodSkupiny, 20, sol.podskupina))
					continue;

				// ulozime si nazov skupiny a zvysime pocitadlo stringov
				PodSkupiny[pocet] = sol.podskupina;
				pocet++;
			}

			return PodSkupiny;
		}
		#endregion
		#region M: zistenie, ci pole obsahuje dany retazec
		public bool ArrayDoesContain(string[] array, int count, string what)
		{
			int i;
			
			for(i=0; i<count; i++)
				if(array[i]==what)
					return true;

			return false;
		}
		#endregion
		#region M: nastav pocet pouziti solutionu na pozicii 'index'
		public void SetUsageCount(int index, int cnt)
		{
			int max;
			Tsolution dummy = new Tsolution();

			max = this.GetCount();
			
			// nastavim hodnotu 'PocetZobrazeni'
			if(index>=0 && index<max)
			{
				dummy = (Tsolution) zoznam[index];

				dummy.PocetZobrazeni = cnt;

				zoznam[index] = dummy;
			}
		}
		#endregion
		#region metoda na prevod Stringu na Int
		public int StrToInt(string s)
		{
			int res=0;
			int i,len;

			if(s==null)
				return 0;

			len=s.Length;

			for(i=0; i<len; i++)
				res = res*10 + (((int)s[i])-48);
 
			return res;
		}
		#endregion
		#region M: nacitanie poctu pouzitia solutions zo suboru
		public void LoadStatistics()
		{
			string str;
			StreamReader sr;
			FileInfo f;
			int ind=0,cnt;

			f = new FileInfo("statistics.txt");
		
			// ak subor neexistuje
			if(!f.Exists)
				return;
			
			sr = f.OpenText();
        
			// ak bol problem s citanim suboru
			if(sr==null)
				return;
	
			// v nekonecnom cykle nacitavame
			while(true)
			{
				// ak nic nenacitalo, EOF
				if((str = sr.ReadLine())==null)
					break;

				// prevedieme String na Int
				cnt = this.StrToInt(str);

				// ulozime
				this.SetUsageCount(ind, cnt);
				
				// inkrementujeme index
				ind++;
			}

			sr.Close();
		}
		#endregion
		#region M: ulozenie poctu pouzitia solutions do suboru
		public void SaveStatistics()
		{
			string str;
			StreamReader sr;
			FileInfo f;
			int ind=0,cnt,i;
			Tsolution sol;

			// otvorime subor
			StreamWriter sw = new StreamWriter("statistics.txt");
					
			// ak bol problem s otvorenim
			if(sw==null)
				return;
			
			// prejdeme vsetky solutions
			cnt = this.GetCount();

			for(i=0; i<cnt; i++)
			{
				sol = (Tsolution) this.zoznam[i];

				sw.WriteLine("{0}", sol.PocetZobrazeni);
			}

			// zavrieme subor
			sw.Close();
		}
		#endregion
		#region M: ziskaj solution, ktore bolo pouzite najviac krat
		public Tsolution GetSolutionMaxUsage()
		{
			int cnt, max=0, mInd=0, i;
			Tsolution dummy;

			dummy = new Tsolution();
			dummy.nSyptomov = 0;

			cnt = this.GetCount();
		
			// prejdem vsetky solutions
			for(i=0; i<cnt; i++)
			{
				// ziskam z pozicie 'i' 
				dummy = (Tsolution) zoznam[i];

				if(dummy.PocetZobrazeni > max)
				{
					max  = dummy.PocetZobrazeni;
					mInd = i;
				}
			}

			return (Tsolution) zoznam[mInd];
		}
		#endregion
		#endregion
	}
	#endregion
}