using UUN;
using System;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.Web;
using System.Text;

namespace UUN
{
    /// <summary>
    /// 表一个页面系统中的页面
    /// </summary>
    public class 页面
    {
        public bool 是否内容;

        public int ID;
        public int 上级ID;
        public String 页面名称;
        public bool 页面类型;
        public String 顶部代码;
        public String 底部代码;
        public bool 是否包含子节点;
        public String 对齐方式;

        public String XML位置
        {
            get
            {
                return HttpContext.Current.Server.MapPath("~/Template/" +
                (是否内容 ? "Content" : "Club") +
                "/" + 程序.设置["默认" + (是否内容 ? "" : "社区") + "模板"] +
                "/SystemPage/" + ID + ".xml");
            }
        }
        public String 代码位置
        {
            get
            {
                return "Template/" +
                (是否内容 ? "Content" : "Club") +
                "/" + 程序.设置["默认" + (是否内容 ? "" : "社区") + "模板"] +
                "/SystemPage_Aspx/" + ID;
            }
        }
        public String 管理代码位置
        {
            get
            {
                return "Template/" +
                (是否内容 ? "Content" : "Club") +
                "/" + 程序.设置["默认" + (是否内容 ? "" : "社区") + "模板"] +
                "/Adm_SystemPage_Aspx/" + ID;
            }
        }

        public Dictionary<String, 页面项> 页面项数据;

        public 页面()
        {

        }

        public 页面(int ID,bool 生成项数据,bool 是否内容)
        {
            this.ID = ID;
            this.是否内容 = 是否内容;

            String 代码内容 = File.ReadAllText(XML位置, Encoding.UTF8);
            XmlReader 读取 = XmlReader.Create(new StringReader(代码内容));
            while (读取.Read())
                if (读取.NodeType == XmlNodeType.Element && 读取.Name == "page")
                    break;

            上级ID = Convert.ToInt32(读取.GetAttribute("parentid"));
            页面名称 = 读取.GetAttribute("name");
            页面类型 = 读取.GetAttribute("type").ToLower() == "true";
            顶部代码 = 读取.GetAttribute("top");
            底部代码 = 读取.GetAttribute("bottom");
            是否包含子节点 = Convert.ToBoolean(读取.GetAttribute("haschild"));
            对齐方式 = 读取.GetAttribute("align");

            if (生成项数据)
            {
                页面项数据 = new Dictionary<string, 页面项>();
                while (读取.Read())
                    if (读取.NodeType==XmlNodeType.Element&&读取.Name == "item")
                        页面项数据.Add(读取.GetAttribute("index"), 生成页面项对象(读取));
            }

            读取.Close();
        }

        private 页面项 生成页面项对象(XmlReader 读取)
        {
            页面项 项 = new 页面项();
            项.索引=读取.GetAttribute("index");
            项.项名称 = 读取.GetAttribute("name");
            项.项类型 = 读取.GetAttribute("type");
            项.项内容 = 读取.GetAttribute("content").Split('"');
            项.项排序 = Convert.ToInt32(读取.GetAttribute("sort"));
            项.是否隐藏 = Convert.ToBoolean(读取.GetAttribute("ishidden"));
            项.是否换行 = Convert.ToBoolean(读取.GetAttribute("isbr"));

            项.是否WAP = 页面类型;

            for (int i = 0; i < 项.项内容.Length; i++)
                项.项内容[i] = HttpUtility.HtmlDecode(项.项内容[i]);

            return 项;
        }
        /// <summary>
        /// 将页面项上移一位
        /// </summary>
        /// <param name="项标识"></param>
        public void 上移项(String 项标识)
        {
            String 上项标识 = null;
            foreach (String Key in 页面项数据.Keys)
            {
                if (Key == 项标识)
                    break;
                上项标识 = Key;
            }

            if (上项标识 == null)
                return;

            Dictionary<String, 页面项> 新项数据 = new Dictionary<string, 页面项>();
            页面项 上项数据 = null;

            foreach (String Key in 页面项数据.Keys)
            {
                if (Key == 上项标识)
                {
                    上项数据 = 页面项数据[Key];
                    continue;
                }

                if (上项数据 != null)
                {
                    页面项 项数据 = 页面项数据[Key];
                    int 上项排序 = 上项数据.项排序;
                    上项数据.项排序 = 项数据.项排序;
                    项数据.项排序 = 上项排序;

                    新项数据.Add(项数据.索引, 项数据);
                    新项数据.Add(上项数据.索引, 上项数据);
                    上项数据 = null;
                }
                else
                    新项数据.Add(Key, 页面项数据[Key]);
            }

            页面项数据 = 新项数据;
        }
        /// <summary>
        /// 将页面项下移一位
        /// </summary>
        /// <param name="项标识"></param>
        public void 下移项(String 项标识)
        {
            Dictionary<String, 页面项> 新项数据 = new Dictionary<string, 页面项>();
            页面项 上项数据 = null;

            int i = 1;
            foreach (String Key in 页面项数据.Keys)
            {
                if (Key == 项标识&&i<页面项数据.Count)
                {
                    上项数据 = 页面项数据[Key];
                    continue;
                }

                if (上项数据 != null)
                {
                    页面项 项数据 = 页面项数据[Key];
                    int 上项排序 = 上项数据.项排序;
                    上项数据.项排序 = 项数据.项排序;
                    项数据.项排序 = 上项排序;

                    新项数据.Add(Key, 项数据);
                    新项数据.Add(上项数据.索引, 上项数据);
                    上项数据 = null;
                }
                else
                    新项数据.Add(Key, 页面项数据[Key]);
                i++;
            }

            页面项数据 = 新项数据;
        }
        /// <summary>
        /// 更改页面排序后重新排序
        /// </summary>
        public void 更新排序()
        {
            if (页面项数据.Count < 1)
                return;

            页面项[] 页面项数组 = new 页面项[页面项数据.Count];
            int i2 = 0;
            foreach (String 键 in 页面项数据.Keys)
            {
                页面项数组[i2] = 页面项数据[键];
                i2++;
            }

            for (int i = 0; i < 页面项数组.Length; i++)
                for (int i1 = 0; i1 < 页面项数组.Length - i - 1; i1++)
                    if (页面项数组[i1].项排序 > 页面项数组[i1 + 1].项排序)
                    {
                        页面项 项 = 页面项数组[i1];
                        页面项数组[i1] = 页面项数组[i1 + 1];
                        页面项数组[i1 + 1] = 项;
                    }


            页面项数据 = new Dictionary<string, 页面项>();
            for (int i = 0; i < 页面项数组.Length; i++)
            {
                页面项 项 = 页面项数组[i];
                页面项数据.Add(项.索引, 项);
            }
        }
        /// <summary>
        /// 将页面项重新排序
        /// </summary>
        public void 重新排序()
        {
            int i = 1;
            foreach (String Key in 页面项数据.Keys)
            {
                页面项数据[Key].项排序 = i;
                i++;
            }
        }
        /// <summary>
        /// 获取页面项的最高排序
        /// </summary>
        /// <returns></returns>
        public int 最高排序()
        {
            if (页面项数据.Count == 0)
                return 1;
            else
            {
                int 返回值 = 0;
                foreach (String Key in 页面项数据.Keys)
                    返回值 = 页面项数据[Key].项排序;
                return 返回值 + 1;
            }
        }
        /// <summary>
        /// 将页面对象转换成XML文本格式
        /// </summary>
        /// <returns></returns>
        public String 生成XML代码()
        {
            StringBuilder 返回值 = new StringBuilder();
            
            XmlWriterSettings XWS = new XmlWriterSettings();
            XWS.Indent = true;
            XWS.ConformanceLevel = ConformanceLevel.Auto;
            XWS.IndentChars = "\t";

            XmlWriter 写入 = XmlWriter.Create(返回值, XWS);
            写入.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");
            写入.WriteStartElement("xml");

            写入.WriteStartElement("page");

            写入.WriteAttributeString("id", this.ID.ToString());
            写入.WriteAttributeString("parentid", this.上级ID.ToString());
            写入.WriteAttributeString("name", this.页面名称);
            写入.WriteAttributeString("type", this.页面类型.ToString());
            写入.WriteAttributeString("top", this.顶部代码);
            写入.WriteAttributeString("bottom", this.底部代码);
            写入.WriteAttributeString("haschild", this.是否包含子节点.ToString());
            写入.WriteAttributeString("align", this.对齐方式);

            foreach (String 键 in 页面项数据.Keys)
                页面项数据[键].生成XML代码(写入);

            写入.WriteEndElement();

            写入.WriteEndElement();
            写入.Close();

            return 返回值.ToString();
        }
        /// <summary>
        /// 将页面保存
        /// </summary>
        public void 保存XML代码()
        {
            File.WriteAllText(XML位置, 生成XML代码(), Encoding.UTF8);
        }
        /// <summary>
        /// 将页面对象生成为模板代码
        /// </summary>
        /// <returns></returns>
        public String 生成代码()
        {
            String 返回值= 顶部代码.Replace("{$CMS:页面名称$}", HttpUtility.HtmlEncode(页面名称))
                .Replace("{$CMS:对齐方式$}", 对齐方式);

            foreach (String 键 in 页面项数据.Keys)
                if (!页面项数据[键].是否隐藏)
                {
                    返回值 += 页面项数据[键].生成代码();
                    if (页面项数据[键].是否换行)
                        返回值 += "<br/>";
                }

            返回值 += 底部代码.Replace("{$CMS:上级页面$}", this.上级ID.ToString())
                .Replace("{$CMS:上级页面名称$}", 上级ID==0?"":HttpUtility.HtmlEncode(new 页面(上级ID, false, 是否内容).页面名称))
                .Replace("{$CMS:包含上级页面$}", @"
{$aspx
if("+上级ID+@">2)
{

$}
")
                .Replace("{$CMS:/包含上级页面$}", @"
{$aspx
}
$}
");

            return 返回值;
        }
        /// <summary>
        /// 将页面对象编译成.NET文件并保存
        /// </summary>
        public void 保存代码(访问 访问)
        {
            编译器 编译 = new 编译器(访问.HC, 访问.连接, "页面相关", 页面类型);
            编译.开始执行代码 = 编译.开始执行代码.Replace("$所在位置$", 页面名称)
                .Replace("$内容类型$", "网站页面")
                .Replace("$内容小类型$", 页面名称);

            String ASPX代码, CS代码;
            CS代码 = 编译.编译(生成代码(), 代码位置, out ASPX代码);
            File.WriteAllText(访问.HC.Server.MapPath("~/" + 代码位置 + ".aspx"), ASPX代码, Encoding.UTF8);
            File.WriteAllText(访问.HC.Server.MapPath("~/" + 代码位置 + ".aspx.cs"), CS代码, Encoding.UTF8);
        }
        /// <summary>
        /// 将页面对象编译成管理代码
        /// </summary>
        /// <returns></returns>
        public String 生成管理代码()
        {
            String 返回值 = @"
<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" ""DTD/xhtml1-strict.dtd"">
<html xmlns=""http://www.w3.org/1999/xhtml"">
<head>
<meta http-equiv=""cache-control"" content=""no-cache""/>
<meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8"" />
<title>管理</title>
</head>
<body>
<div>";
            /*
<style type=""text/css""> 
<!--
A {FONT-SIZE: 9pt; COLOR: #339933; TEXT-DECORATION: none;WIDTH:100%}
A:link {TEXT-DECORATION: none}
A:visited {TEXT-DECORATION: none}
A.normal {FONT-SIZE: 9pt; COLOR: #bb0011; TEXT-DECORATION: none}
A.normal:hover {COLOR: #0000ff; TEXT-DECORATION: none}
TD {FONT-SIZE: 9pt; LINE-HEIGHT: 11pt}
SELECT {FONT-SIZE: 9pt; BACKGROUND-COLOR: #eeeeee; TEXT-ALIGN: center}
SELECT.smallselsect {FONT-SIZE: 9pt; COLOR: rgb(0,0,128)}
TH {FONT-WEIGHT: bold; FONT-SIZE: 11pt}
.input {BORDER-RIGHT: #000000 2px dotted; BORDER-TOP: #000000 2px dotted; FONT-SIZE: 9pt; BORDER-LEFT: #000000 2px dotted; BORDER-BOTTOM: #000000 2px dotted; BACKGROUND-COLOR: #ffffff; TEXT-ALIGN: center}
INPUT.smallinput {FONT-SIZE: 9pt; COLOR: rgb(0,0,128); HEIGHT: 12pt}
.comm {BACKGROUND-COLOR: #fff2ac}
FONT.bigfont {FONT-SIZE: 11pt; FONT-FAMILY: ""宋体""; TEXT-DECORATION: none}
TEXTAREA.smallarea {FONT-SIZE: 9pt; COLOR: rgb(0,0,128); BACKGROUND-COLOR: white}
.shadow {FONT-SIZE: 9pt; FILTER: dropshadow(color=""#000011"", offx=1, offy=1, positive=2); MARGIN: 10px; WIDTH: 100%; COLOR: #aaaaaa; POSITION: relative}
.3d {FONT-SIZE: 9pt; FILTER: glow(color=ffffff,strength=1) shadow(color=#aaaaaa,direction:90); MARGIN: 0px; WIDTH: 100%; COLOR: #3333ff; POSITION: relative}
.menuitems {PADDING-RIGHT: 15px; PADDING-LEFT: 5px; FONT-SIZE: 9pt; CURSOR: hand; COLOR: black; FONT-FAMILY: ""宋体""}
.skin {BORDER-RIGHT: buttonhighlight 2px outset; BORDER-TOP: buttonhighlight 2px outset; FONT-SIZE: 10pt; VISIBILITY: hidden; BORDER-LEFT: buttonhighlight 2px outset; WIDTH: 120px; CURSOR: default; LINE-HEIGHT: 18px; BORDER-BOTTOM: buttonhighlight 2px outset; FONT-FAMILY: ""宋体""; POSITION: absolute; BACKGROUND-COLOR: menu; TEXT-ALIGN: left}
-->
</style>
 
<SCRIPT language=""JavaScript""> 
<!--

function showmenuie5() {

            var menustr=""<a class=\""menuitems\"" target=\""XinXi\"" url=\""YeMian/ZengJiaWenJianJia.aspx?ti=_\"">　增加文件夹</a><br/>"";
            menustr+=""<hr/>""
            menustr+=""<a class=\""menuitems\"" target=\""XinXi\"" url=\""YeMian/ZengJiaWAPWenJian.aspx?ti=_\"">　增加WAP文件</a><br/>"";
            menustr+=""<a class=\""menuitems\"" target=\""XinXi\"" url=\""YeMian/ZengJia3GWenJian.aspx?ti=_\"">　增加3G文件</a>"";
            menustr+=""<a class=\""menuitems\"" target=\""XinXi\"" url=\""YeMian/DPage_Add.aspx?ti=_\"">　增加动态文件</a>"";
            ie5menu.innerHTML=menustr;
    
    var rightedge = document.body.clientWidth-event.clientX;
    var bottomedge = document.body.clientHeight-event.clientY;
    if (rightedge < ie5menu.offsetWidth)
        ie5menu.style.left = document.body.scrollLeft + event.clientX - ie5menu.offsetWidth;
    else
        ie5menu.style.left = document.body.scrollLeft + event.clientX;
    if (bottomedge < ie5menu.offsetHeight)
        ie5menu.style.top = document.body.scrollTop + event.clientY - ie5menu.offsetHeight;
    else
        ie5menu.style.top = document.body.scrollTop + event.clientY;

    ie5menu.style.visibility='visible';
}
//-->
</script>
<script type=""text/javascript"">
function showmenu(pid_)
{
pid=pid_;
showmenuie5();
}
function hidemenu()
{
hidemenuie5();
}
</script>
</head>
<body>
<div><div class=""skin"" id=""ie5menu"" style=""filter:alpha(opacity=0); position:absolute; width:120px; height:5px; z-index:2; visibility: hidden; left: 0px; top: 0px;""> 
 
</div>
";*/

            foreach (String 键 in 页面项数据.Keys)
                if (!页面项数据[键].是否隐藏)
                {
                    返回值 += 页面项数据[键].生成管理代码();
                    if (页面项数据[键].是否换行)
                        返回值 += "<br/>";
                }

            返回值 += @"
</div>
</body>
</html>
";

            return 返回值;
        }
        /// <summary>
        /// 将页面对象编译成管理代码并保存
        /// </summary>
        public void 保存管理代码(访问 访问)
        {
            编译器 编译 = new 编译器(访问.HC, 访问.连接, "页面相关", false);
            编译.开始执行代码 = 编译.开始执行代码.Replace("$所在位置$", 页面名称)
                .Replace("$内容类型$", "网站页面")
                .Replace("$内容小类型$", 页面名称);

            String ASPX代码, CS代码;
            CS代码 = 编译.编译(生成管理代码(), 代码位置, out ASPX代码);
            File.WriteAllText(访问.HC.Server.MapPath("~/" + 管理代码位置 + ".aspx"), ASPX代码, Encoding.UTF8);
            File.WriteAllText(访问.HC.Server.MapPath("~/" + 管理代码位置 + ".aspx.cs"), CS代码, Encoding.UTF8);
        }
    }
}