using Oracle.ManagedDataAccess.Client;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace co_zpracování
{
    internal static class Zpracovani
    {
        #region Zpracování       
        
        /// <summary>
        /// Zpracování slo souborů
        /// </summary>
        /// <param name="Zastavit"></param>
        /// <param name="Status"></param>
        /// <param name="soubor">Celá adresa souboru včetně přípony.</param>
        /// <param name="id">Login jméno</param>
        /// <param name="password">Login heslo</param>
        /// <param name="pocetAsync">Počet kolik audittrailů ze souboru se bude zpracovávat najednou paralelně</param>
        /// <returns></returns>
        public async static Task ZpracujSoubor(CancellationToken Zastavit, IProgress<Status> Progress, Soubor Adresar, string id, string password, int pocetAsync)
        {
            var task = Task.Run(async () =>
            {
                // --- 1 Získání základních údajů o úloze --- // (u automatického zpracování se využívá metoda HledejSoubor z třídy soubor přímo v metodě buttonu)
                
                string soubor = Adresar.AdrSouboru;
                string nazevSouboru = Soubor.GetSoubor(soubor);
                //Progress.Report(new Status(String.Format("Soubor - {0}; adresa souboru - {1}.", nazevSouboru, Adresar.AdrSouboru), "blue")); // zrušit
                //Thread.Sleep(6000);     // zrušit po testování vyjímek a soubor systému
                if (Zastavit.IsCancellationRequested)
                {
                    Adresar.MoveFile(soubor, Progress);
                    Zastavit.ThrowIfCancellationRequested();
                }
                //throw new FileFormatException();  // Zrušit po testování vyjímek a soubor systému

                // Rozloží název souboru na elementární informace
                int Rok = Soubor.GetRok(soubor);
                byte Kvartal = Soubor.GetKvartal(soubor);
                string Uloha = Soubor.GetUloha(soubor);
                RoleEnum Role = Soubor.GetRole(soubor);
                Kraje Kraj = Soubor.GetKraj(soubor);
                string TazSoubor = Soubor.GetTazSoubor(soubor);

                // odstraní z adresy příponu pro práci s rozzipovaným souborem (změnit podle toho, kam se bude rozzipovávat)
                string adresaSouboru = Path.Combine(Adresar.AdrTemp, nazevSouboru.Split('.')[0]);

                Progress.Report(new Status(String.Format("{0} - zahájení zpracování ({1}).", nazevSouboru, DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss")),"green"));
                if (Zastavit.IsCancellationRequested)
                {
                    Adresar.MoveFile(soubor, Progress);
                    Zastavit.ThrowIfCancellationRequested();
                }

                // --- 2 Rozzipování souboru --- //

                #region Unzip

                // Rozzipuje soubor
                Progress.Report(new Status(String.Format("{0} - rozzipování do {1}.", nazevSouboru, adresaSouboru), "black"));
                Adresar.Unzip(soubor, adresaSouboru, "eds_slo");
                if (Zastavit.IsCancellationRequested)
                {
                    Adresar.MoveFile(soubor, Progress);
                    Zastavit.ThrowIfCancellationRequested();
                }
                #endregion

                // --- 3 Zpracování kontaktů a pagin --- //
                // Staré kontakty maže a nahraje nové, paginy se aktualizují.

                #region Kontakty a Paginy
                // Vytvoří objekty s connection stringy
                Pagina orDbPagina = new Pagina(id, password);
                Kontakty orDbKontakt = new Kontakty(id, password);

                // Vytvoří název a zkontroluje existenci tabulek paginy a kontakty v Oracle
                orDbPagina.ConnOpen();
                string TabPaginaNazev = orDbPagina.TabulkaGetNazev(Uloha, Rok, Kvartal, Role);
                orDbPagina.ConnClose();
                orDbKontakt.ConnOpen();
                string TabKontaktNazev = orDbKontakt.TabulkaGetNazev(Uloha, Rok, Kvartal, Role);
                orDbKontakt.ConnClose();
                
                Progress.Report(new Status(String.Format("{0} - zpracování kontaktů a pagin.", nazevSouboru), "black"));
                await Task.Run(() => ZpracujPaginy(adresaSouboru, Rok, Kvartal, Uloha, Role, Kraj, TazSoubor, orDbPagina, TabPaginaNazev, orDbKontakt, TabKontaktNazev, id, password, Zastavit, Progress, Adresar, soubor));
                if (Zastavit.IsCancellationRequested)
                {
                    Adresar.MoveFile(soubor, Progress);
                    Zastavit.ThrowIfCancellationRequested();
                }
                #endregion

                // --- 4 Zpracování audittrailů --- //

                #region Audittrail
                // Vytvoří objekty s connection stringy
                Audittrail orDbAudittrail = new Audittrail(id, password);
                AudittrailChyba orDbAudittrailChyba = new AudittrailChyba(id, password);

                // Vytvoří název a zkontroluje existenci tabulek Audittrail a Audittrail_Chyba v Oracle
                orDbAudittrail.ConnOpen();
                string TabAudittrailNazev = orDbAudittrail.TabulkaGetNazev(Uloha, Rok, Kvartal, Role);
                orDbAudittrail.ConnClose();
                orDbAudittrailChyba.ConnOpen();
                string TabAudittrailChybaNazev = orDbAudittrailChyba.TabulkaGetNazev(Uloha, Rok, Kvartal, Role);
                orDbAudittrailChyba.ConnClose();

                // Vytvoří v Oracle tabulky 
                orDbAudittrail.VytvoritTabulku(TabAudittrailNazev);
                orDbAudittrailChyba.VytvoritTabulku(TabAudittrailChybaNazev);

                // Cesta vně rozzipovaného souboru k .adt souborům
                string AdtCesta = Path.Combine(adresaSouboru, string.Format("{0}.adt", Uloha));
                string[] Audittraily = Directory.GetFiles(adresaSouboru, "*.adt");
                string AdtSoubor = null;
                DataTable dtKontakty = orDbKontakt.VstupDoDotazniku1(TabKontaktNazev);

                #region Procházení adt po jednom (zakomentované)
                // Prochází .adt soubory ve slo souboru
                /*foreach (string adt in Audittraily)
                {
                    Zastavit.ThrowIfCancellationRequested();
                    string AdtBezPripony = Path.GetFileNameWithoutExtension(adt);
                    if (AdtBezPripony.Contains("_"))
                        AdtSoubor = Path.GetFileName(adt);
                    else
                        AdtSoubor = string.Format("{0}_{1}.adt", AdtBezPripony, TazSoubor);

                    Status.Report(String.Format("{0} - zpracování audittrailu {1}.", nazevSouboru, Path.GetFileName(adt)));

                    // Maže data z tabulky Audittrail a Audittail_Chyba podle názvu .adt souboru pro případ, že bylo zpracování přerušeno předčastně
                    orDbAudittrail.SmazatData(TabAudittrailNazev, AdtSoubor);
                    orDbAudittrailChyba.SmazatData(TabAudittrailChybaNazev, AdtSoubor);

                    // Zpracuje daný .adt soubor
                    await Task.Run(() => ZpracujAdt(adt, AdtSoubor, orDbAudittrail, TabAudittrailNazev, orDbAudittrailChyba, TabAudittrailChybaNazev, orDbKontakt, TabKontaktNazev, Zastavit));
                }*/
                #endregion
                #region Procházení adt po pěti (zakomentované)
                // Prochází .adt soubory ve slo souboru po pěti
                /*double pocetAdt = Math.Ceiling((double)Audittraily.Length / (double)5);
                int posledniAdt = 0;
                for (int i = 0; i < pocetAdt; i++)
                {
                    Task[] tasks = new Task[5];
                    int x = 0;
                    while (posledniAdt < Audittraily.Length && x < 5)
                    {
                        Zastavit.ThrowIfCancellationRequested();
                        string AdtBezPripony = Path.GetFileNameWithoutExtension(Audittraily[posledniAdt]);
                        if (AdtBezPripony.Contains("_"))
                            AdtSoubor = Path.GetFileName(Audittraily[posledniAdt]);
                        else
                            AdtSoubor = string.Format("{0}_{1}.adt", AdtBezPripony, TazSoubor);

                        Status.Report(String.Format("{0} - zpracování audittrailu {1}.", nazevSouboru, Path.GetFileName(Audittraily[posledniAdt])));

                        // Maže data z tabulky Audittrail a Audittail_Chyba podle názvu .adt souboru pro případ, že bylo zpracování přerušeno předčastně
                        orDbAudittrail.SmazatData(TabAudittrailNazev, AdtSoubor);
                        orDbAudittrailChyba.SmazatData(TabAudittrailChybaNazev, AdtSoubor);

                        //tasks[x] = Task.Run(() => ZpracujAdt(Audittraily[posledniAdt], AdtSoubor, orDbAudittrail, TabAudittrailNazev, orDbAudittrailChyba, TabAudittrailChybaNazev, orDbKontakt, TabKontaktNazev, Zastavit));
                        tasks[x] = ZpracujAdt(Audittraily[posledniAdt], AdtSoubor, orDbAudittrail, TabAudittrailNazev, orDbAudittrailChyba, TabAudittrailChybaNazev, orDbKontakt, TabKontaktNazev, Zastavit, dtKontakty);

                        posledniAdt++;
                        x++;
                    }
                    foreach(Task ukol in tasks)
                    {
                        /*if(ukol != null)
                            await ukol;
                if (ukol != null)
                            await Task.Run(() => ukol);
                    }                 
                }*/
                #endregion
                #region Procházení adt po stanoveném počtu dynamicky
                int posledniAdt = 0;
                Task[] tasks = new Task[pocetAsync];
                int Iterace = 0;
                while (posledniAdt < Audittraily.Length)
                {
                    while (posledniAdt < Audittraily.Length && Iterace < pocetAsync)
                    {
                        if (Zastavit.IsCancellationRequested)
                        {
                            Adresar.MoveFile(soubor, Progress);
                            Zastavit.ThrowIfCancellationRequested();
                        }

                        string AdtBezPripony = Path.GetFileNameWithoutExtension(Audittraily[posledniAdt]);
                        if (AdtBezPripony.Contains("_"))
                            AdtSoubor = Path.GetFileName(Audittraily[posledniAdt]);
                        else
                            AdtSoubor = string.Format("{0}_{1}.adt", AdtBezPripony, TazSoubor);
                        
                        Progress.Report(new Status(String.Format("{0} - zpracování audittrailu {1}.", nazevSouboru, Path.GetFileName(Audittraily[posledniAdt])), "black"));

                        // Maže data z tabulky Audittrail a Audittail_Chyba podle názvu .adt souboru pro případ, že bylo zpracování přerušeno předčastně
                        orDbAudittrail.SmazatData(TabAudittrailNazev, AdtSoubor);
                        orDbAudittrailChyba.SmazatData(TabAudittrailChybaNazev, AdtSoubor);

                        tasks[Iterace] = ZpracujAdt(Audittraily[posledniAdt], AdtSoubor, orDbAudittrail, TabAudittrailNazev, orDbAudittrailChyba, TabAudittrailChybaNazev, orDbKontakt, TabKontaktNazev, Zastavit, dtKontakty, Progress, Adresar, soubor);

                        posledniAdt++;
                        Iterace++;
                    }
                    for (int i = 0; i < pocetAsync; i++)
                    {
                        if (posledniAdt < Audittraily.Length && tasks[i] != null && tasks[i].IsCompleted)
                        {
                            await Task.Run(() => tasks[i]);

                            if (Zastavit.IsCancellationRequested)
                            {
                                Adresar.MoveFile(soubor, Progress);
                                Zastavit.ThrowIfCancellationRequested();
                            }

                            string AdtBezPripony = Path.GetFileNameWithoutExtension(Audittraily[posledniAdt]);
                            if (AdtBezPripony.Contains("_"))
                                AdtSoubor = Path.GetFileName(Audittraily[posledniAdt]);
                            else
                                AdtSoubor = string.Format("{0}_{1}.adt", AdtBezPripony, TazSoubor);
                            
                            Progress.Report(new Status(String.Format("{0} - zpracování audittrailu {1}.", nazevSouboru, Path.GetFileName(Audittraily[posledniAdt])), "black"));

                            // Maže data z tabulky Audittrail a Audittail_Chyba podle názvu .adt souboru pro případ, že bylo zpracování přerušeno předčastně
                            orDbAudittrail.SmazatData(TabAudittrailNazev, AdtSoubor);
                            orDbAudittrailChyba.SmazatData(TabAudittrailChybaNazev, AdtSoubor);

                            tasks[i] = ZpracujAdt(Audittraily[posledniAdt], AdtSoubor, orDbAudittrail, TabAudittrailNazev, orDbAudittrailChyba, TabAudittrailChybaNazev, orDbKontakt, TabKontaktNazev, Zastavit, dtKontakty, Progress, Adresar, soubor);

                            posledniAdt++;
                        }
                    }
                    if (posledniAdt == Audittraily.Length)
                    {
                        foreach (Task ukol in tasks)
                        {
                            if (ukol != null)
                                await ukol;
                        }
                    }                        
                }
                #endregion

                #endregion
                
                Progress.Report(new Status(String.Format("{0} - zpracování dokončeno.", nazevSouboru), "green"));
                Adresar.Dokonceno(soubor, Progress);
                orDbPagina.ConnClose();
                orDbKontakt.ConnClose();
                orDbAudittrail.ConnClose();
                orDbAudittrailChyba.ConnClose();
            });
            await task;
        }

        #endregion

        #region Audittrail

        /// <summary>
        /// Převod Audittrail do Oracle databáze
        /// </summary>
        /// <param name="adtCesta">Cesta přímo k soubůrům audittrailu</param>
        /// <param name="Soubor">název souboru uvnitř slo/slog/slogcr adresáře</param>
        /// <param name="orDbAudittrail"></param>
        /// <param name="TabAudittrailNazev"></param>
        /// <param name="orDbAudittrailChyba"></param>
        /// <param name="TabAudittrailChybaNazev"></param>
        /// <param name="orDbKontakt"></param>
        /// <param name="TabKontaktNazev"></param>
        public async static Task ZpracujAdt(string adtCesta, string Soubor, Audittrail orDbAudittrail, string TabAudittrailNazev, AudittrailChyba orDbAudittrailChyba, string TabAudittrailChybaNazev, Kontakty orDbKontakt, string TabKontaktNazev, CancellationToken Zastavit, DataTable dtKontakty, IProgress<Status> Progress, Soubor Adresar, string AdresaSouboru)
        {
            var task = Task.Run(() =>
            {
                string nazevSouboru = co_zpracování.Soubor.GetSoubor(AdresaSouboru);

                //DataTable dtKontakty = orDbKontakt.VstupDoDotazniku1(TabKontaktNazev);  // datatable s kontakty
                DataTable dtAudittrail = Audittrail.GetDt();
                DataTable dtAudittrailChyba = AudittrailChyba.GetDt();

                UInt64? PK = null;
                byte? PorKont = null;
                TimeSpan? RozdilCasu;
                string Akce;
                int? ID_Form = null;
                string Hodnota;
                string Hodnota_puvodni;
                string Field;
                string Status;
                string PricinaAkce;
                string Poznamka;
                string Paralelni_blok;
                string Prikaz;
                // -------------------------------------------------------------

                string TextRadku = "";  //Text aktuálního záznamu
                int RadekCislo = 0; //Číslo řádku aktuálního záznamu
                DateTime? DatumPredchozi = null;    //Datum predchoziho zaznamu 

                bool StartSessionJe; //Aktuální záznam je "StartSesion"
                bool StartSessionByl = false;   //"StartSesion" nebyl dosud ukončen
                DateTime StartSessionDatumACas = DateTime.Now; //Datum a čas posledního "StartSesion"
                int StartSessionCisloRadku = 0; //Číslo řádku při poslední akci "StartSesion"

                bool EnterFormJe;   //Aktuální záznam je "Enter Form"
                bool EnterFormByl = false;  //"Enter Form" nebyl dosud ukončen

                bool EnterFieldJe;  //Aktuální záznam je "EnterField"
                string EnterFieldNazev = "";    //Název fieldu při posledním záznamu "EnterField"
                string EnterFieldHodnota = "";  //Hodnota fieldu při posledním záznamu "EnterField"
                DateTime EnterFieldCas = DateTime.Now; //Datum a čas fildu při posledním záznamu "EnterField"
                TimeSpan? Field_Cas;

                string[] CastiSloupce;
                int RadkuCelkem = System.IO.File.ReadAllLines(adtCesta).Length;

                using (Microsoft.VisualBasic.FileIO.TextFieldParser tfp = new Microsoft.VisualBasic.FileIO.TextFieldParser(adtCesta, Encoding.GetEncoding(1250)))
                {

                    tfp.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
                    tfp.Delimiters = new string[] { "," };
                    tfp.HasFieldsEnclosedInQuotes = true;

                    string[] aktualniRadek;
                    //Loop through all of the fields in the file.
                    //If any lines are corrupt, report an error and continue parsing.
                    while (!tfp.EndOfData)
                    {
                        if (Zastavit.IsCancellationRequested)
                        {
                            Adresar.MoveFile(AdresaSouboru, Progress);
                            Zastavit.ThrowIfCancellationRequested();
                        }

                        //---definice proměných používaných pro uložení do databáze---
                        RozdilCasu = null;
                        Field_Cas = null;
                        Akce = null;
                        Hodnota = null;
                        Hodnota_puvodni = null;
                        Field = null;
                        Status = null;
                        PricinaAkce = null;
                        Poznamka = null;
                        Paralelni_blok = null;
                        Prikaz = null;
                        //-----------------------------------------
                        StartSessionJe = false;
                        EnterFormJe = false;
                        EnterFieldJe = false;



                        try
                        {
                            RadekCislo = Convert.ToInt32(tfp.LineNumber);
                            TextRadku = tfp.PeekChars(1000);
                            aktualniRadek = tfp.ReadFields();
                        }
                        // Include code here to handle the row.
                        catch (Microsoft.VisualBasic.FileIO.MalformedLineException ex)
                        {
                            AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, String.Format("Nepodařilo se separovat řádek. ({0})", ex));
                            continue;
                        }

                        try
                        {
                            CastiSloupce = aktualniRadek[1].Split(':');
                            switch (CastiSloupce[0])
                            {
                                case "Enter Field":
                                    Akce = "Enter Field";
                                    Field = CastiSloupce[1];
                                    EnterFieldJe = true;
                                    EnterFieldNazev = Field;
                                    EnterFieldCas = DateTime.Parse(aktualniRadek[0]);
                                    break;
                                case "Leave Field":
                                    Akce = "Leave Field";
                                    Field = CastiSloupce[1];
                                    if ((EnterFieldNazev == Field))
                                    {
                                        Hodnota_puvodni = EnterFieldHodnota;
                                        Field_Cas = DateTime.Parse(aktualniRadek[0]).Subtract(EnterFieldCas);
                                    }
                                    else
                                    {
                                        AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající EnterField");
                                    }

                                    break;
                                case "Start Session":
                                    Akce = "Start Session";
                                    StartSessionJe = true;
                                    StartSessionByl = true;
                                    StartSessionCisloRadku = RadekCislo;
                                    EnterFormByl = false;
                                    PorKont = null;
                                    //Proměnné EnterFieldNazev, EnterFieldHodnota se nenulují u "Leave Field",
                                    //protože Leave Field může nastat vícekrát za sebou
                                    EnterFieldNazev = "";
                                    EnterFieldHodnota = null;
                                    break;
                                case "End Session":
                                    Akce = "End Session";
                                    EnterFormByl = false;
                                    if (!StartSessionByl)
                                    {
                                        AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající StartSession");
                                    }

                                    StartSessionByl = false;
                                    break;
                                case "Enter Form":
                                    EnterFormByl = true;
                                    EnterFormJe = true;
                                    Akce = "Enter Form";
                                    ID_Form = Convert.ToInt32(CastiSloupce[1]);
                                    if (!StartSessionByl)
                                    {
                                        AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Před EnterForm nebyl nalezen StartSession");
                                    }

                                    break;
                                case "Leave Form":
                                    Akce = "Leave Form";
                                    if (!EnterFormByl)
                                    {
                                        AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající StartSession EnterForm");
                                    }

                                    break;
                                case "Action":
                                    Akce = CastiSloupce[1];
                                    break;
                                default:
                                    throw new NotImplementedException();
                            }

                            for (int i = 2; i <= (aktualniRadek.Length - 1); i++)
                            {
                                CastiSloupce = aktualniRadek[i].Split(':');
                                switch (CastiSloupce[0])
                                {
                                    case "Field":
                                        Field = CastiSloupce[1];
                                        break;
                                    case "Value":
                                        Hodnota = CastiSloupce[1];
                                        for (byte ics = 2; ics <= (CastiSloupce.Length - 1); ics++)   //'V textu se mohla nacházet dvojtečka, která text rozdělila na více částí
                                        {
                                            Hodnota += (":" + CastiSloupce[ics]);
                                        }

                                        if (EnterFieldJe)
                                        {
                                            EnterFieldHodnota = Hodnota;
                                        }

                                        break;
                                    case "Cause":
                                        PricinaAkce = CastiSloupce[1];
                                        break;
                                    case "Status":
                                        Status = CastiSloupce[1];
                                        break;
                                    case "Key":
                                        PK = Convert.ToUInt64(CastiSloupce[1].Replace(" ", "0")); //Nahrazení je nutné, protože u SILCU se vyskytuje čtyřmístná pagina
                                        break;
                                    case "Remark":
                                        Poznamka = CastiSloupce[1];
                                        for (byte ics = 2; ics <= (CastiSloupce.Length - 1); ics++)
                                        {
                                            Poznamka += (":" + CastiSloupce[ics]);  // V textu se mohla nacházet dvojteka;
                                        }

                                        break;
                                    case "Parallel":
                                        Paralelni_blok = CastiSloupce[1];
                                        break;
                                    case "Command":
                                        Prikaz = CastiSloupce[1];
                                        break;
                                    default:
                                        throw new NotImplementedException();
                                }
                            }
                            if (EnterFormJe)
                            {
                                //Nalezení kontaktu, který odpovídá vstupu do dotazníku - do 30 sec
                                DateTime StartSesionDatumACas_30s = StartSessionDatumACas.AddSeconds(-30);
                                string filtr = string.Format("PK = \'{0}\' AND ({1} = \'#{2}#\' OR {1} < \'#{2}#\')", PK, "DATUMODSYSTEMOVE", StartSessionDatumACas);
                                DataRow[] dr = dtKontakty.Select(filtr, "DATUMODSYSTEMOVE DESC");
                                if (((dr.Length > 0) && (Convert.ToDateTime(dr[0]["DATUMODSYSTEMOVE"]) >= StartSesionDatumACas_30s)))
                                {
                                    PorKont = byte.Parse(Convert.ToString(dr[0]["PORKONT"]));
                                }
                                else
                                {
                                    PorKont = null;
                                    //db.Audittrail_chyby_Vlozit(TabulkaPrefix, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající kontakt")
                                }
                                //Aktualizace předchozí akce "Start Session". Aktualizují se pole PK a ID_FORM
                                if (StartSessionByl)
                                {
                                    Audittrail_Aktualizovat(ref dtAudittrail, StartSessionCisloRadku, PK, PorKont, ID_Form);
                                }
                            }
                            if ((DatumPredchozi != null))
                            {
                                RozdilCasu = DateTime.Parse(aktualniRadek[0]).Subtract(Convert.ToDateTime(DatumPredchozi));
                            }
                            else
                            {
                                RozdilCasu = new TimeSpan();
                            }

                            //Uložení záznamu do databáze
                            Audittrail_Vlozit(ref dtAudittrail, RadekCislo, Soubor, PK, PorKont, Convert.ToDateTime(aktualniRadek[0]), TimeSpan.Parse(Convert.ToString(RozdilCasu)), Akce, ID_Form, Hodnota, Hodnota_puvodni, Field, Status, PricinaAkce, Poznamka, Paralelni_blok, Prikaz, Field_Cas);

                            if (StartSessionJe)
                            {
                                StartSessionDatumACas = DateTime.Parse(aktualniRadek[0]);
                            }

                            if (!EnterFormByl)
                            {
                                PK = null;
                                ID_Form = null;
                            }

                            DatumPredchozi = DateTime.Parse(aktualniRadek[0]);
                        }
                        catch (Exception ex)
                        {
                            AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, ex.Message);
                        }
                    }
                }

                if (Zastavit.IsCancellationRequested)
                {
                    Adresar.MoveFile(AdresaSouboru, Progress);
                    Zastavit.ThrowIfCancellationRequested();
                }

                orDbAudittrail.UlozData(TabAudittrailNazev, ref dtAudittrail);
                orDbAudittrailChyba.UlozData(TabAudittrailChybaNazev, ref dtAudittrailChyba);
            });
            await task;
        }
        /// <summary>
        /// Stará verze
        /// </summary>
        /// <param name="adtCesta">Cesta přímo k souborům audittrailu (uvnitř rozzipovaného slo souboru)</param>
        /// <param name="Soubor">Název .adt souboru uvnitř rozzipovaného slo souboru</param>
        /// <param name="orDbAudittrail"></param>
        /// <param name="TabAudittrailNazev"></param>
        /// <param name="orDbAudittrailChyba"></param>
        /// <param name="TabAudittrailChybaNazev"></param>
        /// <param name="orDbKontakt"></param>
        /// <param name="TabKontaktNazev"></param>
        /// <param name="zastavit"></param>
        public static void ZpracujAdt(string adtCesta, string Soubor, Audittrail orDbAudittrail, string TabAudittrailNazev, AudittrailChyba orDbAudittrailChyba, string TabAudittrailChybaNazev, Kontakty orDbKontakt, string TabKontaktNazev, CancellationToken zastavit)
        {

            DataTable dtKontakty = orDbKontakt.VstupDoDotazniku1(TabKontaktNazev);  // datatable s kontakty
            DataTable dtAudittrail = Audittrail.GetDt();
            DataTable dtAudittrailChyba = AudittrailChyba.GetDt();

            UInt64? PK = null;
            byte? PorKont = null;
            TimeSpan? RozdilCasu;
            string Akce;
            int? ID_Form = null;
            string Hodnota;
            string Hodnota_puvodni;
            string Field;
            string Status;
            string PricinaAkce;
            string Poznamka;
            string Paralelni_blok;
            string Prikaz;
            // -------------------------------------------------------------

            string TextRadku = "";  //Text aktuálního záznamu
            int RadekCislo = 0; //Číslo řádku aktuálního záznamu
            DateTime? DatumPredchozi = null;    //Datum predchoziho zaznamu 

            bool StartSessionJe; //Aktuální záznam je "StartSesion"
            bool StartSessionByl = false;   //"StartSesion" nebyl dosud ukončen
            DateTime StartSessionDatumACas = DateTime.Now; //Datum a čas posledního "StartSesion"
            int StartSessionCisloRadku = 0; //Číslo řádku při poslední akci "StartSesion"

            bool EnterFormJe;   //Aktuální záznam je "Enter Form"
            bool EnterFormByl = false;  //"Enter Form" nebyl dosud ukončen

            bool EnterFieldJe;  //Aktuální záznam je "EnterField"
            string EnterFieldNazev = "";    //Název fieldu při posledním záznamu "EnterField"
            string EnterFieldHodnota = "";  //Hodnota fieldu při posledním záznamu "EnterField"
            DateTime EnterFieldCas = DateTime.Now; //Datum a čas fildu při posledním záznamu "EnterField"
            TimeSpan? Field_Cas;

            string[] CastiSloupce;
            int RadkuCelkem = System.IO.File.ReadAllLines(adtCesta).Length;

            using (Microsoft.VisualBasic.FileIO.TextFieldParser tfp = new Microsoft.VisualBasic.FileIO.TextFieldParser(adtCesta, Encoding.GetEncoding(1250)))
            {

                tfp.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
                tfp.Delimiters = new string[] { "," };
                tfp.HasFieldsEnclosedInQuotes = true;

                string[] aktualniRadek;
                //Loop through all of the fields in the file.
                //If any lines are corrupt, report an error and continue parsing.
                while (!tfp.EndOfData)
                {
                    //if (worker.CancellationPending)
                    //{
                    //    e.Cancel = true;
                    //    worker.ReportProgress(0, new BgwReport("Audittrial - zpracování přerušeno uživatelem.", Color.Blue, true));
                    //    return;
                    //}

                    //worker.ReportProgress(int.Parse(Convert.ToString(100 * (tfp.LineNumber / RadkuCelkem))), new BgwReport(string.Format("Audittrial - řádek {0} z {1}.", tfp.LineNumber, RadkuCelkem), Color.Black, false));
                    zastavit.ThrowIfCancellationRequested();

                    //---definice proměných používaných pro uložení do databáze---
                    RozdilCasu = null;
                    Field_Cas = null;
                    Akce = null;
                    Hodnota = null;
                    Hodnota_puvodni = null;
                    Field = null;
                    Status = null;
                    PricinaAkce = null;
                    Poznamka = null;
                    Paralelni_blok = null;
                    Prikaz = null;
                    //-----------------------------------------
                    StartSessionJe = false;
                    EnterFormJe = false;
                    EnterFieldJe = false;



                    try
                    {
                        RadekCislo = Convert.ToInt32(tfp.LineNumber);
                        TextRadku = tfp.PeekChars(1000);
                        aktualniRadek = tfp.ReadFields();
                    }
                    // Include code here to handle the row.
                    catch (Microsoft.VisualBasic.FileIO.MalformedLineException ex)
                    {
                        AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, String.Format("Nepodařilo se separovat řádek. ({0})", ex));
                        continue;
                    }

                    try
                    {
                        CastiSloupce = aktualniRadek[1].Split(':');
                        switch (CastiSloupce[0])
                        {
                            case "Enter Field":
                                Akce = "Enter Field";
                                Field = CastiSloupce[1];
                                EnterFieldJe = true;
                                EnterFieldNazev = Field;
                                EnterFieldCas = DateTime.Parse(aktualniRadek[0]);
                                break;
                            case "Leave Field":
                                Akce = "Leave Field";
                                Field = CastiSloupce[1];
                                if ((EnterFieldNazev == Field))
                                {
                                    Hodnota_puvodni = EnterFieldHodnota;
                                    Field_Cas = DateTime.Parse(aktualniRadek[0]).Subtract(EnterFieldCas);
                                }
                                else
                                {
                                    AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající EnterField");
                                }

                                break;
                            case "Start Session":
                                Akce = "Start Session";
                                StartSessionJe = true;
                                StartSessionByl = true;
                                StartSessionCisloRadku = RadekCislo;
                                EnterFormByl = false;
                                PorKont = null;
                                //Proměnné EnterFieldNazev, EnterFieldHodnota se nenulují u "Leave Field",
                                //protože Leave Field může nastat vícekrát za sebou
                                EnterFieldNazev = "";
                                EnterFieldHodnota = null;
                                break;
                            case "End Session":
                                Akce = "End Session";
                                EnterFormByl = false;
                                if (!StartSessionByl)
                                {
                                    AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající StartSession");
                                }

                                StartSessionByl = false;
                                break;
                            case "Enter Form":
                                EnterFormByl = true;
                                EnterFormJe = true;
                                Akce = "Enter Form";
                                ID_Form = Convert.ToInt32(CastiSloupce[1]);
                                if (!StartSessionByl)
                                {
                                    AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Před EnterForm nebyl nalezen StartSession");
                                }

                                break;
                            case "Leave Form":
                                Akce = "Leave Form";
                                if (!EnterFormByl)
                                {
                                    AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající StartSession EnterForm");
                                }

                                break;
                            case "Action":
                                Akce = CastiSloupce[1];
                                break;
                            default:
                                throw new NotImplementedException();
                        }

                        for (int i = 2; i <= (aktualniRadek.Length - 1); i++)
                        {
                            CastiSloupce = aktualniRadek[i].Split(':');
                            switch (CastiSloupce[0])
                            {
                                case "Field":
                                    Field = CastiSloupce[1];
                                    break;
                                case "Value":
                                    Hodnota = CastiSloupce[1];
                                    for (byte ics = 2; ics <= (CastiSloupce.Length - 1); ics++)   //'V textu se mohla nacházet dvojtečka, která text rozdělila na více částí
                                    {
                                        Hodnota += (":" + CastiSloupce[ics]);
                                    }

                                    if (EnterFieldJe)
                                    {
                                        EnterFieldHodnota = Hodnota;
                                    }

                                    break;
                                case "Cause":
                                    PricinaAkce = CastiSloupce[1];
                                    break;
                                case "Status":
                                    Status = CastiSloupce[1];
                                    break;
                                case "Key":
                                    PK = Convert.ToUInt64(CastiSloupce[1].Replace(" ", "0")); //Nahrazení je nutné, protože u SILCU se vyskytuje čtyřmístná pagina
                                    break;
                                case "Remark":
                                    Poznamka = CastiSloupce[1];
                                    for (byte ics = 2; ics <= (CastiSloupce.Length - 1); ics++)
                                    {
                                        Poznamka += (":" + CastiSloupce[ics]);  // V textu se mohla nacházet dvojteka;
                                    }

                                    break;
                                case "Parallel":
                                    Paralelni_blok = CastiSloupce[1];
                                    break;
                                case "Command":
                                    Prikaz = CastiSloupce[1];
                                    break;
                                default:
                                    throw new NotImplementedException();
                            }
                        }
                        if (EnterFormJe)
                        {
                            //Nalezení kontaktu, který odpovídá vstupu do dotazníku - do 30 sec
                            DateTime StartSesionDatumACas_30s = StartSessionDatumACas.AddSeconds(-30);
                            string filtr = string.Format("PK = \'{0}\' AND ({1} = \'#{2}#\' OR {1} < \'#{2}#\')", PK, "DATUMODSYSTEMOVE", StartSessionDatumACas);
                            DataRow[] dr = dtKontakty.Select(filtr, "DATUMODSYSTEMOVE DESC");
                            if (((dr.Length > 0) && (Convert.ToDateTime(dr[0]["DATUMODSYSTEMOVE"]) >= StartSesionDatumACas_30s)))
                            {
                                PorKont = byte.Parse(Convert.ToString(dr[0]["PORKONT"]));
                            }
                            else
                            {
                                PorKont = null;
                                //db.Audittrail_chyby_Vlozit(TabulkaPrefix, RadekCislo, Soubor, TextRadku, "Nebyl nalezen odpovídající kontakt")
                            }
                            //Aktualizace předchozí akce "Start Session". Aktualizují se pole PK a ID_FORM
                            if (StartSessionByl)
                            {
                                Audittrail_Aktualizovat(ref dtAudittrail, StartSessionCisloRadku, PK, PorKont, ID_Form);
                            }
                        }
                        if ((DatumPredchozi != null))
                        {
                            RozdilCasu = DateTime.Parse(aktualniRadek[0]).Subtract(Convert.ToDateTime(DatumPredchozi));
                        }
                        else
                        {
                            RozdilCasu = new TimeSpan();
                        }

                        //Uložení záznamu do databáze
                        Audittrail_Vlozit(ref dtAudittrail, RadekCislo, Soubor, PK, PorKont, Convert.ToDateTime(aktualniRadek[0]), TimeSpan.Parse(Convert.ToString(RozdilCasu)), Akce, ID_Form, Hodnota, Hodnota_puvodni, Field, Status, PricinaAkce, Poznamka, Paralelni_blok, Prikaz, Field_Cas);

                        if (StartSessionJe)
                        {
                            StartSessionDatumACas = DateTime.Parse(aktualniRadek[0]);
                        }

                        if (!EnterFormByl)
                        {
                            PK = null;
                            ID_Form = null;
                        }

                        DatumPredchozi = DateTime.Parse(aktualniRadek[0]);
                    }
                    catch (Exception ex)
                    {
                        AudittrailChybaVlozit(ref dtAudittrailChyba, RadekCislo, Soubor, TextRadku, ex.Message);
                    }
                }
            }

            orDbAudittrail.UlozData(TabAudittrailNazev, ref dtAudittrail);
            orDbAudittrailChyba.UlozData(TabAudittrailChybaNazev, ref dtAudittrailChyba);
        }

        internal static void Audittrail_Vlozit(ref DataTable dtAudittrail, int Radek, string Soubor, UInt64? PK, byte? PorKont, DateTime? Datum_cas, TimeSpan RozdilCasu, string Akce, int? ID_Form, string Hodnota, string Hodnota_puvodni, string Field, string Status, string PricinaAkce, string Poznamka, string Paralelni_blok, string Prikaz, TimeSpan? Field_Cas)
        {
            DataRow dtRow = dtAudittrail.NewRow();
            dtRow["Radek"] = Radek;
            dtRow["Soubor"] = Soubor;
            dtRow["PK"] = Microsoft.VisualBasic.Interaction.IIf(PK != null, PK, DBNull.Value);
            dtRow["PorKont"] = Microsoft.VisualBasic.Interaction.IIf(PorKont != null, PorKont, DBNull.Value);
            dtRow["Datum_Cas"] = Convert.ToString(Datum_cas);
            string rz;
            if ((RozdilCasu.Ticks >= 0))
            {
                rz = string.Format("{0} {1}:{2}:{3}.{4}", RozdilCasu.Days, RozdilCasu.Hours, RozdilCasu.Minutes, RozdilCasu.Seconds, RozdilCasu.Milliseconds);
            }
            else
            {
                rz = string.Format("-{0} {1}:{2}:{3}.{4}", Math.Abs(RozdilCasu.Days), Math.Abs(RozdilCasu.Hours), Math.Abs(RozdilCasu.Minutes), Math.Abs(RozdilCasu.Seconds), Math.Abs(RozdilCasu.Milliseconds));
            }

            // dtRow("RozdilCasu") = rz
            dtRow["RozdilCasu"] = RozdilCasu;
            dtRow["Akce"] = Microsoft.VisualBasic.Interaction.IIf(Akce != null, Akce, DBNull.Value);
            dtRow["ID_Form"] = Microsoft.VisualBasic.Interaction.IIf(ID_Form != null, ID_Form, DBNull.Value);
            dtRow["Hodnota"] = Microsoft.VisualBasic.Interaction.IIf(Hodnota != null, Hodnota, DBNull.Value);
            dtRow["Hodnota_puvodni"] = Microsoft.VisualBasic.Interaction.IIf(Hodnota_puvodni != null, Hodnota_puvodni, DBNull.Value);
            dtRow["Field"] = Microsoft.VisualBasic.Interaction.IIf(Field != null, Field, DBNull.Value);
            dtRow["Status"] = Microsoft.VisualBasic.Interaction.IIf(Status != null, Status, DBNull.Value);
            dtRow["PricinaAkce"] = Microsoft.VisualBasic.Interaction.IIf(PricinaAkce != null, PricinaAkce, DBNull.Value);
            dtRow["Poznamka"] = Microsoft.VisualBasic.Interaction.IIf(Poznamka != null, Poznamka, DBNull.Value);
            dtRow["Paralelni_blok"] = Microsoft.VisualBasic.Interaction.IIf(Paralelni_blok != null, Paralelni_blok, DBNull.Value);
            dtRow["Prikaz"] = Microsoft.VisualBasic.Interaction.IIf(Prikaz != null, Prikaz, DBNull.Value);
            dtRow["Field_Cas"] = Microsoft.VisualBasic.Interaction.IIf(Field_Cas != null, Field_Cas, DBNull.Value);
            dtAudittrail.Rows.Add(dtRow);
        }

        internal static void Audittrail_Aktualizovat(ref DataTable dtAudittrail, int Radek, UInt64? PK, byte? PorKont, int? ID_Form)
        {
            DataRow[] dtRows = dtAudittrail.Select(string.Format("Radek={0}", Radek));
            if ((dtRows.Length == 1))
            {
                dtRows[0]["PK"] = Microsoft.VisualBasic.Interaction.IIf(PK != null, PK, DBNull.Value);
                dtRows[0]["PorKont"] = Microsoft.VisualBasic.Interaction.IIf(PorKont != null, PorKont, DBNull.Value);
                dtRows[0]["ID_Form"] = Microsoft.VisualBasic.Interaction.IIf(ID_Form != null, ID_Form, DBNull.Value);
            }
            else
            {
                throw new Exception("Nebyl nalezen jeden řádek.");
            }
        }

        static void AudittrailChybaVlozit(ref DataTable dtAudittrailChyba, int Radek, string Soubor, string Zdroj, string Chyba)
        {
            DataRow[] StejnyRadek = dtAudittrailChyba.Select(("Radek=" + Radek.ToString()));
            if ((StejnyRadek.Length == 0))
            {
                DataRow dtRow = dtAudittrailChyba.NewRow();
                dtRow["Radek"] = Radek;
                dtRow["Soubor"] = Soubor;
                dtRow["Zdroj"] = Zdroj;
                dtRow["Chyba"] = Chyba;
                dtAudittrailChyba.Rows.Add(dtRow);
            }
            else
            {
                StejnyRadek[0]["Chyba"] += Environment.NewLine + Chyba;
            }
        }

        #endregion

        #region Paginy a Kontakty (změnit help za Uloha)

        /// <summary>
        /// Nahrání pagin a kontaktů, paginy se nemažou ale aktualizují
        /// </summary>
        /// <param name="soubor">zde bude celá cesta včetně jména slo/slog/slogcr souboru</param>
        /// <param name="id"></param>
        /// <param name="password"></param>
        public static void ZpracujPaginy(string soubor, int Rok, byte Kvartal, string Uloha, RoleEnum Role, Kraje Kraj, string TazSoubor, Pagina orDbPagina, string TabPaginaNazev, Kontakty orDbKontakt, string TabKontaktNazev, string id, string password)
        {
            //string help = "ISD"; // pomocná testovací proměnná, vymazat a v kódu nahradit za Uloha (toto je při testování třeba vzhledem k tomu, že testovací soubor je původně ISD)
            orDbPagina.VytvoritTabulku(TabPaginaNazev);
            orDbKontakt.VytvoritTabulku(TabKontaktNazev);

            switch (Role)
            {
                case RoleEnum.Tazatel:
                    orDbKontakt.SmazatData(TabKontaktNazev, TabPaginaNazev, TazSoubor);
                    break;
                case RoleEnum.Garant:
                    orDbKontakt.SmazatData(TabKontaktNazev, Kraj);
                    break;
                case RoleEnum.SprávceČR:
                    orDbKontakt.SmazatData(TabKontaktNazev);
                    break;
                default:
                    throw new Exception("Špatný původ souboru.");
            }

            string dbKontaktCesta = Path.Combine(soubor, "Kontakty.mdb");

            if (!IsolatedStorage.ExistujeSoubor("MDB"))
            {
                var w = new HesloMDB();
                if (w.ShowDialog() == true)
                {
                    IsolatedStorage.ZapisSoubor("MDB", Krypt.Kryptuj(w.Heslo));
                }
                else
                {
                    throw new System.IO.FileNotFoundException("Šifrovaný soubor s heslem pro MDB souboty kontaktů nebyl nalezen.");
                }
            }
            string connStr = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"{0}\";Jet OLEDB:Database Password={1};", dbKontaktCesta, Krypt.Dekryptuj(IsolatedStorage.CtiSoubor("MDB")));

            // Poznámka: Right(Poznamka,2000) - pokud je více znaků, pak nelze zapstat do Oraclu
            string sql = string.Format("SELECT VAL(IIF([Pagina]<9999,[Okres] & '0' & [Pagina], [Okres] & [Pagina])) AS PK, " + " CisBytu, CisObec, ID_VyslSetr, ID_VyslSetr_Pred, " + "Modul, NazObec, ObdZar, OsobniCislo, PocClenDom, PocDom, PosNav, " + "Right(Poznamka,2000) As Poznamka, RefRok, RefObd, SO, TazSoubor, Vlna, VyslHD1, VyslHD2 " + "FROM Pagina " + "WHERE Uloha='{0}';", Uloha);  // změnit help => Uloha

            DataTable dtPagina = Pagina.GetDt();
            using (OleDbDataAdapter da = new OleDbDataAdapter(sql, connStr))
            {
                da.Fill(dtPagina);
            }

            using (OracleConnection ConnOra = new OracleConnection(dbBase.GetConnStr(id, password)))
            {
                using (OracleCommand cmd = new OracleCommand("SETDOM.Pagina_UPSERT_P", ConnOra))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("pNazevTabulky", OracleDbType.Varchar2);
                    cmd.Parameters[0].Value = "SETDOM." + TabPaginaNazev;
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PK());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_CisBytu());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_CisObec());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr_Pred());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Modul());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_NazObec());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ObdZar());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_OsobniCislo());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PocClenDom());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PocDom());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PosNav());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Poznamka());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_RefRok());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_RefObd());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_SO());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_TazSoubor());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Vlna());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_VyslHD1());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_VyslHD2());

                    ConnOra.Open();

                    foreach (DataRow dr in dtPagina.Rows)
                    {
                        //cmd.Parameters.Add("pNazevTabulky", OracleDbType.Varchar2);
                        //cmd.Parameters["pNazevTabulky"].Value = TabPaginaNazev;
                        cmd.Parameters["pPK"].Value = dr["PK"].ToString();
                        cmd.Parameters["pCisBytu"].Value = dr["CisBytu"];
                        cmd.Parameters["pCisObec"].Value = dr["CisObec"];
                        cmd.Parameters["pID_VyslSetr"].Value = dr["ID_VyslSetr"];
                        cmd.Parameters["pID_VyslSetr_Pred"].Value = dr["ID_VyslSetr_Pred"];
                        cmd.Parameters["pModul"].Value = dr["Modul"];
                        cmd.Parameters["pNazObec"].Value = dr["NazObec"];
                        cmd.Parameters["pObdZar"].Value = dr["ObdZar"];
                        cmd.Parameters["pOsobniCislo"].Value = dr["OsobniCislo"];
                        cmd.Parameters["pPocClenDom"].Value = dr["PocClenDom"];
                        cmd.Parameters["pPocDom"].Value = dr["PocDom"];
                        cmd.Parameters["pPosNav"].Value = dr["PosNav"];
                        cmd.Parameters["pPoznamka"].Value = dr["Poznamka"];
                        cmd.Parameters["pRefRok"].Value = dr["RefRok"];
                        cmd.Parameters["pRefObd"].Value = dr["RefObd"];
                        cmd.Parameters["pSO"].Value = dr["SO"];
                        cmd.Parameters["pTazSoubor"].Value = dr["TazSoubor"];
                        cmd.Parameters["pVlna"].Value = dr["Vlna"];
                        cmd.Parameters["pVyslHD1"].Value = dr["VyslHD1"];
                        cmd.Parameters["pVyslHD2"].Value = dr["VyslHD2"];
                        cmd.ExecuteNonQuery();
                    }
                }

                ConnOra.Close();
            }

            // Nahrání kontaktů
            // Poznámka: Right(Poznamka,2000) - pokud je více znaků, pak nelze zapstat do Oraclu
            // Okres<>0: filtrují se všeobecné kontakty (obnova ze zálohy, synchonizace, apod.)

            sql = string.Format("SELECT VAL(IIF([Pagina]<9999,[Okres] & '0' & [Pagina], [Okres] & [Pagina])) AS PK, " + "PorKont, DatumOdSkutecne, DatumDoSkutecne, " + "DatumOdSystemove, DatumDoSystemove, DatumDalsiSchuzka, " + "ID_VyslSetr, ID_Akce, OsobniCislo, Right(Poznamka,2000) As Poznamka, " + "Dalkove, Zobrazit " + "FROM Kontakt " + "WHERE Uloha='{0}' And Okres<>0;", Uloha);    // změnit help => Uloha

            DataTable dtKontakt = Kontakty.GetDt();

            using (OleDbDataAdapter da = new OleDbDataAdapter(sql, connStr))
            {
                da.Fill(dtKontakt);
            }

            foreach (DataRow dr in dtKontakt.Rows)
            {
                dr.SetAdded();
            }

            orDbKontakt.UlozData(TabKontaktNazev, ref dtKontakt);
            orDbPagina.ConnClose();
        }

        /// <summary>
        /// Nahrání pagin a kontaktů, paginy se nemažou ale aktualizují, Cancellation Token
        /// </summary>
        /// <param name="soubor"></param>
        /// <param name="Rok"></param>
        /// <param name="Kvartal"></param>
        /// <param name="Uloha"></param>
        /// <param name="Role"></param>
        /// <param name="Kraj"></param>
        /// <param name="TazSoubor"></param>
        /// <param name="orDbPagina"></param>
        /// <param name="TabPaginaNazev"></param>
        /// <param name="orDbKontakt"></param>
        /// <param name="TabKontaktNazev"></param>
        /// <param name="id"></param>
        /// <param name="password"></param>
        public static void ZpracujPaginy(string soubor, int Rok, byte Kvartal, string Uloha, RoleEnum Role, Kraje Kraj, string TazSoubor, Pagina orDbPagina, string TabPaginaNazev, Kontakty orDbKontakt, string TabKontaktNazev, string id, string password, CancellationToken Zastavit, IProgress<Status> Progress, Soubor Adresar, string AdresaSouboru)
        {
            string help = "ISD"; // pomocná testovací proměnná, vymazat a v kódu nahradit za Uloha (toto je při testování třeba vzhledem k tomu, že testovací soubor je původně ISD)
            string nazevSouboru = co_zpracování.Soubor.GetSoubor(AdresaSouboru);

            orDbPagina.VytvoritTabulku(TabPaginaNazev);
            orDbKontakt.VytvoritTabulku(TabKontaktNazev);

            switch (Role)
            {
                case RoleEnum.Tazatel:
                    orDbKontakt.SmazatData(TabKontaktNazev, TabPaginaNazev, TazSoubor);
                    break;
                case RoleEnum.Garant:
                    orDbKontakt.SmazatData(TabKontaktNazev, Kraj);
                    break;
                case RoleEnum.SprávceČR:
                    orDbKontakt.SmazatData(TabKontaktNazev);
                    break;
                default:
                    throw new Exception("Špatný původ souboru.");
            }

            string dbKontaktCesta = Path.Combine(soubor, "Kontakty.mdb");

            if (!IsolatedStorage.ExistujeSoubor("MDB"))
            {
                var w = new HesloMDB();
                if (w.ShowDialog() == true)
                {
                    IsolatedStorage.ZapisSoubor("MDB", Krypt.Kryptuj(w.Heslo));
                }
                else
                {
                    Adresar.MoveFile(AdresaSouboru, Progress);
                    Zastavit.ThrowIfCancellationRequested();
                }
            }
            string connStr = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"{0}\";Jet OLEDB:Database Password={1};", dbKontaktCesta, Krypt.Dekryptuj(IsolatedStorage.CtiSoubor("MDB")));

            // Poznámka: Right(Poznamka,2000) - pokud je více znaků, pak nelze zapstat do Oraclu
            string sql = string.Format("SELECT VAL(IIF([Pagina]<9999,[Okres] & '0' & [Pagina], [Okres] & [Pagina])) AS PK, " + " CisBytu, CisObec, ID_VyslSetr, ID_VyslSetr_Pred, " + "Modul, NazObec, ObdZar, OsobniCislo, PocClenDom, PocDom, PosNav, " + "Right(Poznamka,2000) As Poznamka, RefRok, RefObd, SO, TazSoubor, Vlna, VyslHD1, VyslHD2 " + "FROM Pagina " + "WHERE Uloha='{0}';", help/*Uloha*/);  // změnit help => Uloha

            DataTable dtPagina = Pagina.GetDt();
            using (OleDbDataAdapter da = new OleDbDataAdapter(sql, connStr))
            {
                da.Fill(dtPagina);
            }

            using (OracleConnection ConnOra = new OracleConnection(dbBase.GetConnStr(id, password)))
            {
                using (OracleCommand cmd = new OracleCommand("SETDOM.Pagina_UPSERT_P", ConnOra))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("pNazevTabulky", OracleDbType.Varchar2);
                    cmd.Parameters[0].Value = "SETDOM." + TabPaginaNazev;
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PK());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_CisBytu());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_CisObec());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ID_VyslSetr_Pred());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Modul());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_NazObec());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_ObdZar());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_OsobniCislo());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PocClenDom());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PocDom());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_PosNav());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Poznamka());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_RefRok());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_RefObd());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_SO());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_TazSoubor());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_Vlna());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_VyslHD1());
                    cmd.Parameters.Add(Pagina.GetParametrSloupec_VyslHD2());

                    ConnOra.Open();

                    foreach (DataRow dr in dtPagina.Rows)
                    {
                        if (Zastavit.IsCancellationRequested)
                        {
                            Adresar.MoveFile(AdresaSouboru, Progress);
                            Zastavit.ThrowIfCancellationRequested();
                        }
                        //cmd.Parameters.Add("pNazevTabulky", OracleDbType.Varchar2);
                        //cmd.Parameters["pNazevTabulky"].Value = TabPaginaNazev;
                        cmd.Parameters["pPK"].Value = dr["PK"].ToString();
                        cmd.Parameters["pCisBytu"].Value = dr["CisBytu"];
                        cmd.Parameters["pCisObec"].Value = dr["CisObec"];
                        cmd.Parameters["pID_VyslSetr"].Value = dr["ID_VyslSetr"];
                        cmd.Parameters["pID_VyslSetr_Pred"].Value = dr["ID_VyslSetr_Pred"];
                        cmd.Parameters["pModul"].Value = dr["Modul"];
                        cmd.Parameters["pNazObec"].Value = dr["NazObec"];
                        cmd.Parameters["pObdZar"].Value = dr["ObdZar"];
                        cmd.Parameters["pOsobniCislo"].Value = dr["OsobniCislo"];
                        cmd.Parameters["pPocClenDom"].Value = dr["PocClenDom"];
                        cmd.Parameters["pPocDom"].Value = dr["PocDom"];
                        cmd.Parameters["pPosNav"].Value = dr["PosNav"];
                        cmd.Parameters["pPoznamka"].Value = dr["Poznamka"];
                        cmd.Parameters["pRefRok"].Value = dr["RefRok"];
                        cmd.Parameters["pRefObd"].Value = dr["RefObd"];
                        cmd.Parameters["pSO"].Value = dr["SO"];
                        cmd.Parameters["pTazSoubor"].Value = dr["TazSoubor"];
                        cmd.Parameters["pVlna"].Value = dr["Vlna"];
                        cmd.Parameters["pVyslHD1"].Value = dr["VyslHD1"];
                        cmd.Parameters["pVyslHD2"].Value = dr["VyslHD2"];
                        cmd.ExecuteNonQuery();
                    }
                }

                ConnOra.Close();
            }

            // Nahrání kontaktů
            // Poznámka: Right(Poznamka,2000) - pokud je více znaků, pak nelze zapstat do Oraclu
            // Okres<>0: filtrují se všeobecné kontakty (obnova ze zálohy, synchonizace, apod.)

            sql = string.Format("SELECT VAL(IIF([Pagina]<9999,[Okres] & '0' & [Pagina], [Okres] & [Pagina])) AS PK, " + "PorKont, DatumOdSkutecne, DatumDoSkutecne, " + "DatumOdSystemove, DatumDoSystemove, DatumDalsiSchuzka, " + "ID_VyslSetr, ID_Akce, OsobniCislo, Right(Poznamka,2000) As Poznamka, " + "Dalkove, Zobrazit " + "FROM Kontakt " + "WHERE Uloha='{0}' And Okres<>0;", help/*Uloha*/);    // změnit help => Uloha

            DataTable dtKontakt = Kontakty.GetDt();

            using (OleDbDataAdapter da = new OleDbDataAdapter(sql, connStr))
            {
                da.Fill(dtKontakt);
            }

            foreach (DataRow dr in dtKontakt.Rows)
            {
                dr.SetAdded();
            }

            if (Zastavit.IsCancellationRequested)
            {
                Adresar.MoveFile(AdresaSouboru, Progress);
                Zastavit.ThrowIfCancellationRequested();
            }

            orDbKontakt.UlozData(TabKontaktNazev, ref dtKontakt);
            orDbPagina.ConnClose();
        }

        #endregion
    }
}
