using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Xml;
using System.Text.RegularExpressions;
using System.ComponentModel;
using FObjBase;
using System.Xml.Serialization;

namespace OBJ_FileBus
{
    public class Client : INotifyPropertyChanged
    {
        /// <summary>
        /// 文件系统读写 
        /// </summary>
        private FileSystemInfoRW mFileSystemInfo = new FileSystemInfoRW();

        private bool hasinit;
        public bool HasInit
        {
            get
            {
                return hasinit;
            }
            set
            {
                if (hasinit != value)
                {
                    hasinit = value;
                    NotifyPropertyChanged("HasInit");
                }
            }
        }

        #region 根路径
        /// <summary>
        /// 根路径
        /// </summary>
        private string m_rootPath;
        public string RootPath
        {
            set
            {
                SetRootPath(value);
            }
            get
            {
                return m_rootPath;
            }
        }
        private bool SetRootPath(string path)
        {
            m_rootPath = path;
            if (!Directory.Exists(m_rootPath))
            {
                try
                {
                    Directory.CreateDirectory(m_rootPath);
                }
                catch
                {
                    return false;
                }
            }
            Load();
            return true;
        }

        /// <summary>
        /// 根文件结构
        /// </summary>
        private FileElement mRootFileElement = new FileElement();
        public FileElement Root
        {
            get
            {
                return mRootFileElement;
            }
        }
        #endregion
        private void ClearAllEventArgs() 
        {
            //关掉所有进度
            foreach (FileBusEventArgs e in mEventArgs)
            {
                e.NoConnect();
            }
            mEventArgs.Clear();        
        }


        public Client(string rootPath)
        {
            RootPath = @"filebus\"+rootPath;
            m_service.Add("readinfo", new FuncHandle(CBF_ReadInfo));
            m_service.Add("read", new FuncHandle(CBF_Read));
            m_service.Add("write", new FuncHandle(CBF_Write));
            m_service.Add("addpush", new FuncHandle(CBF_PushRegist));
            m_service.Add("rmpush", new FuncHandle(CBF_PushRegist));
            m_service.Add("rm", new FuncHandle(CBF_Del));
            m_service.Add("push", new FuncHandle(CBF_Push));

            PropertyChanged += new PropertyChangedEventHandler(Client_PropertyChanged);
            PollModule.Current.Poll_Config(PollModule.POLL_CONFIG.ADD,
                new PollModule.PollHandler(DisposeEvent), TimeSpan.FromMilliseconds(1));
        }

        void Client_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "HasInit") 
            {
                if (!HasInit) 
                {
                    ClearAllEventArgs();
                }
            }
        }
        /// <summary>
        /// 获取本地路径
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public string GetAbsPath(string path)
        {
            if (path.StartsWith(@"\"))
            {
                return RootPath + path;
            }
            else
            {
                return RootPath + @"\" + path;
            }
        }
        private string GetFileInfoPath()
        {
            return RootPath + @".fileinfo.xml";
        }
        
        private void Load()
        {
            string filePath = GetFileInfoPath();
            mRootFileElement = new FileElement(FileAttributes.Directory, @"\");
            Root.Load(filePath);
            Root.BeChanged = false;
        }
        private void Save()
        {
            if (Root.BeChanged)
            {
                string filePath = GetFileInfoPath();
                Root.Save(filePath);
                Root.BeChanged = false;
            }
        }

        public delegate void SendMessageEventHandler(byte[] msg);
        public event SendMessageEventHandler SendMessageEvent;

        private void Send(byte[] msg)
        {
            if (SendMessageEvent != null)
                SendMessageEvent(msg);
        }

        #region FileBusEventArgs
        public class FileBusEventArgs : EventArgs
        {
            public enum STATE
            {
                //客户端自定义
                WAIT_SEND,//等待执行
                WAIT_REPLY,//等待回复
                IDLE//已经处理完
            }
            public STATE mState = STATE.WAIT_SEND;//状态
            public ERRNO mErrno;//错误代码
            public int mWaitCnt = 0;//等待次数
            public EventHandler handler;//事件
            public void Handler() { if (handler != null)handler(mClient, this); }
            public object mClient;
            public void NoConnect()
            {
                if (mState != STATE.IDLE)
                {
                    mState = STATE.IDLE;
                    mErrno = ERRNO.NOCONNECT;
                    Handler();
                }
            }
            public override string ToString()
            {
                return this.GetType().ToString() + " " + mErrno.ToString() + " " + mState.ToString();
            }
            /// <summary>
            /// 发起者,用于关闭都为该发起者建立的通信
            /// </summary>
            public object sponsor;
        }
        public class ReadInfoEventArgs : FileBusEventArgs
        {
            public string mPath;
        }
        public class RWEventArgs : FileBusEventArgs 
        
        {
            /// <summary>
            /// 路径
            /// </summary>
            public string mPath;
            /// <summary>
            /// 文件 or 文件夹 
            /// </summary>
            public FileAttributes mFileAttributes;
            /// <summary>
            /// 总文件大小
            /// </summary>
            public UInt32 mFileSize;
            /// <summary>
            /// 包大小
            /// </summary>
            public UInt16 mPackageSize = 0x3500;//OBJ 会把大包分为N个小包,小包为0x4000
            /// <summary>
            /// 当前传输的包
            /// </summary>
            public UInt16 mPackageNo = 0;
            /// <summary>
            /// 远端,全局唯一标识
            /// </summary>
            public string guid_remote;
            /// <summary>
            /// 本地,全局唯一标识
            /// </summary>
            public string guid_local;

            public string GetFilePath(string path)
            {
                if (mFileAttributes == FileAttributes.Normal)
                    return path;
                else
                    return path + @".fileinfo.xml";
            }
        }
        public class ReadEventArgs : RWEventArgs 
        {
        
        }
        public class WriteEventArgs : RWEventArgs
        {
        }
        public class PushRegistEventArgs : FileBusEventArgs
        {
            public string mPath;//路径
            public bool bIsAdd;//是添加
        }
        public class PushEventArgs : FileBusEventArgs
        {
            public string mPath;//路径
        }
        public class DelEventArgs : FileBusEventArgs
        {
            public string mPath;//路径
        }
        //事件运行列表,运行完,就会从此列表删除
        List<FileBusEventArgs> mEventArgs = new List<FileBusEventArgs>();
        #endregion

        #region 发送
        private void Send(Message message) 
        {
            Send(message.ToBytes());
        }
        #endregion

        #region 功能
        private delegate void FuncHandle(Message message);

        Dictionary<string, FuncHandle> m_service =
            new Dictionary<string, FuncHandle>();
        /// <summary>
        /// 功能号分发
        /// </summary>
        /// <param name="ADUBuffer"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public void RequestService(byte[] order_bytes)
        {
            //获取指令
            //转换为xml 解码
            Message message = Message.Bytes2Message(order_bytes);
            //获取指令
            string order = message.order;

            DateTime dt2 = DateTime.Now;

            if (m_service.ContainsKey(order))
            {
                m_service[order](message);
            }
            DateTime dt1 = DateTime.Now;
            Console.WriteLine("Client RequestService " + (dt1 - dt2).TotalMilliseconds.ToString() + " " + (dt1 - dtlast).TotalMilliseconds.ToString());
            dtlast = dt1;

        }

        /// <summary>
        /// 放于 OnPoll 中,处理所有任务
        /// </summary>
        private void DisposeEvent()
        {
            var waitcnt_list = from _eventargs in mEventArgs
                               where _eventargs.mState == FileBusEventArgs.STATE.WAIT_SEND
                               select _eventargs.mWaitCnt;
            if (waitcnt_list.Count() == 0)
                return;

            var waitcnt_max = waitcnt_list.Max();

            var eventargs =
                (from _eventargs in mEventArgs
                 where (_eventargs.mWaitCnt == waitcnt_max) && (_eventargs.mState == FileBusEventArgs.STATE.WAIT_SEND)
                 select _eventargs).First();

            foreach (FileBusEventArgs eargs in mEventArgs)
            {
                eargs.mWaitCnt++;
            }

            eventargs.mWaitCnt = 0;
            eventargs.mState = FileBusEventArgs.STATE.WAIT_REPLY;
            if (eventargs is PushRegistEventArgs)
            {
                PushRegistEventArgs e = eventargs as PushRegistEventArgs;
                Send(new Message()
                {
                    order = (e.bIsAdd) ? "addpush" : "rmpush",
                    args = new PushParamMessageArgs() { path = e.mPath }
                });
            }
            else if (eventargs is DelEventArgs)
            {
                DelEventArgs e = eventargs as DelEventArgs;
                Send(new Message()
                {
                    order = "rm",
                    args = new FileOptMessageArgs() { path = e.mPath }
                });
            }
            else if (eventargs is ReadInfoEventArgs)
            {
                ReadInfoEventArgs e = eventargs as ReadInfoEventArgs;
                Send(new Message()
                {
                    order = "readinfo",
                    args = new FileOptMessageArgs() { path = e.mPath }
                });
            }
            else if (eventargs is ReadEventArgs)
            {
                ReadEventArgs e = eventargs as ReadEventArgs;
                Send(new Message()
                {
                    order = "read",
                    args = new ReadParamMessageArgs() { 
                        path = e.mPath, 
                        guid = e.guid_remote,
                        package_size = e.mPackageSize, 
                        package_no = e.mPackageNo }
                });
            }
            else if (eventargs is WriteEventArgs)
            {
                WriteEventArgs e = eventargs as WriteEventArgs;
                byte[] filecontent;
                mFileSystemInfo.GetContent(
                    GetAbsPath(e.mPath), 
                    ref e.guid_local,
                    e.mPackageNo, e.mPackageSize, out filecontent, out e.mFileSize);

                Send(new Message()
                {
                    order = "write",
                    args = new WriteParamMessageArgs() 
                    { 
                        path = e.mPath, 
                        guid = e.guid_remote,
                        fileattr = FileAttributes.Normal,
                        filesize = e.mFileSize,
                        package_size = e.mPackageSize, 
                        package_no = e.mPackageNo,
                        filecontent = filecontent
                    }
                });
            }
        }
        

        #region 读取文件或文件夹 信息,直接更新根文件结构
        public ReadInfoEventArgs ReadInfo(string path, object sponsor, EventHandler handler)
        {
            ReadInfoEventArgs eventargs = new ReadInfoEventArgs()
            {
                mPath = path,
                handler = handler,
                mClient = this,
                sponsor = sponsor
            };

            if (HasInit)
                mEventArgs.Add(eventargs);
            else
                eventargs.NoConnect();

            return eventargs;
        }
        
        private void CBF_ReadInfo(Message message)
        {
            ReadInfoRetMessageArgs args = message.args as ReadInfoRetMessageArgs;

            ERRNO errno = args.errno;
            string path = args.path;

            ReadInfoEventArgs ea;
            {
                var eal = from _eventargs in mEventArgs
                          where (_eventargs is ReadInfoEventArgs) &&
                          ((_eventargs as ReadInfoEventArgs).mPath == path) &&
                          (_eventargs.mState == FileBusEventArgs.STATE.WAIT_REPLY)
                          select _eventargs;

                if (eal.Count() == 0)
                {
                    //出错,收了不该收到的
                    //throw new Exception("出错,收了不该收到的");
                    return;
                }

                ea = eal.First() as ReadInfoEventArgs;
            }

            ea.mState = FileBusEventArgs.STATE.IDLE;
            ea.mErrno = errno;

            if (errno == ERRNO.OK)
            {
                FileElement fe = new FileElement(
                    args.fileattr,
                    Path.GetFileName(path)) 
                    { 
                        LastWriteTime = args.lastwritetime,
                        CreateTime = args.createtime,
                        Size = args.size
                    };
                //TODO
                //只更新一个,不更新内容
                Root.ToUpdate(path, fe, false);
                Save();
            }
            else if (errno == ERRNO.NOEXIST)
            {

            }

            ea.Handler();
            mEventArgs.Remove(ea);
        }
        #endregion

        #region 读取 文件夹 或 文件 内容,直接更新根文件结构 和 本地文件
        public ReadEventArgs Read(string path, object sponsor, EventHandler handler) 
        {
            ReadEventArgs eventargs = new ReadEventArgs()
            {
                mPath = path,
                handler = handler,
                mClient = this,
                sponsor = sponsor
            };
            if (HasInit)
                mEventArgs.Add(eventargs);
            else
                eventargs.NoConnect();

            return eventargs;
        }

        DateTime dtlast = DateTime.Now;
        private void CBF_Read(Message message)
        {
            ReadRetMessageArgs args = message.args as ReadRetMessageArgs;
            ERRNO errno = args.errno;
            string path = args.path;

            ReadEventArgs ea;
            {
                var eal = from _eventargs in mEventArgs
                          where (_eventargs is ReadEventArgs) &&
                          ((_eventargs as ReadEventArgs).mPath == path) &&
                          (_eventargs.mState == FileBusEventArgs.STATE.WAIT_REPLY)
                          select _eventargs;

                if (eal.Count() == 0)
                {
                    //出错,收了不该收到的
                    //throw new Exception("出错,收了不该收到的");
                    return;
                }

                ea = eal.First() as ReadEventArgs;
            }


            ea.mState = FileBusEventArgs.STATE.IDLE;
            ea.mErrno = errno;

            ea.mFileAttributes = args.fileattr;
            ea.mFileSize = args.filesize;
            ea.mPackageNo = args.package_no;
            ea.mPackageSize = args.package_size;
            ea.guid_remote = args.guid;
            if ((errno == ERRNO.DOING) || (errno == ERRNO.OK)) 
            {
                //当为文件时,p就是path
                //当为文件夹时,p = path+“.fileinfo.xml”
                string p = ea.GetFilePath(GetAbsPath(path));

                FileSystemInfoRW.OptFileContentResult ret =
                    mFileSystemInfo.SetFileContent(
                    p, ref ea.guid_local, 
                    args.filesize, 
                    args.package_size,
                    args.package_no,
                    args.filecontent);
                
                if(errno == ERRNO.DOING)
                {
                    FileElement fe = new FileElement(args.fileattr, Path.GetFileName(path))
                    {
                        CreateTime = args.createtime,
                        LastWriteTime = args.lastwritetime,
                        Size = (int)args.filesize,
                        DownloadSize = args.package_size * (args.package_no+1)
                    };
                    Root.ToUpdate(path, fe, false);

                    //还要继续读
                    ea.mPackageNo++;
                    ea.mState = FileBusEventArgs.STATE.WAIT_SEND;
                }
                else
                {
                    FileElement fe;
                    if (args.fileattr == FileAttributes.Directory)
                    {
                        fe = new FileElement();
                        fe.Load(p);
                        File.Delete(p);
                        fe.Size = (int)args.filesize;
                        fe.DownloadSize = (int)args.filesize;

                    }
                    else
                    {
                        fe = new FileElement(FileAttributes.Normal, Path.GetFileName(path)) 
                        { 
                            CreateTime = args.createtime,
                            LastWriteTime = args.lastwritetime,
                            Size = (int)args.filesize,
                            DownloadSize = (int)args.filesize
                        };
                    }
                    //把fe更新到Root中
                    //所有的内容都会被替换
                    fe = Root.ToUpdate(path, fe, true);
                    Root.SetUpdateFlag(path, false);
                    Save();

                    DelNoHereFiles(fe);
                }
            }
            else if (errno == ERRNO.NOEXIST)
            {

            }

            ea.Handler();

            if (ea.mState == FileBusEventArgs.STATE.IDLE)
                mEventArgs.Remove(ea);
        }
        #endregion

        #region 写入文件

        public WriteEventArgs Write(string path, object sponsor, EventHandler handler)
        {
            WriteEventArgs eventargs = new WriteEventArgs()
            {
                mPath = path,
                handler = handler,
                mClient = this,
                sponsor = sponsor
            };
            if (HasInit)
                mEventArgs.Add(eventargs);
            else
                eventargs.NoConnect();

            return eventargs;
        }
        private void CBF_Write(Message message)
        {
            WriteRetMessageArgs args = message.args as WriteRetMessageArgs;
            ERRNO errno = args.errno;
            string path = args.path;

            WriteEventArgs ea;
            {
                var eal = from _eventargs in mEventArgs
                          where (_eventargs is WriteEventArgs) &&
                          ((_eventargs as WriteEventArgs).mPath == path) &&
                          (_eventargs.mState == FileBusEventArgs.STATE.WAIT_REPLY)
                          select _eventargs;

                if (eal.Count() == 0)
                {
                    //出错,收了不该收到的
                    //throw new Exception("出错,收了不该收到的");
                    return;
                }

                ea = eal.First() as WriteEventArgs;
            }

            ea.mState = FileBusEventArgs.STATE.IDLE;
            ea.mErrno = errno;
            ea.guid_remote = args.guid;
            if (errno == ERRNO.DOING) 
            {
                FileElement fe = new FileElement( args.fileattr, Path.GetFileName(path))
                {
                    LastWriteTime = args.lastwritetime,
                    CreateTime = args.createtime,
                    Size = (int)ea.mFileSize,
                    DownloadSize = (ea.mPackageNo+1) * ea.mPackageSize
                };
                //只更新一个,不更新内容
                Root.ToUpdate(path, fe, false);

                ea.mPackageNo++;
                ea.mState = FileBusEventArgs.STATE.WAIT_SEND;
            }
            else if (errno == ERRNO.OK)
            {
                FileElement fe = new FileElement(args.fileattr, Path.GetFileName(path))
                {
                    LastWriteTime = args.lastwritetime,
                    CreateTime = args.createtime,
                    Size = (int)ea.mFileSize,
                    DownloadSize = (int)ea.mFileSize
                };
                //只更新一个,不更新内容
                Root.ToUpdate(path, fe, false);
                Root.SetUpdateFlag(path, false);
                Save();
            }
            else if (errno == ERRNO.ERROR)
            {

            }

            ea.Handler();

            if (ea.mState == FileBusEventArgs.STATE.IDLE)
                mEventArgs.Remove(ea);
        }
        #endregion

        #region 删除文件或文件夹

        public DelEventArgs Del(string path, object sponsor, EventHandler handler)
        {
            DelEventArgs eventargs = new DelEventArgs()
            {
                mPath = path,
                handler = handler,
                mClient = this,
                sponsor = sponsor
            };

            if (HasInit)
                mEventArgs.Add(eventargs);
            else
                eventargs.NoConnect();

            return eventargs;
        }
        private void CBF_Del(Message message)
        {
            //errno 错误代码
            //order 指令字符串
            //如:
            //3 rm sysparam.ini
            RetMessageArgs args = message.args as RetMessageArgs;
            ERRNO errno = args.errno;
            string path = args.path;


            DelEventArgs ea;
            {
                var eal = from _eventargs in mEventArgs
                          where (_eventargs is DelEventArgs) &&
                          ((_eventargs as DelEventArgs).mPath == path) &&
                          (_eventargs.mState == FileBusEventArgs.STATE.WAIT_REPLY)
                          select _eventargs;

                if (eal.Count() == 0)
                {
                    //出错,收了不该收到的
                    //throw new Exception("CBF_Del 出错,收了不该收到的 path" + path);
                    return;
                }

                ea = eal.First() as DelEventArgs;
            }

            ea.mState = FileBusEventArgs.STATE.IDLE;
            ea.mErrno = errno;

            if (errno == ERRNO.OK)
            {

            }
            else if (errno == ERRNO.NOEXIST)
            {

            }

            ea.Handler();
            mEventArgs.Remove(ea);
        }

        #endregion

        #region 推送注册
        public PushRegistEventArgs PushRegist(string path, object sponsor, bool isAdd, EventHandler handler)
        {
            PushRegistEventArgs eventargs = new PushRegistEventArgs()
            {
                mPath = path,
                handler = handler,
                mClient = this,
                bIsAdd = isAdd,
                sponsor = sponsor
            };

            if (HasInit)
                mEventArgs.Add(eventargs);
            else
                eventargs.NoConnect();

            return eventargs;
        }
        private void CBF_PushRegist(Message message)
        {
            //errno = 0 正常
            //"addpush"
            //注册的数量
            PushRetMessageArgs args = message.args as PushRetMessageArgs;
            ERRNO errno = args.errno;
            string order = message.order;

            bool isAdd = false;
            if (order == "addpush")
                isAdd = true;
            string path = args.path;

            PushRegistEventArgs ea;
            {
                var eal = from _eventargs in mEventArgs
                          where (_eventargs is PushRegistEventArgs) &&
                          ((_eventargs as PushRegistEventArgs).bIsAdd == isAdd) &&
                          ((_eventargs as PushRegistEventArgs).mPath.CompareTo(path)==0) &&
                          (_eventargs.mState == FileBusEventArgs.STATE.WAIT_REPLY)
                          select _eventargs;

                if (eal.Count() == 0)
                {
                    //出错,收了不该收到的
                    //throw new Exception("出错,收了不该收到的");
                    if (isAdd) 
                    {
                        //本地没有这个推送请求,关闭服务器的推送服务
                        PushRegist(path, null, false, null);
                    }
                    return;
                }

                ea = eal.First() as PushRegistEventArgs;
            }

            ea.mState = FileBusEventArgs.STATE.IDLE;
            ea.mErrno = errno;

            if (errno == ERRNO.OK)
            {

            }
            else if (errno == ERRNO.NOEXIST)
            {

            }

            ea.Handler();
            mEventArgs.Remove(ea);

            if (ea.bIsAdd)
            {
                PushEventArgs pushea = new PushEventArgs();
                
                pushea.mClient = ea.mClient;
                pushea.mState = FileBusEventArgs.STATE.WAIT_REPLY;
                pushea.mPath = ea.mPath;
                pushea.mErrno = ERRNO.PUSH;
                pushea.handler = ea.handler;
                pushea.sponsor = ea.sponsor;
                mEventArgs.Add(pushea);
            }
            else
            {
                var eal = from pushea in mEventArgs
                          where (pushea is PushEventArgs) &&
                          ((pushea as PushEventArgs).mPath == ea.mPath)
                          select pushea;
                if (eal.Count() > 0)
                {
                    mEventArgs.Remove(eal.First());
                }
                else
                {
                    //异常出错
                    //throw new Exception("不能找到PushEventArgs " + ea.mPath);
                }
            }
        }
        #endregion

        #region 发起者已经不存在,关闭它所建立的通信
        /// <summary>
        /// 发起者,已经不存在,关闭它所建立的通信
        /// </summary>
        /// <param name="magic">全局唯一标示,由GetMagic()产生</param>
        public void FreeComm(object sponsor) 
        {
            List<FileBusEventArgs> eal = new List<FileBusEventArgs>();
            eal.AddRange(from _eventargs in mEventArgs
                         where (_eventargs.sponsor == sponsor)
                      select _eventargs);

            //删除所有
            foreach (var ea in eal)
            {
                if (ea is PushEventArgs) //取消注册
                {
                    PushEventArgs ea_push = ea as PushEventArgs;
                    PushRegist(ea_push.mPath, null, false, null);
                }
                
                ea.mState = FileBusEventArgs.STATE.IDLE;
                mEventArgs.Remove(ea);
            }
        }
        #endregion

        #endregion

        private void CBF_Push(Message message)
        {
            PushMessageArgs args = message.args as PushMessageArgs;

            string path = args.path;

            var eal = from _eventargs in mEventArgs
                      where (_eventargs is PushEventArgs) &&
                      ((_eventargs as PushEventArgs).mPath == path)
                      select _eventargs;

            if (eal.Count() == 0)
            {
                //出错,收了不该收到的
                //throw new Exception("出错,收了不该收到的 path=" + path);
                //不需要这个推送,关闭服务的推送服务
                PushRegist(path, null, false, null);
                return;
            }

            PushEventArgs ea = eal.First() as PushEventArgs;

            FileElement fe = new FileElement(args.fileattr, Path.GetFileName(path))
            {
                LastWriteTime = args.lastwritetime,
                CreateTime = args.createtime,
                Size = args.size
            };
            //只更新一个,不更新内容
            Root.ToUpdate(path, fe, false);
            Save();

            ea.Handler();
        }


        private void DelNoHereFiles(FileElement fe) 
        {
            if (fe.FileAttr == FileAttributes.Directory)
            {
                string path=GetAbsPath(fe.FullName);
                if (Directory.Exists(path))
                {
                    string[] filenames = Directory.GetFiles(path);
                    foreach (string filename in filenames)
                    {
                        var cnt = (from _fe in fe.child where _fe.Name.CompareTo(Path.GetFileName(filename)) == 0 select _fe).Count();
                        if (cnt == 0)
                        {
                            File.Delete(filename);
                        }
                    }
                    filenames = Directory.GetDirectories(path);
                    foreach (string filename in filenames)
                    {
                        var cnt = (from _fe in fe.child where _fe.Name.CompareTo(Path.GetFileName(filename)) == 0 select _fe).Count();
                        if (cnt == 0)
                        {
                            Directory.Delete(filename);
                        }
                    }
                }
            }
        }
        #region INotifyPropertyChanged 成员
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}