using System;
using System.Web.UI;
using System.IO;
using System.Web.UI.WebControls;
using System.Collections.Generic;

namespace ExWeb
{
    public partial class Mod_Directory : Mod
    {
        public static string Help_Description =
            "Anzeige des Inhalts eines Verzeichnisses"
            + "\r\n"
            + "\r\nDieses Modul darf nur einmal auf einer Seite verwendet werden";

        public static string[][] Help_Attributes = new string[][]
        {
            // Attribut, Wert, DefaultWert, Optional, Hilfe
            new string[] {"Pat","string","","opt","Pfad","Pat=\"/verzeichnis/\""},
            new string[] {"ShowFile","all image code web", "all", "opt","Darstellung des Inhalts","ShowFiles=\"image\""},
            new string[] {"Pattern","string","*","opt","Wildcard-Zeichenfolge zur Dateienauswahl","Pattern=\"*.txt\""},
            new string[] {"Link","inline self blank new frame none auto","inline","opt","Darstellung des Inhalts","Link=\"new\""},
            new string[] {"Recursive","0 1","0","opt","Zeige auch Dateien in Unterverzeichnissen","Recursive=\"1\""},
            new string[] {"NoExt","0 1","0","opt","Erweiterung unterdrücken","NoExt=\"1\""},
            new string[] {"Src","0 1","0","opt","Zeige Quellkode","Src=\"1\""},
            new string[] {"Menu","prevnext vertical all","all","opt","Menu","Menu=\"prevnext\""},
        };
        protected string _Pat = "/";
        public string Pat
        {
            set
            {
                if (!value.EndsWith("/")) value += "/";
                _Pat = value;
            }
        }
        FILETYPE _showfile = FILETYPE.ALL;
        public string showfile
        {
            set
            {
                switch (value.ToLower())
                {
                    default:
                    case "all":
                        _showfile = FILETYPE.ALL;
                        break;
                    case "image":
                        _showfile = FILETYPE.IMAGE;
                        break;
                    case "code":
                        _showfile = FILETYPE.CODE;
                        break;
                    case "web":
                        _showfile = FILETYPE.WEB;
                        break;
                }
            }
            get
            {
                switch (_showfile)
                {
                    default:
                    case FILETYPE.ALL:
                        return "all";
                    case FILETYPE.IMAGE:
                        return "image";
                    case FILETYPE.CODE:
                        return "code";
                    case FILETYPE.WEB:
                        return "web";
                }
            }
        }
        enum LINK { NONE, INLINE, SELF, BLANK, FRAME, AUTO };
        LINK _link = LINK.INLINE;
        public string link
        {
            set
            {
                switch (value.ToLower())
                {
                    case "none":
                        _link = LINK.NONE;
                        break;
                    case "inline":
                        _link = LINK.INLINE;
                        break;
                    case "self":
                        _link = LINK.SELF;
                        break;
                    case "blank":
                        _link = LINK.BLANK;
                        break;
                    case "frame":
                        _link = LINK.FRAME;
                        break;
                    default:
                    case "auto":
                        _link = LINK.AUTO;
                        break;
                }
            }
        }
        enum DISPLAY { RAW, PRE, HIGH, HEX };
        bool _NoExt = false;
        public string NoExt
        {
            set
            {
                _NoExt = (value == "1");
            }
        }
        string _Pattern = "*";
        public string Pattern
        {
            set
            {
                if (value != "") _Pattern = value;
            }
        }
        bool _Recursive = false;
        public string Recursive
        {
            set
            {
                _Recursive = (value == "1");
            }
        }
        bool _Src = false;
        public string Src
        {
            set
            {
                _Src = (value == "1");
            }
            get
            {
                return (_Src ? "1" : "0");
            }
        }
        enum MENU { PREVNEXT, VERTICAL, BOTH };
        MENU _menu = MENU.BOTH;
        public string menu
        {
            set
            {
                switch (value.ToLower())
                {
                    case "vertical":
                        _menu = MENU.VERTICAL;
                        break;
                    case "prevnext":
                        _menu = MENU.PREVNEXT;
                        break;
                    default:
                    case "both":
                        _menu = MENU.BOTH;
                        break;
                }
            }
        }
        protected void Page_LoadComplete(object sender, EventArgs e)
        {
            SetPanelLayout(this.Controls);
        }
        public new void Page_Init(object sender, EventArgs e)
        {
            Page.LoadComplete += new EventHandler(Page_LoadComplete);
        }
        public new void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                IncludeDirectory();
            }
        }
        string Capitalize(string Text)
        {
            string[] parts = Text.Split(new char[] { ' ' });
            for (int i = 0; i < parts.Length; i++)
            {
                parts[i] = parts[i].Trim();
                parts[i] = parts[i].Substring(0, 1).ToUpper() + parts[i].Substring(1);
            }
            Text = "";
            for (int i = 0; i < parts.Length; i++)
            {
                Text += parts[i] + " ";
            }
            return Text;
        }
        string GetNameCheckExtension(string fiName, int Index, int IndexToShow)
        {
            const string Indent = "   ";
            string Name = fiName;
            if (_NoExt) Name = Path.GetFileNameWithoutExtension(Name);
            Name = Capitalize(Name);
            int IndexSpace = Name.IndexOf(' ');
            int Chapter = -1;
            if (IndexSpace > 0)
            {
                if (int.TryParse(Name.Substring(0, IndexSpace), out Chapter))
                {
                    Name = Name.Substring(IndexSpace + 1);
                    while (Chapter / 10 > 0)
                    {
                        if (Chapter%10 != 0)
                            Name = Indent + Name;
                        Chapter = Chapter / 10;
                    }
                }
            }
            if (_link != LINK.NONE)
            {
                // if (Index == IndexToShow) Name = "* " + Name;
                if (Index == IndexToShow) Name = "<b><i>" + Name + "</i></b>";
            }
            return Name;
        }
        string GetName(string fiName, string RelativePath)
        {
            string Name = fiName;
            if (_Recursive)
            {
                Name = RelativePath + Name;
            }
            if (_NoExt) Name = Path.GetFileNameWithoutExtension(Name);
            return Name;
        }
        void IncludeDirectory()
        {
            string AbsolutePath = "";

            int IndexToShow = Mod.GetQs_Int("id", 0, this.Page);

            Pat = Mod.GetQs_String("pat", _Pat, this.Page);
            showfile = GetQs_String("showfile", _showfile.ToString(), this.Page);
            Recursive = GetQs_String("recursive", _Recursive ? "1" : "0", this.Page);
            link = GetQs_String("link", _link.ToString(), this.Page);
            _NoExt = GetQs_Bool("noext", _NoExt, this.Page);
            _Src = GetQs_Bool("src", _Src, this.Page);
            menu = GetQs_String("menu", _menu.ToString(), this.Page);

            if (_Pat == "") // Path not set, take current Path
            {
                _Pat = Request.AppRelativeCurrentExecutionFilePath;
                _Pat = _Pat.Substring(0, _Pat.LastIndexOf("/") + 1);
                if (_Pat.StartsWith("~")) _Pat = _Pat.Substring(1);
                AbsolutePath = Server.MapPath(_Pat);
                AbsolutePath = Path.GetDirectoryName(AbsolutePath);
            }
            else
            {
                AbsolutePath = Server.MapPath(_Pat);
            }
            if (!_Pat.EndsWith("/")) _Pat += "/";

            DirectoryInfo diri = new DirectoryInfo(AbsolutePath);
            if (!diri.Exists)
            {
                Panel_Module.Visible = false;
                return;
            }
            int Index = 0;
            int IndexPrevious = -1;
            int IndexActual = -1;
            int IndexNext = -1;
            string RelativePath = "";
            // Collect All Files To Be Displayed
            List<string> filestoshow = GetFiles(this.Page, _Pat, _Pattern, _Recursive, _showfile);
            if (filestoshow.Count == 0)
            {
                Panel_Module.Visible = false;
                return;
            }
            switch (_link)
            {
                default:
                case LINK.SELF:
                case LINK.BLANK:
                    Panel_Content.Visible = false;
                    break;
                case LINK.INLINE:
                case LINK.FRAME:
                    Panel_Content.Visible = true;
                    break;
            }
            switch (_link)
            {
                case LINK.SELF:
                    _Target = "_self";
                    break;
                case LINK.BLANK:
                    _Target = "_blank";
                    break;
                case LINK.FRAME:
                    _Target = "frame";
                    break;
                default:
                case LINK.INLINE:
                case LINK.NONE:
                    _Target = "";
                    break;
            }
            string FrameID = "frame";
            string[] RequiresServer = Mod.GetConfigStringList("Ext_WebServer", true);
            for (int i = 0; i < filestoshow.Count; i++)
            {
                string fi = filestoshow[i];
                RelativePath = fi; if (fi.Contains("/")) RelativePath = fi.Substring(0, fi.LastIndexOf("/"));
                string Extension = Path.GetExtension(fi).ToLower();
                string Name = fi; if (fi.Contains("/")) Name = fi.Substring(fi.LastIndexOf("/") + 1);
                if (Name.StartsWith("."))
                    continue;
                if (Index == IndexToShow)
                {
                    if (Index > 0) IndexPrevious = Index - 1;
                    if (Index < filestoshow.Count - 1) IndexNext = Index + 1;
                    IndexActual = Index;
                    if (Panel_Content.Visible)
                    {
                        ModImage.Visible = false;
                        ModInline.Visible = false;
                        switch (_link)
                        {
                            default:
                            case LINK.NONE:
                                break;
                            case LINK.FRAME:
                            case LINK.INLINE:
                                if (IsImage(Extension))
                                {
                                    ModImage.Visible = true;
                                    ModImage.PathToImage = GetPathFromRelativePath(_Pat + fi);
                                    ModImage.Image = GetNameFromRelativePath(_Pat + fi);
                                    ModImage.UseLightBox = "1";
                                    ModImage.Cap = fi;
                                    break;
                                }
                                if (IsCode(Extension))
                                {
                                    if (_Src)
                                    {
                                        ModInline.Mode = "high";
                                        ModInline.Visible = true;
                                        ModInline.Pat = GetPathFromRelativePath(_Pat + fi);
                                        ModInline.Fil = GetNameFromRelativePath(_Pat + fi);
                                        ModInline.Cap = fi;
                                    }
                                    else
                                    {
                                        ModInline.Visible = true;
                                        ModInline.Pat = GetPathFromRelativePath(_Pat + fi);
                                        ModInline.Fil = GetNameFromRelativePath(_Pat + fi);
                                        ModInline.Cap = fi;
                                        ModInline.Mode = "frame";
                                        /*
                                        if (Mod.IsInList(Extension, RequiresServer))
                                        {
                                            bool forceframe = true;
                                            ModInline.Mode = (forceframe ? "frame" : "http");
                                        }
                                        else
                                        {
                                            ModInline.Mode = "raw";
                                        }
                                         */
                                    }
                                    break;
                                }
                                break;
                        }
                    }
                }
                string TextToDisplay = fi;

                switch (_menu)
                {
                    case MENU.PREVNEXT:
                        break;
                    case MENU.BOTH:
                    case MENU.VERTICAL:
                        switch (_link)
                        {
                            case LINK.NONE:
                                TreeView_Directory.Nodes.Add(new TreeNode(GetNameCheckExtension(TextToDisplay, Index, IndexToShow), "0", "", "", ""));
                                break;
                            case LINK.FRAME:
                                TreeView_Directory.Nodes.Add(new TreeNode(GetNameCheckExtension(TextToDisplay, Index, IndexToShow), "0", "", Request.CurrentExecutionFilePath + "?" + GetQSParts(Index, fi), "_self"));
                                break;
                            case LINK.BLANK:
                                TreeView_Directory.Nodes.Add(new TreeNode(GetNameCheckExtension(TextToDisplay, Index, IndexToShow), "0", "", _Pat + Name, "_blank"));
                                break;
                            case LINK.INLINE:
                                TreeView_Directory.Nodes.Add(new TreeNode(GetNameCheckExtension(TextToDisplay, Index, IndexToShow), "0", "", Request.CurrentExecutionFilePath + "?" + GetQSParts(Index, fi), "_self"));
                                break;
                            default:
                                TreeView_Directory.Nodes.Add(new TreeNode(GetNameCheckExtension(TextToDisplay, Index, IndexToShow), "0", "", (_Recursive ? _Pat + Name : _Pat + fi) + "?" + GetQSParts(Index, fi), _Target));
                                break;
                        }
                        break;
                }
                Index++;
            }
            switch (_menu)
            {
                case MENU.PREVNEXT:
                case MENU.BOTH:
                    if (IndexPrevious > -1)
                    {
                        switch (_link)
                        {
                            case LINK.NONE:
                                break;
                            case LINK.FRAME:
                                HyperLink_Previous.NavigateUrl = "/Src.aspx?" + GetQSParts(Index, filestoshow[IndexActual]);
                                HyperLink_Next.Target="frame";
                                break;
                            case LINK.BLANK:
                                HyperLink_Previous.NavigateUrl = "/Src.aspx?" + GetQSParts(Index, filestoshow[IndexActual]);
                                HyperLink_Next.Target="_blank";
                                break;
                            case LINK.INLINE:
                                HyperLink_Previous.NavigateUrl = Request.CurrentExecutionFilePath + "?" + GetQSParts(IndexPrevious, filestoshow[IndexActual]);
                                break;
                            default:
                                HyperLink_Previous.NavigateUrl = (_Recursive ? _Pat + GetName(filestoshow[IndexPrevious], RelativePath) : _Pat + filestoshow[IndexPrevious]) + "?" + GetQSParts(IndexPrevious, filestoshow[IndexActual]);
                                break;
                        }
                        HyperLink_Previous.Target = _Target;
                    }
                    if (IndexNext > -1)
                    {
                        switch (_link)
                        {
                            case LINK.NONE:
                                break;
                            case LINK.FRAME:
                                HyperLink_Next.NavigateUrl = "/Src.aspx?" + GetQSParts(Index, filestoshow[IndexActual]);
                                HyperLink_Next.Target="frame";
                                break;
                            case LINK.BLANK:
                                HyperLink_Next.NavigateUrl = "/Src.aspx?" + GetQSParts(Index, filestoshow[IndexActual]);
                                HyperLink_Next.Target = "_blank";
                                break;
                            case LINK.INLINE:
                                HyperLink_Next.NavigateUrl = Request.CurrentExecutionFilePath + "?" + GetQSParts(IndexNext, filestoshow[IndexActual]);
                                break;
                            default:
                                HyperLink_Next.NavigateUrl = (_Recursive ? _Pat + GetName(filestoshow[IndexNext], RelativePath) : _Pat + filestoshow[IndexNext]) + "?" + GetQSParts(IndexNext, filestoshow[IndexActual]);
                                break;
                        }
                        HyperLink_Next.Target = Target;
                    }
                    break;
                case MENU.VERTICAL:
                    break;
            }
            TreeView_Directory.Visible = false;
            Panel_PrevNext.Visible = false;
            switch (_menu)
            {
                case MENU.PREVNEXT:
                    Panel_PrevNext.Visible = true;
                    break;
                case MENU.BOTH:
                    TreeView_Directory.Visible = true;
                    Panel_PrevNext.Visible = true;
                    break;
                case MENU.VERTICAL:
                    TreeView_Directory.Visible = true;
                    break;
            }
        }
        string GetQSParts(int Index, string Name)
        {
            return "id=" + Index + "&fil=" + Name + "&mod=directory&recursive=" + (_Recursive ? "1" : "0") + "&noext=" + (_NoExt ? "1" : "0") + "&pat=" + _Pat + "&showfile=" + _showfile + "&link=" + _link + "&src=" + Src;
        }
    }
}