using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using ICSharpCode.Core;
using Mesnac.Action.Base;
using Mesnac.Basic;
using Mesnac.Codd.Session;
using Mesnac.Controls.Base;

namespace Mesnac.Action.Default.Purview
{

    /// <summary>
    /// 窗体、控件权限信息加载类
    /// 创建人:郑立兵
    /// 创建时间:2013-7-25
    /// 说明:从工程文件中加载窗体、控件权限信息至数据表中
    /// </summary>
    public class LoadPurview : DatabaseAction , IAction
    {
        private string caption = StringParser.Parse(ResourceService.GetString("Mesnac_Dialog_Caption"));    //提示

        private string _projectPath = Path.Combine( Application.StartupPath , "Data" , "MCProject" , "nodeForm" );   //组态工程路径
        List<FormPurview> listPurview = null;

        public void Run(RuntimeParameter runtime)
        {
            base.RunIni(runtime);//必须调用
            string msg1 = StringParser.Parse(ResourceService.GetString("Mesnac_Action_Default_Purview_LoadPurview_msg1"));  //您确定重新加载所有权限?
            string msg2 = StringParser.Parse(ResourceService.GetString("Mesnac_Action_Default_Purview_LoadPurview_msg2"));  //重要警告
            if (MessageBox.Show(msg1, msg2, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
            {
                return;
            }
            ICSharpCode.Core.LoggingService<LoadPurview>.Debug("通用方法——将权限窗体加载至数据库");

            DbHelper dbHelper = NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Local);
            if (dbHelper == null)
            {
                return;
            }
            dbHelper.ClearParameter();
            dbHelper.CommandType = CommandType.Text;
            dbHelper.CommandText = "UPDATE BasForm SET DeleteFlag='1';UPDATE BasFormFunction SET DeleteFlag='1';";
            dbHelper.ExecuteNonQuery();

            listPurview = new List<FormPurview>();

            #region 命令
            Dictionary<string, List<string>> dic = XmlHandler.GetProjectCommands(Path.Combine(Application.StartupPath, "Data", "MCProject"));
            foreach (string actionname in dic.Keys)
            {
                listPurview.Add(new FormPurview(string.Empty, actionname, actionname, "Command"));
            }
            #endregion

            #region 画面
            if (Directory.Exists(_projectPath))
            {
                DirectoryInfo dicInfo = new DirectoryInfo(_projectPath);
                FileInfo[] files = dicInfo.GetFiles("*.xml", SearchOption.AllDirectories);
                if (files.Length > 0)
                {
                    string cleandown;
                    StreamReader sr;
                    XmlDocument doc;
                    foreach (FileInfo file in files)
                    {
                        try
                        {
                            sr = new StreamReader(file.FullName);
                            cleandown = sr.ReadToEnd();
                            sr.Close();
                            cleandown = "<DOCUMENT_ELEMENT FILE_NAME=\"" + Path.GetFileNameWithoutExtension(file.Name) + "\">" + cleandown + "</DOCUMENT_ELEMENT>";
                            doc = new XmlDocument();
                            doc.LoadXml(cleandown);
                            loadPurview(doc);
                        }
                        catch (Exception ex)
                        {
                            Console.Write(ex.Message);
                        }
                    }
                }
            }
            #endregion

            freshPurview(dbHelper);

            string msg3 = StringParser.Parse(ResourceService.GetString("Mesnac_Action_Default_Purview_LoadPurview_msg3"));      //信息加载完成!
            ShowMsg(msg3);
        }

        private void loadPurview( XmlDocument doc )
        {
            if ( doc == null )
                return;

            XmlNode nForm = doc.DocumentElement.FirstChild;//窗体组态保存xml时,规定第一个元素是Form
            if ( nForm != null )
            {
                FormPurview formPurview = new FormPurview( nForm );
                if ( !string.IsNullOrEmpty( formPurview.PurviewName ) && !string.IsNullOrEmpty( formPurview.PurviewText ) && !string.IsNullOrEmpty( formPurview.PurviewType ) )
                    listPurview.Add( formPurview );
            }
        }

        private void freshPurview( DbHelper helper )
        {
            if ( listPurview == null )
                return;

            StringBuilder sb;
            helper.CommandType = CommandType.Text;

            foreach ( FormPurview pur in listPurview )
            {
                sb = new StringBuilder();
                sb.AppendLine( "IF EXISTS(SELECT * FROM BasForm WHERE FormName=@FormName)" );
                sb.AppendLine( "UPDATE BasForm SET FormText=@FormText, FormType=@FormType, DeleteFlag='0' OUTPUT inserted.GUID WHERE FormName=@FormName;" );
                sb.AppendLine( "ELSE" );
                sb.AppendLine( "INSERT INTO BasForm(GUID,FormName,FormText,FormType,DeleteFlag) OUTPUT inserted.GUID" );
                sb.Append( "VALUES(NEWID(),@FormName,@FormText,@FormType,'0');" );

                helper.ClearParameter();
                helper.AddParameter( "@FormName" , pur.PurviewName );
                helper.AddParameter( "@FormText" , pur.PurviewText );
                helper.AddParameter( "@FormType" , pur.PurviewType );
                helper.CommandText = sb.ToString();
                string formGUID = helper.ToScalar() as string;

                if ( String.IsNullOrEmpty(formGUID) || pur.FunctionList == null || pur.FunctionList.Count < 1 )
                    continue;
                foreach ( FunctionPurview func in pur.FunctionList )
                {
                    freshFunction( func , helper , formGUID );
                }
            }
        }

        private void freshFunction( FunctionPurview func , DbHelper helper , string formGUID )
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine( "IF EXISTS(SELECT * FROM BasFormFunction WHERE FormGUID=@FormGUID AND FunctionName=@FunctionName)" );
            sb.AppendLine( "UPDATE BasFormFunction SET FunctionText=@FunctionText, FunctionType=@FunctionType, DeleteFlag='0' WHERE FormGUID=@FormGUID AND FunctionName=@FunctionName;" );
            sb.AppendLine( "ELSE" );
            sb.AppendLine( "INSERT INTO BasFormFunction(GUID,FormGUID,FunctionName,FunctionText,FunctionType,DeleteFlag)" );
            sb.Append( "VALUES(NEWID(),@FormGUID,@FunctionName,@FunctionText,@FunctionType,'0');" );

            helper.ClearParameter();
            helper.AddParameter( "@FormGUID" , formGUID );
            helper.AddParameter( "@FunctionName" , func.PurviewName );
            helper.AddParameter( "@FunctionText" , func.PurviewText );
            helper.AddParameter( "@FunctionType" , func.PurviewType );
            helper.CommandText = sb.ToString();
            helper.ExecuteNonQuery();
        }
    }

    /// <summary>
    /// 窗体权限类
    /// </summary>
    class FormPurview : APurview
    {
        private List<FunctionPurview> listFunction = null;

        public FormPurview( XmlNode node )
        {
            if ( node != null )
            {
                XmlAttribute att = node.OwnerDocument.DocumentElement.Attributes[ "FILE_NAME" ];//;node.Attributes[ "name" ];
                if ( att != null )
                    PurviewName = att.Value;

                XmlNode n = node.SelectSingleNode( "Property[@name=\"Text\"]" );
                if ( n != null )
                    PurviewText = n.InnerText;

                att = node.Attributes[ "type" ];
                if ( att != null )
                    PurviewType = att.Value.Split( ',' )[ 0 ];

                FunctionPurview func;
                listFunction = new List<FunctionPurview>();
                XmlNodeList cnList = node.SelectNodes( "//Property[@name=\"MCPurview\"]" );
                foreach ( XmlNode cn in cnList )
                {
                    if ( cn.ParentNode.Attributes[ "name" ].Value == PurviewName )
                        continue;
                    if ( cn.InnerText.ToLower() != "true" )
                        continue;

                    func = new FunctionPurview( cn.ParentNode );
                    if ( !string.IsNullOrEmpty( func.PurviewName ) && !string.IsNullOrEmpty( func.PurviewText ) && !string.IsNullOrEmpty( func.PurviewType ) )
                        listFunction.Add( func );
                }
            }
        }
        public FormPurview( string objId , string formName , string formText , string formType )
            : base( objId , formName , formText , formType )
        {
            listFunction = new List<FunctionPurview>();
        }

        public List<FunctionPurview> FunctionList
        {
            get
            {
                return listFunction;
            }
        }

        public override DataTable GetPurviews( DbHelper dbhelper )
        {
            if ( dbhelper == null )
                return null;

            dbhelper.ClearParameter();
            dbhelper.CommandType = CommandType.Text;
            dbhelper.CommandText = "SELECT GUID,FormName,FormText,FormType FROM BasForm WHERE DeleteFlag='0'";
            return dbhelper.ToDataTable();
        }
    }

    /// <summary>
    /// 控件权限类
    /// </summary>
    class FunctionPurview : APurview
    {
        public FunctionPurview( XmlNode node )
        {
            
            if ( node != null )
            {
                string tabValuePrefix = String.Empty;
                string tabTextPrefix = String.Empty;
                if (this.IsOwnerTabControl(node))
                {
                    XmlNode tabControlNode = this.GetTabControlOwner(node);
                    int tagPages = this.GetTabControlPages(tabControlNode);
                    if (tagPages > 1)
                    {
                        XmlNode tabPageNode = this.GetTabPageOwner(node);
                        if (tabPageNode != null)
                        {
                            XmlAttribute attPage = tabPageNode.Attributes["name"];
                            if (attPage != null)
                            {
                                tabValuePrefix = attPage.Value;
                            }
                            XmlNode nPage = tabPageNode.SelectSingleNode("Property[@name=\"Text\"]");
                            if (nPage != null)
                            {
                                tabTextPrefix = nPage.InnerText;
                            }
                        }
                    }
                }


                XmlAttribute att = node.Attributes[ "name" ];
                if ( att != null )
                {
                    if (String.IsNullOrEmpty(tabValuePrefix))
                    {
                        PurviewName = att.Value;
                    }
                    else
                    {
                        PurviewName = String.Format("[{0}]{1}", tabValuePrefix, att.Value);
                    }
                }

                XmlNode n = node.SelectSingleNode( "Property[@name=\"Text\"]" );
                if ( n != null )
                {
                    if (String.IsNullOrEmpty(tabTextPrefix))
                    {
                        PurviewText = n.InnerText;
                    }
                    else
                    {
                        PurviewText = String.Format("[{0}]{1}", tabTextPrefix, n.InnerText);
                    }
                }

                att = node.Attributes[ "type" ];
                if ( att != null )
                    PurviewType = att.Value.Split( ',' )[ 0 ];
            }
        }
        public FunctionPurview( string objId , string functionName , string functionText , string functionType )//string formId ,
            : base( objId , functionName , functionText , functionType )
        {
        }
        public override DataTable GetPurviews( DbHelper dbhelper )
        {
            if ( dbhelper == null )
                return null;

            dbhelper.ClearParameter();
            dbhelper.CommandType = CommandType.Text;
            dbhelper.CommandText = "SELECT GUID,FormGUID,FunctionName,FunctionText,FunctionType FROM BasFormFunction WHERE DeleteFlag='0'";
            return dbhelper.ToDataTable();
        }

        /// <summary>
        /// 判断节点是否属于选项卡控件
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private bool IsOwnerTabControl(XmlNode node)
        {
            if (node != null && node.Attributes != null)
            {
                XmlAttribute att = node.Attributes["type"];
                if (att != null && att.Value != null && att.Value.StartsWith("System.Windows.Forms.TabControl"))
                {
                    return true;
                }
                else
                {
                    return IsOwnerTabControl(node.ParentNode);
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 获取父级选项卡节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private XmlNode GetTabControlOwner(XmlNode node)
        {
            if (node != null && node.Attributes != null)
            {
                XmlAttribute att = node.Attributes["type"];
                if (att != null && att.Value != null && att.Value.StartsWith("System.Windows.Forms.TabControl"))
                {
                    return node;
                }
                else
                {
                    return GetTabControlOwner(node.ParentNode);
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 获取选项卡的数量
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private int GetTabControlPages(XmlNode node)
        {
            if (node != null)
            {
                int count = 0;
                XmlNodeList nodeList = node.SelectNodes("Object");
                foreach(XmlNode xn in nodeList)
                {
                    if (xn.Attributes != null)
                    {
                        XmlAttribute att = xn.Attributes["type"];
                        if (att != null && att.Value.StartsWith("System.Windows.Forms.TabPage"))
                        {
                            count++;
                        }
                    }
                }
                return count;
            }
            else
            {
                return 0;
            }
        }
        /// <summary>
        /// 获取所属选项卡页
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private XmlNode GetTabPageOwner(XmlNode node)
        {
            if (node != null)
            {
                if (node.Attributes != null)
                {
                    XmlAttribute att = node.Attributes["type"];
                    if (att != null && att.Value.StartsWith("System.Windows.Forms.TabPage"))
                    {
                        return node;
                    }
                    else
                    {
                        return GetTabPageOwner(node.ParentNode);
                    }
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }
    }

    interface IPurview
    {
        DataTable GetPurviews( DbHelper dbhelper );
    }

    abstract class APurview : IPurview
    {
        protected APurview()
        {
        }

        public APurview( string GUID , string purviewName , string purviewText , string purviewType )
        {
            this.GUID = GUID;
            this.PurviewName = purviewName;
            this.PurviewText = purviewText;
            this.PurviewType = purviewType;
        }
        public string GUID
        {
            get;
            set;
        }
        public string PurviewName
        {
            get;
            set;
        }
        public string PurviewText
        {
            get;
            set;
        }
        public string PurviewType
        {
            get;
            set;
        }

        #region IPurview 成员


        public abstract DataTable GetPurviews( DbHelper dbhelper );

        #endregion
    }
}