/// <summary> Constructor for a new instance of the Thematic_Headings_AdminViewer class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <remarks> Postback from handling saving the new settings is handled here in the constructor </remarks>
        public Settings_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            // Determine the extension codes
            extensionCodes = new List<string>();
            if ((UI_ApplicationCache_Gateway.Configuration.Extensions != null) && (UI_ApplicationCache_Gateway.Configuration.Extensions.Extensions != null) && (UI_ApplicationCache_Gateway.Configuration.Extensions.Extensions.Count > 0))
            {
                SortedList<string, string> extensionSorter = new SortedList<string, string>();
                foreach (ExtensionInfo thisInfo in UI_ApplicationCache_Gateway.Configuration.Extensions.Extensions)
                    extensionSorter[thisInfo.Code] = thisInfo.Code;
                extensionCodes = extensionSorter.Values.ToList();
            }

            // If the RequestSpecificValues.Current_User cannot edit this, go back
            if (( RequestSpecificValues.Current_User == null ) || ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Portal_Admin)))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // Determine if this user has limited rights
            if ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Host_Admin))
            {
                limitedRightsMode = true;
                readonlyMode = true;
            }
            else
            {
                limitedRightsMode = ((!RequestSpecificValues.Current_User.Is_Host_Admin) && (UI_ApplicationCache_Gateway.Settings.Servers.isHosted));
                readonlyMode = false;
            }

            // Load the settings either from the local session, or from the engine
            currSettings = HttpContext.Current.Session["Admin_Settings"] as Admin_Setting_Collection;
            if (currSettings == null)
            {
                currSettings = SobekEngineClient.Admin.Get_Admin_Settings(RequestSpecificValues.Tracer);
                if (currSettings != null)
                {
                    HttpContext.Current.Session["Admin_Settigs"] = currSettings;

                    // Build the setting values
                    build_setting_objects_for_display();
                }
                else
                {
                    actionMessage = "Error pulling the settings from the engine";
                }
            }

            #region Determine the mode and submode

            // Determine the current mode and submode
            if ((RequestSpecificValues.Current_Mode.Remaining_Url_Segments != null) && (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 0))
            {
                switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[0].ToLower())
                {
                    case "settings":
                        mainMode = Settings_Mode_Enum.Settings;
                        break;

                    case "config":
                        mainMode = Settings_Mode_Enum.Configuration;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "files":
                                    configSubMode = Settings_Configuration_SubMode_Enum.Files;
                                    break;

                                case "log":
                                    configSubMode = Settings_Configuration_SubMode_Enum.Reading_Log;
                                    break;
                            }
                        }
                        break;

                    case "builder":
                        mainMode = Settings_Mode_Enum.Builder;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "settings":
                                    builderSubEnum = Settings_Builder_SubMode_Enum.Builder_Settings;
                                    break;

                                case "folders":
                                    builderSubEnum = Settings_Builder_SubMode_Enum.Builder_Folders;
                                    break;

                                case "modules":
                                    builderSubEnum = Settings_Builder_SubMode_Enum.Builder_Modules;
                                    break;
                            }
                        }
                        break;

                    case "metadata":
                        mainMode = Settings_Mode_Enum.Metadata;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "fields":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.Fields;
                                    break;

                                case "filereaders":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.Metdata_Reader_Writers;
                                    break;

                                case "metsreaders":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.METS_Section_Reader_Writers;
                                    break;

                                case "metsprofiles":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.METS_Writing_Profiles;
                                    break;

                                case "modules":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.Metadata_Modules_To_Include;
                                    break;
                            }
                        }
                        break;

                    case "engine":
                        mainMode = Settings_Mode_Enum.Engine;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "authentication":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Authentication;
                                    break;

                                case "briefitem":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Brief_Item_Mapping;
                                    break;

                                case "contact":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Contact_Form;
                                    break;

                                case "endpoints":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Engine_Server_Endpoints;
                                    break;

                                case "oaipmh":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.OAI_PMH;
                                    break;

                                case "qctool":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.QcTool;
                                    break;
                            }
                        }
                        break;

                    case "ui":
                        mainMode = Settings_Mode_Enum.UI;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "citation":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Citation_Viewer;
                                    break;

                                case "mapeditor":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Map_Editor;
                                    break;

                                case "microservices":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Microservice_Client_Endpoints;
                                    break;

                                case "template":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Template_Elements;
                                    break;

                                case "viewers":
                                    uiSubEnum = Settings_UI_SubMode_Enum.HTML_Viewer_Subviewers;
                                    break;
                            }
                        }
                        break;

                    case "html":
                        mainMode = Settings_Mode_Enum.HTML;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "missing":
                                    htmlSubEnum = Settings_HTML_SubMode_Enum.Missing_Page;
                                    break;

                                case "noresults":
                                    htmlSubEnum = Settings_HTML_SubMode_Enum.No_Results;
                                    break;

                                case "usageemail":
                                    htmlSubEnum = Settings_HTML_SubMode_Enum.Usage_Email;
                                    break;
                            }
                        }
                        break;

                    case "extensions":
                        extensionSubMode = -1;
                        mainMode = Settings_Mode_Enum.Extensions;
                        if ((extensionCodes.Count > 0) && (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1))
                        {
                            int tryExtensionNum;
                            if (Int32.TryParse(RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1], out tryExtensionNum))
                            {
                                if ((tryExtensionNum > 0) && (tryExtensionNum <= extensionCodes.Count))
                                    extensionSubMode = tryExtensionNum;
                            }
                        }
                        break;
                }
            }

            #endregion

            // Establish some default, starting values
            actionMessage = String.Empty;
            category_view = Convert.ToBoolean(RequestSpecificValues.Current_User.Get_Setting("Settings_AdminViewer:Category_View", "false"));

            // Determine the redirect URL now
            string[] origUrlSegments = RequestSpecificValues.Current_Mode.Remaining_Url_Segments;
            RequestSpecificValues.Current_Mode.Remaining_Url_Segments = new string[] { "%SETTINGSCODE%" };
            redirectUrl = UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode);
            RequestSpecificValues.Current_Mode.Remaining_Url_Segments = origUrlSegments;

            // Is this a post-back requesting to save all this data?
            if (RequestSpecificValues.Current_Mode.isPostBack)
            {
                NameValueCollection form = HttpContext.Current.Request.Form;

                if (form["admin_settings_order"] == "category")
                {
                    RequestSpecificValues.Current_User.Add_Setting("Settings_AdminViewer:Category_View", "true");
                    SobekCM_Database.Set_User_Setting(RequestSpecificValues.Current_User.UserID, "Settings_AdminViewer:Category_View", "true");
                    category_view = true;
                }

                if (form["admin_settings_order"] == "alphabetical")
                {
                    RequestSpecificValues.Current_User.Add_Setting("Settings_AdminViewer:Category_View", "false");
                    SobekCM_Database.Set_User_Setting(RequestSpecificValues.Current_User.UserID, "Settings_AdminViewer:Category_View", "false");
                    category_view = false;
                }

                string action_value = form["admin_settings_action"];
                if ((action_value == "save") && (RequestSpecificValues.Current_User.Is_System_Admin))
                {
                    save_setting_values(RequestSpecificValues, mainMode );
                }
                if ((mainMode == Settings_Mode_Enum.Extensions) && (extensionSubMode > 0))
                {
                    // Get the code
                    string plugin_code = extensionCodes[extensionSubMode - 1];
                    if (action_value == "enable_plugin")
                    {
                        EnableExtensionMessage response = SobekEngineClient.Admin.Plugin_Enable(plugin_code, RequestSpecificValues.Tracer);
                        actionMessage = response.Message;

                        // If not successful, and there are errors, copy those over
                        if ((!response.Success) && (response.Errors != null) && (response.Errors.Count > 0))
                        {
                            actionMessage = actionMessage + "<ul>";
                            foreach (string thisError in response.Errors)
                                actionMessage = actionMessage + "<li>" + thisError + "</li>";
                            actionMessage = actionMessage + "</ul>";
                        }
                    }

                    if (action_value == "disable_plugin")
                    {
                        EnableExtensionMessage response = SobekEngineClient.Admin.Plugin_Disable(plugin_code, RequestSpecificValues.Tracer);
                        actionMessage = response.Message;

                        // If not successful, and there are errors, copy those over
                        if ((!response.Success) && (response.Errors != null) && (response.Errors.Count > 0))
                        {
                            actionMessage = actionMessage + "<ul>";
                            foreach (string thisError in response.Errors)
                                actionMessage = actionMessage + "<li>" + thisError + "</li>";
                            actionMessage = actionMessage + "</ul>";
                        }
                    }
                }
                if (mainMode == Settings_Mode_Enum.HTML)
                {
                    if (htmlSubEnum == Settings_HTML_SubMode_Enum.Missing_Page)
                    {
                        try
                        {
                            string missing_contents = form["missing_page_content"].Trim();
                            string file_name = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network, "design", "webcontent", "missing.html");
                            StreamWriter writer = new StreamWriter(file_name, false);
                            writer.Write(missing_contents);
                            writer.Flush();
                            writer.Close();

                            SobekEngineClient.WebContent.Clear_Special_Missing_Page(RequestSpecificValues.Tracer);
                        }
                        catch
                        {
                            actionMessage = "ERROR: Unable to write the new missing page HTML to the file.";
                        }
                    }

                    if (htmlSubEnum == Settings_HTML_SubMode_Enum.No_Results)
                    {
                        try
                        {
                            string no_results_content = form["no_results_content"].Trim();
                            string file_name = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network, "design", "webcontent", "noresults.html");
                            StreamWriter writer = new StreamWriter(file_name, false);
                            writer.Write(no_results_content);
                            writer.Flush();
                            writer.Close();

                            HttpContext.Current.Application["NORESULTS"] = null;
                        }
                        catch
                        {
                            actionMessage = "ERROR: Unable to write the no results page HTML to the file.";
                        }
                    }

                    if (htmlSubEnum == Settings_HTML_SubMode_Enum.Usage_Email)
                    {
                        try
                        {
                            string usage_email_content = form["usage_email_content"].Trim();
                            string file_name = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network, "design", "extra", "stats", "stats_email_body.txt");
                            StreamWriter writer = new StreamWriter(file_name, false);
                            writer.Write(usage_email_content.Replace("[%", "<%").Replace("%]", "%>"));
                            writer.Flush();
                            writer.Close();

                            actionMessage = "Updated the statistics usage email body text.";

                        }
                        catch
                        {
                            actionMessage = "ERROR: Unable to write the usage email body to the file.";
                        }
                    }

                }

            }
        }
        private void save_setting_values(RequestCache RequestSpecificValues, Settings_Mode_Enum MainMode)
        {
            List<Admin_Setting_Value> pageSettings = null;

            // Determine which page of settings to save
            if (MainMode == Settings_Mode_Enum.Settings)
            {
                // Get the tab page index
                int tabPage = -1;
                if ((RequestSpecificValues.Current_Mode.Remaining_Url_Segments != null) && (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1))
                {
                    if (!Int32.TryParse(RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1], out tabPage))
                        tabPage = -1;
                }

                // Only try to save if it is valid
                if ((tabPage >= 1) && (tabPage <= tabPageNames.Count))
                {
                    // Get the tab page settings
                    string tabPageNameKey = tabPageNames.Keys[tabPage - 1];
                    string tabPageName = tabPageNames[tabPageNameKey];
                    pageSettings = settingsByPage[tabPageName];
                }
            }

            // Pretty simple if this is the builder setting page
            if (MainMode == Settings_Mode_Enum.Builder)
                pageSettings = builderSettings;

            // If no settings found for this .. just return
            if (pageSettings == null)
                return;

            // Get the collection of values posted back from user
            NameValueCollection form = HttpContext.Current.Request.Form;

            // First, create the setting lookup by ID, and the list of IDs to look for
            List<short> settingIds = new List<short>();
            Dictionary<short, Admin_Setting_Value> settingsObjsById = new Dictionary<short, Admin_Setting_Value>();
            foreach (Admin_Setting_Value value in pageSettings)
            {
                // If this is readonly, will not prepare to update
                if ((!Is_Value_ReadOnly(value, readonlyMode, limitedRightsMode)) && (!value.Hidden))
                {
                    settingIds.Add(value.SettingID);
                    settingsObjsById[value.SettingID] = value;
                }
            }

            // Now, step through and get the values for each of these
            List<Simple_Setting> newValues = new List<Simple_Setting>();
            foreach (short id in settingIds)
            {
                // Get the setting information
                Admin_Setting_Value thisValue = settingsObjsById[id];

                if (form["setting" + id] != null)
                {
                    newValues.Add(new Simple_Setting(thisValue.Key, form["setting" + id], thisValue.SettingID));
                }
                else
                {
                    newValues.Add(new Simple_Setting(thisValue.Key, String.Empty, thisValue.SettingID));
                }
            }

            // Now, validate all this
            errorBuilder = new StringBuilder();
            isValid = true;
            validate_update_entered_data(newValues);

            // Now, assign the values from the simple settings back to the main settings
            // object.  This is to allow for the validation process to make small changes
            // to the values the user entered, like different starts or endings
            foreach (Simple_Setting thisSetting in newValues)
            {

                settingsObjsById[thisSetting.SettingID].Value = thisSetting.Value;
            }

            if (isValid)
            {
                // Try to save each setting
                int errors = newValues.Count(NewSetting => !SobekCM_Database.Set_Setting(NewSetting.Key, NewSetting.Value));

                // Prepare the action message
                if (errors > 0)
                    actionMessage = "Save completed, but with " + errors + " errors.";
                else
                    actionMessage = "Settings saved";

                // Assign this to be used by the system
                UI_ApplicationCache_Gateway.ResetSettings();

                // Get all the settings again
                build_setting_objects_for_display();
            }
            else
            {
                actionMessage = errorBuilder.ToString().Replace("\n", "<br />");
            }
        }