/// Execute main logic for Index block
        public override void Execute()
        {
            if (pagesArray == null)
            {
                Initialize();
            }

            DataAccess.SetErrorDelegate(context.Response.End);

            var pageInfo = this.context.Request.TestPage(pagesArray, "home");

            // Test action name
            if (!pageInfo.ContainsKey("page"))
            {
                this.context.Response.End("Error in parameters -- no page");
                return;
            }

            var pageName  = (String)pageInfo["page"];
            var className = (String)pageInfo["class"];

            //this.context.Request.Initialize();
            if (INT(pageInfo["post_required"]) == 1)
            {
                this.context.Request.ExtractPostVars();
            }
            else
            {
                this.context.Request.ExtractAllVars();
            }
            //echo "In Index -- " . Print_r(this, true);
            this.context["Page"] = pageName;

            var apiName = (String)pageInfo["api"];

            this.context.Api = BLANK(apiName) ? "" : apiName; // Blank (html) or "rest" for now

            var engine = this.context.PushEngine(true);

            var prepare = new THashtable();

            prepare["[#Site_Name]"] = Config.SITE_NAME;
            var pFromVars  = this.context.Request.Contains("p") ? this.context.Request["p"] : "home";
            var idFromVars = this.context.Request.Contains("id") ? this.context.Request["id"] : null;
            var title      = Config.SITE_NAME;

            if (pFromVars != "home")
            {
                title = CAT(title, " :: ", pFromVars, (!NUL(idFromVars) ? CAT(" :: ", idFromVars) : null));
            }

            prepare["[#Title]"] = title; //TODO -- need unique title on each page
            prepare.Put("[#Keywords]",
                        this.context.TestRun ? Config.SITE_KEYWORDS :
                        Strings.Replace("[#Platform]", Config.PLATFORM, Config.SITE_KEYWORDS)
                        );
            prepare.Put("[#Description]",
                        this.context.TestRun ? Config.SITE_DESCRIPTION :
                        Strings.Replace("[#Platform]", Config.PLATFORM, Config.SITE_DESCRIPTION)
                        );
            prepare["[#Styles]"] = CAT(
                (this.context.TestRun ? null : Config.TOP_DIR),
                this.context.IsMobile ? "styles2" : "styles");
            prepare["[#ContentType]"] = "text/html; charset=UTF-8";
            prepare["[#Top]"]         = engine.IncludeTemplate("Top");
            prepare["[#Menu]"]        = engine.IncludeTemplate("Menu");

            // Get included page either from cache or build it from the scratch
            var errorContent = engine.IncludeTemplate(CAT("Pages/", className), "check");

            if (!BLANK(errorContent))
            {
                prepare["[#Page]"] = errorContent;
            }
            else
            {
                if (Config.CACHE_PAGES /* && !Config.DontCache.Contains(pageName)*/) //TODO!!!
                {
                    prepare["[#Page]"] = Util.ShowFromCache(engine, this.context.CacheFolder, pageName, className);
                }
                else
                {
                    prepare["[#Page]"] = engine.IncludeTemplate(CAT("Pages/", className));
                }
            }

            if (/*Config.RssAllowed != null && */ Config.SHOW_BOTTOM)
            {
                // Get bottom block either from cache or build it from the scratch
                if (Config.CACHE_PAGES)
                {
                    prepare["[#Bottom]"] = Util.ShowFromCache(engine, this.context.CacheFolder, BLANK(apiName) ? "bottom" : CAT(apiName, "_bottom"), "Bottom");
                }
                else
                {
                    prepare["[#Bottom]"] = engine.IncludeTemplate("Bottom");
                }
            }

            prepare.Put("[#Github_Repo]",
                        this.context.TestRun ? Config.GITHUB_REPO :
                        Strings.Replace("[#Platform]", Strings.ToLowerCase(Config.PLATFORM), Config.GITHUB_REPO)
                        );
            prepare.Put("[#Powered_By]",
                        this.context.TestRun ? Config.POWERED_BY :
                        Strings.Replace("[#Platform]", Config.PLATFORM, Config.POWERED_BY)
                        );

            this.context.Response.WriteHeader("Content-type", CAT(
                                                  (BLANK(apiName) ? "text/html" : Config.API_CONTENT), "; charset=UTF-8")
                                              );
            this.Write("index", prepare);

            // Fix <title>
            //TODO -- comment for now
            //newTitle = Util.ExtractInfo(content, "<input type=\"hidden\" name=\"s_Title\" value=\"", "\" />");
            //if (!BLANK(newTitle))
            //    content = Regex.Replace(content, "<title>(.*?)</title>", CAT("<title>", Config.SITE_NAME, " -- ", newTitle, "</title>"), RegexOptions.IgnoreCase);

            this.context.Response.Write(engine.GetPrintString());
            this.context.Response.End();
        }
        /// Execute main logic for Bottom block
        public override void Execute()
        {
            var prepare = new THashtable();

            prepare.Put("[#Items_By_Category]",
                        CAT(Config.NAME_ITEMS, "_by_", this.context["Name_Category"]));

            var doCategory = new DOCategory(this.context.Connection);
            var dsCategory = doCategory.EnumAll(Config.SHOW_EMPTY ? null : "_this.i_Counter <> 0",
                                                Config.SORT_CATEGORIES == null ? null : CAT("_this.", Config.SORT_CATEGORIES));
            var size  = dsCategory.GetSize();
            int size3 = size % 3;
            int n1    = INT(size / 3) + (size3 == 0 ? 0 : 1);
            int n2    = n1 * 2;

            Object[] nn           = ARR(0, n1, n2, size);
            var      filterBlocks = new TArrayList();

            for (int td = 0; td < 3; td++)
            {
                var filterBlock = new THashtable();
                var rows        = new TArrayList();
                for (int n = INT(nn[td]); n < INT(nn[td + 1]); n++)
                {
                    var oCategory = dsCategory.GetRow(n);
                    if (NUL(oCategory))
                    {
                        continue;
                    }
                    var counter = INT(oCategory["i_Counter"]);
                    if (Config.SHOW_EMPTY == false && INT(counter) == 0)
                    {
                        continue;
                    }
                    var key  = STR(oCategory["s_CatId"]);
                    var name = STR(oCategory["s_Name"]);
                    var row  = new THashtable();
                    row["[#Link]"]     = this.GetLink(Config.INDEX_PAGE, "?p=items&filter=", "items/filter/", key);
                    row["[#LinkText]"] = name;
                    //if (counter > 0)
                    row["[#Counter]"] = counter;
                    rows.Add(row);
                }
                filterBlock["[#Rows]"] = rows;
                filterBlocks.Add(filterBlock);
            }
            prepare["[#FilterBlocks]"] = filterBlocks;

            if (!this.context.IsMobile)
            {
                //dsCategory = doCategory.EnumAll(null, Config.SORT_CATEGORIES == null ? null : CAT("_this.", Config.SORT_CATEGORIES));
                size  = dsCategory.GetSize();                 //50
                size3 = size % 3;                             //2
                n1    = INT(size / 3) + (size3 == 0 ? 0 : 1); //17.3
                n2    = n1 * 2;                               //34.6
                nn    = ARR(0, n1, n2, size);
                var rssBlocks = new TArrayList();
                for (int td = 0; td < 3; td++)
                {
                    var rssBlock = new THashtable();
                    var rows     = new TArrayList();
                    for (int n = INT(nn[td]); n < INT(nn[td + 1]); n++)
                    {
                        var oCategory = dsCategory.GetRow(n);
                        if (NUL(oCategory))
                        {
                            continue;
                        }
                        var key  = STR(oCategory["s_CatId"]);
                        var name = STR(oCategory["s_Name"]);
                        //counter = INT(oCategory["i_Counter"]);
                        var row = new THashtable();
                        row["[#Link]"]     = this.GetLink(Config.RSS_PAGE, "?filter=", "rss/", CAT(key, (this.context.FineUrls ? ".xml" : null)));
                        row["[#LinkText]"] = name;
                        rows.Add(row);
                    }
                    rssBlock["[#Rows]"] = rows;
                    rssBlocks.Add(rssBlock);
                }
                prepare["[#RssBlocks]"] = rssBlocks;
            }
            this.Write("bottom", prepare);
        }