using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Web.Configuration;
using System.Web.UI;
using System.Xml;
using System.Xml.Xsl;

namespace ExWeb
{
    public partial class Mod
    {
        public static SortedList<string, string> GetQs(Page p)
        {
            NameValueCollection nvc = new NameValueCollection(p.Request.QueryString);
            SortedList<string, string> list = new SortedList<string, string>();
            for (int i = 0; i < nvc.Count; i++)
            {
                //for (int j = 0; j < nvc.Keys.Count; j++)
                //{
                string Key = nvc.Keys[i];
                list.Add(Key, nvc[Key]);
                //}
            }
            return list;
        }
        public enum FILETYPE { ALL, IMAGE, CODE, WEB };
        public static string GetConfigString(string key)
        {
            NameValueCollection nvc = WebConfigurationManager.AppSettings;
            return nvc[key];
        }
        public static string[] GetConfigStringList(string key, bool ToLower)
        {
            string Value = GetConfigString(key);
            string[] Values = Value.Split(new char[] { ',' });
            for (int i = 0; i < Values.Length; i++)
            {
                Values[i] = Values[i].Trim();
                if (ToLower) Values[i] = Values[i].ToLower();
            }
            return Values;
        }
        public static bool IsImage(string Extension)
        {
            return IsInList(Extension, GetConfigStringList("Ext_Image", true));
        }
        public static bool IsCode(string Extension)
        {
            return IsInList(Extension, GetConfigStringList("Ext_Code", true));
        }
        public static bool IsInList(string Extension, FILETYPE filetype)
        {
            switch (filetype)
            {
                default:
                case FILETYPE.ALL:
                    return true;
                case FILETYPE.IMAGE:
                    return IsInList(Extension, GetConfigStringList("Ext_Image", true));
                case FILETYPE.CODE:
                    return IsInList(Extension, GetConfigStringList("Ext_Code", true));
                case FILETYPE.WEB:
                    return IsInList(Extension, GetConfigStringList("Ext_Web", true));
            }
            return true;
        }
        public static bool IsInList(string Extension, string[] strList)
        {
            if (!Extension.StartsWith(".")) Extension = "." + Extension;
            for (int i = 0; i < strList.Length; i++)
            {
                if (Extension == strList[i])
                    return true;
            }
            return false;
        }
        public static string MakeLink(string strText, string strPath, string strTarget)
        {
            if ((strText == "") && (strPath == "")) return "";
            if (strPath == "") return strText;
            if (strText == "") strText = strPath;
            return "<a href=\"" + strPath + "\" target=\"" + strTarget + "\">" + strText + "</a>";
        }
        public static string Untag(string Html)
        {
            return Html.Replace("<", "<").Replace(">", ">");
        }
        public static List<string> GetFiles(Page p, string _ModPath, string _Pattern, bool Recursive, FILETYPE filetype)
        {
            return FilterFiles(GetFiles(p, _ModPath, _Pattern, Recursive), filetype);
        }
        public static List<string> FilterFiles(List<string> files, FILETYPE filetype)
        {
            List<string> files_selected = new List<string>();
            switch (filetype)
            {
                case FILETYPE.ALL:
                    return files;
                case FILETYPE.CODE:
                case FILETYPE.WEB:
                case FILETYPE.IMAGE:
                    for (int i = 0; i < files.Count; i++)
                    {
                        string Extension = Path.GetExtension(files[i]);
                        if (IsInList(Extension, filetype))
                            files_selected.Add(files[i]);
                    }
                    break;
            }
            return files_selected;
        }
        public static List<string> GetFiles(Page p, string _ModPath, string _Pattern, bool Recursive)
        {
            List<string> Files = new List<string>();
            string AbsolutePath = "";

            if (_ModPath == null) _ModPath = "";
            if (_ModPath == "")
            {
                _ModPath = p.Request.AppRelativeCurrentExecutionFilePath;
                _ModPath = _ModPath.Substring(0, _ModPath.LastIndexOf("/") + 1);
                if (_ModPath.StartsWith("~")) _ModPath = _ModPath.Substring(1);
                AbsolutePath = p.Server.MapPath(_ModPath);
                AbsolutePath = Path.GetDirectoryName(AbsolutePath);
            }
            else
            {
                AbsolutePath = p.Server.MapPath(_ModPath);
            }
            if (!_ModPath.EndsWith("/")) _ModPath += "/";

            DirectoryInfo diri = new DirectoryInfo(AbsolutePath);
            if (!diri.Exists)
            {
                return Files;
            }

            FileSystemInfo[] fsi = diri.GetFileSystemInfos(_Pattern, (Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly));
            for (int i = 0; i < fsi.Length; i++)
            {
                FileSystemInfo fsii = fsi[i];
                if ((fsii.Attributes & FileAttributes.Directory) == FileAttributes.Directory) // dont show directories
                    continue;
                string[] PathParts = fsi[i].FullName.Split(new char[] { '/', '\\' });
                bool ForbiddenElement = false;
                for (int j = 0; j < PathParts.Length; j++)
                    if (PathParts[j].StartsWith(".")) // Directories and files starting with "." are forbidden
                    {
                        ForbiddenElement = true;
                        break;
                    }
                if (!ForbiddenElement)
                    Files.Add(GetPathRelative(fsi[i].FullName, _ModPath));
            }
            return Files;
        }
        public static string GetQs_String(string key, string value0, Page p)
        {
            string Value = p.Request.QueryString[key];
            if (Value == null) Value = "";
            return (Value == "" ? value0 : Value);
        }
        public static int GetQs_Int(string key, int value0, Page p)
        {
            string Value = p.Request.QueryString[key];
            int iValue = value0;
            int.TryParse(Value, out iValue);
            return iValue;
        }
        public static bool GetQs_Bool(string key, bool value0, Page p)
        {
            string Value = p.Request.QueryString[key];
            if (Value == null) return value0;
            if (Value == "1") return true;
            if (Value == "0") return false;
            return value0;
        }
        public static string GetPathRelative(string AbsolutePath, string RelativePath)
        {
            string RelativePathAndFileName = "";
            AbsolutePath = AbsolutePath.ToLower().Replace("\\", "/");
            RelativePath = RelativePath.ToLower().Replace("\\", "/");
            if (!RelativePath.EndsWith("/")) RelativePath += "/";
            int Position = AbsolutePath.LastIndexOf(RelativePath);
            if (Position >= 0) RelativePathAndFileName = AbsolutePath.Substring(Position + RelativePath.Length);
            if (RelativePathAndFileName == null) RelativePathAndFileName = "";
            return RelativePathAndFileName;
        }
        public static string GetPathFromRelativePath(string RelativePath)
        {
            string RPath = "";
            if (!RelativePath.Contains("/")) return "";
            RPath = RelativePath.Substring(0, RelativePath.LastIndexOf("/"));
            if (!RPath.EndsWith("/")) RPath += "/";
            return RPath;
        }
        public static string GetNameFromRelativePath(string RelativePath)
        {
            string Name = "";
            if (!RelativePath.Contains("/")) return Name;
            Name = RelativePath.Substring(RelativePath.LastIndexOf("/") + 1);
            return Name;
        }
        // http://stackoverflow.com/questions/1879395/how-to-generate-a-stream-from-a-string
        public static Stream GenerateStreamFromString(string s)
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }
        // http://www.dpawson.co.uk/xsl/sect2/pretty.html
        public static string XlsIndent = 
            "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
            + "<xsl:output method=\"xml\" indent=\"yes\" /> <!-- here's the trick -->"
            + "<xsl:template match=\"*\">"
            + "   <xsl:copy>"
            + "      <xsl:copy-of select=\"@*\" />"
            + "      <xsl:apply-templates />"
            + "   </xsl:copy>"
            + "</xsl:template>"
            + " <xsl:template match=\"comment()|processing-instruction()\">"
            + "   <xsl:copy />"
            + "</xsl:template>"
            + "</xsl:stylesheet>";
        public static string XmlIndent(string Xml)
        {
            return XmlXslTransform(Xml, XlsIndent);
        }
        public static string XmlXslTransform(string Xml, string Xsl)
        {
            // format // http://www.ezzylearning.com/tutorial.aspx?tid=7913273

            Stream strm = Mod.GenerateStreamFromString(Xml);
            XmlReader xmlr = XmlReader.Create(strm);

            Stream strm_Xls = Mod.GenerateStreamFromString(Xsl);
            XmlReader xmlr_Xmls = XmlReader.Create(strm_Xls);

            XslCompiledTransform processor = new XslCompiledTransform();
            processor.Load(xmlr_Xmls);
            MemoryStream ms = new MemoryStream();
            processor.Transform(xmlr, null, ms);
            ms.Seek(0, SeekOrigin.Begin);
            StreamReader reader_o = new StreamReader(ms);
            string output = reader_o.ReadToEnd();
            ms.Close();
            return output;
        }
    }
}