using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Vrh.OneReport.Lib.Areas.OneReport.Helpers
{
    public class LangHelperNS : LangHelper
    {

        private struct ItemSeparatorDescriptor
        {
            public string _start;
            public string _separator;
            public string _end;
        }

        #region static variables

        public static LangHelperNS QueryView = new LangHelperNS(QueryModuleNamespace + ".View.");
        public static LangHelperNS QueryXML = new LangHelperNS(QueryModuleNamespace + ".QueriesXml.");
        public static LangHelperNS UserQueryXML = new LangHelperNS(QueryModuleNamespace + ".");
        public static LangHelperNS ReportView = new LangHelperNS(ReportModuleNamespace + ".View.");
        public static LangHelperNS ReportXML = new LangHelperNS(ReportModuleNamespace + ".ReportsXml.");

        #endregion static variables


        public const string QueryModuleNamespace = "Query";

        public const string ReportModuleNamespace = "Report";

        public const string UNUSEDNS = "UNUSED";

        #region instance variables

        private string _namespace;

        private ItemSeparatorDescriptor _separators = new ItemSeparatorDescriptor();

        #endregion instance variables

        private LangHelperNS(string nameSpace)
        {
            _namespace = nameSpace;
            _separators._start = "#";
            _separators._separator = "#";
            _separators._end = "#";
        }

        public LangHelperNS(LangHelperNS orig, string startsep, string middlesep, string endsep)
            : base(orig)
        {
            _namespace = orig._namespace;
            _separators._start = startsep;
            _separators._separator = middlesep;
            _separators._end = endsep;
        }

        public override string GetTranslation(string WordCode, string defaultText = null)
        {
            return base.GetTranslation(_namespace + WordCode, defaultText);
        }

        public override void StoreTranslation(string WordCode, string text, string languageCode = "hu-HU")
        {
            base.StoreTranslation(_namespace + WordCode, text, languageCode);
        }

        public string TranslateText(string ns, string text)
        {
            string tmp, rv = string.Empty;
            string wcprefix = string.IsNullOrEmpty(ns) ? string.Empty : ns + ".";
            int pos = text.IndexOf(_separators._start), pos2, pos3;

            if (pos >= 0)
            {
                for (; pos >= 0; pos = text.IndexOf(_separators._start))
                {
                    if (pos > 0)
                        rv += text.Substring(0, pos);
                    tmp = text.Substring(pos + _separators._start.Length);
                    pos2 = tmp.IndexOf(_separators._separator);
                    if (pos2 >= 0)
                    {
                        string wordcode = wcprefix + tmp.Substring(0, pos2);
                        string defaulttext, result;

                        tmp = tmp.Substring(pos2 + _separators._separator.Length);
                        if ((pos3 = tmp.IndexOf(_separators._end)) >= 0)
                        {
                            defaulttext = tmp.Substring(0, pos3);
                            text = tmp.Substring(pos3 + _separators._end.Length);
                        }
                        else
                        {
                            defaulttext = tmp;
                            text = string.Empty;
                        }
                        if ((result = GetTranslation(wordcode, string.Empty)) == string.Empty)
                        {
                            StoreTranslation(wordcode, defaulttext);
                            result = defaulttext;
                        }
                        rv += result;
                    }
                    else if (!string.IsNullOrEmpty(_separators._end))
                    {
                        if ((pos3 = tmp.IndexOf(_separators._end)) >= 0)
                        {
                            rv += GetTranslation(wcprefix + tmp.Substring(0, pos3));
                            text = tmp.Substring(pos3 + _separators._end.Length);
                        }
                        else
                        {
                            rv += GetTranslation(wcprefix + tmp);
                            text = string.Empty;
                        }
                    }
                    else
                    {
                        rv += GetTranslation(wcprefix + tmp);
                        text = string.Empty;
                    }
                }
            }
            else
                rv = text;

            return rv;
        }

        private void InitializeTranslation(Dictionary<string, string> words, string languageCode = "hu-HU")
        {
            if (_CollectWordCodes && _usedWordCodes == null)
            {
                _usedWordCodes = new HashSet<string>();
            }
            LangHelper.InitializeTranslation(_namespace, words, languageCode, _usedWordCodes);
        }

        private void purgeUnusedWordCodes(string moduleNamespace, HashSet<string> stored)
        {
            if (_usedWordCodes != null && _namespace != null && _namespace.StartsWith(moduleNamespace + "."))
            {
                string group = _namespace.Substring(0, _namespace.Length - 1);

                stored.ExceptWith(_usedWordCodes);

                _usedWordCodes = null;
            }
        }

        public static void InitializeWordCodes()
        {
            LangHelperNS.QueryView.InitializeTranslation(new Dictionary<string, string>()
            {
                {"DateTime.PreviousMonth", "Előző hónap"},
                {"DateTime.NextMonth", "Következő hónap"},
                {"DateTime.TimeTitle", "Idő beállítása"},
                {"DateTime.TimeText", "Idő"},
                {"DateTime.HourText", "óra"},
                {"DateTime.MinuteText", "perc"},
                {"DateTime.SecondText", "mp"},
                {"DateTime.MillisecondText", "ms"},
                {"DateTime.DateFormat", "yyyy-MM-dd"},
                {"DateTime.ShortTimeFormat", "HH:mm"},
                {"DateTime.LongTimeFormat", "HH:mm:ss"},
                {"DateTime.MonthNames", "január,február,március,április,május,június,július,augusztus,szeptember,október,november,december"},
                {"DateTime.AbbreviatedMonthNames", "jan.,febr.,márc.,ápr.,máj.,jún.,júl.,aug.,szept.,okt.,nov.,dec."},
                {"DateTime.DayNames", "vasárnap,hétfő,kedd,szerda,csütörtök,péntek,szombat"},
                {"DateTime.AbbreviatedDayNames", "V,H,K,Sze,Cs,P,Szo"},
                {"DateTime.ShortestDayNames", "V,H,K,Sze,Cs,P,Szo"},
                {"DateTime.CloseButtonText", "Bezár"},
                {"DateTime.NowButtonText", "Most"},

                {"Datagrid.TextModeText", "Teszt üzemmód"},
                {"Datagrid.RowsCountText", "Talált sorok száma"},
                {"Datagrid.RowsPerPageText", "Sor/lap"},
                {"Datagrid.DisplayNthRecordText", "A {0}. rekord megnézése"},
                {"Datagrid.SimpleFilterButtonText", "Egyszerű szűrés"},
                {"Datagrid.SimpleFilterButtonHint", "Egyszerű szűrés bekapcsolása."},
                {"Datagrid.ApplyButtonText", "Alkalmaz"},
                {"Datagrid.ApplyButtonHint", "Az adatok frissítése."},
                {"Datagrid.ProgressTextForApplyButton", "Adatok frissítése folyamatban, kérem, várjon...."},
                {"Datagrid.DeleteButtonText", "Töröl"},
                {"Datagrid.DeleteButtonHint", "A szűrőfeltételek törlése és a szűrés elrejtése."},
                {"Datagrid.NoFilterText", "Nincs szűrés"},
                {"Datagrid.BackToListButtonText", "Visza a listához"},
                {"Datagrid.BackToListButtonHint", "Visza a listához"},
                {"Datagrid.SearchButtonText", "Keresés"},
                {"Datagrid.SearchButtonHint", "Keresés a sorba rendezett oszlop tartalmában."},
                {"Datagrid.ProgressTextForSearchButton", "Keresés folymatban, kérem, várjon..."},
                {"Datagrid.NextButtonText", "Következő"},
                {"Datagrid.NextButtonHint", "Rááll a következő illeszkedő elemre, ha van."},
                {"Datagrid.ProgressTextForNextButton", "Keresés folymatban..."},
                {"Datagrid.DefaultProgressText", "művelet végrehajtása folyamatban...."},
                {"Datagrid.NoMatchingDataText", "Nincs a keresésnek megfelelő érték."},
                {"Datagrid.NoMoreDataText", "Nincs már több illeszkedő érték."},

                {"Filters.SQLFilterLabel", "Általános SQL feltétel"},
                {"Filters.DeleteFilterButtonHint", "Feltétel törlése"},
                {"Filters.DeleteFilterConfirmText", "Biztosan törli a feltételt (és a hozzá tartozó feltételeket)?"},
                {"Filters.AddFilterButtonHint", "Feltétel hozzáadása"},
                {"Filters.AddFilterGroupButtonHint", "Zárójeles kifejezés hozzáadása"},
                {"Filters.CommonFilterText", "Azok a sorok, melyekre"},
                {"Filters.And", "és"},
                {"Filters.TestButtonText", "Tesztelés"},
                {"Filters.ProgressTextForTestButton", "Tesztadatok összegyűjtése folyamatban...."},

                {"Settings.Label", "Beállítások"},
                {"Settings.Hint", "A sor fölfelé vagy lefelé mozgatásával befolyásolható a lekérdezésben megjelemő oszlopok sorrendje."},
                {"Settings.ReferenceHint", "Hivatkozás"},
                {"Settings.LabelHint", "A lekérdezés fejlécében szerepló azonosító."},
                {"Settings.LabelText", "Címke"},
                {"Settings.DBFieldNameHint", "Az adatbázisban szerepló mezőazonosító."},
                {"Settings.DBFieldNameText", "Mezőnév"},
                {"Settings.FieldWidthHint", "A lekérdezés oszlopának szélessége (pixel)."},
                {"Settings.FieldWidthText", "Szélesség"},
                {"Settings.FieldVisibleHint", "Kikapcsolt állapotban a mezőhöz tartozó oszlop nem jelenik meg a lekérdezésben."},
                {"Settings.FieldVisibleText", "Látható"},
                {"Settings.CancelButtonText", "Módosítások elvetése"},

                {"Main.HelpLabel", "Súgó"},
                {"Main.SaveButtonText", "Mentés"},
                {"Main.SaveButtonHint", "Beállítások és szűrőfeltételek mentése"},
                {"Main.RenameButtonText", "Átnevezés"},
                {"Main.RenameButtonHint", "Mentett beállítások és szűrőfeltételek átnevezése"},
                {"Main.InputTextForRename", "Adja meg a beállítás új nevét!"},
                {"Main.CreateButtonText", "Új"},
                {"Main.CreateButtonHint", "Új tárolóhely beállítások és szűrőfeltételek mentéséhez"},
                {"Main.InputTextForCreate", "Adja meg az új beállítás nevét!"},
                {"Main.DeleteButtonText", "Törlés"},
                {"Main.InputTextForDelete", "Biztosan törölni kívánja a '{0}' beállítást?"},
                {"Main.DeleteButtonHint", "Aktuális beállítások és szűrőfeltételek törlése"},
                {"Main.FilterCheckBoxText", "Adatszűrés"},
                {"Main.FilterCheckBoxHint", "Szűrőfeltételek hatásának ideiglenes kikapcsolás a feltételek megtartásával."},
                {"Main.ProgresstextForFiltering", "Adatgyűjtés és frissítés folyamatban..."},
                {"Main.FilterButtonText", "Szűrés"},
                {"Main.FilterButtonHint", "Szűrőfeltételek"},
                {"Main.SettingsButtonText", "Beállítások"},
                {"Main.SettingsButtonHint", "Beállítások"},
                {"Main.RefreshButtonText", "Adatgyűjtés és frissítés"},
                {"Main.RefreshButtonHint", "Adatok ismételt előállítása az adatbázis pillanatnyi állapota alapján"},
                {"Main.ProgressTextForRefresh", "Adatgyűjtés és frissítés folyamatban..."},
                {"Main.DataExportButtonText", "Adatexportálás"},
                {"Main.DataExportButtonHint", "Adatok exportálása CSV formátumba"},
                {"Main.BackToQueryIndex", "Visszatérés a lekérdezés főképernyőjére"},
                {"Main.DefaultSettingsText", "Alapértelmezés"},
                {"Main.UnknownFormat", "Nem azonosítható formátum: {0}({1})"},

                {"Help.GeneralHelpTitle", "Általános ismertető"},

                {"Query.UnknownDataType", "Ismeretlen adattípus: {0}"},
                {"Query.NullValueText", "nincs megadva érték"},
                {"Query.NotNullValueText", "van megadva valamilyen érték"},
                {"Query.Operator.Equal", "egyenlő"},
                {"Query.True", "igaz"},
                {"Query.False", "hamis"},
                {"Query.Operator.NotEqual", "nem egyenlő"},
                {"Query.Operator.Between", "a következők között van:"},
                {"Query.Operator.GreaterThan", "nagyobb, mint"},
                {"Query.Operator.NotGreaterThan", "nem nagyobb, mint"},
                {"Query.Operator.NotLowerThan", "nem kisebb, mint"},
                {"Query.Operator.LowerThan", "kisebb, mint"},
                {"Query.Operator.Contains", "tartalmazza:"},
                {"Query.Operator.NotContains", "nem tartalmazza:"},
                {"Query.Operator.StartsWith", "így kezdődik:"},
                {"Query.Operator.NotStartsWith", "nem így kezdődik:"},
                {"Query.Operator.And", "a feltételek mindegyike teljesül"},
                {"Query.Operator.Or", "a feltételek közül legalább egy teljesül"},
                {"Query.Operator.NotAnd", "a feltételek közül legalább egy nem teljesül"},
                {"Query.Operator.NotOr", "a feltételek egyike sem teljesül"},
                {"Query.FieldRequired", "A mezőt ki kell tölteni!"},
                {"Query.UsersQueriesText", "{0} lekérdezései"},
                {"Query.UserText", "Felhasználó"},

                {"Query.UnknownTypeInGeneralText", "Ismeretlen típus: {0}, helye 'userroles/general'"},
                {"Query.UnknownTypeInListText", "Ismeretlen típus: {0}, lista ID: '{1}'"},
                {"Query.NoAccessRightText", "Nincs a '{0}' felhasználónak joga a '{1}/{2}' lekérdezéshez."},
                {"Query.UnknownTypeInQueryText", "Ismeretlen típus: {0}, lekérdezés ID: '{1}'"},
                {"Query.NoQueryXMLFileText", "Nincs megadva vagy nem létezik a lekérdezés-leíró fájl!"},
                {"Query.NoParameterNameText", "Névtelen SQL paraméter (XML rész: 'initcommand', fájlnév: '{0}')!"},
                {"Query.UnknownTypeInUserQueryText", "Ismeretlen típus: {0}, helye 'query', fájl: {1}"},
                {"Query.NoDatabaseConnectionStringText", "Nincs megadva adatbázis-kapcsolatleíró (lekérdezés ID: '{0)', fájl: {1}!"},
                {"Query.NoTableNameInQueryText", "Nincs megadva táblanév (lekérdezés ID: '{0)', fájl: {1}!"},
                {"Query.NoLinkNameInQueryText", "Nincs neve a hivatkozásnak (lekérdezés ID: '{0}', fájl: {1})!"},
                {"Query.DuplicateParameterNameInLinkText", "Duplikált paraméter: {0} (link: '{1}', fájl: {2})"},
                {"Query.UnknownTypeInLinkText", "Ismeretlen típus: {0}, link: '{1}', fájl: {2}"},
                {"Query.InvalidFieldDescriptorText", "Hibás mezőleíró, nincs 'ID' (fájl: {0})!"},
                {"Query.DuplicatedFieldDescriptorText", "Duplikált mezőleíró (ID: '{0}', fájl: {1})!"},
                {"Query.BadLinkInFieldDescriptorText", "Hibás hivatkozás, hiányzó 'link' attribútum (mező: '{0}', fájl: {1})!"},
                {"Query.MissingParameterNameInLinkInFieldDescriptorText", "Hibás hivatkozás, hiányzó paraméternév (mező: '{0}', link: '{1}',  fájl: {2})!"},
                {"Query.MissingParameterValueInLinkInFieldDescriptorText", "Hibás hivatkozás, hiányzó paraméterérték (mező: '{0}', link: '{1}', paraméter: '{2}',  fájl: {3})!"},
                {"Query.DuplicatedParameterNameInLinkInFieldDescriptorText", "Hibás hivatkozás, duplikált paraméter (mező: '{0}', link: '{1}', paraméter: '{2}',  fájl: {3})!"},
                {"Query.DuplicatedLinkInFieldDescriptorText", "Duplikált hivatkozás (cél lekérdezés: '{0}', link: '{1}',  fájl: {2})!"},
                {"Query.BadOrMissingFileNameText", "Nincs megadva vagy hibás a lista fájl neve (lista ID: '{0}')"},
                {"Query.NoNameInSubQueryText", "Nincs neve az allekérdezésnek (lekérdezés ID: '{0}', fájl: {1})!"}
            });
            LangHelperNS.ReportView.InitializeTranslation(new Dictionary<string, string>()
            {
                {"DateTime.PreviousMonth", "Előző hónap"},
                {"DateTime.NextMonth", "Következő hónap"},
                {"DateTime.TimeTitle", "Idő beállítása"},
                {"DateTime.TimeText", "Idő"},
                {"DateTime.HourText", "óra"},
                {"DateTime.MinuteText", "perc"},
                {"DateTime.SecondText", "mp"},
                {"DateTime.MillisecondText", "ms"},
                {"DateTime.DateFormat", "yyyy-MM-dd"},
                {"DateTime.ShortTimeFormat", "HH:mm"},
                {"DateTime.LongTimeFormat", "HH:mm:ss"},
                {"DateTime.MonthNames", "január,február,március,április,május,június,július,augusztus,szeptember,október,november,december"},
                {"DateTime.AbbreviatedMonthNames", "jan.,febr.,márc.,ápr.,máj.,jún.,júl.,aug.,szept.,okt.,nov.,dec."},
                {"DateTime.DayNames", "vasárnap,hétfő,kedd,szerda,csütörtök,péntek,szombat"},
                {"DateTime.AbbreviatedDayNames", "V,H,K,Sze,Cs,P,Szo"},
                {"DateTime.ShortestDayNames", "V,H,K,Sze,Cs,P,Szo"},
                {"DateTime.CloseButtonText", "Bezár"},
                {"DateTime.NowButtonText", "Most"},

                {"Display.ListButton", "Lista készítése"},
                {"Display.ParametersButton", "Paraméterek módosítása"},

                {"Report.UnknownDataTypeText", "Ismeretlen adattípus: {0}, paraméter neve: {1}"},
                {"Report.UnknownOperatorText", "Ismeretlen operátor: '{0}', paraméter neve: {1}"},
                {"Report.FieldRequiredText", "A mezőt ki kell tölteni!"},
                {"Report.StringTooShortText", "Túl rövid a mező tartalma (min. {0} karakter kell)!"},
                {"Report.StringTooLongText", "Túl hosszú a mező tartalma (max. {0} karakter lehet)!"},
                {"Report.ValueTooSmallText", "Nagyobb értéket kell megadni (min. {0} kell)!"},
                {"Report.ValueTooLargeText", "Kisebb értéket kell megadni (max. {0} lehet)!"},
                {"Report.ValueNotFoundInDatabaseText", "Nincs ilyen érték az adatbázisban: {0}!"},
                {"Report.UsersReportsText", "{0} listái"},
                {"Report.UserText", "Felhasználó"},
                {"Report.UnknownTypeInGeneralText", "Ismeretlen típus: {0}, helye 'userroles/general'"},
                {"Report.UnknownTypeInListText", "Ismeretlen típus: {0}, lista ID: '{1}'"},
                {"Report.NoAccessRightText", "Nincs a '{0}' felhasználónak joga a '{1}/{2}' listához."},
                {"Report.UnknownTypeInReportText", "Ismeretlen típus: {0}, lista ID: '{1}'"},
                {"Report.DuplicateParameterNameText", "Duplikált paraméter (reportfile/param): {0}, lista ID: '{1}'"},
                {"Report.MissingParameterNameText", "Hiányzó paraméternév (reportfile/param), lista ID: '{0}'"},
                {"Report.NoParameterNameText", "Nincs neve a paraméternek (lista ID: '{0}')!"},
                {"Report.SpinControlMisuseText", "Spincontrol jelenleg csak egész számoknál használható (paraméter '{0}', lista ID: '{1}')"},
                {"Report.DuplicateSQLReplaceText", "Duplikált 'sqlreplace' azonosító: {0} (paraméter: '{1}', lista ID: '{2}')"},
                {"Report.InvalidReferenceDefinitionText", "Hibás referencia definíció, nincs 'sql' rész (paraméter: '{0}', lista ID: '{1}')"},
                {"Report.InvalidDatasetDefinitionText", "Hibás adatkapcsolatleíró (lista ID = {0}): nincs megadva név!"},
                {"Report.NoSQLParameterNameText", "Névtelen SQL paraméter (adatkapcsolat neve: '{0}', lista ID: '{1}')!"},
                {"Report.UnknownTypeInDatasetDescriptionText", "Hibás adatkapcsolatleíró (name = {0}): ismeretlen típus: {1} (lista ID: '{2}')!"},
                {"Report.NoDataCommandInDatasetDescriptionText", "Hibás adatkapcsolatleíró (name = {0}): nincs 'datacommand' elem (lista ID: '{1}')!"},
                {"Report.NoReportFileNameText", "Nncs megadva vagy hibás a report fájl neve (lista ID: '{0}')"}

            });
        }

        public static new HashSet<string> PurgeAllUnusedWordCodes(string moduleNamespace)
        {
            HashSet<string> stored = null;

            foreach (FieldInfo fieldInfo in typeof(LangHelperNS).GetFields(BindingFlags.Public | BindingFlags.Static).Where(x => x.FieldType == typeof(LangHelperNS)))
            {
                var item = fieldInfo.GetValue(null) as LangHelperNS;

                if (item != null)
                {
                    if (stored == null)
                        stored = item.GetStoredWordCodesForGroup(moduleNamespace);
                    item.purgeUnusedWordCodes(moduleNamespace, stored);
                }
            }

            if (stored == null)
            {
                stored = new HashSet<string>();
            }
            else
            {
                foreach (var wordcode in stored)
                {
                    LangHelperNS.QueryView.AddPrefixToWordCode(wordcode, UNUSEDNS);
                }
            }

            return stored;
        }
    }
}
