/// <summary> Write the nav-bar section
 /// from the item viewer to the item display html</summary>
 /// <param name="Output"> Stream to which to write </param>
 /// <param name="Prototyper"> Current item viewer prototyper </param>
 /// <param name="CurrentViewer"> Current item viewer which will be used to fill the primary part of the page </param>
 /// <param name="CurrentItem"> Current item which is being displayed </param>
 /// <param name="RequestSpecificValues"> Other, request specific values, such as the current mode, user, etc.. </param>
 /// <param name="Behaviors"> Behaviors for the current view and situation </param>
 public void Write_HTML(TextWriter Output, iItemViewerPrototyper Prototyper, iItemViewer CurrentViewer, BriefItemInfo CurrentItem, RequestCache RequestSpecificValues, List <HtmlSubwriter_Behaviors_Enum> Behaviors)
 {
     // Allow the item/page viewer to show anything in the left navigational menu
     if (CurrentViewer != null)
     {
         CurrentViewer.Write_Left_Nav_Menu_Section(Output, RequestSpecificValues.Tracer);
     }
 }
        /// <summary> Write the standard item menu to the item display html</summary>
        /// <param name="Output"> Stream to which to write </param>
        /// <param name="Prototyper"> Current item viewer prototyper </param>
        /// <param name="CurrentViewer"> Current item viewer which will be used to fill the primary part of the page </param>
        /// <param name="CurrentItem"> Current item which is being displayed </param>
        /// <param name="RequestSpecificValues"> Other, request specific values, such as the current mode, user, etc.. </param>
        /// <param name="Behaviors"> Behaviors for the current view and situation </param>
        public void Write_HTML(TextWriter Output, iItemViewerPrototyper Prototyper, iItemViewer CurrentViewer, BriefItemInfo CurrentItem, RequestCache RequestSpecificValues, List <HtmlSubwriter_Behaviors_Enum> Behaviors)
        {
            //// First, check that the menu provider was created
            //if (menuProvider == null)
            //{
            //    // Was there some configuration information?
            //    if (UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu != null)
            //    {
            //        if ((UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Class == "SobekCM.Library.ItemViewer.Menu.StandardItemMenuProvider") && (String.IsNullOrWhiteSpace(UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Assembly)))
            //            menuProvider = new StandardItemMenuProvider();
            //        else
            //        {
            //            try
            //            {
            //                string assemblyName = UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Assembly;
            //                string assemblyFilePath = Engine_ApplicationCache_Gateway.Configuration.Extensions.Get_Assembly(assemblyName);
            //                Assembly dllAssembly = Assembly.LoadFrom(assemblyFilePath);
            //                Type readerWriterType = dllAssembly.GetType(UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Class);
            //                menuProvider = (iItemMenuProvider)Activator.CreateInstance(readerWriterType);
            //            }
            //            catch (Exception)
            //            {
            //                // Do nothing here... will be fixed in the next couple lines of code
            //            }
            //        }
            //    }

            //    // Finally, just set to the standard if there was a problem
            //    if (menuProvider == null)

            //}

            if (menuProvider == null)
            {
                menuProvider = new StandardItemMenuProvider();
            }

            // The item viewer can choose to override the standard item menu
            if ((!Behaviors.Contains(HtmlSubwriter_Behaviors_Enum.Item_Subwriter_Suppress_Item_Menu)) && (menuProvider != null))
            {
                // Determine the current mode
                string currentCode = RequestSpecificValues.Current_Mode.ViewerCode ?? String.Empty;
                if (Prototyper != null)
                {
                    currentCode = Prototyper.ViewerCode;
                }

                // Should the LINKS be included?
                bool include_links = !Behaviors.Contains(HtmlSubwriter_Behaviors_Enum.Item_Subwriter_Suppress_Item_Menu_Links);

                // Let the menu provider write the menu
                menuProvider.Add_Main_Menu(Output, currentCode, RequestSpecificValues.Flags.ItemRestrictedFromUserByIp, RequestSpecificValues.Flags.ItemCheckedOutByOtherUser, CurrentItem, RequestSpecificValues.Current_Mode, RequestSpecificValues.Current_User, include_links, RequestSpecificValues.Tracer);
            }
        }
示例#3
0
        /// <summary> Write the item wordmarks to the item display html</summary>
        /// <param name="Output"> Stream to which to write </param>
        /// <param name="Prototyper"> Current item viewer prototyper </param>
        /// <param name="CurrentViewer"> Current item viewer which will be used to fill the primary part of the page </param>
        /// <param name="CurrentItem"> Current item which is being displayed </param>
        /// <param name="RequestSpecificValues"> Other, request specific values, such as the current mode, user, etc.. </param>
        /// <param name="Behaviors"> Behaviors for the current view and situation </param>
        public void Write_HTML(TextWriter Output, iItemViewerPrototyper Prototyper, iItemViewer CurrentViewer, BriefItemInfo CurrentItem, RequestCache RequestSpecificValues, List <HtmlSubwriter_Behaviors_Enum> Behaviors)
        {
            // Add any wordmarks
            if ((CurrentItem.Behaviors.Wordmarks != null) && (CurrentItem.Behaviors.Wordmarks.Count > 0))
            {
                Output.WriteLine("\t<div id=\"sbkIsw_Wordmarks\">");

                // Compute the URL options which may be needed
                string url_options = UrlWriterHelper.URL_Options(RequestSpecificValues.Current_Mode);
                string urlOptions1 = String.Empty;
                string urlOptions2 = String.Empty;
                if (url_options.Length > 0)
                {
                    urlOptions1 = "?" + url_options;
                    urlOptions2 = "&" + url_options;
                }

                // Step through each wordmark mentioned in the brief item
                foreach (string thisIcon in CurrentItem.Behaviors.Wordmarks)
                {
                    // Look for a match in the dictionary
                    if (UI_ApplicationCache_Gateway.Icon_List.ContainsKey(thisIcon))
                    {
                        Wordmark_Icon wordmarkInfo = UI_ApplicationCache_Gateway.Icon_List[thisIcon];

                        Output.WriteLine("\t\t" + wordmarkInfo.HTML.Replace("<%BASEURL%>", RequestSpecificValues.Current_Mode.Base_URL).Replace("<%URLOPTS%>", url_options).Replace("<%?URLOPTS%>", urlOptions1).Replace("<%&URLOPTS%>", urlOptions2));
                    }
                }

                Output.WriteLine("\t</div>");
            }
            //else
            //{
            //    Output.WriteLine("\t<div id=\"sbkIsw_NoWordmarks\">&nbsp;</div>");
            //}
        }
        /// <summary> Configure the viewers for a single brief item to match this user interface settings </summary>
        /// <param name="BriefItem"> Brief item to adjust selected viewers </param>
        public static void Configure_Brief_Item_Viewers(BriefItemInfo BriefItem)
        {
            // Ensure the necessary dictionaries are built
            configureItemViewers();

            // If the brief item already has the UI built, skip this
            if ((BriefItem.UI != null) && (BriefItem.UI.Viewers_By_Priority != null) && (BriefItem.UI.Viewers_Menu_Order != null))
            {
                return;
            }

            // Now, add the UI object (if null) and set the values
            if (BriefItem.UI == null)
            {
                BriefItem.UI = new BriefItem_UI();
            }
            if (BriefItem.UI.Viewers_By_Priority == null)
            {
                BriefItem.UI.Viewers_By_Priority = new List <string>();
            }
            if (BriefItem.UI.Viewers_Menu_Order == null)
            {
                BriefItem.UI.Viewers_Menu_Order = new List <string>();
            }

            // Use a sorted list to build the menu order
            SortedDictionary <float, string> menuOrderSort = new SortedDictionary <float, string>();

            // Step through each viewer included from the database
            foreach (BriefItem_BehaviorViewer viewer in BriefItem.Behaviors.Viewers)
            {
                // If this is an EXCLUDE viewer, just skip it here
                if (viewer.Excluded)
                {
                    continue;
                }

                // Verify a match in the UI configuration for the actual item viewers
                if (!viewTypeToItemViewerPrototyper.ContainsKey(viewer.ViewerType))
                {
                    continue;
                }

                // Get the item prototype object
                iItemViewerPrototyper protoTyper = viewTypeToItemViewerPrototyper[viewer.ViewerType];

                // Verify this prototyper is not NULL and believes it should be added
                if ((protoTyper != null) && (protoTyper.Include_Viewer(BriefItem)))
                {
                    // Add this view to the ordained views
                    BriefItem.UI.Viewers_By_Priority.Add(viewer.ViewerType);

                    // Check for collisions on the menu order
                    float menuOrder = viewer.MenuOrder;
                    while (menuOrderSort.ContainsKey(menuOrder))
                    {
                        menuOrder = menuOrder + .001f;
                    }

                    // Also add this to the menu order sorted list
                    menuOrderSort[menuOrder] = viewer.ViewerType;

                    // Also add this to the dictionary for lookup
                    BriefItem.UI.Add_Viewer_Code(protoTyper.ViewerCode, protoTyper.ViewerType);
                }
            }

            // Also, add each of the management style viewers, that are not generally stored in the database
            // but we will still double check it wasn't already added
            foreach (ItemSubViewerConfig viewerConfig in mgmtViewerConfigs)
            {
                // Verify a match in the UI configuration for the actual item viewers
                if (!viewTypeToItemViewerPrototyper.ContainsKey(viewerConfig.ViewerType))
                {
                    continue;
                }

                // Is it ALREADY added though? (may be added with EXCLUDE set to true)
                if (BriefItem.UI.Includes_Viewer_Type(viewerConfig.ViewerType))
                {
                    continue;
                }

                // Get the item prototype object
                iItemViewerPrototyper protoTyper = viewTypeToItemViewerPrototyper[viewerConfig.ViewerType];

                // Verify this prototyper is not NULL and believes it should be added
                if ((protoTyper != null) && (protoTyper.Include_Viewer(BriefItem)))
                {
                    // Add this view to the ordained views
                    BriefItem.UI.Viewers_By_Priority.Add(viewerConfig.ViewerType);

                    // Check for collisions on the menu order
                    float menuOrder = viewerConfig.ManagementOrder;
                    while (menuOrderSort.ContainsKey(menuOrder))
                    {
                        menuOrder = menuOrder + .001f;
                    }

                    // Also add this to the menu order sorted list
                    menuOrderSort[menuOrder] = viewerConfig.ViewerType;

                    // Also add this to the dictionary for lookup
                    BriefItem.UI.Add_Viewer_Code(protoTyper.ViewerCode, protoTyper.ViewerType);
                }
            }

            // Add the viewers back in menu order to the menu order portion
            foreach (float thisKey in menuOrderSort.Keys)
            {
                BriefItem.UI.Viewers_Menu_Order.Add(menuOrderSort[thisKey]);
            }
        }
        private static iItemViewerPrototyper configurePrototyper(string assembly, string className)
        {
            // Was an assembly indicated
            if (String.IsNullOrEmpty(assembly))
            {
                // Return a standard class
                switch (className)
                {
                //case "SobekCM.Library.ItemViewer.Viewers.GIF_ItemViewer_Prototyper":
                //    return new GIF_ItemViewer_Prototyper();

                case "SobekCM.Library.ItemViewer.Viewers.Citation_MARC_ItemViewer_Prototyper":
                    return(new Citation_MARC_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Citation_Standard_ItemViewer_Prototyper":
                    return(new Citation_Standard_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Directory_ItemViewer_Prototyper":
                    return(new Directory_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Downloads_ItemViewer_Prototyper":
                    return(new Downloads_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.EmbeddedVideo_ItemViewer_Prototyper":
                    return(new EmbeddedVideo_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Flash_ItemViewer_Prototyper":
                    return(new Flash_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.GnuBooks_PageTurner_ItemViewer_Prototyper":
                    return(new GnuBooks_PageTurner_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Google_Map_ItemViewer_Prototyper":
                    return(new Google_Map_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Google_Coordinate_Entry_ItemViewer_Prototyper":
                    return(new Google_Coordinate_Entry_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.HTML_ItemViewer_Prototyper":
                    return(new HTML_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.JPEG_ItemViewer_Prototyper":
                    return(new JPEG_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.JPEG2000_ItemViewer_Prototyper":
                    return(new JPEG2000_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.ManageMenu_ItemViewer_Prototyper":
                    return(new ManageMenu_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Metadata_Links_ItemViewer_Prototyper":
                    return(new Metadata_Links_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Milestones_ItemViewer_Prototyper":
                    return(new Milestones_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.MultiVolumes_ItemViewer_Prototyper":
                    return(new MultiVolumes_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.PDF_ItemViewer_Prototyper":
                    return(new PDF_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.QC_ItemViewer_Prototyper":
                    return(new QC_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Related_Images_ItemViewer_Prototyper":
                    return(new Related_Images_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Restricted_ItemViewer_Prototyper":
                    return(new Restricted_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.TEI_ItemViewer_Prototyper":
                    return(new TEI_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Text_ItemViewer_Prototyper":
                    return(new Text_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Text_Search_ItemViewer_Prototyper":
                    return(new Text_Search_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.TrackingSheet_ItemViewer_Prototyper":
                    return(new TrackingSheet_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Tracking_ItemViewer_Prototyper":
                    return(new Tracking_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Usage_Stats_ItemViewer_Prototyper":
                    return(new Usage_Stats_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.Video_ItemViewer_Prototyper":
                    return(new Video_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.UF_Archives_ItemViewer_Prototyper":
                    return(new UF_Archives_ItemViewer_Prototyper());

                case "SobekCM.Library.ItemViewer.Viewers.UF_Media_ItemViewer_Prototyper":
                    return(new UF_Media_ItemViewer_Prototyper());
                }

                // If it made it here, there is no assembly, but it is an unexpected type.
                // Just create it from the same assembly then
                try
                {
                    Assembly dllAssembly            = Assembly.GetCallingAssembly();
                    Type     prototyperType         = dllAssembly.GetType(className);
                    iItemViewerPrototyper returnObj = (iItemViewerPrototyper)Activator.CreateInstance(prototyperType);
                    return(returnObj);
                }
                catch (Exception)
                {
                    // Not sure exactly what to do here, honestly
                    return(null);
                }
            }


            // An assembly was indicated
            try
            {
                // Try to find the file/path for this assembly then
                Assembly dllAssembly      = null;
                string   assemblyFilePath = UI_ApplicationCache_Gateway.Configuration.Extensions.Get_Assembly(assembly);
                if (assemblyFilePath != null)
                {
                    dllAssembly = Assembly.LoadFrom(assemblyFilePath);
                }
                Type prototyperType             = dllAssembly.GetType(className);
                iItemViewerPrototyper returnObj = (iItemViewerPrototyper)Activator.CreateInstance(prototyperType);
                return(returnObj);
            }
            catch (Exception ee)
            {
                // Not sure exactly what to do here, honestly
                if (ee.Message.Length > 0)
                {
                    return(null);
                }
                return(null);
            }

            return(null);
        }
        private static void configureItemViewers()
        {
            // If already configured, do nothing
            if ((viewTypeToItemViewerPrototyper != null) && (viewTypeToItemViewerPrototyper.Count > 0) &&
                (viewerCodeToItemViewerPrototyper != null) && (viewerCodeToItemViewerPrototyper.Count > 0))
            {
                return;
            }

            // Make sure the dictionaries are not null
            if (viewerCodeToItemViewerPrototyper == null)
            {
                viewerCodeToItemViewerPrototyper = new Dictionary <string, iItemViewerPrototyper>(StringComparer.OrdinalIgnoreCase);
            }
            if (viewTypeToItemViewerPrototyper == null)
            {
                viewTypeToItemViewerPrototyper = new Dictionary <string, iItemViewerPrototyper>(StringComparer.OrdinalIgnoreCase);
            }
            if (mgmtViewerConfigs == null)
            {
                mgmtViewerConfigs = new List <ItemSubViewerConfig>();
            }

            // Temporary sorter
            SortedDictionary <float, ItemSubViewerConfig> mgmtOrder = new SortedDictionary <float, ItemSubViewerConfig>();

            // Step through all the potential item viewers prototypes in the dictionary
            foreach (ItemSubViewerConfig thisViewerConfig in UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.Viewers)
            {
                // If this is not enabled, skip it
                if (!thisViewerConfig.Enabled)
                {
                    continue;
                }

                // Get the code and viewer type
                string code = thisViewerConfig.ViewerCode;
                string type = thisViewerConfig.ViewerType;

                // Build the prototyper
                iItemViewerPrototyper prototyper = configurePrototyper(thisViewerConfig.Assembly, thisViewerConfig.Class);

                // If this failed to create a prototyper move on
                if (prototyper == null)
                {
                    continue;
                }

                // Add any other configuration here
                if (!String.IsNullOrEmpty(thisViewerConfig.ViewerCode))
                {
                    prototyper.ViewerCode = thisViewerConfig.ViewerCode;
                }
                if ((thisViewerConfig.PageExtensions != null) && (thisViewerConfig.PageExtensions.Length > 0))
                {
                    prototyper.FileExtensions = thisViewerConfig.PageExtensions;
                }
                else if ((thisViewerConfig.FileExtensions != null) && (thisViewerConfig.FileExtensions.Length > 0))
                {
                    prototyper.FileExtensions = thisViewerConfig.FileExtensions;
                }

                // Add this to the dictionaries
                viewTypeToItemViewerPrototyper[type] = prototyper;
                viewerCodeToItemViewerPrototyper[prototyper.ViewerCode] = prototyper;

                // Was this a management viewer?
                if (thisViewerConfig.ManagementViewer)
                {
                    // Get the order and ensure there are no collisions
                    float orderValue = thisViewerConfig.ManagementOrder;
                    while (mgmtOrder.ContainsKey(orderValue))
                    {
                        orderValue += .001f;
                    }

                    // Add this to the sort list
                    mgmtOrder[orderValue] = thisViewerConfig;
                }
            }

            // Add the sorted viewers to the sort list, in sorted order
            mgmtViewerConfigs = mgmtOrder.Values.ToList();
        }
        /// <summary> Write the table of contents to the item display html</summary>
        /// <param name="Output"> Stream to which to write </param>
        /// <param name="Prototyper"> Current item viewer prototyper </param>
        /// <param name="CurrentViewer"> Current item viewer which will be used to fill the primary part of the page </param>
        /// <param name="CurrentItem"> Current item which is being displayed </param>
        /// <param name="RequestSpecificValues"> Other, request specific values, such as the current mode, user, etc.. </param>
        /// <param name="Behaviors"> Behaviors for the current view and situation </param>
        public void Write_HTML(TextWriter Output, iItemViewerPrototyper Prototyper, iItemViewer CurrentViewer, BriefItemInfo CurrentItem, RequestCache RequestSpecificValues, List <HtmlSubwriter_Behaviors_Enum> Behaviors)
        {
            // If there is no TOC, just return
            if ((CurrentItem == null) || (CurrentItem.Images_TOC == null) || (CurrentItem.Images_TOC.Count <= 1))
            {
                return;
            }

            string table_of_contents = "TABLE OF CONTENTS";

            //string hide_toc = "HIDE TABLE OF CONTENTS";
            //string show_toc_text = "SHOW TABLE OF CONTENTS";

            if (RequestSpecificValues.Current_Mode.Language == Web_Language_Enum.French)
            {
                table_of_contents = "TABLE DES MATIERES";
                //hide_toc = "MASQUER L'INDEX";
                //show_toc_text = "VOIR L'INDEX";
            }

            if (RequestSpecificValues.Current_Mode.Language == Web_Language_Enum.Spanish)
            {
                table_of_contents = "INDICE";
                //hide_toc = "ESCONDA INDICE";
                //show_toc_text = "MOSTRAR INDICE";
            }

            // Get the item URL
            string item_url    = RequestSpecificValues.Current_Mode.Base_URL + CurrentItem.BibID + "/" + CurrentItem.VID;
            string viewer_code = RequestSpecificValues.Current_Mode.ViewerCode.Replace(RequestSpecificValues.Current_Mode.Page.ToString(), "#");

            if (viewer_code.IndexOf("#") < 0)
            {
                viewer_code = "#";
            }

            Output.WriteLine();
            Output.WriteLine("  <script type=\"text/javascript\" src=\"" + UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Jstree_Js + "\"></script>");
            Output.WriteLine("  <div class=\"sbkIsw_ShowTocRow\">" + table_of_contents + "</div>");
            Output.WriteLine("  <div id=\"tocTree\" class=\"sbkIsw_TocTreeView\">");
            Output.WriteLine("    <ul>");

            List <BriefItem_TocElement> tocElements = CurrentItem.Images_TOC;
            int lastLevel       = -1;
            int currentLevel    = 0;
            int nextLevel       = 0;
            int currentSequence = 0;
            int nextSequence    = 0;
            int selectSequence  = Convert.ToInt32(RequestSpecificValues.Current_Mode.Page);

            //int sequence = 0;
            for (int i = 0; i < tocElements.Count; i++)
            {
                // Get this level and sequence
                currentLevel    = tocElements[i].Level.HasValue ? tocElements[i].Level.Value : 1;
                currentSequence = tocElements[i].Sequence;

                // Get the next level and sequence
                if (i + 1 < tocElements.Count)
                {
                    nextSequence = tocElements[i + 1].Sequence;
                }
                else
                {
                    nextSequence = selectSequence + 1;
                }

                // If this is not the first, then look to close any previous ones
                if (i > 0)
                {
                    if (lastLevel == currentLevel)
                    {
                        Output.WriteLine("</li>");
                    }
                    else if (lastLevel < currentLevel)
                    {
                        Output.WriteLine();
                        Output.WriteLine(indent(lastLevel) + "  <ul>");
                    }
                    else // lastLevel > currentLevel
                    {
                        Output.WriteLine("</li>");

                        while (lastLevel > currentLevel)
                        {
                            lastLevel--;

                            Output.WriteLine(indent(lastLevel) + "  </ul>");
                            Output.WriteLine(indent(lastLevel) + "</li>");
                        }
                    }
                }

                // Write this one
                if (Behaviors.Contains(HtmlSubwriter_Behaviors_Enum.Item_Subwriter_Suppress_TOC_Links))
                {
                    Output.Write(indent(currentLevel) + "<li><abbr title=\"" + tocElements[i].Name.Replace("\"", "'") + "\">" + tocElements[i].Shortened_Name);
                }
                else
                {
                    string page_url = item_url + "/" + viewer_code.Replace("#", currentSequence.ToString());

                    Output.Write(indent(currentLevel) + "<li><a href=\"" + page_url + "\" title=\"" + tocElements[i].Name + "\" >");

                    // Is this the current location?
                    if ((selectSequence >= currentSequence) && (selectSequence < nextSequence))
                    {
                        Output.Write("<span class=\"sbkIsw_SelectedTocTreeViewItem\">" + tocElements[i].Shortened_Name + "</span>");
                    }
                    else
                    {
                        Output.Write(tocElements[i].Shortened_Name);
                    }
                    Output.Write("</a>");
                }


                lastLevel = currentLevel;
            }

            // Close this
            Output.WriteLine("</li>");
            while (lastLevel > 1)
            {
                lastLevel--;

                Output.WriteLine(indent(lastLevel) + "  </ul>");
                Output.WriteLine(indent(lastLevel) + "</li>");
            }


            Output.WriteLine("    </ul>");
            Output.WriteLine("  </div>");
            Output.WriteLine();

            Output.WriteLine("  <script type=\"text/javascript\">");
            Output.WriteLine("    $('#tocTree').jstree( {\"core\": { \"themes\":{ \"icons\":false } } }).bind(\"select_node.jstree\", function (e, data) { var href = data.node.a_attr.href; document.location.href = href; });");
            Output.WriteLine("    $('#tocTree').jstree('open_all');");
            Output.WriteLine("  </script>");
            Output.WriteLine();
        }
        /// <summary> Constructor for a new instance of the JPEG_ItemViewer class, used to display JPEGs linked to
        /// pages in a digital resource </summary>
        /// <param name="BriefItem"> Digital resource object </param>
        /// <param name="CurrentUser"> Current user, who may or may not be logged on </param>
        /// <param name="CurrentRequest"> Information about the current request </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <param name="JPEG_ViewerCode"> JPEG viewer code, as determined by configuration files </param>
        /// <param name="FileExtensions"> File extensions that this viewer allows, as determined by configuration files </param>
        public JPEG_ItemViewer(BriefItemInfo BriefItem, User_Object CurrentUser, Navigation_Object CurrentRequest, Custom_Tracer Tracer, string JPEG_ViewerCode, string[] FileExtensions)
        {
            // Add the trace
            if (Tracer != null)
            {
                Tracer.Add_Trace("JPEG_ItemViewer.Constructor");
            }

            // Save the arguments for use later
            this.BriefItem      = BriefItem;
            this.CurrentUser    = CurrentUser;
            this.CurrentRequest = CurrentRequest;

            // Set the behavior properties
            Behaviors = EmptyBehaviors;

            // Is the JPEG2000 viewer included in this item?
            bool zoomableViewerIncluded = BriefItem.UI.Includes_Viewer_Type("JPEG2000");

            string[] jpeg2000_extensions = null;
            if (zoomableViewerIncluded)
            {
                iItemViewerPrototyper jp2Prototyper = ItemViewer_Factory.Get_Viewer_By_ViewType("JPEG2000");
                if (jp2Prototyper == null)
                {
                    zoomableViewerIncluded = false;
                }
                else
                {
                    zoomableViewerCode  = jp2Prototyper.ViewerCode;
                    jpeg2000_extensions = jp2Prototyper.FileExtensions;
                }
            }

            // Set some default values
            width  = 500;
            height = -1;
            includeLinkToZoomable = false;

            // Determine the page
            page = 1;
            if (!String.IsNullOrEmpty(CurrentRequest.ViewerCode))
            {
                int tempPageParse;
                if (Int32.TryParse(CurrentRequest.ViewerCode.Replace(JPEG_ViewerCode.Replace("#", ""), ""), out tempPageParse))
                {
                    page = tempPageParse;
                }
            }

            // Just a quick range check
            if (page > BriefItem.Images.Count)
            {
                page = 1;
            }

            // Try to set the file information here
            if ((!set_file_information(FileExtensions, zoomableViewerIncluded, jpeg2000_extensions)) && (page != 1))
            {
                // If there was an error, just set to the first page
                page = 1;
                set_file_information(FileExtensions, zoomableViewerIncluded, jpeg2000_extensions);
            }

            // Since this is a paging viewer, set the viewer code
            if (String.IsNullOrEmpty(CurrentRequest.ViewerCode))
            {
                CurrentRequest.ViewerCode = JPEG_ViewerCode.Replace("#", page.ToString());
            }
        }
        /// <summary> Write the item title bar to the item display html</summary>
        /// <param name="Output"> Stream to which to write </param>
        /// <param name="Prototyper"> Current item viewer prototyper </param>
        /// <param name="CurrentViewer"> Current item viewer which will be used to fill the primary part of the page </param>
        /// <param name="CurrentItem"> Current item which is being displayed </param>
        /// <param name="RequestSpecificValues"> Other, request specific values, such as the current mode, user, etc.. </param>
        /// <param name="Behaviors"> Behaviors for the current view and situation </param>
        public void Write_HTML(TextWriter Output, iItemViewerPrototyper Prototyper, iItemViewer CurrentViewer, BriefItemInfo CurrentItem, RequestCache RequestSpecificValues, List <HtmlSubwriter_Behaviors_Enum> Behaviors)
        {
            // The item viewer can choose to override the standard item titlebar
            if (!Behaviors.Contains(HtmlSubwriter_Behaviors_Enum.Item_Subwriter_Suppress_Titlebar))
            {
                Output.WriteLine("<!-- Show the title and any other important item information -->");
                Output.WriteLine("<section id=\"sbkIsw_Titlebar\" role=\"banner\">");

                if (String.Compare(CurrentItem.VID, "00000", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    string grouptitle = "NO TITLE";
                    if ((CurrentItem.Behaviors != null) && (!String.IsNullOrWhiteSpace(CurrentItem.Behaviors.GroupTitle)))
                    {
                        grouptitle = CurrentItem.Behaviors.GroupTitle;
                    }
                    if (grouptitle.Length > 125)
                    {
                        Output.WriteLine("\t<h1 itemprop=\"name\"><abbr title=\"" + grouptitle + "\">" + grouptitle.Substring(0, 120) + "..</abbr></h1>");
                    }
                    else
                    {
                        Output.WriteLine("\t<h1 itemprop=\"name\">" + grouptitle + "</h1>");
                    }
                }
                else
                {
                    string final_title = CurrentItem.Title ?? "NO TITLE";

                    // Add the Title if there is one
                    if (final_title.Length > 0)
                    {
                        // Is this a newspaper?
                        bool newspaper = (String.Compare(CurrentItem.Behaviors.GroupType, "NEWSPAPER", StringComparison.OrdinalIgnoreCase) == 0);

                        // Does a custom setting override the default behavior to add a date?
                        if ((newspaper) && (UI_ApplicationCache_Gateway.Settings.Contains_Additional_Setting("Item Viewer.Include Date In Title")) && (UI_ApplicationCache_Gateway.Settings.Get_Additional_Setting("Item Viewer.Include Date In Title").ToUpper() == "NEVER"))
                        {
                            newspaper = false;
                        }

                        // Add the date if it should be added
                        if ((newspaper) && (!String.IsNullOrEmpty(CurrentItem.Web.Date)))
                        {
                            if (final_title.Length > 125)
                            {
                                Output.WriteLine("\t<h1 itemprop=\"name\"><abbr title=\"" + final_title + "\">" + final_title.Substring(0, 120) + "..</abbr> ( " + CurrentItem.Web.Date + " )</h1>");
                            }
                            else
                            {
                                Output.WriteLine("\t<h1 itemprop=\"name\">" + final_title + " ( " + CurrentItem.Web.Date + " )</h1>");
                            }
                        }
                        else
                        {
                            if (final_title.Length > 125)
                            {
                                Output.WriteLine("\t<h1 itemprop=\"name\"><abbr title=\"" + final_title + "\">" + final_title.Substring(0, 120) + "..</abbr></h1>");
                            }
                            else
                            {
                                Output.WriteLine("\t<h1 itemprop=\"name\">" + final_title + "</h1>");
                            }
                        }
                    }


                    // Add the link if there is one
                    // Links_BriefItemMapper
                    if ((CurrentItem.Web != null) && (!String.IsNullOrEmpty(CurrentItem.Web.Title_Box_Additional_Link)))
                    {
                        // Get the translated TYPE
                        string type = UI_ApplicationCache_Gateway.Translation.Get_Translation((CurrentItem.Web.Title_Box_Additional_Link_Type ?? "Related Link"), RequestSpecificValues.Current_Mode.Language);

                        // Add the link
                        Output.WriteLine("\t" + CurrentItem.Web.Title_Box_Additional_Link + " ( " + type + " )<br />");
                    }


                    // If there is an ACCESSION number and this is an ARTIFACT, include that at the top
                    BriefItem_DescriptiveTerm accessNumber = CurrentItem.Get_Description("Accession Number");
                    if ((accessNumber != null) && (accessNumber.Values != null) && (accessNumber.Values.Count > 0))
                    {
                        Output.WriteLine("\t" + UI_ApplicationCache_Gateway.Translation.Get_Translation("Accession number", RequestSpecificValues.Current_Mode.Language) + " " + accessNumber.Values[0].Value + "<br />");
                    }
                }


                Output.WriteLine("</section>");
                Output.WriteLine();
            }
        }
        /// <summary> Constructor for a new instance of the Item_HtmlSubwriter class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        public Item_HtmlSubwriter( RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            // First, check that the menu provider was created
            if (menuProvider == null)
            {
                // Was there some configuration information?
                if (UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu != null)
                {
                    if ((UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Class == "SobekCM.Library.ItemViewer.Menu.StandardItemMenuProvider") && (String.IsNullOrWhiteSpace(UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Assembly)))
                        menuProvider = new StandardItemMenuProvider();
                    else
                    {
                        try
                        {
                            string assemblyName = UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Assembly;
                            string assemblyFilePath = Engine_ApplicationCache_Gateway.Configuration.Extensions.Get_Assembly(assemblyName);
                            Assembly dllAssembly = Assembly.LoadFrom(assemblyFilePath);
                            Type readerWriterType = dllAssembly.GetType(UI_ApplicationCache_Gateway.Configuration.UI.WriterViewers.Items.MainMenu.Class);
                            menuProvider = (iItemMenuProvider)Activator.CreateInstance(readerWriterType);
                        }
                        catch (Exception)
                        {
                            // Do nothing here... will be fixed in the next couple lines of code
                        }
                    }
                }

                // Finally, just set to the standard if there was a problem
                if ( menuProvider == null )
                    menuProvider = new StandardItemMenuProvider();
            }

            // Add the trace
            if (RequestSpecificValues.Tracer != null)
                RequestSpecificValues.Tracer.Add_Trace("Item_HtmlSubwriter.Constructor");

            showZoomable = (String.IsNullOrEmpty(UI_ApplicationCache_Gateway.Settings.Servers.JP2ServerUrl));

            searchResultsCount = 0;

            // Determine if the TOC should be shown
            showToc = false;
            if (HttpContext.Current.Session["Show TOC"] != null)
            {
                Boolean.TryParse(HttpContext.Current.Session["Show TOC"].ToString(), out showToc);
            }

            // Try to get the current item
            currentItem = SobekEngineClient.Items.Get_Item_Brief(RequestSpecificValues.Current_Mode.BibID, RequestSpecificValues.Current_Mode.VID, true, RequestSpecificValues.Tracer);
            RequestSpecificValues.Current_Mode.VID = currentItem.VID;

            // Ensure the UI portion has been configured for this user interface
            ItemViewer_Factory.Configure_Brief_Item_Viewers(currentItem);

            // Set some flags based on the resource type
            is_bib_level = (String.Compare(currentItem.VID, "00000", StringComparison.OrdinalIgnoreCase) == 0);
            is_ead = (String.Compare(currentItem.Type, "EAD", StringComparison.OrdinalIgnoreCase) == 0);

            // Look for TEI-type item
            is_tei = false;
            if ((UI_ApplicationCache_Gateway.Configuration.Extensions != null) &&
                (UI_ApplicationCache_Gateway.Configuration.Extensions.Get_Extension("TEI") != null) &&
                (UI_ApplicationCache_Gateway.Configuration.Extensions.Get_Extension("TEI").Enabled))
            {
                string tei_file = currentItem.Behaviors.Get_Setting("TEI.Source_File");
                string xslt_file = currentItem.Behaviors.Get_Setting("TEI.XSLT");
                if ((tei_file != null) && (xslt_file != null))
                {
                    is_tei = true;
                }
            }

            // Determine if this user can edit this item
            userCanEditItem = false;
            if (RequestSpecificValues.Current_User != null)
            {
                userCanEditItem = RequestSpecificValues.Current_User.Can_Edit_This_Item(currentItem.BibID, currentItem.Type, currentItem.Behaviors.Source_Institution_Aggregation, currentItem.Behaviors.Holding_Location_Aggregation, currentItem.Behaviors.Aggregation_Code_List );
            }

            // Check that this item is not checked out by another user
            itemCheckedOutByOtherUser = false;
            if (currentItem.Behaviors.Single_Use)
            {
                if (!Engine_ApplicationCache_Gateway.Checked_List.Check_Out(currentItem.Web.ItemID, HttpContext.Current.Request.UserHostAddress))
                {
                    itemCheckedOutByOtherUser = true;
                }
            }

            // Check to see if this is IP restricted
            restriction_message = String.Empty;
            if (currentItem.Behaviors.IP_Restriction_Membership > 0)
            {
                if (HttpContext.Current != null)
                {
                    int user_mask = (int)HttpContext.Current.Session["IP_Range_Membership"];
                    int comparison = currentItem.Behaviors.IP_Restriction_Membership & user_mask;
                    if (comparison == 0)
                    {
                        itemRestrictedFromUserByIp = true;

                        int restriction = currentItem.Behaviors.IP_Restriction_Membership;
                        int restriction_counter = 1;
                        while (restriction % 2 != 1)
                        {
                            restriction = restriction >> 1;
                            restriction_counter++;
                        }
                        if (Engine_ApplicationCache_Gateway.IP_Restrictions[restriction_counter] != null)
                            restriction_message = Engine_ApplicationCache_Gateway.IP_Restrictions[restriction_counter].Item_Restricted_Statement;
                        else
                            restriction_message = "Restricted Item";
                    }
                }
            }

            // If this item is restricted by IP than alot of the upcoming code is unnecessary
            if ((RequestSpecificValues.Current_User != null) && ((!itemRestrictedFromUserByIp) || (userCanEditItem) || (RequestSpecificValues.Current_User.Is_Internal_User)))
            {
                #region Region suppressed currently - was for adding feature to a map image?

                //// Searching for EAD/EAC type items is different from others
                //if (!isEadTypeItem)
                //{
                //    // If there is a coordinate search, and polygons, do that
                //    // GEt the geospatial metadata module
                //    GeoSpatial_Information geoInfo = RequestSpecificValues.Current_Item.Get_Metadata_Module(GlobalVar.GEOSPATIAL_METADATA_MODULE_KEY) as GeoSpatial_Information;
                //    if ((geoInfo != null) && (geoInfo.hasData))
                //    {
                //        if ((currentMode.Coordinates.Length > 0) && (geoInfo.Polygon_Count > 1))
                //        {
                //            // Determine the coordinates in this search
                //            string[] splitter = currentMode.Coordinates.Split(",".ToCharArray());

                //            if (((splitter.Length > 1) && (splitter.Length < 4)) || ((splitter.Length == 4) && (splitter[2].Length == 0) && (splitter[3].Length == 0)))
                //            {
                //                Double.TryParse(splitter[0], out providedMaxLat);
                //                Double.TryParse(splitter[1], out providedMaxLong);
                //                providedMinLat = providedMaxLat;
                //                providedMinLong = providedMaxLong;
                //            }
                //            else if (splitter.Length >= 4)
                //            {
                //                Double.TryParse(splitter[0], out providedMaxLat);
                //                Double.TryParse(splitter[1], out providedMaxLong);
                //                Double.TryParse(splitter[2], out providedMinLat);
                //                Double.TryParse(splitter[3], out providedMinLong);
                //            }

                //            // Now, if there is length, determine the count of results
                //            searchResultsString = new List<string>();
                //            if (searchResultsString.Count > 0)
                //            {
                //                searchResultsCount = searchResultsString.Count;

                //                // Also, look to see where the current point lies in the matching, current polygon
                //                if ((providedMaxLong == providedMinLong) && (providedMaxLat == providedMinLat))
                //                {
                //                    foreach (Coordinate_Polygon itemPolygon in geoInfo.Polygons)
                //                    {
                //                        // Is this the current page?
                //                        if (itemPolygon.Page_Sequence == currentMode.Page)
                //                        {
                //                            if (itemPolygon.is_In_Bounding_Box(providedMaxLat, providedMaxLong))
                //                            {
                //                                searchMatchOnThisPage = true;
                //                                ReadOnlyCollection<Coordinate_Point> boundingBox = itemPolygon.Bounding_Box;
                //                                featureYRatioLocation = Math.Abs(((providedMaxLat - boundingBox[0].Latitude)/(boundingBox[0].Latitude - boundingBox[1].Latitude)));
                //                                featureXRatioLocation = Math.Abs(((providedMaxLong - boundingBox[0].Longitude)/(boundingBox[0].Longitude - boundingBox[1].Longitude)));
                //                            }
                //                        }
                //                    }
                //                }
                //            }
                //        }
                //    }
                //}

                #endregion

                // Is this a postback?
                if (RequestSpecificValues.Current_Mode.isPostBack)
                {
                    // Handle any actions from standard user action (i.e., email, add to bookshelf, etc. )
                    if (HttpContext.Current.Request.Form["item_action"] != null)
                    {
                        string action = HttpContext.Current.Request.Form["item_action"].ToLower().Trim();

                        if (action == "email")
                        {
                            string address = HttpContext.Current.Request.Form["email_address"].Replace(";", ",").Trim();
                            string comments = HttpContext.Current.Request.Form["email_comments"].Trim();
                            string format = HttpContext.Current.Request.Form["email_format"].Trim().ToUpper();
                            if (address.Length > 0)
                            {
                                // Determine the email format
                                bool is_html_format = format != "TEXT";

                                // CC: the user, unless they are already on the list
                                string cc_list = RequestSpecificValues.Current_User.Email;
                                if (address.ToUpper().IndexOf(RequestSpecificValues.Current_User.Email.ToUpper()) >= 0)
                                    cc_list = String.Empty;

                                // Send the email
                                HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", !Item_Email_Helper.Send_Email(address, cc_list, comments, RequestSpecificValues.Current_User.Full_Name, RequestSpecificValues.Current_Mode.Instance_Abbreviation, currentItem, is_html_format, HttpContext.Current.Items["Original_URL"].ToString(), RequestSpecificValues.Current_User.UserID)
                                    ? "Error encountered while sending email" : "Your email has been sent");

                                HttpContext.Current.Response.Redirect(HttpContext.Current.Items["Original_URL"].ToString(), false);
                                HttpContext.Current.ApplicationInstance.CompleteRequest();
                                RequestSpecificValues.Current_Mode.Request_Completed = true;
                                return;
                            }
                        }

                        if (action == "add_item")
                        {
                            string usernotes = HttpContext.Current.Request.Form["add_notes"].Trim();
                            string foldername = HttpContext.Current.Request.Form["add_bookshelf"].Trim();
                            bool open_bookshelf = HttpContext.Current.Request.Form["open_bookshelf"] != null;

                            if (SobekCM_Database.Add_Item_To_User_Folder(RequestSpecificValues.Current_User.UserID, foldername, currentItem.BibID, currentItem.VID, 0, usernotes, RequestSpecificValues.Tracer))
                            {
                                RequestSpecificValues.Current_User.Add_Bookshelf_Item(currentItem.BibID, currentItem.VID);

                                // Ensure this user folder is not sitting in the cache
                                CachedDataManager.Remove_User_Folder_Browse(RequestSpecificValues.Current_User.UserID, foldername, RequestSpecificValues.Tracer);

                                HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", "Item was saved to your bookshelf.");

                                if (open_bookshelf)
                                {
                                    HttpContext.Current.Session.Add("ON_LOAD_WINDOW", "?m=lmfl" + foldername.Replace("\"", "%22").Replace("'", "%27").Replace("=", "%3D").Replace("&", "%26") + "&vp=1");
                                }
                            }
                            else
                            {
                                HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", "ERROR encountered while trying to save to your bookshelf.");
                            }

                            HttpContext.Current.Response.Redirect(HttpContext.Current.Items["Original_URL"].ToString(), false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            RequestSpecificValues.Current_Mode.Request_Completed = true;
                            return;
                        }

                        if (action == "remove")
                        {
                            if (SobekCM_Database.Delete_Item_From_User_Folders(RequestSpecificValues.Current_User.UserID, currentItem.BibID, currentItem.VID, RequestSpecificValues.Tracer))
                            {
                                RequestSpecificValues.Current_User.Remove_From_Bookshelves(currentItem.BibID, currentItem.VID);
                                CachedDataManager.Remove_All_User_Folder_Browses(RequestSpecificValues.Current_User.UserID, RequestSpecificValues.Tracer);
                                HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", "Item was removed from your bookshelves.");
                            }
                            else
                            {
                                HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", "ERROR encountered while trying to remove item from your bookshelves.");
                            }

                            HttpContext.Current.Response.Redirect(HttpContext.Current.Items["Original_URL"].ToString(), false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            RequestSpecificValues.Current_Mode.Request_Completed = true;
                            return;
                        }

                        if (action.IndexOf("add_tag") == 0)
                        {
                            int tagid = -1;
                            if (action.Replace("add_tag", "").Length > 0)
                            {
                                tagid = Convert.ToInt32(action.Replace("add_tag_", ""));
                            }
                            string description = HttpContext.Current.Request.Form["add_tag"].Trim();
                            int new_tagid = SobekCM_Database.Add_Description_Tag(RequestSpecificValues.Current_User.UserID, tagid, currentItem.Web.ItemID, description, RequestSpecificValues.Tracer);
                            if (new_tagid > 0)
                            {
                                currentItem.Web.Add_User_Tag(RequestSpecificValues.Current_User.UserID, RequestSpecificValues.Current_User.Full_Name, description, DateTime.Now, new_tagid);
                                RequestSpecificValues.Current_User.Has_Descriptive_Tags = true;
                            }

                            HttpContext.Current.Response.Redirect(HttpContext.Current.Items["Original_URL"].ToString(), false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            RequestSpecificValues.Current_Mode.Request_Completed = true;
                            return;
                        }

                        if (action.IndexOf("delete_tag") == 0)
                        {
                            if (action.Replace("delete_tag", "").Length > 0)
                            {
                                int tagid = Convert.ToInt32(action.Replace("delete_tag_", ""));
                                if (currentItem.Web.Delete_User_Tag(tagid, RequestSpecificValues.Current_User.UserID))
                                {
                                    SobekCM_Database.Delete_Description_Tag(tagid, RequestSpecificValues.Tracer);
                                }
                            }
                            HttpContext.Current.Response.Redirect(HttpContext.Current.Items["Original_URL"].ToString(), false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            RequestSpecificValues.Current_Mode.Request_Completed = true;
                            return;
                        }
                    }
                }

                // Handle any request from the internal header for the item
                if ((HttpContext.Current != null) && (HttpContext.Current.Request.Form["internal_header_action"] != null) && (RequestSpecificValues.Current_User != null))
                {
                    // Pull the action value
                    string internalHeaderAction = HttpContext.Current.Request.Form["internal_header_action"].Trim();

                    // Was this to save the item comments?
                    if (internalHeaderAction == "save_comments")
                    {
                        string new_comments = HttpContext.Current.Request.Form["intheader_internal_notes"].Trim();
                        if (SobekCM_Item_Database.Save_Item_Internal_Comments(currentItem.Web.ItemID, new_comments))
                            currentItem.Web.Internal_Comments = new_comments;
                    }
                }
            }

            // Set the code for bib level mets to show the volume tree by default
            if ((is_bib_level) && (String.IsNullOrEmpty(RequestSpecificValues.Current_Mode.ViewerCode)))
            {
                RequestSpecificValues.Current_Mode.ViewerCode = "allvolumes1";
            }

            // If there is a file name included, look for the sequence of that file
            if (!String.IsNullOrEmpty(RequestSpecificValues.Current_Mode.Page_By_FileName))
            {
                int page_sequence = currentItem.Page_Sequence_By_FileName(RequestSpecificValues.Current_Mode.Page_By_FileName);
                if (page_sequence > 0)
                {
                    RequestSpecificValues.Current_Mode.ViewerCode = page_sequence.ToString();
                    RequestSpecificValues.Current_Mode.Page = (ushort)page_sequence;
                }
            }

            // Get the valid viewer code
            RequestSpecificValues.Tracer.Add_Trace("Item_HtmlSubwriter.Add_Controls", "Getting the appropriate item viewer");
            prototyper = ItemViewer_Factory.Get_Item_Viewer(currentItem, RequestSpecificValues.Current_Mode.ViewerCode);
            if (( prototyper != null ) && ( prototyper.Has_Access(currentItem, RequestSpecificValues.Current_User, !String.IsNullOrEmpty(restriction_message))))
                pageViewer = prototyper.Create_Viewer(currentItem, RequestSpecificValues.Current_User, RequestSpecificValues.Current_Mode, RequestSpecificValues.Tracer );
            else
            {
                // Since the user did not have access to THAT viewer, try to find one that he does have access to
                if (currentItem.UI.Viewers_By_Priority != null)
                {
                    foreach (string viewerType in currentItem.UI.Viewers_By_Priority)
                    {
                        prototyper = ItemViewer_Factory.Get_Viewer_By_ViewType(viewerType);
                        if ((prototyper != null) && (prototyper.Has_Access(currentItem, RequestSpecificValues.Current_User, !String.IsNullOrEmpty(restriction_message))))
                        {
                            pageViewer = prototyper.Create_Viewer(currentItem, RequestSpecificValues.Current_User, RequestSpecificValues.Current_Mode, RequestSpecificValues.Tracer);
                            break;
                        }
                    }
                }

            }

            // If execution should end, do it now
            if (RequestSpecificValues.Current_Mode.Request_Completed)
                return;

            // If there were NO views, then pageViewer could be null
            if (pageViewer == null)
                pageViewer = new NoViews_ItemViewer();

            RequestSpecificValues.Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Created " + pageViewer.GetType().ToString().Replace("SobekCM.Library.ItemViewer.Viewers.", ""));

            // Assign the rest of the information, if a page viewer was created
            behaviors = new List<HtmlSubwriter_Behaviors_Enum>();
            if (pageViewer != null)
            {
                // Get the list of any special behaviors
                pageViewerBehaviors = pageViewer.ItemViewer_Behaviors;
                if ( pageViewerBehaviors != null )
                    behaviors.AddRange(pageViewerBehaviors);
                else
                    pageViewerBehaviors = new List<HtmlSubwriter_Behaviors_Enum>();
            }
            else
            {
                pageViewerBehaviors = new List<HtmlSubwriter_Behaviors_Enum>();
            }

            // ALways suppress the banner and skip to main content
            if (behaviors == null)
                behaviors = new List<HtmlSubwriter_Behaviors_Enum>();

            if (!behaviors.Contains(HtmlSubwriter_Behaviors_Enum.Suppress_Banner))
                behaviors.Add(HtmlSubwriter_Behaviors_Enum.Suppress_Banner);
            if (!behaviors.Contains(HtmlSubwriter_Behaviors_Enum.Include_Skip_To_Main_Content_Link))
                behaviors.Add(HtmlSubwriter_Behaviors_Enum.Include_Skip_To_Main_Content_Link);

            //if ((searchMatchOnThisPage) && ((PageViewer.ItemViewer_Type == ItemViewer_Type_Enum.JPEG) || (PageViewer.ItemViewer_Type == ItemViewer_Type_Enum.JPEG2000)))
            //{
            //    if (PageViewer.ItemViewer_Type == ItemViewer_Type_Enum.JPEG2000)
            //    {
            //        Aware_JP2_ItemViewer jp2_viewer = (Aware_JP2_ItemViewer) PageViewer;
            //        jp2_viewer.Add_Feature("Red", "DrawEllipse", ((int) (featureXRatioLocation*jp2_viewer.Width)), ((int) (featureYRatioLocation*jp2_viewer.Height)), 800, 800);

            //    }
            //}
        }
        public void Add_Main_Menu(TextWriter Output, string CurrentCode, bool ItemRestrictedFromUserByIP, bool ItemCheckedOutByOtherUser, BriefItemInfo CurrentItem, Navigation_Object CurrentMode, User_Object CurrentUser, bool Include_Links, Custom_Tracer Tracer)
        {
            // Can this user (if there is one) edit this item?
            bool canManage = (CurrentUser != null) && (CurrentUser.Can_Edit_This_Item(CurrentItem.BibID, CurrentItem.Type, CurrentItem.Behaviors.Source_Institution_Aggregation, CurrentItem.Behaviors.Holding_Location_Aggregation, CurrentItem.Behaviors.Aggregation_Code_List));

            // Add the item views
            Output.WriteLine("<!-- Add the different view and social options -->");
            Output.WriteLine("<nav class=\"sbkMenu_Bar\" id=\"sbkIsw_MenuBar\" role=\"navigation\" aria-label=\"Item menu\">");
            Output.WriteLine("\t<h2 class=\"hidden-element\">Item menu</h2>");

            // Add the sharing buttons if this is not restricted by IP address or checked out
            if ((!ItemRestrictedFromUserByIP) && (!ItemCheckedOutByOtherUser) && (!CurrentMode.Is_Robot))
            {
                string add_text    = "Add";
                string remove_text = "Remove";
                string send_text   = "Send";
                string print_text  = "Print";
                if (canManage)
                {
                    add_text    = String.Empty;
                    remove_text = String.Empty;
                    send_text   = String.Empty;
                    print_text  = String.Empty;
                }

                string logOnUrl   = String.Empty;
                bool   isLoggedOn = CurrentUser != null && CurrentUser.LoggedOn;
                if (!isLoggedOn)
                {
                    string returnUrl = UrlWriterHelper.Redirect_URL(CurrentMode);

                    CurrentMode.Mode          = Display_Mode_Enum.My_Sobek;
                    CurrentMode.My_Sobek_Type = My_Sobek_Type_Enum.Logon;
                    CurrentMode.Return_URL    = returnUrl;
                    logOnUrl               = UrlWriterHelper.Redirect_URL(CurrentMode);
                    CurrentMode.Mode       = Display_Mode_Enum.Item_Display;
                    CurrentMode.Return_URL = String.Empty;
                }

                Output.WriteLine("\t<div id=\"menu-right-actions\">");

                if ((CurrentItem.Web != null) && (CurrentItem.Web.ItemID > 0))
                {
                    string print_item_form_open_url = UI_ApplicationCache_Gateway.Settings.Servers.Engine_URL + "items/html/print/" + CurrentItem.BibID + "/" + CurrentItem.VID + "/" + CurrentMode.ViewerCode;
                    Output.WriteLine("\t\t<span id=\"printbuttonitem\" class=\"action-sf-menu-item\" onclick=\"print_form_open('" + print_item_form_open_url + "');\"><img src=\"" + Static_Resources_Gateway.Printer_Png + "\" alt=\"\" style=\"vertical-align:middle\" /><span id=\"printbuttonspan\">" + print_text + "</span></span>");
                }
                else
                {
                    Output.WriteLine("\t\t<span id=\"printbuttonitem\" class=\"action-sf-menu-item\" onclick=\"window.print();return false;\"><img src=\"" + Static_Resources_Gateway.Printer_Png + "\" alt=\"\" style=\"vertical-align:middle\" /><span id=\"printbuttonspan\">" + print_text + "</span></span>");
                }


                if (isLoggedOn)
                {
                    string email_item_form_open_url = UI_ApplicationCache_Gateway.Settings.Servers.Engine_URL + "items/html/send/" + CurrentItem.BibID + "/" + CurrentItem.VID;
                    Output.WriteLine("\t\t<span id=\"sendbuttonitem\" class=\"action-sf-menu-item\" onclick=\"email_form_open('" + email_item_form_open_url + "');\"><img src=\"" + Static_Resources_Gateway.Email_Png + "\" alt=\"\" style=\"vertical-align:middle\" /><span id=\"sendbuttonspan\">" + send_text + "</span></span>");


                    if ((CurrentItem.Web != null) && (CurrentItem.Web.ItemID > 0))
                    {
                        if (CurrentUser.Is_In_Bookshelf(CurrentItem.BibID, CurrentItem.VID))
                        {
                            Output.WriteLine("\t\t<span id=\"addbuttonitem\" class=\"action-sf-menu-item\" onclick=\"return remove_item_itemviewer();\"><img src=\"" + Static_Resources_Gateway.Minussign_Png + "\" alt=\"\" style=\"vertical-align:middle\" /><span id=\"addbuttonspan\">" + remove_text + "</span></span>");
                        }
                        else
                        {
                            // Determine the URL
                            string add_item_form_open_url = UI_ApplicationCache_Gateway.Settings.Servers.Engine_URL + "items/html/bookshelf/" + CurrentUser.UserID + "/" + CurrentItem.BibID + "/" + CurrentItem.VID;
                            Output.WriteLine("\t\t<span id=\"addbuttonitem\" class=\"action-sf-menu-item\" onclick=\"add_item_form_open('" + add_item_form_open_url + "');return false;\"><img src=\"" + Static_Resources_Gateway.Plussign_Png + "\" alt=\"\" style=\"vertical-align:middle\" /><span id=\"addbuttonspan\">" + add_text + "</span></span>");
                        }
                    }
                }
                else
                {
                    Output.WriteLine("\t\t<span id=\"sendbuttonitem\" class=\"action-sf-menu-item\" onclick=\"window.location='" + logOnUrl + "';return false;\"><img src=\"" + Static_Resources_Gateway.Email_Png + "\" alt=\"\" style=\"vertical-align:middle\" /><span id=\"sendbuttonspan\">" + send_text + "</span></span>");

                    if ((CurrentItem.Web != null) && (CurrentItem.Web.ItemID > 0))
                    {
                        Output.WriteLine("\t\t<span id=\"addbuttonitem\" class=\"action-sf-menu-item\" onclick=\"window.location='" + logOnUrl + "';return false;\"><img src=\"" + Static_Resources_Gateway.Plussign_Png + "\" alt=\"\" style=\"vertical-align:middle\" /><span id=\"addbuttonspan\">" + add_text + "</span></span>");
                    }
                }

                string share_item_form_open_url = UI_ApplicationCache_Gateway.Settings.Servers.Engine_URL + "items/html/share/" + CurrentItem.BibID + "/" + CurrentItem.VID;
                Output.WriteLine("\t\t<span id=\"sharebuttonitem\" class=\"action-sf-menu-item\" onclick=\"toggle_share_form('share_button', '" + share_item_form_open_url + "');\"><span id=\"sharebuttonspan\">Share</span></span>");


                Output.WriteLine("\t</div>");
                Output.WriteLine();
            }


            Output.WriteLine("\t<ul class=\"sf-menu\" id=\"sbkIhs_Menu\">");


            // Save the current view type
            ushort page       = CurrentMode.Page.HasValue ? CurrentMode.Page.Value : (ushort)1;
            ushort subpage    = CurrentMode.SubPage.HasValue ? CurrentMode.SubPage.Value : (ushort)1;
            string viewerCode = CurrentMode.ViewerCode;

            CurrentMode.SubPage = 0;

            // Add any PRE-MENU instance options
            string first_pre_menu_option  = String.Empty;
            string second_pre_menu_option = String.Empty;
            string third_pre_menu_option  = String.Empty;

            if (UI_ApplicationCache_Gateway.Settings.Contains_Additional_Setting("Item Viewer.Static First Menu Item"))
            {
                first_pre_menu_option = UI_ApplicationCache_Gateway.Settings.Get_Additional_Setting("Item Viewer.Static First Menu Item");
            }
            if (UI_ApplicationCache_Gateway.Settings.Contains_Additional_Setting("Item Viewer.Static Second Menu Item"))
            {
                second_pre_menu_option = UI_ApplicationCache_Gateway.Settings.Get_Additional_Setting("Item Viewer.Static Second Menu Item");
            }
            if (UI_ApplicationCache_Gateway.Settings.Contains_Additional_Setting("Item Viewer.Static Third Menu Item"))
            {
                third_pre_menu_option = UI_ApplicationCache_Gateway.Settings.Get_Additional_Setting("Item Viewer.Static Third Menu Item");
            }
            if ((first_pre_menu_option.Length > 0) || (second_pre_menu_option.Length > 0) || (third_pre_menu_option.Length > 0))
            {
                if (first_pre_menu_option.Length > 0)
                {
                    string[] first_splitter = first_pre_menu_option.Replace("[", "").Replace("]", "").Split(";".ToCharArray());
                    if (first_splitter.Length > 0)
                    {
                        Output.WriteLine("\t\t<li><a href=\"" + first_splitter[1] + "\" title=\"" + HttpUtility.HtmlEncode(first_splitter[0]) + "\">" + HttpUtility.HtmlEncode(first_splitter[0]) + "</a></li>");
                    }
                }
                if (second_pre_menu_option.Length > 0)
                {
                    string[] second_splitter = second_pre_menu_option.Replace("[", "").Replace("]", "").Split(";".ToCharArray());
                    if (second_splitter.Length > 0)
                    {
                        Output.WriteLine("\t\t<li><a href=\"" + second_splitter[1] + "\" title=\"" + HttpUtility.HtmlEncode(second_splitter[0]) + "\">" + HttpUtility.HtmlEncode(second_splitter[0]) + "</a></li>");
                    }
                }
                if (third_pre_menu_option.Length > 0)
                {
                    string[] third_splitter = third_pre_menu_option.Replace("[", "").Replace("]", "").Split(";".ToCharArray());
                    if (third_splitter.Length > 0)
                    {
                        Output.WriteLine("\t\t<li><a href=\"" + third_splitter[1] + "\" title=\"" + HttpUtility.HtmlEncode(third_splitter[0]) + "\">" + HttpUtility.HtmlEncode(third_splitter[0]) + "</a></li>");
                    }
                }
            }

            // Add the item level viewers - collect the menu portions
            List <Item_MenuItem> menuItems = new List <Item_MenuItem>();

            foreach (string viewType in CurrentItem.UI.Viewers_Menu_Order)
            {
                iItemViewerPrototyper prototyper = ItemViewer_Factory.Get_Viewer_By_ViewType(viewType);
                if (prototyper.Has_Access(CurrentItem, CurrentUser, ItemRestrictedFromUserByIP))
                {
                    prototyper.Add_Menu_Items(CurrentItem, CurrentUser, CurrentMode, menuItems, ItemRestrictedFromUserByIP);
                }
            }

            // Now, get ready to start adding the menu items
            Dictionary <string, List <Item_MenuItem> > topMenuToChildren = new Dictionary <string, List <Item_MenuItem> >(StringComparer.OrdinalIgnoreCase);

            foreach (Item_MenuItem menuItem in menuItems)
            {
                if (topMenuToChildren.ContainsKey(menuItem.MenuStripText))
                {
                    topMenuToChildren[menuItem.MenuStripText].Add(menuItem);
                }
                else
                {
                    topMenuToChildren[menuItem.MenuStripText] = new List <Item_MenuItem> {
                        menuItem
                    };
                }
            }

            // Now, step through the menu items
            foreach (Item_MenuItem topMenuItem in menuItems)
            {
                HTML_Helper(Output, topMenuItem, CurrentMode, CurrentCode, topMenuToChildren, Include_Links);
            }

            // Set current submode back
            CurrentMode.Page       = page;
            CurrentMode.ViewerCode = viewerCode;
            CurrentMode.SubPage    = subpage;

            Output.WriteLine("\t</ul>");
            Output.WriteLine("</nav>");
            Output.WriteLine();


            Output.WriteLine("<!-- Initialize the main item menu -->");
            Output.WriteLine("<script>");
            Output.WriteLine("\tjQuery(document).ready(function () { jQuery('ul.sf-menu').superfish(); });");
            Output.WriteLine("</script>");
            Output.WriteLine();
        }