/// <summary>
        /// Returns markup to link to the parent directory of the
        /// tilde directory path of the context.
        ///
        /// Returns an empty string if there is an error or if
        /// the context is at the web site root directory level.
        /// </summary>
        /// <param name="context">Web site HttpContext object</param>
        /// <param name="filename">The target file name</param>
        public static string MakeParentDirectoryLinkMarkup
            (HttpContext context, string filename)
        {
            if (context == null)
            {
                return("");
            }

            string tildeDirectoryPath =
                HttpContextTools.GetTildeDirectoryPath(context);

            if (tildeDirectoryPath == SourceTools.tildeStart)
            {
                return("");
            }

            int n = tildeDirectoryPath.Length;

            string path = tildeDirectoryPath.Substring(0, n - 1);

            int m = path.LastIndexOf('/');

            path = path.Substring(0, m + 1);

            if (filename == null)
            {
                filename = "";
            }

            return("<p>Parent Directory:</p>\n"
                   + MakeDirectoryLink(context, path, filename));
        }
        /// <summary>
        /// Returns the markup for the list of servable files
        /// in the same directory
        /// as the context web directory.
        ///
        /// Each file name will link to the file so that it
        /// may be served.
        ///
        /// The optional comment heads the list of file names.
        /// If omitted, a default comment is constructed.
        /// </summary>
        /// <param name="context">Web site HttpContext object</param>
        /// <param name="comment">Optional comment to head list</param>
        public static string MakeServableListMarkup
            (HttpContext context, string comment)
        {
            if (context == null)
            {
                return("");
            }

            List <string> servablelist =
                HttpContextTools.MakeServableList(context);

            int count = servablelist.Count;

            if (count == 0)
            {
                return("");
            }

            StringBuilder builder = new StringBuilder();

            builder.Append(HTML_Tools.open_p);

            if (StringTools.IsTrivial(comment))
            {
                string tildePath =
                    HttpContextTools.GetTildeDirectoryPath(context);

                builder.Append("Servable files in ");
                builder.Append(tildePath);
                builder.Append(" [");
                builder.Append(count);
                builder.Append("]:");
            }
            else
            {
                builder.Append(comment);
            }

            builder.Append(HTML_Tools.shut_p);

            foreach (string name in servablelist)
            {
                builder.Append(HTML_Tools.open_div);
                builder.Append(HTML_Tools.open_anchor);
                builder.Append(name);
                builder.Append(HTML_Tools.mid_anchor_blank);
                builder.Append(HTML_Tools.open_code);
                builder.Append(name);
                builder.Append(HTML_Tools.shut_code);
                builder.Append(HTML_Tools.shut_anchor);
                builder.Append(HTML_Tools.shut_div);
            }

            return(builder.ToString());
        }
        /// <summary>
        /// Make the body markup for the AutoImage utility.
        /// </summary>
        /// <param name="context">Web site HttpContext object</param>
        /// <param name="onlyPublic">If true restrict to public subdirectories</param>
        public static string MakeAutoImageMarkup
            (HttpContext context, bool onlyPublic)
        {
            StringBuilder builder = new StringBuilder();

            // path in the file system
            string directoryPath =
                FileTools.GetDirectoryPath(context);

            // path as a tilde web directory path
            string tildeDirectoryPath =
                HttpContextTools.GetTildeDirectoryPath(context);

            List <string> subdirectoryList =
                HttpContextTools.MakeSubdirectoryList(context, onlyPublic);

            List <string> imageList =
                HttpContextTools.MakeFileList(context, FileTools.IMAGE);

            int M = subdirectoryList.Count;
            int N = imageList.Count;

            // create markup

            builder.Append("\n<p><b>Web Directory: ");
            builder.Append(tildeDirectoryPath);
            builder.Append("</b></p>\n");

            if (M > 0)
            {
                builder.Append("\n<p><b>Subdirectories:</b></p>\n");

                MakeSubdirectoryLinks(builder, subdirectoryList);
            }

            builder.Append("\n<p><b>Image Count in this Web Directory: ");
            builder.Append(N);
            builder.Append("</b></p>\n");

            MakeImageLinks(builder, directoryPath, imageList);

            return(builder.ToString());
        }
        public void ProcessRequest(HttpContext context)
        {
            string title = AutoFileTools.autoFileTitle;

            string headMarkup =
                HttpContextTools.MakeStyleSheetLinks(context)
                +
                HttpContextTools.MakeJavascriptReferences(context);

            string bodyMarkup =
                AutoFileTools.MakeAutoFileMarkup(context, onlyPublic);

            string markup =
                HTML_Tools.MakePageMarkup
                    (null, title, headMarkup, null, bodyMarkup);

            context.Response.ContentType =
                HTML_Tools.htmlContentType;

            context.Response.Write(markup);
        }
        /// <summary>
        /// Returns a link to the given tilde directory path
        /// with the filename appended.
        ///
        /// The filename may be:
        ///
        ///   * Empty, so a default servable file will be used
        ///
        ///   * A pseudo filename handled by an IHttpHandler
        ///
        ///   * Some other filename known to be present in the
        ///     directory
        ///
        /// If the tilde directory path does not end is a slash
        /// then its file name component will be removed.
        ///
        /// Returns an empty string if an error occurs.
        /// </summary>
        /// <param name="context">Web site HttpContext object</param>
        /// <param name="tildeDirectoryPath">Tilde directory path</param>
        /// <param name="filename">Target file name</param>
        public static string MakeDirectoryLink
            (HttpContext context, string tildeDirectoryPath, string filename)
        {
            try
            {
                tildeDirectoryPath =
                    HttpContextTools.GetDirectoryPath(tildeDirectoryPath);

                string directoryPath =
                    HttpContextTools.MakeMergedPath(context, tildeDirectoryPath);

                if (filename == null)
                {
                    filename = "";
                }

                StringBuilder builder = new StringBuilder();

                builder.Append(HTML_Tools.open_div);
                builder.Append(HTML_Tools.open_anchor);
                builder.Append(directoryPath);
                builder.Append(filename);
                builder.Append(HTML_Tools.mid_anchor_blank);
                builder.Append(HTML_Tools.open_code);
                builder.Append(tildeDirectoryPath);
                builder.Append(HTML_Tools.shut_code);
                builder.Append(HTML_Tools.shut_anchor);
                builder.Append(HTML_Tools.shut_div);

                return(builder.ToString());
            }
            catch (Exception)
            {
                return("");
            }
        }
        // ToHtml requires a knowledge of the page on which
        // the html will be installed in order to properly
        // compute relative links.
        public string ToHtml(Page page)
        {
            if (!_valid)
            {
                return("<p><code>" + _path + "</code>" + errormessage + "</p>\n");
            }

            StringBuilder builder = new StringBuilder();

            // Show tilde file path
            // Link to the file view utility if viewable

            int  category = FileTools.GetFileCategory(_path);
            bool viewable = category != FileTools.OTHER;

            builder.Append("<p>");

            if (viewable)
            {
                string FileViewTildePath = SourceTools.FileViewTildePath;
                string fileViewURL       = FileTools.GetRelativePath(page, FileViewTildePath);

                builder.Append("<a href ='");
                builder.Append(fileViewURL);
                builder.Append("?");
                builder.Append(_path);
                builder.Append("' target='_blank'>");
            }

            builder.Append("<code>");
            builder.Append(_path);
            builder.Append("</code>");

            if (viewable)
            {
                builder.Append("</a>");
            }

            builder.Append("</p>\n");

            // Add launch link if servable

            bool servable = HttpContextTools.IsServable(_path);

            if (servable)
            {
                string launchURL = FileTools.GetRelativePath(page, _path);

                builder.Append("<p>Launch ");
                builder.Append("<a href ='");
                builder.Append(launchURL);
                builder.Append("' target='_blank'>");
                builder.Append("<code>");
                builder.Append(_path);
                builder.Append("</code>");
                builder.Append("</a>");
                builder.Append("</p>\n");
            }

            builder.Append("<table class='filedata'>\n");

            // File size

            builder.Append("<tr>\n");

            builder.Append("<td>");
            builder.Append("Size");
            builder.Append("</td>\n");

            builder.Append("<td>");
            builder.Append(_size.ToString());
            builder.Append("</td>\n");

            builder.Append("</tr>\n");

            // File date

            builder.Append("<tr>\n");

            builder.Append("<td>");
            builder.Append("Date");
            builder.Append("</td>\n");

            builder.Append("<td>");
            builder.Append(_date.ToYMD());
            builder.Append("</td>\n");

            builder.Append("<td>");
            builder.Append(_date.ToHMS());
            builder.Append("</td>\n");

            builder.Append("</tr>\n");

            // Add image dimensions if applicable

            bool image = (_width > 0) && (_height > 0);

            if (image)
            {
                builder.Append("<tr>\n");

                builder.Append("<td>");
                builder.Append("Dims");
                builder.Append("</td>\n");

                builder.Append("<td>");
                builder.Append(_width.ToString());
                builder.Append(" ");
                builder.Append("&times;");
                builder.Append(" ");
                builder.Append(_height.ToString());
                builder.Append("</td>\n");

                builder.Append("</tr>\n");
            }

            builder.Append("</table>\n");

            return(builder.ToString());
        }
        /// <summary>
        /// Returns a link to the file view utility for the file with
        /// the given tilde path.
        ///
        /// Returns an empty string if an error occurs.
        /// </summary>
        /// <param name="context">Web site HttpContext object</param>
        /// <param name="tildeFilePath">A file tilde path</param>
        public static string MakeFileViewLinkMarkup
            (HttpContext context, string tildeFilePath)
        {
            try
            {
                if (context == null)
                {
                    return("");
                }

                if (StringTools.IsTrivial(tildeFilePath))
                {
                    return("");
                }

                if (!tildeFilePath.StartsWith(SourceTools.tildeStart))
                {
                    return("");
                }

                string filename =
                    HttpContextTools.GetFileName(tildeFilePath);

                string fileviewPath =
                    HttpContextTools.
                    MakeMergedPath(context, fileviewTildePath);

                StringBuilder builder = new StringBuilder();

                builder.Append(openFileViewMarkup);

                // Download button
                builder.Append(Download1);
                builder.Append(tildeFilePath);
                builder.Append(Download2);

                // FileView link
                builder.Append(HTML_Tools.open_span);
                builder.Append(HTML_Tools.open_anchor);
                builder.Append(fileviewPath);
                builder.Append("?");
                builder.Append(tildeFilePath);
                builder.Append(HTML_Tools.mid_anchor_blank);
                builder.Append(HTML_Tools.open_code);
                builder.Append(filename);
                builder.Append(HTML_Tools.shut_code);
                builder.Append(HTML_Tools.shut_anchor);
                builder.Append(HTML_Tools.shut_span);

                // Data for the file

                string filePath =
                    context.Server.MapPath(tildeFilePath);

                FileInfo info = new FileInfo(filePath);

                // bytes
                long bytes = info.Length;

                builder.Append(HTML_Tools.open_span);
                builder.Append(bytes.ToString());
                builder.Append(HTML_Tools.shut_span);

                // most recent date and time
                DateTime mostrecent = info.MostRecentTime();

                builder.Append(HTML_Tools.open_span);
                builder.Append(mostrecent.ToYMD());
                builder.Append(HTML_Tools.shut_span);

                builder.Append(HTML_Tools.open_span);
                builder.Append(mostrecent.ToHMS());
                builder.Append(HTML_Tools.shut_span);

                builder.Append(shutFileViewMarkup);

                return(builder.ToString());
            }
            catch (Exception)
            {
                return("");
            }
        }
        /// <summary>
        /// Returns the markup for links to the list of
        /// subdirectories of the web directory of the context.
        ///
        /// Removes subdirectories that begin with "~/app_".
        ///
        /// After each subdirectory name in a link, inserts a
        /// slash and then a reference to the given filename.
        ///
        /// The filename may be:
        ///
        ///   * Empty, so a default servable file will be used.
        ///
        ///   * A pseudo filename handled by an IHttpHandler.
        ///
        ///   * Some other filename known to be present in all
        ///     subdirectories.
        ///
        ///   * Null, which is treated as empty.
        ///
        /// If there are no subdirectories, then then the empty
        /// string will be returned as the markup.
        ///
        /// The optional comment heads the list of subdirectory
        /// names.  If omitted, a default comment is constructed.
        /// </summary>
        /// <param name="context">Web site HttpContext object</param>
        /// <param name="filename">The target file name</param>
        /// <param name="comment">Optional comment to head list</param>
        /// <param name="onlyPublic">If true restrict to public subdirectories</param>
        public static string MakeSubdirectoryLinkMarkup
            (HttpContext context, string filename,
            string comment, bool onlyPublic)
        {
            if (context == null)
            {
                return("");
            }

            if (filename == null)
            {
                filename = "";
            }

            string tildeDirectoryPath =
                HttpContextTools.GetTildeDirectoryPath(context);

            List <string> subnames =
                HttpContextTools.MakeSubdirectoryList(context, onlyPublic);


            // Remove names that would lead to paths
            // that begin with "~/app_".

            List <string> remove = new List <string>();

            foreach (string name in subnames)
            {
                string subpath = tildeDirectoryPath + name + "/";

                if (!subpath.ToLower().StartsWith("~/app_"))
                {
                    continue;
                }

                remove.Add(name);
            }

            foreach (string name in remove)
            {
                subnames.Remove(name);
            }


            int count = subnames.Count;

            if (count == 0)
            {
                return("");
            }


            StringBuilder builder = new StringBuilder();

            builder.Append(HTML_Tools.open_p);

            if (StringTools.IsTrivial(comment))
            {
                builder.Append("Subdirectories of ");
                builder.Append(tildeDirectoryPath);
                builder.Append(" [");
                builder.Append(count);
                builder.Append("]:");
            }
            else
            {
                builder.Append(comment);
            }

            builder.Append(HTML_Tools.shut_p);

            foreach (string name in subnames)
            {
                string subpath = tildeDirectoryPath + name + "/";

                string directorylink =
                    MakeDirectoryLink(context, subpath, filename);

                builder.Append(directorylink);
            }

            return(builder.ToString());
        }
        /// <summary>
        /// Returns the markup for the list of files
        /// that reside in the context web directory
        /// and that match the given file type.
        ///
        /// Each file name will link to the file viewer.
        ///
        /// The filetype should take one of seven values:
        ///   1: Text files
        ///   2: Image files
        ///   3: Viewable files, that is, text or image files
        ///   4: Non-viewable files
        ///   5: Text files plus non-viewable files
        ///   6: Image files plus non-viewable files
        ///   7: All files
        ///
        /// If no files match the filetype then the empty
        /// string will be returned as the markup.
        ///
        /// The optional comment heads the list of file names.
        /// If omitted, a default comment is provided.
        /// </summary>
        /// <param name="context">Web site HttpContext object</param>
        /// <param name="fileType">The filetype mask</param>
        /// <param name="comment">Optional comment to head list</param>
        /// <param name="extras">If true show extras</param>
        public static string MakeFileListMarkup
            (HttpContext context, int fileType, string comment)
        {
            if (context == null)
            {
                return("");
            }

            fileType &= FileTools.ALL;

            if (fileType == 0)
            {
                return("");
            }

            List <string> filelist =
                HttpContextTools.MakeFileList(context, fileType);

            int count = filelist.Count;

            if (count == 0)
            {
                return("");
            }

            string tildeDirectoryPath =
                HttpContextTools.GetTildeDirectoryPath(context);

            StringBuilder builder = new StringBuilder();

            builder.Append(HTML_Tools.open_p);

            if (StringTools.IsTrivial(comment))
            {
                switch (fileType)
                {
                case 1:
                    builder.Append("Text files in ");
                    break;

                case 2:
                    builder.Append("Image files in ");
                    break;

                case 3:
                    builder.Append("Viewable files in ");
                    break;

                case 4:
                    builder.Append("Non-viewable files in ");
                    break;

                case 5:
                    builder.Append("Text and non-viewable files in ");
                    break;

                case 6:
                    builder.Append("Image and non-viewable files in ");
                    break;

                case 7:
                    builder.Append("All files in ");
                    break;

                default:
                    break;
                }

                builder.Append(tildeDirectoryPath);
                builder.Append(" [");
                builder.Append(count);
                builder.Append("]:");
            }
            else
            {
                builder.Append(comment);
            }

            builder.Append(HTML_Tools.shut_p);

            foreach (string filename in filelist)
            {
                string tildeFilePath = tildeDirectoryPath + filename;

                string filelink =
                    MakeFileViewLinkMarkup(context, tildeFilePath);

                builder.Append(filelink);
            }

            return(builder.ToString());
        }