using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;


namespace UUN
{
    /// <summary>
    /// 列表分页代码的编译
    /// </summary>
    public class 列表分页代码
    {
        private String 代码内容;
        private String _3G代码内容;
        public String 方法库 = "";
        public String _3G方法库 = "";
        public bool 是否内容;
        public 列表分页代码(String 代码内容, String _3G代码内容)
        {
            this.代码内容 = 代码内容.Replace("~/", 程序.安装位置);
            this._3G代码内容 = _3G代码内容.Replace("~/", 程序.安装位置);
        }
        /// <summary>
        /// 将列表分页代码编译成ASP.NET代码
        /// </summary>
        /// <param name="编译结果">代码内容的编译结果</param>
        /// <param name="_3G编译结果">3G代码内容的编译结果</param>
        public void 生成代码(out String 编译结果, out String _3G编译结果)
        {
            编译结果 = 编译代码(false);
            _3G编译结果 = 编译代码(true);
        }
        private String 编译代码(bool 是否3G)
        {
            String 返回值 = "";

            bool 文本_代码 = true;
            String 文本 = "";
            String 代码 = "";

            Char 上个字符 = '\0';
            Char[] 字符 = new char[1];
            int 读取数;
            StringReader 读取 = new StringReader(是否3G?_3G代码内容:代码内容);
            while ((读取数 = 读取.Read(字符, 0, 1)) > 0)
            {
                if (文本_代码 && 字符[0] == '$' && 上个字符 == '{')
                {
                    文本 = 文本.Substring(0, 文本.Length - 1);
                    if (文本 != "")
                        返回值 += "\t\t返回值.Append(@\"" + 文本.Replace("\"", "\"\"") + "\");\r\n";
                    文本_代码 = false;
                    文本 = "";
                    上个字符 = 字符[0];
                    continue;
                }
                if ((!文本_代码) && 字符[0] == '}' && 上个字符 == '$')
                {
                    代码 = 代码.Substring(0, 代码.Length - 1);
                    返回值 += 编译代码段(代码, 是否3G);
                    文本_代码 = true;
                    代码 = "";
                    上个字符 = 字符[0];
                    continue;
                }
                if (文本_代码)
                    文本 += 字符[0].ToString();
                else
                    代码 += 字符[0].ToString();
                上个字符 = 字符[0];
            }
            返回值 += "\t\t返回值.Append(@\"" + 文本.Replace("\"", "\"\"") + "\");\r\n";
            读取.Close();

            return 返回值;
        }
        private String 编译代码段(String 代码,bool 是否3G)
        {
            String 返回值 = "";
            代码 = 代码.Trim();

            if (代码.StartsWith("cms:", StringComparison.OrdinalIgnoreCase))
                返回值 = 编译_CMS(代码, 是否3G);
            else if (代码.StartsWith("aspx", StringComparison.OrdinalIgnoreCase))
                返回值 = 编译_ASPX(代码);
            else if (代码.StartsWith("cs", StringComparison.OrdinalIgnoreCase))
                返回值 = 编译_CS(代码);
            else if (代码.StartsWith("ubb", StringComparison.OrdinalIgnoreCase))
                返回值 = 编译_UBB(代码);

            return 返回值;
        }
        private String 编译_CMS(String 代码, bool 是否3G)
        {
            return 编译模板标签(代码.Substring(4), 是否3G);
        }
        private String 编译模板标签(String 代码, bool 是否3G)
        {
            if (代码.IndexOf("(") == -1)
                return 编译公共标签(代码.Trim(), 是否3G);
            else
            {
                Regex 表达式 = new Regex("^(.+?)\\((.+)\\)$", RegexOptions.Singleline);
                Match 结果 = 表达式.Match(代码);
                if (结果.Success)
                    return 编译模板方法(结果.Groups[1].Value, 结果.Groups[2].Value.Split(','), 是否3G);
                else
                    return "";
            }
        }
        private String 编译公共标签(String 代码, bool 是否3G)
        {
            String 返回值 = "";
            switch (代码)
            {
                case "当前页":
                    返回值 += "\t\t返回值.Append(当前页);\r\n";
                    break;
                case "总页数":
                    返回值 += "\t\t返回值.Append(总页数);\r\n";
                    break;
                case "总记录数":
                    返回值 += "\t\t返回值.Append(总记录数);\r\n";
                    break;
                case "上页地址":
                    返回值 += "\t\t返回值.Append(列表跳页(当前页-1));\r\n";
                    break;
                case "下页地址":
                    返回值 += "\t\t返回值.Append(列表跳页(当前页+1));\r\n";
                    break;
                case "当前地址":
                    返回值 += "\t\t返回值.Append(列表跳页(当前页));\r\n";
                    break;
                case "当前页面":
                    返回值 += "\t\t返回值.Append(当前页面);\r\n";
                    break;
                case "跳页表单项":
                    返回值 += "\t\t返回值.Append("+(是否3G?"_3G跳页表单项":"跳页表单项")+");\r\n";
                    break;
            }
            return 返回值;
        }
        private String 编译模板方法(String 方法名称,String[] 属性数组, bool 是否3G)
        {
            if (方法名称 == "余下全部")
                return 编译模板方法_余下全部(属性数组[0],
                    属性数组[1],
                    是否3G);
            String 返回值 = "";

            switch (方法名称)
            {
                case "页面定位":
                    返回值 += 编译模板方法_列表分页代码_页面定位((属性数组[0]),
                        属性数组[1],
                        Convert.ToInt32(属性数组[2]),
                        是否3G);
                    break;
                case "静态定位":
                    返回值 += 编译模板方法_列表分页代码_静态定位((属性数组[0]),
                        属性数组[1],
                        Convert.ToInt32(属性数组[2]),
                        是否3G);
                    break;
                case "偏移地址":
                    返回值 += 编译模板方法_列表分页代码_偏移地址((属性数组[0]),
                        属性数组[1],
                        Convert.ToInt32(属性数组[2]),
                        是否3G);
                    break;
                case "上页代码":
                    返回值 += 编译模板方法_列表分页代码_上页代码(属性数组[0],
                        属性数组[1],
                        是否3G);
                    break;
                case "下页代码":
                    返回值 += 编译模板方法_列表分页代码_下页代码(属性数组[0],
                        属性数组[1],
                        是否3G);
                    break;
                case "首页代码":
                    返回值 += 编译模板方法_列表分页代码_首页代码(属性数组[0],
                        属性数组[1],
                        是否3G);
                    break;
                case "尾页代码":
                    返回值 += 编译模板方法_列表分页代码_尾页代码(属性数组[0],
                        属性数组[1],
                        是否3G);
                    break;
            }
            return 返回值;
        }

        private String 生成代码项(Hashtable 代码列表, String 项代码)
        {
            String 返回值 = "";
            bool 文本_代码 = true;
            String 文本 = "";
            String 代码 = "";

            Char[] 字符 = new char[1];
            int 读取数;
            StringReader 读取 = new StringReader(项代码);
            while ((读取数 = 读取.Read(字符, 0, 1)) > 0)
            {
                if (字符[0] == '@')
                {
                    if (文本_代码)
                    {
                        返回值 += @"				返回值+=@""" + 文本.Replace("\"", "\"\"") + @""";
";
                        文本_代码 = false;
                        文本 = "";
                        continue;
                    }
                    else
                    {
                        if (代码列表.Contains(代码))
                            返回值 += @"				返回值+=" + 代码列表[代码] + @";
";
                        文本_代码 = true;
                        代码 = "";
                        continue;
                    }
                }
                if (文本_代码)
                    文本 += 字符[0].ToString();
                else
                    代码 += 字符[0].ToString();
            }
            if (文本 != "")
                返回值 += @"				返回值+=@""" + 文本.Replace("\"", "\"\"") + @""";
";
            return 返回值;
        }

        private String 编译模板方法_余下全部(String 包含余下全部代码, String 不包含余下全部代码,bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
	private String 余下全部"+随机值+ @"()
	{
		String 返回值="""";
		if(Request.QueryString[""yx""]==""1"")
		{
";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "生成余下全部地址()");
            方法库 += 生成代码项(代码列表, 不包含余下全部代码);
            方法库 += @"
		}
		else
		{
			if(当前页<总页数)
			{
";
            方法库 += 生成代码项(代码列表, 包含余下全部代码);
            方法库 += @"
			}
		}
		return 返回值;
	}
";
            if (!是否3G)
                this.方法库 += 方法库;
            else
                this._3G方法库 += 方法库;
            String 返回值 = "";
            返回值 += "\t\t返回值.Append(余下全部" + 随机值 + "());\r\n";
            return 返回值;
        }

        private String 编译模板方法_列表分页代码_页面定位(String 项代码, String 当前项代码, int 数量, bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
	private String 页面定位"+随机值+ @"()
	{
		String 返回值="""";
";
            int 前数值, 后数值;
            if (数量 % 2 == 0)
            {
                前数值 = 数量 / 2-1;
                后数值 = 数量 / 2;
            }
            else
            {
                前数值 = 数量 / 2;
                后数值 = 数量 / 2;
            }
            方法库 += @"		for(int i=当前页-"+前数值+";i<=当前页+"+后数值+ @";i++)
			if(i>0&&i<=总页数&&总页数>1)
				if(i==当前页)
				{
				";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "列表跳页(i)");
            代码列表.Add("位置", @"i.ToString()");
            方法库 += 生成代码项(代码列表, 当前项代码);
            方法库 += @"
				}
				else
				{
";
            方法库 += 生成代码项(代码列表, 项代码);

            方法库 += @"				}";
            方法库+=@"
		return 返回值;
	}
";
            if (是否3G)
                this._3G方法库 += 方法库;
            else
                this.方法库 += 方法库;

            String 返回值 = "";

            返回值 += "\t\t返回值.Append(页面定位"+随机值+"());\r\n";
            return 返回值;
        }

        private String 编译模板方法_列表分页代码_静态定位(String 项代码, String 当前项代码, int 数量, bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
	private String 静态定位" + 随机值 + @"()
	{
		String 返回值="""";
		int 数量=" + 数量 + ";\r\n";
            方法库 += @"		int 所在位置=当前页%数量==0?当前页/数量:当前页/数量+1;
		所在位置=所在位置-1;
";
            方法库 += @"		for(int i=(所在位置*数量)+1;i<=(所在位置*数量)+数量;i++)
			if(i>0&&i<=总页数&&总页数>1)
				if(i==当前页)
				{
";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "列表跳页(i)");
            代码列表.Add("位置", @"i.ToString()");
            方法库 += 生成代码项(代码列表, 当前项代码);
            方法库+= @"
				}
				else
				{
";
            方法库 += 生成代码项(代码列表, 项代码);
            方法库 += @"				}";
            方法库+=@"
		return 返回值;
	}
";
            if (是否3G)
                this._3G方法库 += 方法库;
            else
                this.方法库 += 方法库;
            String 返回值 = "";

            返回值 += "\t\t返回值.Append(静态定位" + 随机值 + "());\r\n";

            return 返回值;
        }

        private String 编译模板方法_列表分页代码_偏移地址(String 包含页面代码, String 不包含页面代码, int 数量, bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
		private String 偏移地址"+随机值+ @"()
		{
			String 返回值="""";
			int 页数=当前页+"+数量+@";
";
            方法库 += @"			if(页数>0&&页数<=总页数)
			{
";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "列表跳页(页数)");
            代码列表.Add("位置", "页数.ToString()");
            方法库 += 生成代码项(代码列表, 包含页面代码);
            方法库 += @"
			}
			else
			{
";
            方法库 += 生成代码项(代码列表, 不包含页面代码);
            方法库 += @"
			}
";
            方法库+= @"
			return 返回值;
		}
";
            if (是否3G)
                this._3G方法库 += 方法库;
            else
                this.方法库 += 方法库;
            String 返回值 = "";
            返回值 += "\t\t返回值.Append(偏移地址" + 随机值 + "());\r\n";
            return 返回值;
        }

        private String 编译模板方法_列表分页代码_上页代码(String 包含上页代码, String 不包含上页代码,bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
		private String 上页代码"+随机值+ @"()
		{
			String 返回值="""";
			int 页数=当前页-1;
";
            方法库 += @"			if(当前页>1)
			{
";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "列表跳页(页数)");
            代码列表.Add("位置", "页数.ToString()");
            方法库 += 生成代码项(代码列表, 包含上页代码);
            方法库 += @"
			}
			else
			{
";
            方法库 += 生成代码项(代码列表, 不包含上页代码);
            方法库+=@"
			}
";
            方法库+= @"
			return 返回值;
		}
";
            if (是否3G)
                this._3G方法库 += 方法库;
            else
                this.方法库 += 方法库;
            String 返回值 = "";
            返回值 += "\t\t返回值.Append(上页代码" + 随机值 + "());\r\n";
            return 返回值;
        }

        private String 编译模板方法_列表分页代码_下页代码(String 包含下页代码, String 不包含下页代码,bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
		private String 下页代码"+随机值+ @"()
		{
			String 返回值="""";
			int 页数=当前页+1;
";
            方法库 += @"			if(当前页<总页数)
			{
";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "列表跳页(页数)");
            代码列表.Add("位置", "页数.ToString()");
            方法库 += 生成代码项(代码列表, 包含下页代码);
            方法库 += @"
			}
			else
			{
";
            方法库 += 生成代码项(代码列表, 不包含下页代码);
            方法库+=@"
			}
";
            方法库 += @"
			return 返回值;
		}
";
            if (是否3G)
                this._3G方法库 += 方法库;
            else
                this.方法库 += 方法库;
            String 返回值 = "";
            返回值 += "\t\t返回值.Append(下页代码" + 随机值 + "());\r\n";
            return 返回值;
        }

        private String 编译模板方法_列表分页代码_首页代码(String 包含首页代码, String 不包含首页代码,bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
		private String 首页代码" + 随机值 + @"()
		{
			String 返回值="""";
			int 页数=1;
";
            方法库 += @"			if(当前页!=1)
			{
";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "列表跳页(页数)");
            代码列表.Add("位置", "页数.ToString()");
            方法库 += 生成代码项(代码列表, 包含首页代码);
            方法库 += @"
			}
			else
			{
";
            方法库 += 生成代码项(代码列表, 不包含首页代码);
            方法库 += @"
			}
";
            方法库 += @"
			return 返回值;
		}
";
            if (是否3G)
                this._3G方法库 += 方法库;
            else
                this.方法库 += 方法库;
            String 返回值 = "";
            返回值 += "\t\t返回值.Append(首页代码" + 随机值 + "());\r\n";
            return 返回值;
        }

        private String 编译模板方法_列表分页代码_尾页代码(String 包含尾页代码, String 不包含尾页代码,bool 是否3G)
        {
            String 随机值 = 常用.随机字符(8);
            String 方法库 = "";
            方法库 += @"
		private String 尾页代码" + 随机值 + @"()
		{
			String 返回值="""";
			int 页数=总页数;
";
            方法库 += @"			if(当前页!=总页数)
			{
";
            Hashtable 代码列表 = new Hashtable();
            代码列表.Add("地址", "列表跳页(页数)");
            代码列表.Add("位置", "页数.ToString()");
            方法库 += 生成代码项(代码列表, 包含尾页代码);
            方法库 += @"
			}
			else
			{
";
            方法库 += 生成代码项(代码列表, 不包含尾页代码);
            方法库 += @"
			}
";
            方法库 += @"
			return 返回值;
		}
";
            if (是否3G)
                this._3G方法库 += 方法库;
            else
                this.方法库 += 方法库;
            String 返回值 = "";
            返回值 += "\t\t返回值.Append(尾页代码" + 随机值 + "());\r\n";
            return 返回值;
        }

        private String 编译_ASPX(String 代码)
        {
            if (代码.StartsWith("aspx="))
                return "\t\t返回值.Append(" + 代码.Substring(5) + ");\r\n";
            else
                return 代码.Substring(4);
        }
        private String 编译_CS(String 代码)
        {
            方法库 += 代码.Substring(2);
            return "";
        }
        private String 编译_UBB(String 代码)
        {
            return "\t\t返回值.Append(常用.UBB转换(@\"" + 代码.Substring(3).Replace("\"", "\"\"") + "\",访问.用户));\r\n";
        }
    }
}