/// <summary> Constructor for a new instance of the Folder_Mgmt_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Results_Statistics"> Information about the entire set of results for the current folder </param>
        /// <param name="Paged_Results"> Single page of results for the current folder, within the entire set </param>
        /// <param name="Code_Manager"> Code manager object maintains mapping between SobekCM codes and greenstone codes (used by result_dataset_html_subwriter)</param>
        /// <param name="Item_List"> Object for pulling additional information about each item during display </param>
        /// <param name="currentCollection"> Current item aggregation [UNUSED?] </param>
        /// <param name="htmlSkin"> HTML interface, which determines the header, footer, stylesheet, and other design elements for the rendered HTML</param>
        /// <param name="Translator"> Translation / language support object for writing the user interface is multiple languages</param>
        /// <param name="currentMode"> Mode / navigation information for the current request</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Folder_Mgmt_MySobekViewer(User_Object User,
            Search_Results_Statistics Results_Statistics,
            List<iSearch_Title_Result> Paged_Results,
            Aggregation_Code_Manager Code_Manager,
            Item_Lookup_Object Item_List,
            Item_Aggregation currentCollection, 
            SobekCM_Skin_Object htmlSkin,
            Language_Support_Info Translator, 
            SobekCM_Navigation_Object currentMode,
            Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Folder_Mgmt_MySobekViewer.Constructor", String.Empty);

            user = User;
            pagedResults = Paged_Results;
            resultsStatistics = Results_Statistics;
            codeManager = Code_Manager;
            itemList = Item_List;
            this.htmlSkin = htmlSkin;
            base.Translator = Translator;
            this.currentCollection = currentCollection;

            properFolderName = String.Empty;
            int current_folder_id = -1;
            if (currentMode.My_Sobek_SubMode.Length > 0)
            {
                // Try to get this user folder from the user object
                User_Folder userFolder = user.Get_Folder( currentMode.My_Sobek_SubMode );

                // If the user folder is null, then this folder is not in the current user object
                // This may still be a valid folder though.  Check this by pulling folder list for this
                // user again
                if (userFolder == null)
                {
                    // Get the user from the database again
                    User_Object checkFolderUser = SobekCM_Database.Get_User(user.UserID, Tracer);

                    // Look for this folder in the new user object
                    userFolder = checkFolderUser.Get_Folder(currentMode.My_Sobek_SubMode);
                    if (userFolder == null)
                    {
                        // Invalid folder.. should not have gotten this far though
                        HttpContext.Current.Response.Redirect(currentMode.Base_URL);
                    }
                    else
                    {
                        // Save this to the user so this does not have to happen again
                        user.Add_Folder(userFolder);
                    }
                }

                // Get the proper name and folder id
                Debug.Assert(userFolder != null, "userFolder != null");
                properFolderName = userFolder.Folder_Name;
                current_folder_id = userFolder.Folder_ID;
            }

            if ((currentMode.isPostBack) || ((HttpContext.Current.Request.Form["item_action"] != null) && (HttpContext.Current.Request.Form["item_action"].Length > 0 )))
            {
                try
                {
                    // Pull the standard values
                    NameValueCollection form = HttpContext.Current.Request.Form;

                    string item_action = form["item_action"].Replace(",","").ToUpper().Trim();
                    string bookshelf_items = form["bookshelf_items"].Trim().Replace("%22", "\"").Replace("%27", "'").Replace("%3D", "=").Replace("%26", "&");
                    string bookshelf_params = form["bookshelf_params"].Trim();
                    string add_bookshelf = String.Empty;
                    if ( form["add_bookshelf"] != null )
                        add_bookshelf = form["add_bookshelf"].Trim();

                    if (item_action == "REFRESH_FOLDER")
                    {
                         refresh_user_folders(user, Tracer);
                         Cached_Data_Manager.Remove_All_User_Folder_Browses(user.UserID, Tracer);
                    }

                    if (item_action == "DELETE_FOLDER")
                    {
                        int folder_id = Convert.ToInt32(bookshelf_items);

                        SobekCM_Database.Delete_User_Folder(user.UserID, folder_id, Tracer);
                        Cached_Data_Manager.Clear_Public_Folder_Info(folder_id, Tracer);
                        refresh_user_folders(user, Tracer);
                    }

                    if (item_action == "NEW_BOOKSHELF")
                    {
                        string folder_name = form["new_bookshelf_name"].Trim().Replace("<", "(").Replace(">", ")");
                        int parent_id = Convert.ToInt32(form["new_bookshelf_parent"]);

                        if (SobekCM_Database.Edit_User_Folder(-1, user.UserID, parent_id, folder_name, false, String.Empty, Tracer) > 0)
                        {
                            refresh_user_folders(user, Tracer);
                        }
                    }

                    if ( item_action == "FOLDER_VISIBILITY" )
                    {
                        User_Folder thisFolder = user.Get_Folder(bookshelf_items);
                        if (bookshelf_params.ToUpper() == "PRIVATE")
                        {
                            if (SobekCM_Database.Edit_User_Folder(thisFolder.Folder_ID, user.UserID, -1, thisFolder.Folder_Name, false, String.Empty, Tracer) >= 0)
                                thisFolder.isPublic = false;

                            Cached_Data_Manager.Clear_Public_Folder_Info(thisFolder.Folder_ID, Tracer);
                        }

                        if (bookshelf_params.ToUpper() == "PUBLIC")
                        {
                            if (SobekCM_Database.Edit_User_Folder(thisFolder.Folder_ID, user.UserID, -1, thisFolder.Folder_Name, true, String.Empty, Tracer) >= 0 )
                                thisFolder.isPublic = true;
                        }
                    }

                    if ((item_action == "REMOVE") || ( item_action == "MOVE" ))
                    {
                        if (bookshelf_items.IndexOf("|") > 0)
                        {
                            string[] split_multi_items = bookshelf_items.Split("|".ToCharArray());
                            foreach (string[] split in split_multi_items.Select(thisItem => thisItem.Split("_".ToCharArray())).Where(split => split.Length == 2))
                            {
                                SobekCM_Database.Delete_Item_From_User_Folder(user.UserID, properFolderName, split[0], split[1], Tracer);
                                if (item_action == "MOVE")
                                {
                                    SobekCM_Database.Add_Item_To_User_Folder(user.UserID, add_bookshelf, split[0], split[1], 0, String.Empty, Tracer);
                                }
                            }

                            // Ensure this user folder is not sitting in the cache
                            Cached_Data_Manager.Remove_User_Folder_Browse(user.UserID, properFolderName, Tracer);
                            Cached_Data_Manager.Clear_Public_Folder_Info(current_folder_id, Tracer);
                            if (item_action == "MOVE")
                            {
                                Cached_Data_Manager.Remove_User_Folder_Browse(user.UserID, add_bookshelf, Tracer);
                                User_Folder moved_to_folder = user.Get_Folder(add_bookshelf);
                                if (moved_to_folder != null)
                                {
                                    Cached_Data_Manager.Clear_Public_Folder_Info(moved_to_folder.Folder_ID, Tracer);
                                }
                            }
                        }
                        else
                        {
                                string[] split = bookshelf_items.Split("_".ToCharArray());
                                if (split.Length == 2)
                                {
                                    SobekCM_Database.Delete_Item_From_User_Folder(user.UserID, properFolderName, split[0], split[1], Tracer);
                                    if (item_action == "MOVE")
                                    {
                                        SobekCM_Database.Add_Item_To_User_Folder(user.UserID, add_bookshelf, split[0], split[1], 1, String.Empty, Tracer);
                                    }
                                }

                            // Ensure this user folder is not sitting in the cache
                            Cached_Data_Manager.Remove_User_Folder_Browse(user.UserID, properFolderName, Tracer);
                            Cached_Data_Manager.Clear_Public_Folder_Info(current_folder_id, Tracer);
                            if (item_action == "MOVE")
                            {
                                Cached_Data_Manager.Remove_User_Folder_Browse(user.UserID, add_bookshelf, Tracer);
                                User_Folder moved_to_folder = user.Get_Folder(add_bookshelf);
                                if (moved_to_folder != null)
                                {
                                    Cached_Data_Manager.Clear_Public_Folder_Info(moved_to_folder.Folder_ID, Tracer);
                                }
                            }
                        }
                    }

                    if ( item_action == "EMAIL" )
                    {
                        string comments = form["email_comments"].Trim().Replace(">",")").Replace("<","(");
                        string email = form["email_address"].Trim();
                        string format = HttpContext.Current.Request.Form["email_format"].Trim().ToUpper();

                            string[] split = bookshelf_items.Split("_".ToCharArray());
                            if (split.Length == 2)
                            {
                                SobekCM_Assistant newAssistant = new SobekCM_Assistant();
                                SobekCM_Item newItem;
                                Page_TreeNode newPage;
                                SobekCM_Items_In_Title itemsInTitle;
                                newAssistant.Get_Item(currentMode, Item_List, SobekCM_Library_Settings.Image_URL, null, user, Tracer, out newItem, out newPage, out itemsInTitle );
                                SobekCM_Database.Add_Item_To_User_Folder(user.UserID, add_bookshelf, split[0], split[1], 1, comments, Tracer);

                                // Determine the email format
                                bool is_html_format = (format != "TEXT");

                                // Send this email
                                Item_Email_Helper.Send_Email(email, String.Empty, comments, user.Full_Name, currentMode.SobekCM_Instance_Abbreviation, newItem, is_html_format, currentMode.Base_URL + newItem.BibID + "/" + newItem.VID);
                            }
                    }

                    if ( item_action == "EDIT_NOTES" )
                    {
                        string notes = form["add_notes"].Trim().Replace(">",")").Replace("<","(");

                            string[] split = bookshelf_items.Split("_".ToCharArray());
                            if (split.Length == 2)
                            {
                                SobekCM_Database.Add_Item_To_User_Folder(user.UserID, add_bookshelf, split[0], split[1], 1, notes, Tracer);
                                Cached_Data_Manager.Remove_User_Folder_Browse(user.UserID, add_bookshelf, Tracer);
                            }

                    }
                }
                catch(Exception)
                {
                    // Catches any errors which may occur.  User will be sent back to the same URL,
                    // so any error that occurs should be obvious to the user
                }

                string return_url = HttpContext.Current.Items["Original_URL"].ToString();
                HttpContext.Current.Response.Redirect(return_url, false);

            }
        }
        private static User_Object build_user_object_from_dataset(DataSet ResultSet )
        {
            User_Object user = new User_Object();

            DataRow userRow = ResultSet.Tables[0].Rows[0];
            user.ShibbID = userRow["ShibbID"].ToString();
            user.UserID = Convert.ToInt32(userRow["UserID"]);
            user.UserName = userRow["username"].ToString();
            user.Email = userRow["EmailAddress"].ToString();
            user.Given_Name = userRow["FirstName"].ToString();
            user.Family_Name = userRow["LastName"].ToString();
            user.Send_Email_On_Submission = Convert.ToBoolean(userRow["SendEmailOnSubmission"]);
            user.Can_Submit = Convert.ToBoolean(userRow["Can_Submit_Items"]);
            user.Is_Temporary_Password = Convert.ToBoolean(userRow["isTemporary_Password"]);
            user.Nickname = userRow["Nickname"].ToString();
            user.Organization = userRow["Organization"].ToString();
            user.Organization_Code = userRow["OrganizationCode"].ToString();
            user.Department = userRow["Department"].ToString();
            user.College = userRow["College"].ToString();
            user.Unit = userRow["Unit"].ToString();
            user.Default_Rights = userRow["Rights"].ToString();
            user.Preferred_Language = userRow["Language"].ToString();
            user.Is_Internal_User = Convert.ToBoolean(userRow["Internal_User"]);
            user.Edit_Template_Code = userRow["EditTemplate"].ToString();
            user.Edit_Template_MARC_Code = userRow["EditTemplateMarc"].ToString();
            user.Can_Delete_All = Convert.ToBoolean(userRow["Can_Delete_All_Items"]);
            user.Is_System_Admin = Convert.ToBoolean(userRow["IsSystemAdmin"]);
            user.Is_Portal_Admin = Convert.ToBoolean(userRow["IsPortalAdmin"]);
            user.Include_Tracking_In_Standard_Forms = Convert.ToBoolean(userRow["Include_Tracking_Standard_Forms"]);
            user.Receive_Stats_Emails = Convert.ToBoolean(userRow["Receive_Stats_Emails"]);
            user.Has_Item_Stats = Convert.ToBoolean(userRow["Has_Item_Stats"]);
            user.LoggedOn = true;
            user.Internal_Notes = userRow["InternalNotes"].ToString();
            user.Processing_Technician = Convert.ToBoolean(userRow["ProcessingTechnician"]);
            user.Scanning_Technician = Convert.ToBoolean(userRow["ScanningTechnician"]);

            if (Convert.ToInt32(userRow["descriptions"]) > 0)
                user.Has_Descriptive_Tags = true;

            foreach (DataRow thisRow in ResultSet.Tables[1].Rows)
            {
                user.Add_Template(thisRow["TemplateCode"].ToString(), Convert.ToBoolean(thisRow["GroupDefined"].ToString()));
            }

            foreach (DataRow thisRow in ResultSet.Tables[2].Rows)
            {
                user.Add_Default_Metadata_Set(thisRow["MetadataCode"].ToString(), Convert.ToBoolean(thisRow["GroupDefined"].ToString()));
            }

            user.Items_Submitted_Count = ResultSet.Tables[3 ].Rows.Count;
            foreach (DataRow thisRow in ResultSet.Tables[3 ].Rows)
            {
                if (!user.BibIDs.Contains(thisRow["BibID"].ToString().ToUpper()))
                    user.Add_BibID(thisRow["BibID"].ToString().ToUpper());
            }

            // Add links to regular expressions
            foreach (DataRow thisRow in ResultSet.Tables[4 ].Rows)
            {
                user.Add_Editable_Regular_Expression(thisRow["EditableRegex"].ToString());
            }

            // Add links to aggregations
            foreach (DataRow thisRow in ResultSet.Tables[5 ].Rows)
            {

                user.Add_Aggregation(thisRow["Code"].ToString(), thisRow["Name"].ToString(), Convert.ToBoolean(thisRow["CanSelect"]), Convert.ToBoolean(thisRow["CanEditMetadata"]), Convert.ToBoolean(thisRow["CanEditBehaviors"]), Convert.ToBoolean(thisRow["CanPerformQc"]), Convert.ToBoolean(thisRow["CanUploadFiles"]), Convert.ToBoolean(thisRow["CanChangeVisibility"]), Convert.ToBoolean(thisRow["CanDelete"]), Convert.ToBoolean(thisRow["IsCollectionManager"]), Convert.ToBoolean(thisRow["OnHomePage"]), Convert.ToBoolean(thisRow["IsAggregationAdmin"]), Convert.ToBoolean(thisRow["GroupDefined"]));

            }

            // Add the current folder names
            Dictionary<int, User_Folder> folderNodes = new Dictionary<int, User_Folder>();
            List<User_Folder> parentNodes = new List<User_Folder>();
            foreach (DataRow folderRow in ResultSet.Tables[6 ].Rows)
            {
                string folderName = folderRow["FolderName"].ToString();
                int folderid = Convert.ToInt32(folderRow["UserFolderID"]);
                int parentid = Convert.ToInt32(folderRow["ParentFolderID"]);
                bool isPublic = Convert.ToBoolean(folderRow["isPublic"]);

                User_Folder newFolderNode = new User_Folder(folderName, folderid) {isPublic = isPublic};
                if (parentid == -1)
                    parentNodes.Add(newFolderNode);
                folderNodes.Add(folderid, newFolderNode);
            }
            foreach (DataRow folderRow in ResultSet.Tables[6 ].Rows)
            {
                int folderid = Convert.ToInt32(folderRow["UserFolderID"]);
                int parentid = Convert.ToInt32(folderRow["ParentFolderID"]);
                if (parentid > 0)
                {
                    folderNodes[parentid].Add_Child_Folder(folderNodes[folderid]);
                }
            }
            foreach (User_Folder rootFolder in parentNodes)
                user.Add_Folder(rootFolder);

            // Get the list of BibID/VID associated with this
            foreach (DataRow itemRow in ResultSet.Tables[7 ].Rows)
            {
                user.Add_Bookshelf_Item(itemRow["BibID"].ToString(), itemRow["VID"].ToString());
            }

            // Add the user groups to which this user is a member
            foreach (DataRow groupRow in ResultSet.Tables[8].Rows)
            {
                user.Add_User_Group(groupRow[0].ToString());
            }

            // Get all the user settings
            foreach (DataRow settingRow in ResultSet.Tables[9].Rows)
            {
                user.Add_Setting(settingRow["Setting_Key"].ToString(), settingRow["Setting_Value"].ToString(), false);
            }

            return user;
        }
        private static User_Object build_user_object_from_dataset(DataSet resultSet )
        {
            User_Object user = new User_Object();

            DataRow userRow = resultSet.Tables[0].Rows[0];
            user.UFID = userRow["UFID"].ToString();
            user.UserID = Convert.ToInt32(userRow["UserID"]);
            user.UserName = userRow["username"].ToString();
            user.Email = userRow["EmailAddress"].ToString();
            user.Given_Name = userRow["FirstName"].ToString();
            user.Family_Name = userRow["LastName"].ToString();
            user.Send_Email_On_Submission = Convert.ToBoolean(userRow["SendEmailOnSubmission"]);
            user.Can_Submit = Convert.ToBoolean(userRow["Can_Submit_Items"]);
            user.Is_Temporary_Password = Convert.ToBoolean(userRow["isTemporary_Password"]);
            user.Nickname = userRow["Nickname"].ToString();
            user.Organization = userRow["Organization"].ToString();
            user.Organization_Code = userRow["OrganizationCode"].ToString();
            user.Department = userRow["Department"].ToString();
            user.College = userRow["College"].ToString();
            user.Unit = userRow["Unit"].ToString();
            user.Default_Rights = userRow["Rights"].ToString();
            user.Preferred_Language = userRow["Language"].ToString();
            user.Is_Internal_User = Convert.ToBoolean(userRow["Internal_User"]);
            user.Edit_Template_Code = userRow["EditTemplate"].ToString();
            user.Edit_Template_MARC_Code = userRow["EditTemplateMarc"].ToString();
            user.Is_System_Admin = Convert.ToBoolean(userRow["IsSystemAdmin"]);
            user.Is_Portal_Admin = Convert.ToBoolean(userRow["IsPortalAdmin"]);
            user.Include_Tracking_In_Standard_Forms = Convert.ToBoolean(userRow["Include_Tracking_Standard_Forms"]);
            user.Receive_Stats_Emails = Convert.ToBoolean(userRow["Receive_Stats_Emails"]);
            user.Has_Item_Stats = Convert.ToBoolean(userRow["Has_Item_Stats"]);

            if (Convert.ToInt32(userRow["descriptions"]) > 0)
                user.Has_Descriptive_Tags = true;

            foreach (DataRow thisRow in resultSet.Tables[1].Rows)
            {
                user.Add_Template(thisRow["TemplateCode"].ToString());
            }

            foreach (DataRow thisRow in resultSet.Tables[2].Rows)
            {
                user.Add_Project(thisRow["ProjectCode"].ToString());
            }

            user.Items_Submitted_Count = resultSet.Tables[3 ].Rows.Count;
            foreach (DataRow thisRow in resultSet.Tables[3 ].Rows)
            {
                if (!user.BibIDs.Contains(thisRow["BibID"].ToString().ToUpper()))
                    user.Add_BibID(thisRow["BibID"].ToString().ToUpper());
            }

            // Add links to regular expressions
            foreach (DataRow thisRow in resultSet.Tables[4 ].Rows)
            {
                user.Add_Editable_Regular_Expression(thisRow["EditableRegex"].ToString());
            }

            // Add links to aggregations
            foreach (DataRow thisRow in resultSet.Tables[5 ].Rows)
            {
                user.Add_Aggregation(thisRow["Code"].ToString(), thisRow["Name"].ToString(), Convert.ToBoolean(thisRow["CanSelect"]), Convert.ToBoolean(thisRow["CanEditItems"]), Convert.ToBoolean(thisRow["IsAggregationAdmin"]), Convert.ToBoolean(thisRow["OnHomePage"]));
            }

            // Add the current folder names
            Dictionary<int, User_Folder> folderNodes = new Dictionary<int, User_Folder>();
            List<User_Folder> parentNodes = new List<User_Folder>();
            foreach (DataRow folderRow in resultSet.Tables[6 ].Rows)
            {
                string folderName = folderRow["FolderName"].ToString();
                int folderid = Convert.ToInt32(folderRow["UserFolderID"]);
                int parentid = Convert.ToInt32(folderRow["ParentFolderID"]);
                bool isPublic = Convert.ToBoolean(folderRow["isPublic"]);

                User_Folder newFolderNode = new User_Folder(folderName, folderid) {isPublic = isPublic};
                if (parentid == -1)
                    parentNodes.Add(newFolderNode);
                folderNodes.Add(folderid, newFolderNode);
            }
            foreach (DataRow folderRow in resultSet.Tables[6 ].Rows)
            {
                int folderid = Convert.ToInt32(folderRow["UserFolderID"]);
                int parentid = Convert.ToInt32(folderRow["ParentFolderID"]);
                if (parentid > 0)
                {
                    folderNodes[parentid].Add_Child_Folder(folderNodes[folderid]);
                }
            }
            foreach (User_Folder rootFolder in parentNodes)
                user.Add_Folder(rootFolder);

            foreach (DataRow itemRow in resultSet.Tables[7 ].Rows)
            {
                user.Add_Bookshelf_Item(itemRow["BibID"].ToString(), itemRow["VID"].ToString());
            }

            foreach (DataRow groupRow in resultSet.Tables[8].Rows)
            {
                user.Add_User_Group(groupRow[0].ToString());
            }

            return user;
        }