Item html subwriter renders views on a single digital resource
This class extends the abstractHtmlSubwriter abstract class.
Inheritance: abstractHtmlSubwriter
        private void Finish_writing_html(SobekCM_Item CurrentItem, Page_TreeNode CurrentPage, string Filename, string TextFileLocation )
        {
            bool textSearchable = CurrentItem.Behaviors.Text_Searchable;
            CurrentItem.Behaviors.Text_Searchable = false;
            if (staticSobekcmLocation.Length > 0)
                SobekCM_Library_Settings.Base_Directory = staticSobekcmLocation;

            // Get the skin
            if ((CurrentItem.Behaviors.Web_Skin_Count > 0) && ( !CurrentItem.Behaviors.Web_Skins.Contains( defaultSkin.ToUpper())))
                currentMode.Skin = CurrentItem.Behaviors.Web_Skins[0];

            // Get the skin object
            SobekCM_Skin_Object skinObject = skinsCollection[currentMode.Skin];
            if (skinObject == null)
            {
                skinObject = assistant.Get_HTML_Skin(currentMode, skinsCollection, false, null);
                skinsCollection.Add(skinObject);
            }

            // Create the HTML writer
            Item_HtmlSubwriter itemWriter = new Item_HtmlSubwriter(CurrentItem, CurrentPage, null, codeManager, translations, true, true, currentMode, null, String.Empty, null, tracer) { Mode = currentMode, Skin = skinObject };
            SobekCM_Library_Settings.Base_SobekCM_Location_Relative = currentMode.Base_URL;
            if ((SobekCM_Library_Settings.Base_SobekCM_Location_Relative.Length == 0) || (SobekCM_Library_Settings.Base_SobekCM_Location_Relative.Contains("localhost")))
            {
                SobekCM_Library_Settings.Base_SobekCM_Location_Relative = primaryWebServerUrl;
                currentMode.Base_URL = SobekCM_Library_Settings.Base_SobekCM_Location_Relative;
            }

            // Now that the item viewer is built, set the robot flag to suppress some checks
            currentMode.Is_Robot = true;

            // Create the TextWriter
            StreamWriter writer = new StreamWriter(Filename, false, Encoding.UTF8);

            writer.WriteLine("<!DOCTYPE html>");
            writer.WriteLine("<html>");
            writer.WriteLine("<head>");
            writer.WriteLine("  <title>" + CurrentItem.Bib_Info.Main_Title + "</title>");
            writer.WriteLine();
            writer.WriteLine("  <!-- " + SobekCM_Library_Settings.System_Name + " : SobekCM Digital Repository -->");
            writer.WriteLine();
            writer.WriteLine("  <link href=\"" + SobekCM_Library_Settings.System_Base_URL + "default/SobekCM.min.css\" rel=\"stylesheet\" type=\"text/css\" />");
            writer.WriteLine("  <script type=\"text/javascript\" src=\"" + SobekCM_Library_Settings.System_Base_URL + "default/scripts/jquery/jquery-1.10.2.min.js\"></script>");
            writer.WriteLine("  <script type=\"text/javascript\" src=\"" + SobekCM_Library_Settings.System_Base_URL + "default/scripts/sobekcm_full.min.js\"></script>");
            writer.WriteLine("  <link href=\"" + SobekCM_Library_Settings.System_Base_URL + "default/SobekCM_Item.min.css\" rel=\"stylesheet\" type=\"text/css\" />");

            writer.WriteLine("  <meta name=\"robots\" content=\"index, follow\" />");
            if (skinObject.CSS_Style.Length > 0)
            {
                writer.WriteLine("  <link href=\"" + SobekCM_Library_Settings.System_Base_URL + skinObject.CSS_Style + "\" rel=\"stylesheet\" type=\"text/css\" />");
            }

            string image_src = currentMode.Base_URL + "/" + CurrentItem.Web.AssocFilePath + "/" + CurrentItem.Behaviors.Main_Thumbnail;
            writer.WriteLine("  <link rel=\"image_src\" href=\"" + image_src.Replace("\\", "/").Replace("//", "/").Replace("http:/", "http://") + "\" />");

            writer.WriteLine("</head>");
            writer.WriteLine("<body>");

            // Is this item DARK or PRIVATE
            if ((CurrentItem.Behaviors.Dark_Flag) || ( CurrentItem.Behaviors.IP_Restriction_Membership < 0 ))
            {
                writer.WriteLine("THIS ITEM IS CURRENTLY DARK OR PRIVATE");
                writer.WriteLine("</body>");
                writer.WriteLine("</html>");
                writer.Flush();
                writer.Close();
                return;
            }

            // Add the header
            Display_Header(writer, itemWriter.Skin, CurrentItem);

            // Begin to write the item view
            itemWriter.Write_HTML(writer, tracer);

            if ((CurrentItem.Behaviors.Wordmark_Count > 0) || ((CurrentItem.Web.Static_PageCount > 1) && (CurrentItem.Web.Static_Division_Count > 1)))
            {
                writer.WriteLine("<nav id=\"sbkIsw_Leftnavbar\" style=\"padding-top:3px\">");

                // Write the table of contents as static HTML, rather than the TreeView web control
                if ((CurrentItem.Web.Static_PageCount > 1) && (CurrentItem.Web.Static_Division_Count > 1))
                {
                    writer.WriteLine("  <div class=\"sbkIsw_ShowTocRow\">");
                    writer.WriteLine("    <div class=\"sbkIsw_UpToc\">HIDE TABLE OF CONTENTS</div>");
                    writer.WriteLine("  </div>");

                    writer.WriteLine("<div class=\"sbkIsw_TocTreeView\">");

                    // load the table of contents in the tree
                    TreeView treeView1 = new TreeView();
                    itemWriter.Create_TreeView_From_Divisions(treeView1);

                    // Step through all the parent nodes
                    writer.WriteLine("  <table cellspacing=\"4px\">");
                    foreach (TreeNode thisNode in treeView1.Nodes)
                    {
                        writer.WriteLine("    <tr><td width=\"9px\">&nbsp;</td><td>" + thisNode.Text.Replace("sbkIsw_SelectedTocTreeViewItem", "sbkIsw_TocTreeViewItem") + "</td></tr>");
                    }
                    writer.WriteLine("  </table>");
                    writer.WriteLine("</div>");
                }

            }

            itemWriter.Write_Additional_HTML(writer, tracer);

            //Literal citationLiteral = (Literal)placeHolder.Controls[0];
            //writer.WriteLine(citationLiteral.Text);
            //placeHolder.Controls.Clear();

            writer.WriteLine("<!-- COMMENT HERE -->");

            // Close out this tables and form
            writer.WriteLine("       </tr>");

            // If this is IP restricted, show nothing else
            if (CurrentItem.Behaviors.IP_Restriction_Membership == 0)
            {
                // Add the download list if there are some
                if (CurrentItem.Divisions.Download_Tree.Has_Files)
                {
                    writer.WriteLine("       <tr>");
                    // Create the downloads viewer to ouput the html
                    Download_ItemViewer downloadViewer = new Download_ItemViewer {CurrentItem = CurrentItem, CurrentMode = currentMode};

                    // Add the HTML for this now
                    downloadViewer.Write_Main_Viewer_Section(writer, tracer);
                    writer.WriteLine("       </tr>");
                }

                // If there is a table of contents write it again, this time it will be complete
                // and also show a hierarchy if there is one
                if ((CurrentItem.Web.Static_PageCount > 1) && (CurrentItem.Web.Static_Division_Count > 1))
                {
                    writer.WriteLine("       <tr>");
                    writer.WriteLine("         <td align=\"left\"><span class=\"SobekViewerTitle\">Table of Contents</span></td>");
                    writer.WriteLine("       </tr>");

                    writer.WriteLine("       <tr>");
                    writer.WriteLine("          <td>");
                    writer.WriteLine("            <div class=\"sbkCiv_Citation\">");

                    foreach (abstract_TreeNode treeNode in CurrentItem.Divisions.Physical_Tree.Roots)
                    {
                        recursively_write_toc(writer, treeNode, "&nbsp; &nbsp; ");
                    }

                    writer.WriteLine("            </div>");
                    writer.WriteLine("          </td>");
                    writer.WriteLine("       </tr>");
                }

                // Is the text file location included, in which case any full text should be appended to the end?
                if ((TextFileLocation.Length > 0) && (Directory.Exists(TextFileLocation)))
                {
                    // Get the list of all TXT files in this division
                    string[] text_files = Directory.GetFiles(TextFileLocation, "*.txt");
                    Dictionary<string, string> text_files_existing = new Dictionary<string, string>();
                    foreach (string thisTextFile in text_files)
                    {
                        string text_filename = (new FileInfo(thisTextFile)).Name.ToUpper();
                        text_files_existing[text_filename] = text_filename;
                    }

                    // Are there ANY text files?
                    if (text_files.Length > 0)
                    {
                        // If this has page images, check for related text files
                        List<string> text_files_included = new List<string>();
                        bool started = false;
                        if (CurrentItem.Divisions.Physical_Tree.Has_Files)
                        {
                            // Go through the first 100 text pages
                            List<abstract_TreeNode> pages = CurrentItem.Divisions.Physical_Tree.Pages_PreOrder;
                            int page_count = 0;
                            foreach (Page_TreeNode thisPage in pages)
                            {
                                // Keep track of the page count
                                page_count++;

                                // Look for files in this page
                                if (thisPage.Files.Count > 0)
                                {
                                    bool found_non_thumb_file = false;
                                    foreach (SobekCM_File_Info thisFile in thisPage.Files)
                                    {
                                        // Make sure this is not a thumb
                                        if (thisFile.System_Name.ToLower().IndexOf("thm.jpg") < 0)
                                        {
                                            found_non_thumb_file = true;
                                            string root = thisFile.File_Name_Sans_Extension;
                                            if (text_files_existing.ContainsKey(root.ToUpper() + ".TXT"))
                                            {
                                                string text_file = TextFileLocation + "\\" + thisFile.File_Name_Sans_Extension + ".txt";

                                                // SInce this is marked to be included, save this name
                                                text_files_included.Add(root.ToUpper() + ".TXT");

                                                // For size reasons, we only include the text from the first 100 pages
                                                if (page_count <= 100)
                                                {
                                                    if (!started)
                                                    {
                                                        writer.WriteLine("       <tr>");
                                                        writer.WriteLine("         <td align=\"left\"><span class=\"SobekViewerTitle\">Full Text</span></td>");
                                                        writer.WriteLine("       </tr>");
                                                        writer.WriteLine("       <tr>");
                                                        writer.WriteLine("          <td>");
                                                        writer.WriteLine("            <div class=\"sbkCiv_Citation\">");

                                                        started = true;
                                                    }

                                                    try
                                                    {
                                                        StreamReader reader = new StreamReader(text_file);
                                                        string text_line = reader.ReadLine();
                                                        while (text_line != null)
                                                        {
                                                            writer.WriteLine(text_line + "<br />");
                                                            text_line = reader.ReadLine();
                                                        }
                                                        reader.Close();
                                                    }
                                                    catch
                                                    {
                                                        writer.WriteLine("Unable to read file: " + text_file);
                                                    }

                                                    writer.WriteLine("<br /><br />");
                                                }
                                            }

                                        }

                                        // If a suitable file was found, break here
                                        if (found_non_thumb_file)
                                            break;
                                    }
                                }
                            }

                            // End this if it was ever started
                            if (started)
                            {
                                writer.WriteLine("            </div>");
                                writer.WriteLine("          </td>");
                                writer.WriteLine("       </tr>");
                            }
                        }

                        // Now, check for any other valid text files
                        List<string> additional_text_files = text_files_existing.Keys.Where(ThisTextFile => (!text_files_included.Contains(ThisTextFile.ToUpper())) && (ThisTextFile.ToUpper() != "AGREEMENT.TXT") && (ThisTextFile.ToUpper().IndexOf("REQUEST") != 0)).ToList();

                        // Now, include any additional text files, which would not be page text files, possiblye
                        // full text for included PDFs, Powerpoint, Word Doc, etc..
                        started = false;
                        foreach (string thisTextFile in additional_text_files)
                        {
                            if (!started)
                            {
                                writer.WriteLine("       <tr>");
                                writer.WriteLine("         <td align=\"left\"><span class=\"SobekViewerTitle\">Full Text</span></td>");
                                writer.WriteLine("       </tr>");
                                writer.WriteLine("       <tr>");
                                writer.WriteLine("          <td>");
                                writer.WriteLine("            <div class=\"sbkCiv_Citation\">");

                                started = true;
                            }

                            string text_file = TextFileLocation + "\\" + thisTextFile;

                            try
                            {

                                StreamReader reader = new StreamReader(text_file);
                                string text_line = reader.ReadLine();
                                while (text_line != null)
                                {
                                    writer.WriteLine(text_line + "<br />");
                                    text_line = reader.ReadLine();
                                }
                                reader.Close();
                            }
                            catch
                            {
                                writer.WriteLine("Unable to read file: " + text_file);
                            }

                            writer.WriteLine("<br /><br />");
                        }

                        // End this if it was ever started
                        if (started)
                        {
                            writer.WriteLine("            </div>");
                            writer.WriteLine("          </td>");
                            writer.WriteLine("       </tr>");
                        }
                    }
                }
            }

            writer.WriteLine("      </table>");
            writer.WriteLine("      </div>");

            // Write the footer
            Display_Footer(writer, itemWriter.Skin);

            writer.WriteLine("</body>");
            writer.WriteLine("</html>");

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

            // Restore the text searchable flag and robot flag
            currentMode.Is_Robot = false;
            CurrentItem.Behaviors.Text_Searchable = textSearchable;
        }
        /// <summary> Perform all the work of adding to the response stream back to the web user </summary>
        /// <param name="Navigation_Place_Holder"> Place holder is used to add more complex server-side objects during execution</param>
        /// <param name="TOC_Place_Holder"> Place holder is used to add more complex server-side objects during execution</param>
        /// <param name="Main_Place_Holder"> Place holder is used to add more complex server-side objects during execution</param>
        /// <param name="myUfdcUploadPlaceHolder"> Place holder is used to add more complex server-side objects during execution </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Since this class writes all the output directly to the response stream, this method simply returns, without doing anything</remarks>
        public override void Add_Controls(PlaceHolder Navigation_Place_Holder,
            PlaceHolder TOC_Place_Holder,
            PlaceHolder Main_Place_Holder,
            PlaceHolder myUfdcUploadPlaceHolder, Custom_Tracer Tracer)
        {
            Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Rendering the requested data in html format");

            // Render HTML and add controls depending on the current mode
            switch (currentMode.Mode)
            {
                #region Start adding HTML and controls for SIMPLE WEB CONTENT TEXT mode

                case Display_Mode_Enum.Simple_HTML_CMS:
                    subwriter = new Web_Content_HtmlSubwriter(hierarchyObject, currentMode, htmlSkin, htmlBasedContent, siteMap);

                    // Add any necessary controls
                    if (siteMap != null)
                    {
                        ((Web_Content_HtmlSubwriter)subwriter).Add_Controls(Main_Place_Holder, Tracer);
                    }

                    break;

                #endregion

                #region Start adding HTML and controls for MY SOBEK mode

                case Display_Mode_Enum.My_Sobek:

                    Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Building the my sobek HTML subwriter");

                    // Build the my sobek subwriter
                    mySobekWriter = new MySobek_HtmlSubwriter( results_statistics, paged_results, codeManager, itemList, hierarchyObject, htmlSkin, translator, currentMode, currentItem, aggregationAliases, webSkins, currentUser, ipRestrictionInfo, iconList, urlPortals, statsDateRange, thematicHeadings, Tracer);
                    subwriter = mySobekWriter;
                    mySobekWriter.Hierarchy_Object = hierarchyObject;
                    mySobekWriter.Skin = htmlSkin;
                    mySobekWriter.Mode = currentMode;

                    // If the my sobek writer contains pop up forms, add the header here first
                    if ( mySobekWriter.Contains_Popup_Forms )
                    {
                        StringBuilder header_builder = new StringBuilder();
                        StringWriter header_writer = new StringWriter(header_builder);
                        Display_Header(header_writer, Tracer);
                        LiteralControl header_literal = new LiteralControl(header_builder.ToString());
                        Main_Place_Holder.Controls.Add(header_literal);
                    }

                    // Add any necessary controls
                    mySobekWriter.Add_Controls(Main_Place_Holder, myUfdcUploadPlaceHolder, Tracer);

                    // Finally, add the footer
                    if (mySobekWriter.Contains_Popup_Forms)
                    {
                        StringBuilder footer_builder = new StringBuilder();
                        StringWriter footer_writer = new StringWriter(footer_builder);
                        Display_Footer(footer_writer, Tracer);
                        LiteralControl footer_literal = new LiteralControl(footer_builder.ToString());
                        Main_Place_Holder.Controls.Add(footer_literal);
                    }

                    break;

                #endregion

                #region Start adding HTML and controls for ADMINISTRATIVE mode

                case Display_Mode_Enum.Administrative:

                    Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Building the admin HTML subwriter");

                    // Build the my sobek subwriter
                    adminWriter = new Admin_HtmlSubwriter(results_statistics, paged_results, codeManager, itemList, hierarchyObject, htmlSkin, translator, currentMode, currentItem, aggregationAliases, webSkins, currentUser, ipRestrictionInfo, iconList, urlPortals, statsDateRange, thematicHeadings, Tracer);
                    subwriter = adminWriter;
                    adminWriter.Hierarchy_Object = hierarchyObject;
                    adminWriter.Skin = htmlSkin;
                    adminWriter.Mode = currentMode;

                    // If the my sobek writer contains pop up forms, add the header here first
                    if (adminWriter.Contains_Popup_Forms)
                    {
                        StringBuilder header_builder = new StringBuilder();
                        StringWriter header_writer = new StringWriter(header_builder);
                        Display_Header(header_writer, Tracer);
                        LiteralControl header_literal = new LiteralControl(header_builder.ToString());
                        Main_Place_Holder.Controls.Add(header_literal);
                    }

                    // Add any necessary controls
                    adminWriter.Add_Controls(Main_Place_Holder, myUfdcUploadPlaceHolder, Tracer);

                    // Finally, add the footer
                    if (adminWriter.Contains_Popup_Forms)
                    {
                        StringBuilder footer_builder = new StringBuilder();
                        StringWriter footer_writer = new StringWriter(footer_builder);
                        Display_Footer(footer_writer, Tracer);
                        LiteralControl footer_literal = new LiteralControl(footer_builder.ToString());
                        Main_Place_Holder.Controls.Add(footer_literal);
                    }

                    break;

                #endregion

                #region Start adding HTML and add controls for RESULTS mode

                case Display_Mode_Enum.Results:
                    Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Building the Search Results HTML Subwriter");

                    // Build the results subwriter
                    resultsWriter = new Search_Results_HtmlSubwriter(results_statistics, paged_results, codeManager, translator, itemList, currentUser );
                    subwriter = resultsWriter;
                    resultsWriter.Hierarchy_Object = hierarchyObject;
                    resultsWriter.Skin = htmlSkin;
                    resultsWriter.Mode = currentMode;

                    // Make sure the corresponding 'search' is the latest
                    currentMode.Mode = Display_Mode_Enum.Search;
                    HttpContext.Current.Session["LastSearch"] = currentMode.Redirect_URL();
                    currentMode.Mode = Display_Mode_Enum.Results;

                    // Add the controls and save the tree info in the session state
                    //System.Web.HttpContext.Current.Session["tree_info"] = resultsWriter.Add_Controls(Main_Place_Holder, Tracer, null);
                    resultsWriter.Add_Controls(Main_Place_Holder, Tracer, null);

                    break;

                #endregion

                #region Add HTML and controls for PUBLIC FOLDER mode

                case Display_Mode_Enum.Public_Folder:
                    Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Building the Public Folder HTML Subwriter");

                    // Build the subwriter for this case
                    subwriter = new Public_Folder_HtmlSubwriter(results_statistics, paged_results, codeManager, translator, itemList, currentUser, publicFolder)
                                    {Hierarchy_Object = hierarchyObject, Skin = htmlSkin, Mode = currentMode};

                    // Also try to add any controls
                    ((Public_Folder_HtmlSubwriter)subwriter).Add_Controls(Main_Place_Holder, Tracer, null );
                    break;

                #endregion

                #region Add HTML and controls for COLLECTION VIEWS

                case Display_Mode_Enum.Search:
                case Display_Mode_Enum.Aggregation_Home:
                case Display_Mode_Enum.Aggregation_Browse_Info:
                case Display_Mode_Enum.Aggregation_Browse_By:
                case Display_Mode_Enum.Aggregation_Browse_Map:
                case Display_Mode_Enum.Aggregation_Private_Items:
                case Display_Mode_Enum.Aggregation_Item_Count:
                case Display_Mode_Enum.Aggregation_Usage_Statistics:
                case Display_Mode_Enum.Aggregation_Admin_View:
                    Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Building the Collection HTML Subwriter");

                    // Build the subwriter for this case
                    subwriter = new Aggregation_HtmlSubwriter(hierarchyObject, currentMode, htmlSkin, translator, thisBrowseObject,  results_statistics, paged_results, codeManager, itemList, thematicHeadings, currentUser, ipRestrictionInfo, htmlBasedContent, Tracer);

                    // Also try to add any controls
                    ((Aggregation_HtmlSubwriter) subwriter).Add_Controls(Main_Place_Holder, Tracer);

                    break;

                #endregion

                #region Start adding HTML and add controls for ITEM DISPLAY mode

                case Display_Mode_Enum.Item_Display:
                    if (!currentMode.Invalid_Item)
                    {
                        if (currentItem == null)
                            return;

                        //SobekCM.Library.ItemViewer.Viewers.abstractItemViewer page_viewer = null;

                        //// Set the code for bib level mets to show the volume list by dwe
                        //if ((currentItem.METS.RecordStatus == METS_Record_Status.BIB_LEVEL) && (currentMode.ViewerCode.Length == 0))
                        //{
                        //    currentMode.ViewerCode = "BI1";
                        //}

                        //// Get the valid viewer code
                        //Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Getting the appropriate item viewer");
                        //if (currentMode.ViewerCode != "TS")
                        //{
                        //    if ((currentMode.ViewerCode.Length == 0) && (currentMode.Coordinates.Length > 0))
                        //    {
                        //        currentMode.ViewerCode = "GM";
                        //    }
                        //    currentMode.ViewerCode = currentItem.Behaviors.Get_Valid_Viewer_Code(currentMode.ViewerCode, currentMode.Page);
                        //    SobekCM.Resource_Object.Behaviors.View_Object viewObject = currentItem.Behaviors.Get_Viewer(currentMode.ViewerCode);
                        //    page_viewer = SobekCM.Library.ItemViewer.Viewers.ItemViewer_Factory.Get_Viewer(viewObject, currentItem.Bib_Info.Type.Type.ToUpper());

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

                        //    // Assign the rest of the information, if a page viewer was created
                        //    if (page_viewer != null)
                        //    {
                        //        page_viewer.CurrentItem = currentItem;
                        //        page_viewer.CurrentMode = currentMode;
                        //        page_viewer.Redirect += new SobekCM.Library.ItemViewer.Viewers.Redirect_Requested(itemWriter_Redirect);

                        //        // If this was the citation viewer, pass in the translation object
                        //        string type = page_viewer.GetType().ToString();
                        //        if (page_viewer.GetType().ToString() == "SobekCM.Library.ItemViewer.Viewers.Citation_ItemViewer")
                        //        {
                        //            ((SobekCM.Library.ItemViewer.Viewers.Citation_ItemViewer)page_viewer).Translator = translator;
                        //            if ( currentUser != null )
                        //            {
                        //                ((SobekCM.Library.ItemViewer.Viewers.Citation_ItemViewer)page_viewer).User_Can_Edit_Item = currentUser.Can_Edit_This_Item(currentItem);
                        //            }

                        //        }
                        //    }
                        //}

                        // Determine the browser
                        bool ie = (currentMode.Browser_Type.IndexOf("IE") >= 0 );
                        bool show_toc = false;
                        if (HttpContext.Current.Session["Show TOC"] != null)
                        {
                            Boolean.TryParse(HttpContext.Current.Session["Show TOC"].ToString(), out show_toc);
                        }

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

                        // Check to see if this is IP restricted
                        string 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)
                                {
                                    int restriction = currentItem.Behaviors.IP_Restriction_Membership;
                                    int restriction_counter = 0;
                                    while (restriction % 2 != 1)
                                    {
                                        restriction = restriction >> 1;
                                        restriction_counter++;
                                    }
                                    restriction_message = ipRestrictionInfo[restriction_counter].Item_Restricted_Statement;
                                }
                            }
                        }

                        // Create the item viewer writer
                        Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Building Item Writer");
                        itemWriter = new Item_HtmlSubwriter(currentItem, currentPage, currentUser,
                            codeManager, translator, show_toc, (SobekCM_Library_Settings.JP2_Server.Length > 0),
                            currentMode, hierarchyObject, restriction_message, itemsInTitle, Tracer);
                        subwriter = itemWriter;
                        itemWriter.Mode = currentMode;
                        itemWriter.Skin = htmlSkin;
                        itemWriter.Item_Checked_Out_By_Other_User = itemCheckedOutByOtherUser;

                        // Add the navigation part to this form
                        itemWriter.Add_Nav_Bar_Menu_Section(Navigation_Place_Holder, ie, Tracer);
                        //if (itemWriter.PageViewer != null)
                        //{
                        //    Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Allowing page viewer to add left navigation bar section to <i>navigationPlaceHolder</i>");
                        //    itemWriter.Nav_Bar_Menu_Section_Added = itemWriter.PageViewer.Add_Nav_Bar_Menu_Section(Navigation_Place_Holder, ie, Tracer);
                        //}

                        // Add the TOC section
                        Tracer.Add_Trace("Html_MainWriter.Add_Controls", "Allowing item viewer to add table of contents to <i>tocPlaceHolder</i>");
                        itemWriter.Add_Standard_TOC(TOC_Place_Holder, Tracer);

                        // Add the main viewer section
                        itemWriter.Add_Main_Viewer_Section(Main_Place_Holder, Tracer);
                    }
                    break;

                #endregion

                default:
                    Tracer.Add_Trace("Html_MainWriter.Add_Html_And_Controls", "No controls or html added to page");
                    break;
            }
        }
        private void Finish_writing_html(SobekCM_Item currentItem, Page_TreeNode currentPage, string filename, string text_file_location )
        {
            string bibid = currentItem.BibID;
            currentItem.Behaviors.Text_Searchable = false;

            // Create the HTML writer
            Item_HtmlSubwriter itemWriter = new Item_HtmlSubwriter(currentItem, currentPage, null, codeManager, translations, true, true, currentMode, null, String.Empty, null, tracer)
                                                 {Mode = currentMode, Skin = ufdcInterface};
            SobekCM_Library_Settings.Base_SobekCM_Location_Relative = currentMode.Base_URL;
            if ((SobekCM_Library_Settings.Base_SobekCM_Location_Relative.Length == 0) || (SobekCM_Library_Settings.Base_SobekCM_Location_Relative.Contains("localhost")))
            {
                SobekCM_Library_Settings.Base_SobekCM_Location_Relative = primaryWebServerUrl;
                if (bibid.IndexOf("CA") == 0)
                {
                    currentMode.Skin = "dloc";
                    itemWriter.Skin = dlocInterface;
                    SobekCM_Library_Settings.Base_SobekCM_Location_Relative = "http://www.dloc.com/";
                }
                currentMode.Base_URL = SobekCM_Library_Settings.Base_SobekCM_Location_Relative;
            }

            // Now that the item viewer is built, set the robot flag to suppress some checks
            currentMode.Is_Robot = true;

            // Create the TextWriter
            StreamWriter writer = new StreamWriter(filename, false, Encoding.UTF8);

            // Add the header
            Display_Header(writer, itemWriter.Skin);

            // Begin to write the item view
            itemWriter.Write_HTML(writer, tracer);

            // Write the table of contents as static HTML, rather than the TreeView web control
            if ((currentItem.Web.Static_PageCount > 1) && (currentItem.Web.Static_Division_Count > 1))
            {
                writer.WriteLine("        <ul class=\"SobekNavBarMenu\">" + Environment.NewLine + "          <li class=\"SobekNavBarHeader\"> TABLE OF CONTENTS </li>" + Environment.NewLine + "        </ul>" + Environment.NewLine  +
                                 "        <div class=\"HideTocRow\">" + Environment.NewLine + "          <img src=\"" + SobekCM_Library_Settings.Base_SobekCM_Location_Relative + "design/skins/" + itemWriter.Skin.Skin_Code + "/tabs/cLG.gif\" border=\"0\" alt=\"\" /><img src=\"" + SobekCM_Library_Settings.Base_SobekCM_Location_Relative + "design/skins/" + itemWriter.Skin.Skin_Code + "/tabs/AU.gif\" border=\"0\" alt=\"\" /><span class=\"tab\">HIDE</span><img src=\"" + SobekCM_Library_Settings.Base_SobekCM_Location_Relative + "design/skins/" + itemWriter.Skin.Skin_Code + "/tabs/cRG.gif\" border=\"0\" alt=\"\" />" + Environment.NewLine + "        </div>");
                writer.WriteLine("<div class=\"SobekTocTreeView\">");

                // load the table of contents in the tree
                TreeView treeView1 = new TreeView();
                itemWriter.Create_TreeView_From_Divisions(treeView1);

                // Step through all the parent nodes
                writer.WriteLine("<table cellspacing=\"4px\" >");
                foreach (TreeNode thisNode in treeView1.Nodes)
                {
                    writer.WriteLine("  <tr><td width=\"9px\">&nbsp;</td><td>" + thisNode.Text.Replace("ufdcSelectedTocTreeViewItem", "ufdcTocTreeViewItem") + "</td></tr>");
                }
                writer.WriteLine("</table>");
                writer.WriteLine("</div>");
            }

            itemWriter.Write_Additional_HTML(writer, tracer);
            PlaceHolder placeHolder = new PlaceHolder();
            itemWriter.PageViewer.Add_Main_Viewer_Section(placeHolder, tracer);
            Literal citationLiteral = (Literal)placeHolder.Controls[0];
            writer.WriteLine(citationLiteral.Text);
            placeHolder.Controls.Clear();

            writer.WriteLine("<!-- COMMENT HERE -->");

            // Close out this tables and form
            writer.WriteLine("       </tr>");

            // Add the download list if there are some
            if ( currentItem.Divisions.Download_Tree.Has_Files )
            {
                writer.WriteLine("       <tr>");
                // Create the downloads viewer to ouput the html
                Download_ItemViewer downloadViewer = new Download_ItemViewer
                                                         {CurrentItem = currentItem, CurrentMode = currentMode};

                // Add the HTML for this now
                downloadViewer.Add_Main_Viewer_Section(placeHolder, tracer);
                Literal downloadLiteral = (Literal)placeHolder.Controls[0];
                writer.WriteLine(downloadLiteral.Text);
                writer.WriteLine("       </tr>");
            }

            // If there is a table of contents write it again, this time it will be complete
            // and also show a hierarchy if there is one
            if ((currentItem.Web.Static_PageCount > 1) && (currentItem.Web.Static_Division_Count > 1))
            {
                writer.WriteLine("       <tr>");
                writer.WriteLine("         <td align=\"left\"><span class=\"SobekViewerTitle\">Table of Contents</span></td>");
                writer.WriteLine("       </tr>");

                writer.WriteLine("       <tr>");
                writer.WriteLine("          <td>");
                writer.WriteLine("            <div class=\"SobekCitation\">");

                foreach (abstract_TreeNode treeNode in currentItem.Divisions.Physical_Tree.Roots)
                {
                    recursively_write_toc(writer, treeNode, "&nbsp; &nbsp; ");
                }

                writer.WriteLine("            </div>");
                writer.WriteLine("          </td>");
                writer.WriteLine("       </tr>");
            }

            // Is the text file location included, in which case any full text should be appended to the end?
            if ((text_file_location.Length > 0) && ( Directory.Exists(text_file_location)))
            {
                // Get the list of all TXT files in this division
                string[] text_files = Directory.GetFiles(text_file_location, "*.txt");
                Dictionary<string, string> text_files_existing = new Dictionary<string, string>();
                foreach (string thisTextFile in text_files)
                {
                    string text_filename = (new FileInfo(thisTextFile)).Name.ToUpper();
                    text_files_existing[text_filename] = text_filename;
                }

                // Are there ANY text files?
                if (text_files.Length > 0)
                {
                    // If this has page images, check for related text files
                    List<string> text_files_included = new List<string>();
                    bool started = false;
                    if (currentItem.Divisions.Physical_Tree.Has_Files)
                    {
                        // Go through the first 100 text pages
                        List<abstract_TreeNode> pages = currentItem.Divisions.Physical_Tree.Pages_PreOrder;
                        int page_count = 0;
                        foreach (Page_TreeNode thisPage in pages)
                        {
                            // Keep track of the page count
                            page_count++;

                            // Look for files in this page
                            if (thisPage.Files.Count > 0)
                            {
                                bool found_non_thumb_file = false;
                                foreach (SobekCM_File_Info thisFile in thisPage.Files)
                                {
                                    // Make sure this is not a thumb
                                    if (thisFile.System_Name.ToLower().IndexOf("thm.jpg") < 0)
                                    {
                                        found_non_thumb_file = true;
                                        string root = thisFile.File_Name_Sans_Extension;
                                        if (text_files_existing.ContainsKey(root.ToUpper() + ".TXT"))
                                        {
                                            string text_file = text_file_location + "\\" + thisFile.File_Name_Sans_Extension + ".txt";

                                            // SInce this is marked to be included, save this name
                                            text_files_included.Add(root.ToUpper() + ".TXT");

                                            // For size reasons, we only include the text from the first 100 pages
                                            if (page_count <= 100)
                                            {
                                                if (!started)
                                                {
                                                    writer.WriteLine("       <tr>");
                                                    writer.WriteLine("         <td align=\"left\"><span class=\"SobekViewerTitle\">Full Text</span></td>");
                                                    writer.WriteLine("       </tr>");
                                                    writer.WriteLine("       <tr>");
                                                    writer.WriteLine("          <td>");
                                                    writer.WriteLine("            <div class=\"SobekCitation\">");

                                                    started = true;
                                                }

                                                try
                                                {
                                                    StreamReader reader = new StreamReader(text_file);
                                                    string text_line = reader.ReadLine();
                                                    while (text_line != null)
                                                    {
                                                        writer.WriteLine(text_line + "<br />");
                                                        text_line = reader.ReadLine();
                                                    }
                                                    reader.Close();
                                                }
                                                catch
                                                {
                                                    writer.WriteLine("Unable to read file: " + text_file);
                                                }

                                                writer.WriteLine("<br /><br />");
                                            }
                                        }

                                    }

                                    // If a suitable file was found, break here
                                    if (found_non_thumb_file)
                                        break;
                                }
                            }
                        }

                        // End this if it was ever started
                        if (started)
                        {
                            writer.WriteLine("            </div>");
                            writer.WriteLine("          </td>");
                            writer.WriteLine("       </tr>");
                        }
                    }

                    // Now, check for any other valid text files
                    List<string> additional_text_files = text_files_existing.Keys.Where(thisTextFile => (!text_files_included.Contains(thisTextFile.ToUpper())) && (thisTextFile.ToUpper() != "AGREEMENT.TXT") && (thisTextFile.ToUpper().IndexOf("REQUEST") != 0)).ToList();

                    // Now, include any additional text files, which would not be page text files, possiblye
                    // full text for included PDFs, Powerpoint, Word Doc, etc..
                    foreach (string thisTextFile in additional_text_files)
                    {
                        if (!started)
                        {
                            writer.WriteLine("       <tr>");
                            writer.WriteLine("         <td align=\"left\"><span class=\"SobekViewerTitle\">Full Text</span></td>");
                            writer.WriteLine("       </tr>");
                            writer.WriteLine("       <tr>");
                            writer.WriteLine("          <td>");
                            writer.WriteLine("            <div class=\"SobekCitation\">");

                            started = true;
                        }

                        string text_file = text_file_location + "\\" + thisTextFile;

                        try
                        {

                            StreamReader reader = new StreamReader(text_file);
                            string text_line = reader.ReadLine();
                            while (text_line != null)
                            {
                                writer.WriteLine(text_line + "<br />");
                                text_line = reader.ReadLine();
                            }
                            reader.Close();
                        }
                        catch
                        {
                            writer.WriteLine("Unable to read file: " + text_file);
                        }

                        writer.WriteLine("<br /><br />");
                    }
                }
            }

            writer.WriteLine("      </table>");
            writer.WriteLine("    </td>");
            writer.WriteLine("  </tr>");
            writer.WriteLine("</table>");

            // Write the footer
            Display_Footer(writer, itemWriter.Skin);

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

            // Restore the text searchable flag and robot flag
            currentMode.Is_Robot = false;
            currentItem.Behaviors.Text_Searchable = false;
        }