using System;
using System.Configuration;
using System.Web;
using System.Data;
using System.Web.Caching;
using System.Data.SqlClient;
using System.Collections;
using ASPNET.StarterKit.Portal;

namespace ASPNET.StarterKit.Portal 
{

    //*********************************************************************
    //
    // Configuration Class
    //
    // Class that encapsulates all data logic necessary to add/query/delete
    // tab configuration settings, module configuration settings and module 
    // definition configuration settings from the PortalCfg.xml file.
    //
    //*********************************************************************
    public class Configuration
    {

        //
        // PORTAL
        //

        //*********************************************************************
        //
        // UpdatePortalInfo() Method 
        //
        // The UpdatePortalInfo method updates the name and access settings for the portal.
        // These settings are stored in the Xml file PortalCfg.xml.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public void UpdatePortalInfo (int portalId, String portalName, bool alwaysShow) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Get first record of the "Global" element 
            SiteConfiguration.GlobalRow globalRow = siteSettings.Global.FindByPortalId(portalId);

            // Update the values
            globalRow.PortalId = portalId;
            globalRow.PortalName = portalName;
            globalRow.AlwaysShowEditButton = alwaysShow;

            // Save the changes 
            SaveSiteSettings();
        }
        
        //
        // TABS
        //

        //*********************************************************************
        //
        // AddTab Method 
        //
        // The AddTab method adds a new tab to the portal.  These settings are 
        // stored in the Xml file PortalCfg.xml.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public int AddTab (int portalId, String tabName, int tabOrder) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Create a new TabRow from the Tab table
            SiteConfiguration.TabRow newRow = siteSettings.Tab.NewTabRow();

            // Set the properties on the new row
            newRow.TabName = tabName;
            newRow.TabOrder = tabOrder;
            newRow.MobileTabName = String.Empty;
            newRow.ShowMobile = true;
            newRow.AccessRoles = "All Users;";

            // Add the new TabRow to the Tab table
            siteSettings.Tab.AddTabRow(newRow);

            // Save the changes 
            SaveSiteSettings();

            // Return the new TabID
            return newRow.TabId;
        }
        
        
        //*********************************************************************
        //
        // UpdateTab Method 
        //
        // The UpdateTab method updates the settings for the specified tab. 
        // These settings are stored in the Xml file PortalCfg.xml.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public void UpdateTab (int portalId, int tabId, String tabName, int tabOrder, String authorizedRoles, String mobileTabName, bool showMobile) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate tab in the Tab table and set the properties
            SiteConfiguration.TabRow tabRow = siteSettings.Tab.FindByTabId(tabId);

            tabRow.TabName = tabName;
            tabRow.TabOrder = tabOrder;
            tabRow.AccessRoles = authorizedRoles;
            tabRow.MobileTabName = mobileTabName;
            tabRow.ShowMobile = showMobile;

            // Save the changes 
            SaveSiteSettings();
        }
        
        //*********************************************************************
        //
        // UpdateTabOrder Method 
        //
        // The UpdateTabOrder method changes the position of the tab with respect
        // to other tabs in the portal.  These settings are stored in the Xml 
        // file PortalCfg.xml.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public void UpdateTabOrder (int tabId, int tabOrder) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate tab in the Tab table and set the property
            SiteConfiguration.TabRow tabRow = siteSettings.Tab.FindByTabId(tabId);

            tabRow.TabOrder = tabOrder;

            // Save the changes 
            SaveSiteSettings();
        }
        
        //*********************************************************************
        //
        // DeleteTab Method 
        //
        // The DeleteTab method deletes the selected tab and its modules from 
        // the settings which are stored in the Xml file PortalCfg.xml.  This 
        // method also deletes any data from the database associated with all 
        // modules within this tab.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //      + DeleteModule stored procedure
        //
        //*********************************************************************
        public void DeleteTab(int tabId) 
        {
            //
            // Delete the Tab in the XML file
            //

            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate tab in the Tab table
            SiteConfiguration.TabDataTable tabTable = siteSettings.Tab;
            SiteConfiguration.TabRow tabRow = siteSettings.Tab.FindByTabId(tabId);

            //
            // Delete information in the Database relating to each Module being deleted
            //

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["connectionString"]);
            SqlCommand myCommand = new SqlCommand("Portal_DeleteModule", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterModuleID = new SqlParameter("@ModuleID", SqlDbType.Int, 4);
            myConnection.Open();

            foreach(SiteConfiguration.ModuleRow moduleRow in tabRow.GetModuleRows())
            {
                myCommand.Parameters.Clear();
                parameterModuleID.Value = moduleRow.ModuleId;
                myCommand.Parameters.Add(parameterModuleID);

                // Open the database connection and execute the command
                myCommand.ExecuteNonQuery();
            }

            // Close the connection
            myConnection.Close();

            // Finish removing the Tab row from the Xml file
            tabTable.RemoveTabRow(tabRow);

            // Save the changes 
            SaveSiteSettings();
        }
       
        //
        // MODULES
        //

        //*********************************************************************
        //
        // UpdateModuleOrder Method  
        //
        // The UpdateModuleOrder method updates the order in which the modules
        // in a tab are displayed.  These settings are stored in the Xml file 
        // PortalCfg.xml.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public void UpdateModuleOrder (int ModuleId, int ModuleOrder, String pane) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate Module in the Module table and update the properties
            SiteConfiguration.ModuleRow moduleRow = siteSettings.Module.FindByModuleId(ModuleId);

            moduleRow.ModuleOrder = ModuleOrder;
            moduleRow.PaneName = pane;

            // Save the changes 
            SaveSiteSettings();
        }
        
        
        //*********************************************************************
        //
        // AddModule Method  
        //
        // The AddModule method adds Portal Settings for a new Module within
        // a Tab.  These settings are stored in the Xml file PortalCfg.xml.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public int AddModule(int tabId, int moduleOrder, String paneName, String title, int moduleDefId, int cacheTime, String editRoles, bool showMobile) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Create a new ModuleRow from the Module table
            SiteConfiguration.ModuleRow newModule = siteSettings.Module.NewModuleRow();

            // Set the properties on the new Module
            newModule.ModuleDefId = moduleDefId;
            newModule.ModuleOrder = moduleOrder;
            newModule.ModuleTitle = title;
            newModule.PaneName = paneName;
            newModule.EditRoles = editRoles;
            newModule.CacheTimeout = cacheTime;
            newModule.ShowMobile = showMobile;
            newModule.TabRow = siteSettings.Tab.FindByTabId(tabId);

            // Add the new ModuleRow to the Module table
            siteSettings.Module.AddModuleRow(newModule);

            // Save the changes
            SaveSiteSettings();

            // Return the new Module ID
            return newModule.ModuleId;
        }

        
        //*********************************************************************
        //
        // UpdateModule Method  
        //
        // The UpdateModule method updates the Portal Settings for an existing 
        // Module within a Tab.  These settings are stored in the Xml file
        // PortalCfg.xml.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public int UpdateModule(int moduleId, int moduleOrder, String paneName, String title, int cacheTime, String editRoles, bool showMobile) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate Module in the Module table and update the properties
            SiteConfiguration.ModuleRow moduleRow = siteSettings.Module.FindByModuleId(moduleId);

            moduleRow.ModuleOrder = moduleOrder;
            moduleRow.ModuleTitle = title;
            moduleRow.PaneName = paneName;
            moduleRow.CacheTimeout = cacheTime;
            moduleRow.EditRoles = editRoles;
            moduleRow.ShowMobile = showMobile;

            // Save the changes 
            SaveSiteSettings();

            // Return the existing Module ID
            return moduleId;
        }

        //*********************************************************************
        //
        // DeleteModule Method  
        //
        // The DeleteModule method deletes a specified Module from the settings
        // stored in the Xml file PortalCfg.xml.  This method also deletes any 
        // data from the database associated with this module.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //      + DeleteModule stored procedure
        //
        //*********************************************************************
        public void DeleteModule(int moduleId) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            //
            // Delete information in the Database relating to Module being deleted
            //

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["connectionString"]);
            SqlCommand myCommand = new SqlCommand("Portal_DeleteModule", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterModuleID = new SqlParameter("@ModuleID", SqlDbType.Int, 4);
            myConnection.Open();

            parameterModuleID.Value = moduleId;
            myCommand.Parameters.Add(parameterModuleID);

            // Open the database connection and execute the command
            myCommand.ExecuteNonQuery();
            myConnection.Close();

            // Finish removing Module
            siteSettings.Module.RemoveModuleRow(siteSettings.Module.FindByModuleId(moduleId));

            // Save the changes 
            SaveSiteSettings();
        }


        //*********************************************************************
        //
        // UpdateModuleSetting Method  
        //
        // The UpdateModuleSetting Method updates a single module setting 
        // in the configuration file.  If the value passed in is String.Empty,
        // the Setting element is deleted if it exists.  If not, either a 
        // matching Setting element is updated, or a new Setting element is 
        // created.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public void UpdateModuleSetting(int moduleId, String key, String val) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate Module in the Module table
            SiteConfiguration.ModuleRow moduleRow = siteSettings.Module.FindByModuleId(moduleId);

            // Find the first (only) settings element
            SiteConfiguration.SettingsRow settingsRow;

            if(moduleRow.GetSettingsRows().Length > 0 )
            {
                settingsRow = moduleRow.GetSettingsRows()[0];
            }
            else
            {
                // Add new settings element
                settingsRow = siteSettings.Settings.NewSettingsRow();

                // Set the parent relationship
                settingsRow.ModuleRow = moduleRow;

                siteSettings.Settings.AddSettingsRow(settingsRow);
            }

            // Find the child setting elements
            SiteConfiguration.SettingRow settingRow;

            SiteConfiguration.SettingRow[] settingRows = settingsRow.GetSettingRows();

            if(settingRows.Length == 0)
            {
                // If there are no Setting elements at all, add one with the new name and value,
                // but only if the value is not empty
                if(val != String.Empty)
                {
                    settingRow = siteSettings.Setting.NewSettingRow();

                    // Set the parent relationship and data
                    settingRow.SettingsRow = settingsRow;
                    settingRow.Name = key;
                    settingRow.Setting_Text = val;

                    siteSettings.Setting.AddSettingRow(settingRow);
                }
            }
            else
            {
                // Update existing setting element if it matches
                bool found = false;
                Int32 i;

                // Find which row matches the input parameter "key" and update the
                // value.  If the value is String.Empty, however, delete the row.
                for(i=0; i < settingRows.Length; i++)
                {
                    if(settingRows[i].Name == key)
                    {
                        if(val == String.Empty)
                        {
                            // Delete the row
                            siteSettings.Setting.RemoveSettingRow(settingRows[i]);
                        }
                        else
                        {
                            // Update the value
                            settingRows[i].Setting_Text = val;
                        }

                        found = true;
                    }
                }
                
                if(found == false)
                {
                    // Setting elements exist, however, there is no matching Setting element.
                    // Add one with new name and value, but only if the value is not empty
                    if(val != String.Empty)
                    {
                        settingRow = siteSettings.Setting.NewSettingRow();

                        // Set the parent relationship and data
                        settingRow.SettingsRow = settingsRow;
                        settingRow.Name = key;
                        settingRow.Setting_Text = val;

                        siteSettings.Setting.AddSettingRow(settingRow);
                    }
                }
            }

            // Save the changes 
            SaveSiteSettings();
        }

        //*********************************************************************
        //
        // GetModuleSettings Method  
        //
        // The GetModuleSettings Method returns a hashtable of custom,
        // module-specific settings from the configuration file.  This method is
        // used by some user control modules (Xml, Image, etc) to access misc
        // settings.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public static Hashtable GetModuleSettings(int moduleId) 
        {
            // Create a new Hashtable
            Hashtable _settingsHT = new Hashtable();

            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate Module in the Module table
            SiteConfiguration.ModuleRow moduleRow = siteSettings.Module.FindByModuleId(moduleId);

            // Find the first (only) settings element
            if(moduleRow.GetSettingsRows().Length > 0)
            {
                SiteConfiguration.SettingsRow settingsRow = moduleRow.GetSettingsRows()[0];

                if(settingsRow != null)
                {
                    // Find the child setting elements and add to the hashtable
                    foreach(SiteConfiguration.SettingRow sRow in settingsRow.GetSettingRows())
                    {
                        _settingsHT[sRow.Name] = sRow.Setting_Text;
                    }
                }
            }

            return _settingsHT;
        }

        //
        // MODULE DEFINITIONS
        //

        //*********************************************************************
        //
        // GetModuleDefinitions() Method 
        //
        // The GetModuleDefinitions method returns a list of all module type 
        // definitions for the portal.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public DataRow[] GetModuleDefinitions(int portalId) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate Module in the Module table
            return siteSettings.ModuleDefinition.Select();
        }

        //*********************************************************************
        //
        // AddModuleDefinition() Method 
        //
        // The AddModuleDefinition add the definition for a new module type
        // to the portal.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public int AddModuleDefinition(int portalId, String name, String desktopSrc, String mobileSrc) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Create new ModuleDefinitionRow
            SiteConfiguration.ModuleDefinitionRow newModuleDef = siteSettings.ModuleDefinition.NewModuleDefinitionRow();

            // Set the parameter values
            newModuleDef.FriendlyName = name;
            newModuleDef.DesktopSourceFile = desktopSrc;
            newModuleDef.MobileSourceFile = mobileSrc;

            // Add the new ModuleDefinitionRow to the ModuleDefinition table
            siteSettings.ModuleDefinition.AddModuleDefinitionRow(newModuleDef);

            // Save the changes
            SaveSiteSettings();

            // Return the new ModuleDefID
            return newModuleDef.ModuleDefId;
        }

        //*********************************************************************
        //
        // DeleteModuleDefinition() Method 
        //
        // The DeleteModuleDefinition method deletes the specified module type 
        // definition from the portal.  Each module which is related to the
        // ModuleDefinition is deleted from each tab in the configuration
        // file, and all data relating to each module is deleted from the
        // database.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //    + DeleteModule Stored Procedure
        //
        //*********************************************************************
        public void DeleteModuleDefinition(int defId) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            //
            // Delete information in the Database relating to each Module being deleted
            //

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["connectionString"]);
            SqlCommand myCommand = new SqlCommand("Portal_DeleteModule", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterModuleID = new SqlParameter("@ModuleID", SqlDbType.Int, 4);
            myConnection.Open();

            foreach(SiteConfiguration.ModuleRow moduleRow in siteSettings.Module.Select())
            {
                if(moduleRow.ModuleDefId == defId)
                {
                    myCommand.Parameters.Clear();
                    parameterModuleID.Value = moduleRow.ModuleId;
                    myCommand.Parameters.Add(parameterModuleID);

                    // Delete the xml module associated with the ModuleDef
                    // in the configuration file
                    siteSettings.Module.RemoveModuleRow(moduleRow);

                    // Open the database connection and execute the command
                    myCommand.ExecuteNonQuery();
                }
            }

            myConnection.Close();

            // Finish removing Module Definition
            siteSettings.ModuleDefinition.RemoveModuleDefinitionRow(siteSettings.ModuleDefinition.FindByModuleDefId(defId));

            // Save the changes 
            SaveSiteSettings();
        }
       
        //*********************************************************************
        //
        // UpdateModuleDefinition() Method 
        //
        // The UpdateModuleDefinition method updates the settings for the 
        // specified module type definition.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public void UpdateModuleDefinition(int defId, String name, String desktopSrc, String mobileSrc) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate Module in the Module table and update the properties
            SiteConfiguration.ModuleDefinitionRow modDefRow = siteSettings.ModuleDefinition.FindByModuleDefId(defId);

            modDefRow.FriendlyName = name;
            modDefRow.DesktopSourceFile = desktopSrc;
            modDefRow.MobileSourceFile = mobileSrc;

            // Save the changes 
            SaveSiteSettings();
        }

        //*********************************************************************
        //
        // GetSingleModuleDefinition Method
        //
        // The GetSingleModuleDefinition method returns a ModuleDefinitionRow
        // object containing details about a specific module definition in the
        // configuration file.
        //
        // Other relevant sources:
        //    + SaveSiteSettings() method
        //      + PortalCfg.xml
        //
        //*********************************************************************
        public SiteConfiguration.ModuleDefinitionRow GetSingleModuleDefinition(int defId) 
        {
            // Obtain SiteSettings from Current Context
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Items["SiteSettings"];

            // Find the appropriate Module in the Module table
            return siteSettings.ModuleDefinition.FindByModuleDefId(defId);
        }

        //*********************************************************************
        //
        // GetSiteSettings Static Method
        //
        // The Configuration.GetSiteSettings Method returns a typed
        // dataset of the all of the site configuration settings from the
        // XML configuration file.  This method is used in Global.asax to
        // push the settings into the current HttpContext, so that all of the 
        // pages, content modules and classes throughout the rest of the request
        // may access them.
        //
        // The SiteConfiguration object is cached using the ASP.NET Cache API,
        // with a file-change dependency on the XML configuration file.  Normallly,
        // this method just returns a copy of the object in the cache.  When the
        // configuration is updated and changes are saved to the the XML file,
        // the SiteConfiguration object is evicted from the cache.  The next time 
        // this method runs, it will read from the XML file again and insert a
        // fresh copy of the SiteConfiguration into the cache.
        //
        //*********************************************************************
        public static SiteConfiguration GetSiteSettings()
        {
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Cache["SiteSettings"];

            // If the SiteConfiguration isn't cached, load it from the XML file and add it into the cache.
            if(siteSettings == null)
            {
                // Create the dataset
                siteSettings = new SiteConfiguration();

                // Retrieve the location of the XML configuration file
                string configFile = HttpContext.Current.Server.MapPath(ConfigurationSettings.AppSettings["configFile"]);

                // Set the AutoIncrement property to true for easier adding of rows
                siteSettings.Tab.TabIdColumn.AutoIncrement = true;
                siteSettings.Module.ModuleIdColumn.AutoIncrement = true;
                siteSettings.ModuleDefinition.ModuleDefIdColumn.AutoIncrement = true;

                // Load the XML data into the DataSet
                siteSettings.ReadXml(configFile);
        
                // Store the dataset in the cache
                HttpContext.Current.Cache.Insert("SiteSettings", siteSettings, new CacheDependency(configFile));
            }

            return siteSettings;
        }

        //*********************************************************************
        //
        // SaveSiteSettings Method 
        //
        // The Configuration.SaveSiteSettings overwrites the the XML file with the
        // settings in the SiteConfiguration object in context.  The object will in 
        // turn be evicted from the cache and be reloaded from the XML file the next
        // time GetSiteSettings() is called.
        //
        //*********************************************************************
        public void SaveSiteSettings()
        {
            // Obtain SiteSettings from the Cache
            SiteConfiguration siteSettings = (SiteConfiguration) HttpContext.Current.Cache["SiteSettings"];

            // Check the object
            if(siteSettings == null)
            {
                // If SaveSiteSettings() is called once, the cache is cleared.  If it is
                // then called again before Global.Application_BeginRequest is called, 
                // which reloads the cache, the siteSettings object will be Null 
                siteSettings = GetSiteSettings();
            }
            string configFile = HttpContext.Current.Server.MapPath(ConfigurationSettings.AppSettings["configFile"]);

            // Object is evicted from the Cache here.  
            siteSettings.WriteXml(configFile);
        }
    }

    //*********************************************************************
    //
    // PortalSettings Class
    //
    // This class encapsulates all of the settings for the Portal, as well
    // as the configuration settings required to execute the current tab
    // view within the portal.
    //
    //*********************************************************************

    public class PortalSettings 
    {

        public int          PortalId;
        public String       PortalName;
        public bool         AlwaysShowEditButton;
        public ArrayList    DesktopTabs = new ArrayList();
        public ArrayList    MobileTabs = new ArrayList();
        public TabSettings  ActiveTab = new TabSettings();

        //*********************************************************************
        //
        // PortalSettings Constructor
        //
        // The PortalSettings Constructor encapsulates all of the logic
        // necessary to obtain configuration settings necessary to render
        // a Portal Tab view for a given request.
        //
        // These Portal Settings are stored within PortalCFG.xml, and are
        // fetched below by calling config.GetSiteSettings().
        // The method config.GetSiteSettings() fills the SiteConfiguration
        // class, derived from a DataSet, which PortalSettings accesses.
        //       
        //*********************************************************************

        public PortalSettings(int tabIndex, int tabId) 
        {
            // Get the configuration data
            SiteConfiguration siteSettings = Configuration.GetSiteSettings();

            // Read the Desktop Tab Information, and sort by Tab Order
            foreach(SiteConfiguration.TabRow tRow in siteSettings.Tab.Select("", "TabOrder"))
            {
                TabStripDetails tabDetails = new TabStripDetails();

                tabDetails.TabId = tRow.TabId;
                tabDetails.TabName = tRow.TabName;
                tabDetails.TabOrder = tRow.TabOrder;
                tabDetails.AuthorizedRoles = tRow.AccessRoles;

                this.DesktopTabs.Add(tabDetails);
            }

            // If the PortalSettings.ActiveTab property is set to 0, change it to  
            // the TabID of the first tab in the DesktopTabs collection
            if(this.ActiveTab.TabId == 0)
                this.ActiveTab.TabId = ((TabStripDetails)this.DesktopTabs[0]).TabId;


            // Read the Mobile Tab Information, and sort by Tab Order
            foreach(SiteConfiguration.TabRow mRow in siteSettings.Tab.Select("ShowMobile='true'", "TabOrder"))
            {
                TabStripDetails tabDetails = new TabStripDetails();

                tabDetails.TabId = mRow.TabId;
                tabDetails.TabName = mRow.MobileTabName;
                tabDetails.AuthorizedRoles = mRow.AccessRoles;
                
                this.MobileTabs.Add(tabDetails);
            }

            // Read the Module Information for the current (Active) tab
            SiteConfiguration.TabRow activeTab = siteSettings.Tab.FindByTabId(tabId);

            // Get Modules for this Tab based on the Data Relation
            foreach(SiteConfiguration.ModuleRow moduleRow in activeTab.GetModuleRows())
            {
                ModuleSettings moduleSettings = new ModuleSettings();

                moduleSettings.ModuleTitle = moduleRow.ModuleTitle;
                moduleSettings.ModuleId = moduleRow.ModuleId;
                moduleSettings.ModuleDefId = moduleRow.ModuleDefId;
                moduleSettings.ModuleOrder = moduleRow.ModuleOrder;
                moduleSettings.TabId = tabId;
                moduleSettings.PaneName = moduleRow.PaneName;
                moduleSettings.AuthorizedEditRoles = moduleRow.EditRoles;
                moduleSettings.CacheTime = moduleRow.CacheTimeout;
                moduleSettings.ShowMobile = moduleRow.ShowMobile;

                // ModuleDefinition data
                SiteConfiguration.ModuleDefinitionRow modDefRow = siteSettings.ModuleDefinition.FindByModuleDefId(moduleSettings.ModuleDefId);

                moduleSettings.DesktopSrc = modDefRow.DesktopSourceFile;
                moduleSettings.MobileSrc = modDefRow.MobileSourceFile;
                
                this.ActiveTab.Modules.Add(moduleSettings);
            }

            // Sort the modules in order of ModuleOrder
            this.ActiveTab.Modules.Sort();

            // Get the first row in the Global table
            SiteConfiguration.GlobalRow globalSettings = (SiteConfiguration.GlobalRow) siteSettings.Global.Rows[0];

            // Read Portal global settings 
            this.PortalId = globalSettings.PortalId;
            this.PortalName = globalSettings.PortalName;
            this.AlwaysShowEditButton = globalSettings.AlwaysShowEditButton;
            this.ActiveTab.TabIndex = tabIndex;
            this.ActiveTab.TabId = tabId;
            this.ActiveTab.TabOrder = activeTab.TabOrder;
            this.ActiveTab.MobileTabName = activeTab.MobileTabName;
            this.ActiveTab.AuthorizedRoles = activeTab.AccessRoles;
            this.ActiveTab.TabName = activeTab.TabName;
            this.ActiveTab.ShowMobile = activeTab.ShowMobile;
        }
    }

    //*********************************************************************
    //
    // TabStripDetails Class
    //
    // Class that encapsulates the just the tabstrip details -- TabName, TabId and TabOrder 
    // -- for a specific Tab in the Portal
    //
    //*********************************************************************

    public class TabStripDetails 
    {

        public int          TabId;
        public String       TabName;
        public int          TabOrder;
        public String       AuthorizedRoles;
    }

    //*********************************************************************
    //
    // TabSettings Class
    //
    // Class that encapsulates the detailed settings for a specific Tab 
    // in the Portal
    //
    //*********************************************************************

    public class TabSettings 
    {
                           
        public int          TabIndex;
        public int          TabId;
        public String       TabName;
        public int          TabOrder;
        public String       MobileTabName;
        public String       AuthorizedRoles;
        public bool         ShowMobile;
        public ArrayList    Modules = new ArrayList();
    }

    //*********************************************************************
    //
    // ModuleSettings Class
    //
    // Class that encapsulates the detailed settings for a specific Tab 
    // in the Portal.  ModuleSettings implements the IComparable interface 
    // so that an ArrayList of ModuleSettings objects may be sorted by
    // ModuleOrder, using the ArrayList's Sort() method.
    //
    //*********************************************************************

    public class ModuleSettings : IComparable 
    {

        public int          ModuleId;
        public int          ModuleDefId;
        public int          TabId;
        public int          CacheTime;
        public int          ModuleOrder;
        public String       PaneName;
        public String       ModuleTitle;
        public String       AuthorizedEditRoles;
        public bool         ShowMobile;
        public String       DesktopSrc;
        public String       MobileSrc;


        public int CompareTo(object value) 
        {

            if (value == null) return 1;

            int compareOrder = ((ModuleSettings)value).ModuleOrder;
            
            if (this.ModuleOrder == compareOrder) return 0;
            if (this.ModuleOrder < compareOrder) return -1;
            if (this.ModuleOrder > compareOrder) return 1;
            return 0;
        }
    }

    //*********************************************************************
    //
    // ModuleItem Class
    //
    // This class encapsulates the basic attributes of a Module, and is used
    // by the administration pages when manipulating modules.  ModuleItem implements 
    // the IComparable interface so that an ArrayList of ModuleItems may be sorted
    // by ModuleOrder, using the ArrayList's Sort() method.
    //
    //*********************************************************************

    public class ModuleItem : IComparable 
    {

        private int      _moduleOrder;
        private String   _title;
        private String   _pane;
        private int      _id;
        private int      _defId;

        public int ModuleOrder 
        {

            get 
            {
                return _moduleOrder;
            }
            set 
            {
                _moduleOrder = value;
            }
        }    

        public String ModuleTitle 
        {

            get 
            {
                return _title;
            }
            set 
            {
                _title = value;
            }
        }

        public String PaneName 
        {

            get 
            {
                return _pane;
            }
            set 
            {
                _pane = value;
            }
        }
        
        public int ModuleId 
        {

            get 
            {
                return _id;
            }
            set 
            {
                _id = value;
            }
        }  
  
        public int ModuleDefId 
        {

            get 
            {
                return _defId;
            }
            set 
            {
                _defId = value;
            }
        } 
   
        public int CompareTo(object value) 
        {

            if (value == null) return 1;

            int compareOrder = ((ModuleItem)value).ModuleOrder;
            
            if (this.ModuleOrder == compareOrder) return 0;
            if (this.ModuleOrder < compareOrder) return -1;
            if (this.ModuleOrder > compareOrder) return 1;
            return 0;
        }
    }
    
    //*********************************************************************
    //
    // TabItem Class
    //
    // This class encapsulates the basic attributes of a Tab, and is used
    // by the administration pages when manipulating tabs.  TabItem implements 
    // the IComparable interface so that an ArrayList of TabItems may be sorted
    // by TabOrder, using the ArrayList's Sort() method.
    //
    //*********************************************************************

    public class TabItem : IComparable 
    {

        private int      _tabOrder;
        private String   _name;
        private int      _id;

        public int TabOrder 
        {

            get 
            {
                return _tabOrder;
            }
            set 
            {
                _tabOrder = value;
            }
        }    

        public String TabName 
        {

            get 
            {
                return _name;
            }
            set 
            {
                _name = value;
            }
        }

        public int TabId 
        {

            get 
            {
                return _id;
            }
            set 
            {
                _id = value;
            }
        }  
  
        public int CompareTo(object value) 
        {

            if (value == null) return 1;

            int compareOrder = ((TabItem)value).TabOrder;
            
            if (this.TabOrder == compareOrder) return 0;
            if (this.TabOrder < compareOrder) return -1;
            if (this.TabOrder > compareOrder) return 1;
            return 0;
        }
    }
}