protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        if (SettingsCategoryInfo == null)
        {
            plcContent.Append(GetString("settings.keys.nocategoryselected"));
            StopProcessing = true;
            return;
        }

        ScriptHelper.RegisterTooltip(Page);
        ScriptHelper.RegisterBootstrapTooltip(Page, ".info-icon > i");

        // Loop through all the groups in the category
        int groupCount = 0;
        bool hasOnlyGlobalKeys = true;
        var groups = GetGroups(SettingsCategoryInfo);

        foreach (var group in groups)
        {
            // Get keys
            var keys = GetKeys(group.CategoryID).ToArray();

            // Skip empty group
            if (!keys.Any())
            {
                continue;
            }

            groupCount++;

            // Add category panel for the group
            var pnlGroup = GetCategoryPanel(group, groupCount);
            plcContent.Append(pnlGroup);

            // Loop through all the keys in the group
            int keyCount = 0;
            foreach (var keyInfo in keys)
            {
                // Increase key number for unique control identification
                keyCount++;

                // Update flag when non-global-only key exists
                if (!keyInfo.KeyIsGlobal)
                {
                    hasOnlyGlobalKeys = false;
                }

                // Create key item
                var keyItem = new SettingsKeyItem
                {
                    ParentCategoryPanel = pnlGroup,
                    KeyName = keyInfo.KeyName,
                    KeyType = keyInfo.KeyType,
                    ValidationRegexPattern = keyInfo.KeyValidation,
                    CategoryName = group.CategoryName,
                    ExplanationText = ResHelper.LocalizeString(keyInfo.KeyExplanationText)
                };

                Panel pnlRow = new Panel
                {
                    CssClass = "form-group"
                };
                pnlGroup.Controls.Add(pnlRow);

                // Add label cell to the beginning of the row
                var pnlLabelCell = new Panel
                {
                    CssClass = "editing-form-label-cell"
                };
                pnlRow.Controls.AddAt(0, pnlLabelCell);

                // Continue with the value cell
                pnlRow.Controls.Add(new LiteralControl(@"<div class=""editing-form-value-cell"">"));

                // Create placeholder for the editing control that may end up in an update panel
                var pnlValueCell = new Panel
                {
                    CssClass = "settings-group-inline keep-white-space-fixed"
                };
                var pnlValue = new Panel
                {
                    CssClass = "editing-form-control-nested-control keep-white-space-fixed"
                };
                pnlValueCell.Controls.Add(pnlValue);
                var pnlIcons = new Panel
                {
                    CssClass = "settings-info-group keep-white-space-fixed"
                };
                pnlValueCell.Controls.Add(pnlIcons);

                // Don't show help icon when not provided. (Help icon will be shown if macro resolution results in an empty string.)
                if (!String.IsNullOrWhiteSpace(keyInfo.KeyDescription))
                {
                    Label helpIcon = GetIcon("icon-question-circle", ResHelper.LocalizeString(keyInfo.KeyDescription));
                    pnlIcons.Controls.Add(helpIcon);
                }

                CMSCheckBox chkInherit = null;
                if (mSiteId > 0)
                {
                    // Wrap in update panel for inherit checkbox postback
                    var pnlValueUpdate = new UpdatePanel
                    {
                        ID = string.Format("pnlValueUpdate{0}{1}", groupCount, keyCount),
                        UpdateMode = UpdatePanelUpdateMode.Conditional,
                    };
                    pnlRow.Controls.Add(pnlValueUpdate);

                    // Add inherit checkbox
                    chkInherit = GetInheritCheckBox(groupCount, keyCount);
                    keyItem.InheritCheckBox = chkInherit;

                    pnlValueUpdate.ContentTemplateContainer.Controls.Add(chkInherit);

                    pnlValueUpdate.ContentTemplateContainer.Controls.Add(pnlValueCell);
                }
                else
                {
                    pnlRow.Controls.Add(pnlValueCell);

                    // Add "current site does not inherit the global value" warning for global settings
                    if (SiteContext.CurrentSite != null)
                    {
                        var isCurrentSiteValueInherited = SettingsKeyInfoProvider.IsValueInherited(keyInfo.KeyName, SiteContext.CurrentSiteID);
                        if (!isCurrentSiteValueInherited)
                        {
                            string inheritWarningText = String.Format(GetString("settings.currentsitedoesnotinherit"), ResHelper.LocalizeString(SiteContext.CurrentSite.DisplayName));
                            Label inheritWarningImage = GetIcon("icon-exclamation-triangle warning-icon", HTMLHelper.HTMLEncode(inheritWarningText));

                            pnlIcons.Controls.Add(inheritWarningImage);
                        }
                    }
                }

                // Add explanation text
                if (!String.IsNullOrWhiteSpace(keyItem.ExplanationText))
                {
                    Panel pnlExplanationText = new Panel
                    {
                        CssClass = "explanation-text-settings"
                    };
                    LocalizedLiteral explanationText = new LocalizedLiteral
                    {
                        Text = keyItem.ExplanationText
                    };
                    pnlExplanationText.Controls.Add(explanationText);
                    pnlRow.Controls.Add(pnlExplanationText);
                }

                pnlRow.Controls.Add(new LiteralControl(@"</div>"));

                // Get current values
                keyItem.KeyIsInherited = SettingsKeyInfoProvider.IsValueInherited(keyInfo.KeyName, SiteName);
                keyItem.KeyValue = SettingsKeyInfoProvider.GetValue(keyInfo.KeyName, SiteName);

                // Get value
                string keyValue;
                bool isInherited;
                if (RequestHelper.IsPostBack() && (chkInherit != null))
                {
                    isInherited = Request.Form[chkInherit.UniqueID] != null;
                    keyValue = isInherited ? SettingsKeyInfoProvider.GetValue(keyInfo.KeyName) : SettingsKeyInfoProvider.GetValue(keyInfo.KeyName, SiteName);
                }
                else
                {
                    isInherited = keyItem.KeyIsInherited;
                    keyValue = keyItem.KeyValue;

                    // Set the inherit checkbox state
                    if (!RequestHelper.IsPostBack() && chkInherit != null)
                    {
                        chkInherit.Checked = isInherited;
                    }
                }

                // Add value editing control
                var enabled = !isInherited;
                FormEngineUserControl control = GetFormEngineUserControl(keyInfo, groupCount, keyCount);
                if (control != null)
                {
                    // Add form engine value editing control
                    control.Value = keyValue;
                    pnlValue.Controls.Add(control);

                    // Set form control enabled value, does not work when moved before plcControl.Controls.Add(control)
                    control.Enabled = enabled;

                    keyItem.ValueControl = control;

                    if (chkInherit != null)
                    {
                        chkInherit.CheckedChanged += (sender, args) =>
                        {
                            control.Value = keyValue;
                        };
                    }
                }
                else
                {
                    // Add simple value editing control
                    switch (keyInfo.KeyType.ToLowerCSafe())
                    {
                        case "boolean":
                            // Add checkbox value editing control
                            var @checked = ValidationHelper.GetBoolean(keyValue, false);
                            CMSCheckBox chkValue = GetValueCheckBox(groupCount, keyCount, @checked, enabled);
                            pnlValue.Controls.Add(chkValue);

                            keyItem.ValueControl = chkValue;

                            if (chkInherit != null)
                            {
                                chkInherit.CheckedChanged += (sender, args) =>
                                {
                                    chkValue.Checked = @checked;
                                };
                            }
                            break;

                        case "longtext":
                            // Add text area value editing control
                            var longText = keyValue;
                            var txtValueTextArea = GetValueTextArea(groupCount, keyCount, longText, enabled);
                            if (txtValueTextArea != null)
                            {
                                // Text area control was loaded successfully
                                pnlValue.Controls.Add(txtValueTextArea);
                                keyItem.ValueControl = txtValueTextArea;
                                if (chkInherit != null)
                                {
                                    chkInherit.CheckedChanged += (sender, args) =>
                                    {
                                        txtValueTextArea.Text = longText;
                                    };
                                }
                            }
                            else
                            {
                                // Text area control was not loaded successfully
                                var errorLabel = new FormControlError
                                {
                                    ErrorTitle = "[Error loading the editing control, check the event log for more details]",
                                };
                                pnlValue.Controls.Add(errorLabel);
                            }
                            break;

                        default:
                            // Add textbox value editing control
                            var text = keyValue;
                            TextBox txtValue = GetValueTextBox(groupCount, keyCount, text, enabled);
                            pnlValue.Controls.Add(txtValue);

                            keyItem.ValueControl = txtValue;

                            if (chkInherit != null)
                            {
                                chkInherit.CheckedChanged += (sender, args) =>
                                {
                                    txtValue.Text = text;
                                };
                            }
                            break;
                    }
                }

                // Add label to the label cell when associated control has been resolved
                pnlLabelCell.Controls.Add(GetLabel(keyInfo, keyItem.ValueControl, groupCount, keyCount));

                // Add error label if KeyType is integer or validation expression defined or FormControl is used
                if ((keyInfo.KeyType == "int") || (keyInfo.KeyType == "double") || (keyItem.ValidationRegexPattern != null) || (control != null))
                {
                    Label lblError = GetLabelError(groupCount, keyCount);
                    pnlIcons.Controls.Add(lblError);
                    keyItem.ErrorLabel = lblError;
                }

                mKeyItems.Add(keyItem);
            }
        }

        // Show info message when other than global-only global keys are displayed
        if ((mSiteId <= 0) && (CategoryID > 0) && !hasOnlyGlobalKeys && AllowGlobalInfoMessage)
        {
            ShowInformation(GetString("settings.keys.globalsettingsnote"));
        }

        // Display export and reset links only if some groups were found.
        if (groupCount > 0)
        {
            // Add reset link if required
            if (!RequestHelper.IsPostBack() && QueryHelper.GetInteger("resettodefault", 0) == 1)
            {
                ShowInformation(GetString("Settings-Keys.ValuesWereResetToDefault"));
            }
        }
        else
        {
            // Hide "These settings are global ..." message if no setting found in this group
            if (!string.IsNullOrEmpty(mSearchText))
            {
                var ltrScript = new Literal
                {
                    Text = ScriptHelper.GetScript("DisableHeaderActions();")
                };
                plcContent.Append(ltrScript);
                lblNoData.Visible = true;
            }
        }
    }
    /// <summary>
    /// Validates the settings values and returns true if all are valid.
    /// </summary>
    private bool IsValid()
    {
        // Loop through all settings items
        for (int i = 0; i < mKeyItems.Count; i++)
        {
            SettingsKeyItem item = mKeyItems[i];

            var keyChanged = false;

            if (item.ValueControl is CMSTextBox)
            {
                var textBox = (CMSTextBox)item.ValueControl;
                textBox.Text  = textBox.Text.Trim();
                keyChanged    = (textBox.Text != item.KeyValue);
                item.KeyValue = textBox.Text;
            }
            else if (item.ValueControl is CMSCheckBox)
            {
                var checkBox = (CMSCheckBox)item.ValueControl;
                keyChanged    = (checkBox.Checked.ToString() != item.KeyValue);
                item.KeyValue = checkBox.Checked.ToString();
            }
            else if (item.ValueControl is FormEngineUserControl)
            {
                var control = (FormEngineUserControl)item.ValueControl;
                if (control.IsValid())
                {
                    keyChanged    = Convert.ToString(control.Value) != item.KeyValue;
                    item.KeyValue = Convert.ToString(control.Value);
                }
                else
                {
                    item.ErrorLabel.Text    = String.IsNullOrEmpty(control.ErrorMessage) ? GetString("Settings.ValidationError") : control.ErrorMessage;
                    item.ErrorLabel.Visible = !String.IsNullOrEmpty(item.ErrorLabel.Text);
                    ShowError(GetString("general.saveerror"));
                    return(false);
                }
            }

            if (item.InheritCheckBox != null)
            {
                var inheritanceChanged = item.InheritCheckBox.Checked != item.KeyIsInherited;
                keyChanged          = inheritanceChanged || !item.KeyIsInherited && keyChanged;
                item.KeyIsInherited = item.InheritCheckBox.Checked;
            }

            item.KeyChanged = keyChanged;
            if (!keyChanged)
            {
                continue;
            }

            // Validation result
            string result = string.Empty;

            // Validation using regular expression if there is any
            if (!string.IsNullOrEmpty(item.ValidationRegexPattern) && (item.ValidationRegexPattern.Trim() != string.Empty))
            {
                result = new Validator().IsRegularExp(item.KeyValue, item.ValidationRegexPattern, GetString("Settings.ValidationRegExError")).Result;
            }

            // Validation according to the value type (validate only nonempty values)
            if (string.IsNullOrEmpty(result) && !string.IsNullOrEmpty(item.KeyValue))
            {
                switch (item.KeyType.ToLowerCSafe())
                {
                case "int":
                    result = new Validator().IsInteger(item.KeyValue, GetString("Settings.ValidationIntError")).Result;
                    break;

                case "double":
                    result = new Validator().IsDouble(item.KeyValue, GetString("Settings.ValidationDoubleError")).Result;
                    break;
                }
            }

            if (!string.IsNullOrEmpty(result))
            {
                item.ErrorLabel.Text    = result;
                item.ErrorLabel.Visible = !String.IsNullOrEmpty(result);
                return(false);
            }
            else
            {
                // Update changes
                mKeyItems[i] = item;
            }
        }

        return(true);
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        ScriptHelper.RegisterTooltip(Page);
        if (SettingsCategoryInfo == null)
        {
            plcContent.Controls.Add(new LiteralControl(GetString("settings.keys.nocategoryselected")));
            return;
        }

        if (!RequestHelper.IsCallback())
        {
            ClientScriptManager sm = Page.ClientScript;
            if (sm != null)
            {
                string cbRef = sm.GetCallbackEventReference(this, "arg", "OnCallbacked", "");
                string cbScript = string.Format(@"function InheritCheckChanged(arg, context) {{ {0}; }}", cbRef);
                ScriptHelper.RegisterClientScriptBlock(this, GetType(), "InheritCheckChanged", ScriptHelper.GetScript(cbScript));
                const string script = @"
                function GetElementType(element)
                {
                    var type = null;
                    if (element != null)
                    {
                        // If current element is table, check its children for the type
                        if (element.nodeName.toLowerCase() == 'table')
                        {
                            var childs = element.getElementsByTagName('input');
                            if ((childs != null) && (childs.length > 0))
                            {
                                // Element is radiobuttonlist or checkboxlist
                                type = childs[0].type.toLowerCase() + 'list';
                            }
                        }
                        else
                        {
                            if(element.type)
                            {
                                // Basic element
                                type = element.type.toLowerCase();
                            }
                            else
                            {
                                var childs = element.getElementsByTagName('input');
                                if ((childs != null) && (childs.length > 0))
                                {
                                    // Element is radiobuttonlist or checkboxlist
                                    type = childs[0].type.toLowerCase() + 'list';
                                }
                            }
                        }
                    }
                    return type;
                }
                function SetElementValue(elementId, value)
                {
                    var element = document.getElementById(elementId);
                    var elementType = GetElementType(element);
                    if((element != null) && (elementType != null))
                    {
                        // Take different actions on different value element type
                        switch(elementType)
                        {
                            case 'text':
                            case 'textarea':
                            case 'password':
                            case 'hidden':
                                element.value = value;
                                //alert(element + ' of type \'' + elementType + '\' set to \'' + value + '\'');
                                break;
                            case 'checkbox':
                            case 'radio':
                                element.checked = ((value.toLowerCase() == 'true') || (value.toLowerCase() == '1'));
                                break;
                            case 'select-one':
                            case 'select-multiple':
                                for (var i = 0; i < element.options.length; i++)
                                {
                                    //alert('option value: ' + element.options[i].value);
                                    //alert('option text: ' + element.options[i].text);
                                    if (element.options[i].value == value)
                                    {
                                        element.options[i].selected = true;
                                        break;
                                    }
                                    // Select the top first option if no option has been found
                                    element.options[0].selected = true;
                                }
                                break;
                            case 'radiolist':
                                var childs = element.getElementsByTagName('input');
                                // Get all input elements
                                if ((childs != null) && (childs.length > 0))
                                {
                                    var valueFound = false;
                                    for (var i = 0; i < childs.length; i++)
                                    {
                                        if(childs[i].value == value)
                                        {
                                            // Element with value was found so check it
                                            childs[i].checked = true;
                                            valueFound = true;
                                            break;
                                        }
                                    }
                                    if(!valueFound)
                                    {
                                        // Element was not found, so check the first one
                                        childs[0].checked = true;
                                    }
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }
                function OnCallbacked(arg, context)
                {
                    var args = arg.split('|');
                    // Check if ClientID was defined for the control
                    if(args[3].toLowerCase() == 'true')
                    {
                        return;
                    }
                    // Get handle for the value element
                    var valElement = document.getElementById(args[0]);
                    var elementType = GetElementType(valElement);
                    if((valElement != null) && (elementType != null))
                    {
                        SetElementValue(args[0], args[1]);
                        // Form engine user control in update panel should be prerendered, not just enabled
                        // Get handler for the additional value element
                        var addElement = document.getElementById(args[4]);
                        var addElementType = GetElementType(addElement);
                        if((addElement != null) && (addElementType != null))
                        {
                            SetElementValue(args[4], args[5]);
                        }
                        if((args[2].length > 0) && (document.getElementById(args[2]) != null))
                        {
                            __doPostBack(args[2], '');
                        }
                        else
                        {
                            // Disable value element at the end
                            valElement.disabled = true;
                            var valElementType = GetElementType(valElement);
                            // different disabling for radiobuttonlist and checkboxlist
                            if(valElementType == 'radiolist')
                            {
                                EnableElementChildren(valElement, true);
                            }
                        }
                    }
                }

                function EnableElementChildren(element, disabled)
                {
                    if(element != null)
                    {
                        element.disabled = disabled;
                        var childs = element.getElementsByTagName('input');
                        if ((childs != null) && (childs.length > 0))
                        {
                            for (var i = 0; i < childs.length; i++)
                            {
                                // Enable all children
                                childs[i].disabled = disabled;
                                try
                                {
                                   childs[i].parentNode.disabled = disabled;
                                }
                                catch(e) {}
                            }
                        }
                    }
                }

                function InheritCheckBox_Changed(id, valueElementId, updatePanelId, controlPath)
                {
                    // Get handle for inherit checkbox
                    var cb = document.getElementById(id);
                    if(cb != null)
                    {
                        if(cb.checked)
                        {
                            // Prepare arguments for callback and do callback
                            var args = valueElementId + '|' + controlPath;
                            InheritCheckChanged(args, '');
                        }
                        else
                        {
                            var valElement = document.getElementById(valueElementId);
                            // Form engine user control in update panel should be prerendered, not just enabled
                            if((updatePanelId.length > 0) && (document.getElementById(updatePanelId) != null))
                            {
                                __doPostBack(updatePanelId, '');
                            }
                            else if(valElement != null)
                            {
                                // Enable value element control
                                valElement.disabled = false;
                                var valElementType = GetElementType(valElement);
                                // Additional enabling for checkbox
                                if((valElementType == 'checkbox') && (valElement.parentNode != null))
                                {
                                    valElement.parentNode.disabled = false;
                                }
                                // different enabling for radiobuttonlist and checkboxlist
                                if(valElementType == 'radiolist')
                                {
                                    EnableElementChildren(valElement, false);
                                }
                            }
                        }
                    }
                }";
                ScriptHelper.RegisterClientScriptBlock(this, GetType(), "InheritCheckBox_Changed", ScriptHelper.GetScript(script));
            }
        }

        if (mSettingsCategoryInfo == null)
        {
            return;
        }

        if ((mSiteId <= 0) && (CategoryID > 0) && AllowGlobalInfoMessage)
        {
            lblInfo.Visible = true;
            lblInfo.Text = GetString("settings.keys.globalsettingsnote");
        }

        int groupNo = 0;
        bool hasOnlyGlobalSettings = true;

        mSearchText = QueryHelper.GetString("search", "").Trim();
        mSearchDescription = QueryHelper.GetBoolean("description", false);

        // Loop through all groups for current category
        foreach (SettingsCategoryInfo group in GetGroups())
        {
            // Get keys
            IEnumerable<SettingsKeyInfo> keys = GetKeys(group.CategoryID);

            if ((!string.IsNullOrEmpty(mSearchText)) && (mSearchText.Length >= mSearchLimit))
            {
                // Get searched keys
                keys = GetSearchedKeys(keys);
            }

            if (keys != null)
            {
                bool categoryPanelIsAdded = false;
                int keyNo = 0;
                CategoryPanel p = null;
                bool getCategoryPanel = true;

                // Loop through all setting keys in the current group
                foreach (SettingsKeyInfo key in keys)
                {
                    // Get category panel only if it has some keys
                    if (getCategoryPanel)
                    {
                        p = GetCategoryPanel(group, groupNo); // Create category panel for the group
                        getCategoryPanel = false;
                        groupNo++; // Increase group number for unique control identification
                    }

                    // Update flag when non-global-only key exists
                    if (!key.KeyIsGlobal)
                    {
                        hasOnlyGlobalSettings = false;
                    }

                    if (!categoryPanelIsAdded)
                    {
                        // Add category panel to the placeholder control collection
                        plcContent.Controls.Add(p);
                        categoryPanelIsAdded = true;
                    }
                    keyNo++; // Increase key number for unique control identification
                    // Add display name lable
                    AddControl(p, GetLabel(key, groupNo, keyNo), @"<tr class=""EditingFormRow""><td class=""EditingFormLeftBorder"">&nbsp;</td><td class=""EditingFormLabelCell"" style=""width:250px;"">", @"</td>");
                    // Add help image
                    AddControl(p, GetHelpImage(key, groupNo, keyNo), @"<td style=""width:25px"">", @"</td>");

                    SettingsKeyItem skr = new SettingsKeyItem();
                    skr.ParentCategoryPanelID = p.ID; // Assign category panel ID to be able to find all controls later
                    skr.SettingsKey = key.KeyName;

                    CheckBox chkInherit = GetInheritCheckBox(groupNo, keyNo, out skr.InheritID);
                    bool inheritChecked = false;
                    skr.ValueElementClientID = string.Empty;
                    FormEngineUserControl control = GetFormEngineUserControl(key, groupNo, keyNo);

                    // Add placeholder for the editing control
                    PlaceHolder plcControl = new PlaceHolder();
                    plcControl.ID = string.Format("plcControl_{0}{1}", groupNo, keyNo);
                    AddControl(p, plcControl, @"<td class=""EditingFormValueCell"" style=""width:400px"">", @"</td>");

                    // Add inherit CheckBox
                    AddControl(p, chkInherit, @"<td>", @"</td>");

                    if (control != null)
                    {
                        string defValue = SettingsKeyProvider.GetValue(key.KeyName.ToLower());
                        string value = null;
                        if ((key.KeyValue == null) && (mSiteId > 0))
                        {
                            inheritChecked = true;
                            value = defValue;
                        }
                        else
                        {
                            inheritChecked = false;
                            value = SettingsKeyProvider.GetValue(GetFullKeyName(key.KeyName).ToLower());
                        }
                        control.Value = value;
                        control.Enabled = (URLHelper.IsPostback() && (chkInherit != null)) ? (Request.Form[chkInherit.UniqueID] == null) : !inheritChecked;
                        plcControl.Controls.Add(control);
                        skr.InputControlID = control.ID;
                        skr.Value = value;
                        // Not all engine controls have ValueElementID, when it is not assigned in the structe it will fail during find
                        skr.ValueElementClientID = control.ValueElementID ?? (control.InputClientID ?? UNDEFINED_VALUE_ELEMENT_CLIENT_ID);
                        skr.UpdatePanelClientID = GetUpdatePanelClientId(control);
                        skr.ControlPath = key.KeyEditingControlPath;
                    }
                    else
                    {
                        switch (key.KeyType.ToLower())
                        {
                            case "boolean":
                                CheckBox cbVal = GetCheckBox(key, groupNo, keyNo, out inheritChecked, chkInherit, out skr.InputControlID, out skr.Value);
                                plcControl.Controls.Add(cbVal);
                                skr.ValueElementClientID = cbVal.ClientID;
                                skr.ControlPath = "";
                                break;

                            default:
                                TextBox tbVal = GetTextBox(key, groupNo, keyNo, out inheritChecked, chkInherit, out skr.InputControlID, out skr.Value);
                                plcControl.Controls.Add(tbVal);
                                skr.ValueElementClientID = tbVal.ClientID;
                                skr.ControlPath = "";
                                break;
                        }
                    }
                    // Set the inherit checkbox state
                    if (chkInherit != null)
                    {
                        chkInherit.Checked = !URLHelper.IsPostback() ? inheritChecked : chkInherit.Checked;
                        chkInherit.Attributes.Add("onclick", string.Format(@"InheritCheckBox_Changed(this.id, ""{0}"", ""{1}"", ""{2}"")", skr.ValueElementClientID, skr.UpdatePanelClientID, skr.ControlPath));
                    }

                    // Set the inherited status
                    skr.IsInherited = inheritChecked;

                    p.Controls.Add(GetLabelKeyName(key, groupNo, keyNo)); // Add key name Label

                    skr.Validation = ValidationHelper.GetString(key.KeyValidation, null);
                    if ((mSiteId > 0) && (skr.Validation == null))
                    {
                        SettingsKeyInfo ski = SettingsKeyProvider.GetSettingsKeyInfo(skr.SettingsKey, 0);
                        if (ski != null)
                        {
                            skr.Validation = ski.KeyValidation;
                        }
                    }

                    Label lblError = null;
                    // Add error label if KeyType is integer or validation expression defined or FormControl is used
                    if ((key.KeyType == "int") || (key.KeyType == "double") || (skr.Validation != null) || (control != null))
                    {
                        lblError = GetLabelError(groupNo, keyNo);
                        p.Controls.Add(lblError);
                        skr.ErrorLabelID = lblError.ID;
                    }
                    AddControl(p, lblError, @"<td>", @"</td>");
                    AddLiteral(p, @"<td class=""EditingFormRightBorder"">&nbsp;</td>");

                    skr.Type = key.KeyType;
                    mKeyItems.Add(skr);
                }
                //  AddLiteral(p, @"</table>");
            }
        }

        // Hide info message when only global-only keys are displayed
        if (hasOnlyGlobalSettings)
        {
            lblInfo.Visible = false;
        }

        // Display export and reset links only if some groups were found.
        if (groupNo > 0)
        {
            // Add Export settings link, but only if some category is specified
            if (SettingsCategoryInfo != null && ShowExportLink)
            {
                plcContent.Controls.Add(new LiteralControl(string.Format(@"<a href=""GetSettings.aspx?siteid={0}&categoryid={1}&search={2}&description={3}"">{4}</a>",
                                                         mSiteId, SettingsCategoryInfo.CategoryID, mSearchText, mSearchDescription, GetString("settings.keys.exportsettings"))));

            }

            if (QueryHelper.GetInteger("resettodefault", 0) == 1)
            {
                SetInfoMessage(GetString("Settings-Keys.ValuesWereResetToDefault"), true, false);
            }
        }
        else
        {
            SetInfoMessage("", false, false);
            // Hide "These settings are global..." message if no setting found in this group

            if (!string.IsNullOrEmpty(mSearchText))
            {
                lblInfo.Visible = true;
                lblInfo.Text = GetString("settingskey.nodata");

                string script = @"
                function DisableHeaderActions(){
                        var element = document.getElementById('m_pnlActions');
                        element.style.display = 'none';
                    }
                DisableHeaderActions();
                ";

                Literal ltrScript = new Literal();
                ltrScript.Text = ScriptHelper.GetScript(script);
                plcContent.Controls.Add(ltrScript);

            }
            else
            {
                lblInfo.Visible = false;
            }

        }
    }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        if (SettingsCategoryInfo == null)
        {
            plcContent.Append(GetString("settings.keys.nocategoryselected"));
            StopProcessing = true;
            return;
        }

        ScriptHelper.RegisterTooltip(Page);
        ScriptHelper.RegisterBootstrapTooltip(Page, ".info-icon > i");

        // Loop through all the groups in the category
        int  groupCount        = 0;
        bool hasOnlyGlobalKeys = true;
        var  groups            = GetGroups(SettingsCategoryInfo);

        foreach (var group in groups)
        {
            // Get keys
            var keys = GetKeys(group.CategoryID).ToArray();

            // Skip empty group
            if (!keys.Any())
            {
                continue;
            }

            groupCount++;

            // Add category panel for the group
            var pnlGroup = GetCategoryPanel(group, groupCount);
            plcContent.Append(pnlGroup);

            // Loop through all the keys in the group
            int keyCount = 0;
            foreach (var keyInfo in keys)
            {
                // Increase key number for unique control identification
                keyCount++;

                // Update flag when non-global-only key exists
                if (!keyInfo.KeyIsGlobal)
                {
                    hasOnlyGlobalKeys = false;
                }

                // Create key item
                var keyItem = new SettingsKeyItem
                {
                    ParentCategoryPanel    = pnlGroup,
                    KeyName                = keyInfo.KeyName,
                    KeyType                = keyInfo.KeyType,
                    ValidationRegexPattern = keyInfo.KeyValidation,
                    CategoryName           = group.CategoryName,
                    ExplanationText        = ResHelper.LocalizeString(keyInfo.KeyExplanationText)
                };


                Panel pnlRow = new Panel
                {
                    CssClass = "form-group"
                };
                pnlGroup.Controls.Add(pnlRow);

                // Add label cell to the beginning of the row
                var pnlLabelCell = new Panel
                {
                    CssClass = "editing-form-label-cell"
                };
                pnlRow.Controls.AddAt(0, pnlLabelCell);

                // Continue with the value cell
                pnlRow.Controls.Add(new LiteralControl(@"<div class=""editing-form-value-cell"">"));

                // Create placeholder for the editing control that may end up in an update panel
                var pnlValueCell = new Panel
                {
                    CssClass = "settings-group-inline keep-white-space-fixed"
                };
                var pnlValue = new Panel
                {
                    CssClass = "editing-form-control-nested-control keep-white-space-fixed"
                };
                pnlValueCell.Controls.Add(pnlValue);
                var pnlIcons = new Panel
                {
                    CssClass = "settings-info-group keep-white-space-fixed"
                };
                pnlValueCell.Controls.Add(pnlIcons);

                // Don't show help icon when not provided. (Help icon will be shown if macro resolution results in an empty string.)
                if (!String.IsNullOrWhiteSpace(keyInfo.KeyDescription))
                {
                    Label helpIcon = GetIcon("icon-question-circle", ResHelper.LocalizeString(keyInfo.KeyDescription));
                    pnlIcons.Controls.Add(helpIcon);
                }

                CMSCheckBox chkInherit = null;
                if (mSiteId > 0)
                {
                    // Wrap in update panel for inherit checkbox postback
                    var pnlValueUpdate = new UpdatePanel
                    {
                        ID         = string.Format("pnlValueUpdate{0}{1}", groupCount, keyCount),
                        UpdateMode = UpdatePanelUpdateMode.Conditional,
                    };
                    pnlRow.Controls.Add(pnlValueUpdate);

                    // Add inherit checkbox
                    chkInherit = GetInheritCheckBox(groupCount, keyCount);
                    keyItem.InheritCheckBox = chkInherit;

                    pnlValueUpdate.ContentTemplateContainer.Controls.Add(chkInherit);

                    pnlValueUpdate.ContentTemplateContainer.Controls.Add(pnlValueCell);
                }
                else
                {
                    pnlRow.Controls.Add(pnlValueCell);

                    // Add "current site does not inherit the global value" warning for global settings
                    if (SiteContext.CurrentSite != null)
                    {
                        var isCurrentSiteValueInherited = SettingsKeyInfoProvider.IsValueInherited(keyInfo.KeyName, SiteContext.CurrentSiteID);
                        if (!isCurrentSiteValueInherited)
                        {
                            string inheritWarningText  = String.Format(GetString("settings.currentsitedoesnotinherit"), ResHelper.LocalizeString(SiteContext.CurrentSite.DisplayName));
                            Label  inheritWarningImage = GetIcon("icon-exclamation-triangle warning-icon", HTMLHelper.HTMLEncode(inheritWarningText));

                            pnlIcons.Controls.Add(inheritWarningImage);
                        }
                    }
                }

                // Add explanation text
                if (!String.IsNullOrWhiteSpace(keyItem.ExplanationText))
                {
                    Panel pnlExplanationText = new Panel
                    {
                        CssClass = "explanation-text-settings"
                    };
                    LocalizedLiteral explanationText = new LocalizedLiteral
                    {
                        Text = keyItem.ExplanationText
                    };
                    pnlExplanationText.Controls.Add(explanationText);
                    pnlRow.Controls.Add(pnlExplanationText);
                }

                pnlRow.Controls.Add(new LiteralControl(@"</div>"));

                // Get current values
                keyItem.KeyIsInherited = SettingsKeyInfoProvider.IsValueInherited(keyInfo.KeyName, SiteName);
                keyItem.KeyValue       = SettingsKeyInfoProvider.GetValue(keyInfo.KeyName, SiteName);

                // Get value
                string keyValue;
                bool   isInherited;
                if (RequestHelper.IsPostBack() && (chkInherit != null))
                {
                    isInherited = Request.Form[chkInherit.UniqueID] != null;
                    keyValue    = isInherited ? SettingsKeyInfoProvider.GetValue(keyInfo.KeyName) : SettingsKeyInfoProvider.GetValue(keyInfo.KeyName, SiteName);
                }
                else
                {
                    isInherited = keyItem.KeyIsInherited;
                    keyValue    = keyItem.KeyValue;

                    // Set the inherit checkbox state
                    if (!RequestHelper.IsPostBack() && chkInherit != null)
                    {
                        chkInherit.Checked = isInherited;
                    }
                }

                // Add value editing control
                var enabled = !isInherited;
                FormEngineUserControl control = GetFormEngineUserControl(keyInfo, groupCount, keyCount);
                if (control != null)
                {
                    // Add form engine value editing control
                    control.Value = keyValue;
                    pnlValue.Controls.Add(control);

                    // Set form control enabled value, does not work when moved before plcControl.Controls.Add(control)
                    control.Enabled = enabled;

                    keyItem.ValueControl = control;

                    if (chkInherit != null)
                    {
                        chkInherit.CheckedChanged += (sender, args) =>
                        {
                            control.Value = keyValue;
                        };
                    }
                }
                else
                {
                    // Add simple value editing control
                    switch (keyInfo.KeyType.ToLowerCSafe())
                    {
                    case "boolean":
                        // Add checkbox value editing control
                        var         @checked = ValidationHelper.GetBoolean(keyValue, false);
                        CMSCheckBox chkValue = GetValueCheckBox(groupCount, keyCount, @checked, enabled);
                        pnlValue.Controls.Add(chkValue);

                        keyItem.ValueControl = chkValue;

                        if (chkInherit != null)
                        {
                            chkInherit.CheckedChanged += (sender, args) =>
                            {
                                chkValue.Checked = @checked;
                            };
                        }
                        break;

                    case "longtext":
                        // Add text area value editing control
                        var longText         = keyValue;
                        var txtValueTextArea = GetValueTextArea(groupCount, keyCount, longText, enabled);
                        if (txtValueTextArea != null)
                        {
                            // Text area control was loaded successfully
                            pnlValue.Controls.Add(txtValueTextArea);
                            keyItem.ValueControl = txtValueTextArea;
                            if (chkInherit != null)
                            {
                                chkInherit.CheckedChanged += (sender, args) =>
                                {
                                    txtValueTextArea.Text = longText;
                                };
                            }
                        }
                        else
                        {
                            // Text area control was not loaded successfully
                            var errorLabel = new FormControlError
                            {
                                ErrorTitle = "[Error loading the editing control, check the event log for more details]",
                            };
                            pnlValue.Controls.Add(errorLabel);
                        }
                        break;

                    default:
                        // Add textbox value editing control
                        var     text     = keyValue;
                        TextBox txtValue = GetValueTextBox(groupCount, keyCount, text, enabled);
                        pnlValue.Controls.Add(txtValue);

                        keyItem.ValueControl = txtValue;

                        if (chkInherit != null)
                        {
                            chkInherit.CheckedChanged += (sender, args) =>
                            {
                                txtValue.Text = text;
                            };
                        }
                        break;
                    }
                }

                // Add label to the label cell when associated control has been resolved
                pnlLabelCell.Controls.Add(GetLabel(keyInfo, keyItem.ValueControl, groupCount, keyCount));

                // Add error label if KeyType is integer or validation expression defined or FormControl is used
                if ((keyInfo.KeyType == "int") || (keyInfo.KeyType == "double") || (keyItem.ValidationRegexPattern != null) || (control != null))
                {
                    Label lblError = GetLabelError(groupCount, keyCount);
                    pnlIcons.Controls.Add(lblError);
                    keyItem.ErrorLabel = lblError;
                }

                mKeyItems.Add(keyItem);
            }
        }

        // Show info message when other than global-only global keys are displayed
        if ((mSiteId <= 0) && (CategoryID > 0) && !hasOnlyGlobalKeys && AllowGlobalInfoMessage)
        {
            ShowInformation(GetString("settings.keys.globalsettingsnote"));
        }

        // Display export and reset links only if some groups were found.
        if (groupCount > 0)
        {
            // Add reset link if required
            if (!RequestHelper.IsPostBack() && QueryHelper.GetInteger("resettodefault", 0) == 1)
            {
                ShowInformation(GetString("Settings-Keys.ValuesWereResetToDefault"));
            }
        }
        else
        {
            // Hide "These settings are global ..." message if no setting found in this group
            if (!string.IsNullOrEmpty(mSearchText))
            {
                var ltrScript = new Literal
                {
                    Text = ScriptHelper.GetScript("DisableHeaderActions();")
                };
                plcContent.Append(ltrScript);
                lblNoData.Visible = true;
            }
        }
    }