/// <summary> Finds the home page source file and banner images or html for this item aggregation </summary>
        /// <param name="ThisObject"> Item aggregation to add the home page link and banner html </param>
        /// <remarks>This method is only called if the item aggregation does not have an existing XML configuration file. </remarks>
        protected static void Add_HTML(Complete_Item_Aggregation ThisObject)
        {
            // Just use the standard home text
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text.html"))
            {
                ThisObject.Add_Home_Page_File("html/home/text.html", Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language, false);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_en.html"))
            {
                ThisObject.Add_Home_Page_File("html/home/text_en.html", Web_Language_Enum.English, false);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_fr.html"))
            {
                ThisObject.Add_Home_Page_File("html/home/text_fr.html", Web_Language_Enum.French, false);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_es.html"))
            {
                ThisObject.Add_Home_Page_File("html/home/text_es.html", Web_Language_Enum.Spanish, false);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_sp.html"))
            {
                ThisObject.Add_Home_Page_File("html/home/text_sp.html", Web_Language_Enum.Spanish, false);
            }

            // Just use the standard banner image
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll.jpg"))
            {
                ThisObject.Add_Banner_Image("images/banners/coll.jpg", Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_en.jpg"))
            {
                ThisObject.Add_Banner_Image("images/banners/coll_en.jpg", Web_Language_Enum.English);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_fr.jpg"))
            {
                ThisObject.Add_Banner_Image("images/banners/coll_fr.jpg", Web_Language_Enum.French);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_es.jpg"))
            {
                ThisObject.Add_Banner_Image("images/banners/coll_es.jpg", Web_Language_Enum.Spanish);
            }
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_sp.jpg"))
            {
                ThisObject.Add_Banner_Image("images/banners/coll_sp.jpg", Web_Language_Enum.Spanish);
            }
        }
        private static void read_banners(XmlNodeReader NodeReader, Complete_Item_Aggregation HierarchyObject)
        {
            while (NodeReader.Read())
            {
                // If this is the beginning tag for an element, assign the next values accordingly
                if (NodeReader.NodeType == XmlNodeType.Element)
                {
                    // Get the node name, trimmed and to upper
                    string nodeName = NodeReader.Name.Trim().ToUpper();

                    // switch the rest based on the tag name
                    switch (nodeName)
                    {
                    case "HI:SOURCE":
                        // Check for any attributes to this banner node
                        string lang    = String.Empty;
                        bool   special = false;
                        Item_Aggregation_Front_Banner_Type_Enum type = Item_Aggregation_Front_Banner_Type_Enum.Left;
                        ushort width  = 550;
                        ushort height = 230;

                        if (NodeReader.HasAttributes)
                        {
                            if (NodeReader.MoveToAttribute("lang"))
                            {
                                lang = NodeReader.Value.Trim().ToUpper();
                            }
                            if (NodeReader.MoveToAttribute("type"))
                            {
                                if ((NodeReader.Value.Trim().ToUpper() == "HIGHLIGHT") || (NodeReader.Value.Trim().ToUpper() == "FRONT"))
                                {
                                    special = true;
                                }
                            }
                            if (NodeReader.MoveToAttribute("side"))
                            {
                                switch (NodeReader.Value.Trim().ToUpper())
                                {
                                case "RIGHT":
                                    type = Item_Aggregation_Front_Banner_Type_Enum.Right;
                                    break;

                                case "LEFT":
                                    type = Item_Aggregation_Front_Banner_Type_Enum.Left;
                                    break;

                                case "FULL":
                                    type = Item_Aggregation_Front_Banner_Type_Enum.Full;
                                    break;
                                }
                            }
                            if (NodeReader.MoveToAttribute("width"))
                            {
                                ushort.TryParse(NodeReader.Value, out width);
                            }
                            if (NodeReader.MoveToAttribute("height"))
                            {
                                ushort.TryParse(NodeReader.Value, out height);
                            }
                        }

                        // Now read the banner information and add to the aggregation object
                        NodeReader.Read();
                        if (special)
                        {
                            Item_Aggregation_Front_Banner bannerObj = HierarchyObject.Add_Front_Banner_Image(NodeReader.Value, Web_Language_Enum_Converter.Code_To_Enum(lang));
                            bannerObj.Width  = width;
                            bannerObj.Height = height;
                            bannerObj.Type   = type;
                        }
                        else
                        {
                            HierarchyObject.Add_Banner_Image(NodeReader.Value, Web_Language_Enum_Converter.Code_To_Enum(lang));
                        }


                        break;
                    }
                }

                if ((NodeReader.NodeType == XmlNodeType.EndElement) && (NodeReader.Name.Trim().ToUpper() == "HI:BANNER"))
                {
                    return;
                }
            }
        }
        /// <summary> Add a new aggregation to the system </summary>
        /// <param name="NewAggregation"> Information for the new aggregation </param>
        /// <returns> Message indicating success or any errors encountered </returns>
        public static RestResponseMessage add_new_aggregation(New_Aggregation_Arguments NewAggregation)
        {
            // Convert to the integer id for the parent and begin to do checking
            List <string> errors   = new List <string>();
            int           parentid = -1;

            if (NewAggregation.ParentCode.Length > 0)
            {
                Item_Aggregation_Related_Aggregations parentAggr = Engine_ApplicationCache_Gateway.Codes[NewAggregation.ParentCode];
                if (parentAggr != null)
                {
                    parentid = parentAggr.ID;
                }
                else
                {
                    errors.Add("Parent code is not valid");
                }
            }
            else
            {
                errors.Add("You must select a PARENT for this new aggregation");
            }

            // Validate the code

            if (NewAggregation.Code.Length > 20)
            {
                errors.Add("New aggregation code must be twenty characters long or less");
            }
            else if (NewAggregation.Code.Length == 0)
            {
                errors.Add("You must enter a CODE for this item aggregation");
            }
            else if (Engine_ApplicationCache_Gateway.Codes[NewAggregation.Code.ToUpper()] != null)
            {
                errors.Add("New code must be unique... <i>" + NewAggregation.Code + "</i> already exists");
            }
            else if (Engine_ApplicationCache_Gateway.Settings.Static.Reserved_Keywords.Contains(NewAggregation.Code.ToLower()))
            {
                errors.Add("That code is a system-reserved keyword.  Try a different code.");
            }
            else
            {
                bool alphaNumericTest = NewAggregation.Code.All(C => Char.IsLetterOrDigit(C) || C == '_' || C == '-');
                if (!alphaNumericTest)
                {
                    errors.Add("New aggregation code must be only letters and numbers");
                    NewAggregation.Code = NewAggregation.Code.Replace("\"", "");
                }
            }

            // Was there a type and name
            if (NewAggregation.Type.Length == 0)
            {
                errors.Add("You must select a TYPE for this new aggregation");
            }
            if (NewAggregation.Description.Length == 0)
            {
                errors.Add("You must enter a DESCRIPTION for this new aggregation");
            }
            if (NewAggregation.Name.Length == 0)
            {
                errors.Add("You must enter a NAME for this new aggregation");
            }
            else
            {
                if (NewAggregation.ShortName.Length == 0)
                {
                    NewAggregation.ShortName = NewAggregation.Name;
                }
            }

            // Check for the thematic heading
            int thematicHeadingId = -1;

            if (!String.IsNullOrEmpty(NewAggregation.Thematic_Heading))
            {
                // Look for the matching thematic heading
                foreach (Thematic_Heading thisHeading in Engine_ApplicationCache_Gateway.Thematic_Headings)
                {
                    if (String.Compare(thisHeading.Text, NewAggregation.Thematic_Heading, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        thematicHeadingId = thisHeading.ID;
                        break;
                    }
                }

                // If there was no match, the thematic heading was invalid, unless it was new
                if (thematicHeadingId < 0)
                {
                    if ((!NewAggregation.NewThematicHeading.HasValue) || (!NewAggregation.NewThematicHeading.Value))
                    {
                        errors.Add("Invalid thematic heading indicated");
                    }
                    else if (errors.Count == 0)
                    {
                        // Add the thematic heading first
                        if ((thematicHeadingId < 0) && (NewAggregation.NewThematicHeading.HasValue) && (NewAggregation.NewThematicHeading.Value))
                        {
                            thematicHeadingId = Engine_Database.Edit_Thematic_Heading(-1, 10, NewAggregation.Thematic_Heading, null);
                        }
                    }
                }
            }

            if (errors.Count > 0)
            {
                // Create the error message
                StringBuilder actionMessage = new StringBuilder("ERROR: Invalid entry for new item aggregation.<br />");
                foreach (string error in errors)
                {
                    actionMessage.Append("<br />" + error);
                }

                return(new RestResponseMessage(ErrorRestTypeEnum.InputError, actionMessage.ToString()));
            }



            string language = Web_Language_Enum_Converter.Enum_To_Code(Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language);

            // Try to save the new item aggregation
            if (!Engine_Database.Save_Item_Aggregation(NewAggregation.Code, NewAggregation.Name, NewAggregation.ShortName, NewAggregation.Description, thematicHeadingId, NewAggregation.Type, NewAggregation.Active, NewAggregation.Hidden, NewAggregation.External_Link, parentid, NewAggregation.User, language, null))
            {
                return(new RestResponseMessage(ErrorRestTypeEnum.Exception, "ERROR saving the new item aggregation to the database"));
            }
            // Ensure a folder exists for this, otherwise create one
            try
            {
                string folder = Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + "aggregations\\" + NewAggregation.Code.ToLower();
                if (!Directory.Exists(folder))
                {
                    // Create this directory and all the subdirectories
                    Directory.CreateDirectory(folder);
                    Directory.CreateDirectory(folder + "/html");
                    Directory.CreateDirectory(folder + "/images");
                    Directory.CreateDirectory(folder + "/html/home");
                    Directory.CreateDirectory(folder + "/html/custom/home");
                    Directory.CreateDirectory(folder + "/images/buttons");
                    Directory.CreateDirectory(folder + "/images/banners");
                    Directory.CreateDirectory(folder + "/uploads");

                    // Get the parent name
                    string link_to_parent = String.Empty;
                    Item_Aggregation_Related_Aggregations parentAggr = Engine_ApplicationCache_Gateway.Codes.Aggregation_By_ID(parentid);
                    if (parentAggr != null)
                    {
                        if (String.Compare(parentAggr.Code, "all", StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            link_to_parent = "<p>&larr; Back to <a href=\"<%BASEURL%>\" alt=\"Return to parent collection\">" + parentAggr.Name + "</a></p>" + Environment.NewLine;
                        }
                        else
                        {
                            link_to_parent = "<p>&larr; Back to <a href=\"<%BASEURL%>" + parentAggr.Code + "\" alt=\"Return to parent collection\">" + parentAggr.Name + "</a></p>" + Environment.NewLine;
                        }
                    }

                    // Create a default home text file
                    StreamWriter writer = new StreamWriter(folder + "/html/home/text.html");
                    writer.WriteLine(link_to_parent + "<h3>About " + NewAggregation.Name + "</h3>" + Environment.NewLine + "<p>" + NewAggregation.Description + "</p>" + Environment.NewLine + "<p>To edit this, log on as the aggregation admin and hover over this text to edit it.</p>" + Environment.NewLine);

                    writer.Flush();
                    writer.Close();

                    // Was a button indicated, and does it exist?
                    if ((!String.IsNullOrEmpty(NewAggregation.ButtonFile)) && (File.Exists(NewAggregation.ButtonFile)))
                    {
                        File.Copy(NewAggregation.ButtonFile, folder + "/images/buttons/coll.gif");
                    }
                    else
                    {
                        // Copy the default banner and buttons from images
                        if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.png"))
                        {
                            File.Copy(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.png", folder + "/images/buttons/coll.png");
                        }
                        if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.gif"))
                        {
                            File.Copy(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.gif", folder + "/images/buttons/coll.gif");
                        }
                    }

                    // Was a banner indicated, and does it exist?
                    string banner_file = String.Empty;
                    if ((!String.IsNullOrEmpty(NewAggregation.BannerFile)) && (File.Exists(NewAggregation.BannerFile)))
                    {
                        banner_file = "images/banners/" + Path.GetFileName(NewAggregation.BannerFile);
                        File.Copy(NewAggregation.BannerFile, folder + "//" + banner_file, true);
                    }
                    else
                    {
                        // Try to create a new custom banner
                        bool custom_banner_created = false;

                        // Create the banner with the name of the collection
                        if (Directory.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network + "\\default\\banner_images"))
                        {
                            try
                            {
                                string[] banners = Directory.GetFiles(Engine_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network + "\\default\\banner_images", "*.jpg");
                                if (banners.Length > 0)
                                {
                                    Random randomizer    = new Random();
                                    string banner_to_use = banners[randomizer.Next(0, banners.Length - 1)];
                                    Bitmap bitmap        = (Bitmap)(Image.FromFile(banner_to_use));

                                    RectangleF rectf = new RectangleF(30, bitmap.Height - 55, bitmap.Width - 40, 40);
                                    Graphics   g     = Graphics.FromImage(bitmap);
                                    g.SmoothingMode     = SmoothingMode.AntiAlias;
                                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                    g.PixelOffsetMode   = PixelOffsetMode.HighQuality;
                                    g.DrawString(NewAggregation.Name, new Font("Tahoma", 25, FontStyle.Bold), Brushes.Black, rectf);
                                    g.Flush();

                                    string new_file = folder + "/images/banners/coll.jpg";
                                    if (!File.Exists(new_file))
                                    {
                                        bitmap.Save(new_file, ImageFormat.Jpeg);
                                        custom_banner_created = true;
                                        banner_file           = "images/banners/coll.jpg";
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                // Suppress this Error...
                            }
                        }

                        if ((!custom_banner_created) && (!File.Exists(folder + "/images/banners/coll.jpg")))
                        {
                            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_banner.jpg"))
                            {
                                banner_file = "images/banners/coll.jpg";
                                File.Copy(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_banner.jpg", folder + "/images/banners/coll.jpg", true);
                            }
                        }
                    }

                    // Now, try to create the item aggregation and write the configuration file
                    Custom_Tracer             tracer          = new Custom_Tracer();
                    Complete_Item_Aggregation itemAggregation = SobekEngineClient.Aggregations.Get_Complete_Aggregation(NewAggregation.Code, true, tracer);
                    if (banner_file.Length > 0)
                    {
                        itemAggregation.Banner_Dictionary.Clear();
                        itemAggregation.Add_Banner_Image(banner_file, Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language);
                    }
                    itemAggregation.Write_Configuration_File(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + itemAggregation.ObjDirectory);

                    // If an email shoudl be sent, do that now
                    if (String.Compare(Engine_ApplicationCache_Gateway.Settings.Email.Send_On_Added_Aggregation, "always", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        string user = String.Empty;
                        if (!String.IsNullOrEmpty(NewAggregation.User))
                        {
                            user = NewAggregation.User;
                        }

                        string body = "New aggregation added to this system:\n\n\tCode:\t" + itemAggregation.Code + "\n\tType:\t" + itemAggregation.Type + "\n\tName:\t" + itemAggregation.Name + "\n\tShort:\t" + itemAggregation.ShortName + "\n\tUser:\t" + user + "\n\n" + Engine_ApplicationCache_Gateway.Settings.Servers.Application_Server_URL + "/" + itemAggregation.Code;
                        Email_Helper.SendEmail(Engine_ApplicationCache_Gateway.Settings.Email.System_Email, "New " + itemAggregation.Type + " - " + itemAggregation.ShortName, body, false, Engine_ApplicationCache_Gateway.Settings.System.System_Name);
                    }
                }
            }
            catch
            {
                // Reload the list of all codes, to include this new one and the new hierarchy
                lock (Engine_ApplicationCache_Gateway.Codes)
                {
                    Engine_Database.Populate_Code_Manager(Engine_ApplicationCache_Gateway.Codes, null);
                }

                return(new RestResponseMessage(ErrorRestTypeEnum.Exception, "ERROR completing the new aggregation add"));
            }

            // Reload the list of all codes, to include this new one and the new hierarchy
            lock (Engine_ApplicationCache_Gateway.Codes)
            {
                Engine_Database.Populate_Code_Manager(Engine_ApplicationCache_Gateway.Codes, null);
            }

            // Clear all aggregation information (and thematic heading info) from the cache as well
            CachedDataManager.Aggregations.Clear();

            return(new RestResponseMessage(ErrorRestTypeEnum.Successful, null));
        }