using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace 電子文書回覧監視ツール {
    public partial class Form1 : Form {
        //コンストラクト
        public Form1() {
            InitializeComponent();
            //Microsoft.Win32.SystemEvents.SessionEnding += new Microsoft.Win32.SessionEndingEventHandler(SessionEnding);
            if(File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + "MODE2.xml")) {
                MODE2 = true;
            }
        }

        //戻しデータをリクエストに応じてdatatableで返す
        public DataTable getLoadData(string tableName) {
            if(infodataset == null) {
                return null;
            }
            else {
                return infodataset.Tables[tableName];
            }
        }

        //フィールド定義
        public bool MODE2 = false;
        const int c_white = 1;
        const int c_color = 2;
        int icon = 0;
        List<FileSystemWatcher> watcher = new List<FileSystemWatcher>();
        public List<string> folders = new List<string>();
        public List<string> types = new List<string>();
        public string muskstring;
        public string notmuskstring;
        Folder folderForm;
        DataSet infodataset;

        //監視中断・監視開始 押下
        private void button1_Click(object sender, EventArgs e) {
            switch(button1.Text) {
                case "監視停止":
                    dataGridView2.Enabled = false;
                    button1.Enabled = false;
                    btn消去.Enabled = false;
                    foreach(FileSystemWatcher w in watcher) {
                        w.EnableRaisingEvents = false;
                        if(Environment.UserName == "matsumoto01u") {
                            normalFont(String.Format("DBG Event解除 {0}  {1}", DateTime.Now.ToString("MM/dd HH:mm:ss"), w.Path));
                        }
                    }
                    watcher.Clear();
                    normalFont(String.Format("　　監視停止 {0}", DateTime.Now.ToString("MM/dd HH:mm:ss")));
                    lbl稼働状況.Text = "監視停止中";
                    lbl稼働状況.ForeColor = System.Drawing.Color.Red;
                    notifyIcon1.Visible = notifyIcon2.Visible = false;
                    button1.Text = "監視再開";
                    タスクバー編集オフ();
                    if(!MODE2) {
                        rcv.recieveclose(); //受信停止
                        thread2.Join();
                    }
                    button1.Enabled = true;
                    return;
                case "監視再開":
                    dataGridView2.Enabled = true;
                    button1.Enabled = false;
                    btn消去.Enabled = true;
                    button1.Text = "監視停止";
                    normalFont(String.Format("　　監視再開 {0}", DateTime.Now.ToString("MM/dd HH:mm:ss")));
                    break;
                default:
                    Debug.Fail("ボタン");
                    return;
            }
            folderForm.パラメータ再入手();
            開始処理();
            button1.Enabled = true;
        }

        // ＦＯＲＭ開始
        private System.Threading.Mutex objMutex;
        DateTime starttime;
        Boolean conflict = false;
        string 氏名;

        static List<string> servers = new List<string>();
        static int serverPort;
        public static int watchPort;
        static int trackPort;
        List<string> networks = new List<string>();

        public string version;

        private void Form1_Load(object sender, EventArgs e) {
            objMutex = new System.Threading.Mutex(false, "fdDISP");
            if(objMutex.WaitOne(0, false) == false) {
                if(!MODE2) {
                    if(MessageBox.Show(string.Format("既に監視ツールが稼動していますが、立ち上げますか？　{0}追跡ツール側と連携しないモードで稼動します。", Environment.NewLine), "多重起動の確認", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.No) {
                        conflict = true;
                        this.Close();
                        return;
                    }
                    else {
                        MODE2 = true;
                    }
                }
            }
            dataGridView2.AutoGenerateColumns = true;
            //復元ファイル読み込み
            if(System.IO.File.Exists(Folder.parameterFolder + "savedWatcherinfo.xml")) {
                infodataset = new DataSet();
                infodataset.ReadXml(Folder.parameterFolder + "savedWatcherinfo.xml");
            }
            //パラメータ読み込み
            folderForm = new Folder(this);
            folderForm.構成入手(ref servers, ref serverPort, ref watchPort, ref trackPort, ref networks);
            if(folderForm.パラメータ入手() == false) {
                MessageBox.Show("パラメータ読み込みに失敗したので終了します");
                this.Close();
            }

            //メインFORM復元
            if(infodataset != null) {
                //レイアウト復元

                DataRow r = infodataset.Tables["layoutinfo"].Rows[0];
                int x = (Convert.ToInt32(r[0]) < 0) ? 0 : Convert.ToInt32(r[0]);
                int y = (Convert.ToInt32(r[1]) < 0) ? 0 : Convert.ToInt32(r[1]);
                DesktopLocation = new System.Drawing.Point(x, y);
                int width = (Convert.ToInt32(r[2]) == 0) ? 737 : Convert.ToInt32(r[2]);
                int height = (Convert.ToInt32(r[3]) == 0) ? 184 : Convert.ToInt32(r[3]);
                ClientSize = new System.Drawing.Size(width, height);

                if(Convert.ToInt32(r[4]) > 0 && Convert.ToInt32(r[5]) > 0) {
                    this.splitContainer2.SplitterDistance = Convert.ToInt32(r[4]);
                    this.splitContainer1.SplitterDistance = Convert.ToInt32(r[5]);
                }
                //欄位置復元
                DataRow row = infodataset.Tables["dgcolumninfo"].Rows[0];
                int i = 0;
                foreach(DataGridViewColumn dgcol in dataGridView2.Columns) {
                    if(i < infodataset.Tables["dgcolumninfo"].Columns.Count) { //欄追加時の考慮
                        dgcol.DisplayIndex = Int32.Parse(row[i++].ToString());
                    }
                }
            }
            if(MODE2) {
                label2.Text = "      ↑カラムの移動は見出しをドラッグ　↑メモはダブルクリックで記入　↑並び替えは見出しをクリック";
            }
            else {
                label2.Text = "      ↑カラムの移動は見出しをドラッグ　↑文書コメント・メモはダブルクリックで記入　↑緊急度はクリック　　↑並び替えは見出しをクリック";
            }
            if(ADuser.getUserInfo(Environment.UserName.ToString(), "name", out 氏名) != 0) {
                氏名 = Environment.UserName;
            };
            氏名 = 氏名.Replace(" ", "");
            AssemblyName AssemblyName = Assembly.GetExecutingAssembly().GetName();
            version = AssemblyName.Version.ToString();
            lblVersion.Text += version;
            toolStripStatusLabel1.Text = String.Format("通知数=0");
            starttime = DateTime.Now;
            開始処理();
            normalFont(String.Format("　　監視開始 {0}", starttime.ToString("MM/dd HH:mm:ss")));
        }

        //開始処理（Form-Loadよりcall）
        recieveprocess rcv;
        System.Threading.Thread thread2;
        public UdpClient udp;
        private void 開始処理() {
            if(!MODE2) udp = new UdpClient(watchPort);
            #region 初期フォルダ状態設定
            DataTable t2 = dataSet2.Tables[0];
            DataTable t3 = dataSet3.Tables[0];
            t2.PrimaryKey = new DataColumn[] { t2.Columns[1], t2.Columns[2] };
            t2.Clear();
            t3.Clear();
            for(int i = 0; i < types.Count; i++) {
                string[] f1, f2;
                try {
                    f1 = System.IO.Directory.GetDirectories(folders[i]);
                    f2 = System.IO.Directory.GetFiles(folders[i]);
                }
                catch(Exception ex) {
                    MessageBox.Show(string.Format("読込エラー(フォルダ名＝{2}）。{0}無視します。", Environment.NewLine, ex, folders[i]));
                    continue;
                }
                int cnt = 0;
                foreach(string f in f1) {//フォルダ文書
                    string fn = f.ToUpper().Replace(folders[i] + @"\", "");
                    if(fn.StartsWith("！") || fn.StartsWith("!") || fn.EndsWith(".LNK")) continue;
                    //マスキング
                    if(!fn.Contains(muskstring.ToUpper()) && !fn.Contains(muskstring.ToLower())) continue;
                    if(notmuskstring != "") {
                        bool skip = false;
                        foreach(string s in notmuskstring.Split(',')) {
                            if(fn.Contains(s.ToUpper()) || fn.Contains(s.ToLower())) skip = true;
                        }
                        if(skip) continue;
                    }
                    DataRow r = t2.NewRow();
                    r[0] = "";
                    r[1] = types[i];
                    r[2] = fn;
                    t2.Rows.Add(r);
                    r[7] = System.IO.Directory.GetLastWriteTime(f).ToString("MM/dd HH:mm");
                    cnt++;
                }
                foreach(string f in f2) {//ファイル文書
                    string fn = f.ToUpper().Replace(folders[i] + @"\", "");
                    if(fn.StartsWith("！") || fn.StartsWith("!") || fn.EndsWith(".LNK")) continue;
                    //マスキング
                    if(!fn.Contains(muskstring.ToUpper()) && !fn.Contains(muskstring.ToLower())) continue;
                    if(notmuskstring != "") {
                        bool skip = false;
                        foreach(string s in notmuskstring.Split(',')) {
                            if(fn.Contains(s.ToUpper()) || fn.Contains(s.ToLower())) skip = true;
                        }
                        if(skip) continue;
                    }
                    DataRow r = t2.NewRow();
                    r[0] = "";
                    r[1] = types[i];
                    r[2] = fn;
                    t2.Rows.Add(r);
                    r[7] = System.IO.File.GetLastWriteTime(f).ToString("MM/dd HH:mm");
                    cnt++;
                }
                DataRow r3 = t3.NewRow();
                r3[0] = types[i];
                r3[1] = cnt;
                t3.Rows.Add(r3);
            }
            if(t2.Rows.Count > 0) {
                icon = c_color;
                notifyIcon2.Visible = true;
            }
            else {
                icon = c_white;
                notifyIcon1.Visible = true;
            }
            toolStripStatusLabe2.Text = String.Format("滞留数={0}", t2.Rows.Count);
            notifyIcon2.Text = String.Format("滞留 {0}件\n", t2.Rows.Count);
            タスクバー編集(t2);
            #endregion

            if(!MODE2) {
                rcv = new recieveprocess(this);  //受信スレッド開始
                thread2 = new System.Threading.Thread(new System.Threading.ThreadStart(rcv.recieve));
                thread2.Start();

                sendToServer("putLog", "start");
                foreach(DataRow r in t2.Rows) {  //照会送信
                    sendToServer("getdocumentinfo", folders[types.IndexOf(r[1].ToString())], r[2].ToString());
                }
            }

            #region イベント登録
            int errcount = 0;
            for(int i = 0; i < folders.Count; i++) {
                watcher.Add(new FileSystemWatcher());
                try {
                    watcher[i].Path = folders[i];
                    if(this.muskstring != "") {
                        watcher[i].Filter = "*" + this.muskstring + "*";
                    }
                    watcher[i].NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite;
                    watcher[i].Created += new FileSystemEventHandler(Createdevent);
                    watcher[i].Deleted += new FileSystemEventHandler(Deletedevent);
                    watcher[i].Renamed += new RenamedEventHandler(Renamedevent);
                    watcher[i].Changed += new FileSystemEventHandler(Changedevent);
                    watcher[i].EnableRaisingEvents = true;
                }
                catch(Exception ex) {
                    colorFont("エラー：" + ex.Message + "(これは監視対象から外れます)");
                    errcount++;
                    continue;
                }
            }
            if(errcount == watcher.Count && watcher.Count != 0) {
                MessageBox.Show(string.Format("ファイルサーバへの通知要求登録がすべてエラーとなりました。{0}ログインを必要とするファイルサーバはこのツールを立ち上げる前にログイン済みである必要があります。{0}ご確認下さい。", Environment.NewLine), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            CreatedEventMethod = new DelegateFileSystemEvent(Createdevent);
            DeleteEventMethod = new DelegateFileSystemEvent(Deletedevent);
            RenamedEventMethod = new DelegateRenamedEvent(Renamedevent);
            ChangedEventMethod = new DelegateFileSystemEvent(Changedevent);
            #endregion

            #region 後処理
            button1.Text = "監視停止";
            lbl稼働状況.Text = "監視中...";
            lbl稼働状況.ForeColor = System.Drawing.Color.Blue;
            toolStripStatusLabel4.Text = "";
            タスクバー編集(dataSet2.Tables[0]);
            //timer1.Enabled = true;
            #endregion
            if(MODE2) {
                dataGridView2.Columns["docpriority"].Visible = false;
                dataGridView2.Columns["doccomment"].Visible = false;
                dataGridView2.Columns["trackingperson"].Visible = false;
                toolStripStatusLabel2.Text = "MODE2";
            }
            else {
                toolStripStatusLabel2.Text = "MODE1";
            }
            return; //開始処理完了
        }


        //ファイル通知イベント処理
        int countOFdisplay = 0;
        public volatile Object 行Lock = new Object();
        //作成の場合
        DelegateFileSystemEvent CreatedEventMethod;
        public void Createdevent(object source, FileSystemEventArgs e) {
            if(this.InvokeRequired) {
                object[] args = { source, e };
                this.Invoke(CreatedEventMethod, args);
                return;
            }
            string ename = e.Name.ToUpper();
            string doctype = types[watcher.IndexOf((FileSystemWatcher)source)];
            normalFont(String.Format("　　作成通知 {0}  {1}  {2}", DateTime.Now.ToString("MM/dd HH:mm:ss"), doctype, ename));
            toolStripStatusLabel1.Text = String.Format("通知数={0}", ++countOFdisplay);
            if(!(ename.StartsWith("!") || ename.StartsWith("！") || ename.EndsWith(".LNK"))) {
                if(notmuskstring != "") {
                    bool skip = false;
                    foreach(string s in notmuskstring.Split(',')) {
                        if(ename.Contains(s.ToUpper())) skip = true;
                    }
                    if(skip) return;
                }

                DataTable t = dataSet2.Tables[0];
                DataRow r = t.NewRow();
                r[0] = DateTime.Now.ToString("HH:mm:ss");
                r[1] = doctype;
                r[2] = ename;
                r[7] = System.IO.Directory.GetLastWriteTime(e.FullPath).ToString("MM/dd HH:mm");
                t.Rows.Add(r);
                dataGridView2.CurrentCell = null;
                //
                DataRow r3 = dataSet3.Tables[0].Rows.Find(doctype);
                if(r3 != null) {
                    r3[1] = (int)r3[1] + 1;
                    dataGridView1.CurrentCell = null;
                }
                if(t.Rows.Count > 0 && icon == c_white) {
                    icon = c_color;
                    notifyIcon1.Visible = false;
                    notifyIcon2.Visible = true;
                }
                notifyIcon2.BalloonTipTitle = doctype + " 到着";
                notifyIcon2.BalloonTipText = String.Format("滞留 {0}件", t.Rows.Count);
                notifyIcon2.ShowBalloonTip(10000); //Min 10,000 in win
                notifyIcon2.Text = String.Format("滞留 {0}件\n", t.Rows.Count);
                toolStripStatusLabe2.Text = String.Format("滞留数={0}", t.Rows.Count); ;
                タスクバー編集(t);
                sendToServer("getdocumentinfo", folders[types.IndexOf(r[1].ToString())], r[2].ToString());
                if(folderForm.beepON)
                    soundcontrol.beep();
            }
        }

        //削除の場合
        DelegateFileSystemEvent DeleteEventMethod;
        private void Deletedevent(object source, FileSystemEventArgs e) {
            if(this.InvokeRequired) {
                object[] args = { source, e };
                this.Invoke(DeleteEventMethod, args);
                return;
            }
            string ename = e.Name.ToUpper();
            string doctype = types[watcher.IndexOf((FileSystemWatcher)source)];
            normalFont(String.Format("　　削除通知 {0}  {1}  {2}", DateTime.Now.ToString("MM/dd HH:mm:ss"), doctype, ename));
            toolStripStatusLabel1.Text = String.Format("通知数={0}", ++countOFdisplay);
            string[] keys = { doctype, ename };
            DataRow r = dataSet2.Tables[0].Rows.Find(keys);
            if(r != null) {
                toolStripStatusLabel4.Text = "last=[ " + r[1] + " ] " + r[2] + " ";
                r.Delete();
                dataGridView2.CurrentCell = null;
            }
            //
            DataRow r3 = dataSet3.Tables[0].Rows.Find(doctype);
            if(r3 != null) {
                r3[1] = (int)r3[1] - 1;
                dataGridView1.CurrentCell = null;
            }
            if(dataSet2.Tables[0].Rows.Count == 0 && icon == c_color) {
                icon = c_white;
                notifyIcon1.Visible = true;
                notifyIcon2.Visible = false;
            }
            notifyIcon2.Text = String.Format("滞留 {0}件\n", dataSet2.Tables[0].Rows.Count);
            toolStripStatusLabe2.Text = String.Format("滞留数={0}", dataSet2.Tables[0].Rows.Count); ;
            タスクバー編集(dataSet2.Tables[0]);
        }

        //名前変更の場合
        DelegateRenamedEvent RenamedEventMethod;
        private void Renamedevent(object source, RenamedEventArgs e) {
            if(this.InvokeRequired) {
                object[] args = { source, e };
                this.Invoke(RenamedEventMethod, args);
                return;
            }
            string ename = e.Name.ToUpper();
            string eoldname = e.OldName.ToUpper();
            string doctype = types[watcher.IndexOf((FileSystemWatcher)source)];
            normalFont(String.Format("名前変更通知 {0}  {1}  {2}  【旧名： {3}", DateTime.Now.ToString("MM/dd HH:mm:ss"), doctype, ename, eoldname));
            toolStripStatusLabel1.Text = String.Format("通知数={0}", ++countOFdisplay);
            //
            string[] keys = { doctype, eoldname };
            DataRow r = dataSet2.Tables[0].Rows.Find(keys);
            if(r != null) {
                r[2] = ename;
                dataGridView2.CurrentCell = null;
            }
            if(ename.StartsWith("!") || ename.StartsWith("！") || ename.EndsWith(".LNK")) {
                r.Delete();
            }
        }

        //更新の場合
        string save_doctype, save_ename;
        DelegateFileSystemEvent ChangedEventMethod;
        private void Changedevent(object source, FileSystemEventArgs e) {
            if(this.InvokeRequired) {
                object[] args = { source, e };
                this.Invoke(ChangedEventMethod, args);
                return;
            }
            string ename = e.Name.ToUpper();
            string doctype = types[watcher.IndexOf((FileSystemWatcher)source)];
            if(save_doctype != doctype && save_ename != ename) {
                normalFont(String.Format("　　更新通知 {0}  {1}  {2}", DateTime.Now.ToString("MM/dd HH:mm:ss"), doctype, ename));
                save_doctype = doctype; save_ename = ename;
            }
            toolStripStatusLabel1.Text = String.Format("通知数={0}", ++countOFdisplay);
            //
            string[] keys = { doctype, ename };
            DataRow r = dataSet2.Tables[0].Rows.Find(keys);
            if(r != null) {
                r["updatetime"] = System.DateTime.Now.ToString("MM/dd_HH:mm");
                dataGridView2.CurrentCell = null;
                foreach(DataGridViewRow gr in dataGridView2.Rows) {
                    if(gr.Cells["dockind"].Value.ToString() == doctype && gr.Cells["docfolder"].Value.ToString() == ename) {
                        ((DataGridViewCell)gr.Cells["updatetime"]).Style.ForeColor = Color.Blue;
                        break;
                    }
                }
            }
        }

        private void タスクバー編集オフ() {
            this.Text = String.Format("{0} 監視ツール", "ＸＸ");
        }

        public void タスクバー編集(DataTable t) {
            int highprioritycount = 0;
            int totalcount = 0;
            for(int i = 0; i < t.Rows.Count; i++) {
                if(!t.Rows[i]["dockind"].ToString().StartsWith("!") && !t.Rows[i]["dockind"].ToString().StartsWith("！")) {
                    totalcount++;
                    if(t.Rows[i]["docpriority"].ToString() == "至急") {
                        highprioritycount++;
                    }
                }
            }
            if(MODE2) {
                this.Text = String.Format("{0} 監視ツール", totalcount);
            }
            else {
                this.Text = String.Format("{0}/{1} 監視ツール", highprioritycount, totalcount);
            }
        }


        #region 印書処理
        private void 印刷PToolStripButton_Click(object sender, EventArgs e) {
            FormPrint(this);
        }

        //フォーム印書
        internal void FormPrint(Form frm) {
            //フォームのイメージを取得する
            Graphics mygraphics = frm.CreateGraphics();
            memoryImage = new Bitmap(frm.ClientRectangle.Width, frm.ClientRectangle.Height, mygraphics);
            Graphics memoryGraphics = Graphics.FromImage(memoryImage);
            IntPtr dc1 = mygraphics.GetHdc();
            IntPtr dc2 = memoryGraphics.GetHdc();
            BitBlt(dc2, 0, 0, frm.ClientRectangle.Width, frm.ClientRectangle.Height, dc1, 0, 0, 13369376);
            mygraphics.ReleaseHdc(dc1);
            memoryGraphics.ReleaseHdc(dc2);
            //ダイアログ
            PrintDialog dilg = new PrintDialog();
            dilg.PrinterSettings = new System.Drawing.Printing.PrinterSettings();
            DialogResult ans = dilg.ShowDialog();
            if(ans == DialogResult.OK) {
                //フォームのイメージを印刷する
                System.Drawing.Printing.PrintDocument PrintDocument1 = new System.Drawing.Printing.PrintDocument();
                System.Drawing.Printing.PrinterSettings ps = new System.Drawing.Printing.PrinterSettings();
                ps.DefaultPageSettings.Landscape = true;
                PrintDocument1.PrinterSettings = ps;
                PrintDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(PrintDocument1_PrintPage);
                PrintDocument1.Print();
            }
        }

        [System.Runtime.InteropServices.DllImport("gdi32.dll")]
        private static extern bool BitBlt(IntPtr hdcDest,
             int nXDest, int nYDest, int nWidth, int nHeight,
             IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
        private Bitmap memoryImage;
        //印書イベントハンドラ
        private void PrintDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) {
            e.Graphics.DrawImage(memoryImage, 0, 0);
        }
        #endregion

        //ヘルプボタン押下
        private void ヘルプLToolStripButton_Click(object sender, EventArgs e) {
            About AboutForm = new About(this);
            AboutForm.ShowDialog();
            AboutForm.Dispose();
        }

        //フォーム終了時
        private void Form1_FormClosing(object sender, FormClosingEventArgs e) {//終了処理
            if(!conflict) {
                //timer1.Enabled = false;
                //ファイルウォッチャー解除
                foreach(FileSystemWatcher w in watcher) {
                    w.EnableRaisingEvents = false;
                }
                normalFont(String.Format("　　　　終了 {0}", DateTime.Now.ToString("MM/dd HH:mm:ss")));
                if(!MODE2) {
                    //ログ電文送信
                    TimeSpan elaps = DateTime.Now.Subtract(starttime);
                    string xelaps = string.Format("{0}:{1}:{2}", elaps.Hours, elaps.Minutes, elaps.Seconds);
                    sendToServer("putLog", "fin", textBoxIn.Lines.Length.ToString() + "lines", "elaps" + xelaps);
                    //udp.Close();//送信用クローズ
                    closeCommunication();
                }
                //ログファイル出力
                System.IO.File.AppendAllText(Folder.parameterFolder + "文書監視ログ.txt", textBoxIn.Text, Encoding.GetEncoding("shift_jis"));
                //フォーム位置保存準備
                DataSet infodataset = new DataSet();
                DataTable t = infodataset.Tables.Add("layoutinfo");
                t.Columns.Add("X");
                t.Columns.Add("Y");
                t.Columns.Add("Width");
                t.Columns.Add("Height");
                t.Columns.Add("Splitter2Distance");
                t.Columns.Add("Splitter1Distance");
                t.Rows.Add(this.DesktopLocation.X, DesktopLocation.Y, ClientSize.Width, ClientSize.Height, splitContainer2.SplitterDistance, splitContainer1.SplitterDistance);
                //欄位置保存準備
                t = infodataset.Tables.Add("dgcolumninfo");
                DataRow row = t.NewRow();
                int i = 0;
                foreach(DataGridViewColumn dgcol in dataGridView2.Columns) {
                    t.Columns.Add(dgcol.HeaderText);
                    row[i++] = dgcol.DisplayIndex;
                }
                t.Rows.Add(row);
                //ビープオンオフ保存準備
                infodataset.Tables.Add(folderForm.getSaveTable());
                //ビープ音保存準備
                infodataset.Tables.Add(soundcontrol.getSaveTable());
                //保存ファイルへ出力
                System.IO.StreamWriter istrm = new System.IO.StreamWriter(Folder.parameterFolder + "savedWatcherinfo.xml", false, System.Text.Encoding.UTF8);
                infodataset.WriteXml(istrm);
                istrm.Close();

                if(!MODE2) objMutex.ReleaseMutex(); //ミューテックスを解放する
            }
        }

        //受信終了処理
        private void closeCommunication() {
            if(!MODE2) {
                if(thread2.IsAlive) {
                    rcv.recieveclose(); //受信停止
                    thread2.Join();
                }
            }
        }

        //フォーム終了後
        private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
            objMutex.Close();
            //Microsoft.Win32.SystemEvents.SessionEnding -= new Microsoft.Win32.SessionEndingEventHandler(SessionEnding);
        }

        //終了ボタン押下
        private void button2_Click(object sender, EventArgs e) { //終了ボタン押下
            this.Close();
        }

        //アイコンメニューの終了クリック
        private void 終了ToolStripMenuItem_Click(object sender, EventArgs e) { //タスクトレイで終了
            this.Close();
        }

        //アイコンメニューの表示クリック
        private void 表示するToolStripMenuItem_Click(object sender, EventArgs e) {
            //this.Visible = true;
            if(this.Visible == false) {
                this.Visible = true; // フォームの表示
                if(this.WindowState == FormWindowState.Minimized) {   //最小になってれば
                    this.WindowState = FormWindowState.Normal; // 最小化をやめる
                }
                this.Activate(); // フォームを前面に出す
            }
        }

        //パラメータ設定ボタンクリック
        private void btn設定_Click(object sender, EventArgs e) {
            folderForm.ShowDialog(this);

        }

        //画面を消すボタン
        private void btn消去_Click(object sender, EventArgs e) {
            if(notifyIcon1.Visible == true || notifyIcon2.Visible == true) {
                this.Visible = false;
            }
        }

        //タスクトレイアイコンクリック
        private void notifyIcon1_Click(object sender, EventArgs e) {
            if(((MouseEventArgs)e).Button == MouseButtons.Left) {
                //左マウス
                if(this.Visible == false) {
                    //FORM表示
                    this.Visible = true;
                    if(this.WindowState == FormWindowState.Minimized) {
                        this.WindowState = FormWindowState.Normal;
                    }
                    this.Activate();
                }
                else {
                    //FORM消去
                    this.Visible = false;
                }
            }
            else {
                //右マウス
                if(this.Visible == true) {
                    contextMenuStrip1.Items[1].Enabled = false;
                }
                else {
                    contextMenuStrip1.Items[1].Enabled = true;
                }
            }

        }

        //最初の表示でセルを選択しない
        private void Form1_Shown(object sender, EventArgs e) {
            dataGridView1.CurrentCell = dataGridView2.CurrentCell = null;
        }

        //送信ルーチン
        void sendToServer(params string[] text)  //サーバへ送信
        {
            if(MODE2) return;
            try {
                byte[] bytes = Encoding.UTF8.GetBytes(DateTime.Now.ToString("MM/dd HH:mm:ss") + "|" + 氏名 + "|WATCH|" + version + "|" + string.Join("|", text));
                foreach(string server in servers) {
                    udp.Send(bytes, bytes.Length, server, serverPort);
                }
            }
            catch(Exception) {
                colorFont("udp send To Server exception" );
            }
        }

        void sendToWatcher(params string[] text)  //監視ツールへBC送信
        {
            if(MODE2) return;
            udp.EnableBroadcast = true;
            udp.MulticastLoopback = true;
            try {
                byte[] bytes = Encoding.UTF8.GetBytes(DateTime.Now.ToString("MM/dd HH:mm:ss") + "|" + 氏名 + "|WATCH|" + version + "|" + string.Join("|", text));
                foreach(string network in networks) {
                    udp.Send(bytes, bytes.Length, network, watchPort);
                }
            }
            catch(Exception) {
                colorFont("udp sendToWatcher exception" + Environment.NewLine);
            }
        }

        void sendToTracker(params string[] text)  //追跡ツールへBC送信
        {
            if(MODE2) return;
            udp.EnableBroadcast = true;
            udp.MulticastLoopback = true;
            try {
                byte[] bytes = Encoding.UTF8.GetBytes(DateTime.Now.ToString("MM/dd HH:mm:ss") + "|" + 氏名 + "|WATCH|" + version + "|" + string.Join("|", text));
                foreach(string network in networks) {
                    udp.Send(bytes, bytes.Length, network, trackPort);
                }
            }
            catch(Exception) {
                colorFont("udp sendToTracker exception" + Environment.NewLine);
            }
        }

        //文書を開く
        private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e) {
            if(e.ColumnIndex == 2 && e.RowIndex != -1)//docfolder.indexが0になってしまう！
            {
                string f3 = dataGridView2.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
                string xf1 = dataGridView2.Rows[e.RowIndex].Cells[1].Value.ToString();
                string f1 = folders[types.IndexOf(xf1)];
                Process ex = new Process();
                ex.StartInfo.FileName = f1 + "\\" + f3;  //Explorer
                try {
                    ex.Start();
                    dataGridView2.CurrentCell = null;
                }
                catch(System.ComponentModel.Win32Exception) {
                    MessageBox.Show("文書が見つかりません");
                    colorFont("文書が見つかりません\n");
                }
                catch(Exception exa) {
                    MessageBox.Show(exa.Message);
                }
            }
        }

        //セル修正開始時
        private void dataGridView2_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) {
            beforcell = dataGridView2.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
        }

        //セル修正終了時
        string beforcell;
        private void dataGridView2_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
            if(dataGridView2.Columns[e.ColumnIndex].Name == "doccomment") {
                //コメント欄の修正
                DataGridViewRow gr = dataGridView2.Rows[e.RowIndex];
                if(beforcell != dataGridView2.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()) {
                    //内容に変更あり
                    DataRow dr = ((DataRowView)gr.DataBoundItem).Row;
                    dr["doccomment"] = dr["doccomment"].ToString().Replace('|', '｜');
                    if(dr["trackingperson"].ToString() != "") {
                        sendToServer("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                        sendToWatcher("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                        sendToTracker("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                    }
                    else {
                        string guid = System.Guid.NewGuid().ToString();
                        sendToServer("putdocumentinfo", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString(), guid);
                        sendToWatcher("putdocumentinfo", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString(), guid);
                        dr["trackingperson"] = 氏名;
                    }
                }
            }
            else if(dataGridView2.Columns[e.ColumnIndex].Name == "memo" && e.RowIndex != -1) {
                //メモ欄記入
                DataGridViewRow gr = dataGridView2.Rows[e.RowIndex];
                if(beforcell != gr.Cells[e.ColumnIndex].Value.ToString()) {
                    //内容に変更あり
                    DataRow dr = ((DataRowView)gr.DataBoundItem).Row;
                    dr["memo"] = dr["memo"].ToString().Replace('|', '｜');
                    sendToWatcher("putmemo", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["memo"].ToString());
                }
                //メモ行に色づけ
                if(gr.Cells[e.ColumnIndex].Value.ToString().Length != 0) {
                    gr.DefaultCellStyle.BackColor = Color.Silver;
                }
                else {
                    //メモ無し
                    if(!gr.Cells["dockind"].Value.ToString().StartsWith("!") && !gr.Cells["dockind"].Value.ToString().StartsWith("！")) {
                        gr.DefaultCellStyle.BackColor = Color.Empty;
                    }

                }
            }
        }

        //セルクリック
        private void dataGridView2_CellClick(object sender, DataGridViewCellEventArgs e) {
            if(e.RowIndex < 0) return;
            DataGridViewRow gr = dataGridView2.Rows[e.RowIndex];
            if(dataGridView2.Columns[e.ColumnIndex].Name == "docpriority") {
                //緊急度変更
                if(gr.Cells[e.ColumnIndex].Value.ToString() == "") {
                    if(MessageBox.Show("至急扱いに変更しますか？" + Environment.NewLine + "変更はすぐに他の画面に反映されます。", "緊急度変更", MessageBoxButtons.YesNo) == DialogResult.Yes) {
                        gr.Cells[e.ColumnIndex].Value = "至急";
                        DataRow dr = ((DataRowView)gr.DataBoundItem).Row;
                        if(dr["trackingperson"].ToString() != "") {
                            sendToServer("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                            sendToWatcher("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                            sendToTracker("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                        }
                        else {
                            string guid = System.Guid.NewGuid().ToString();
                            sendToServer("putdocumentinfo", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString(), guid);
                            sendToWatcher("putdocumentinfo", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString(), guid);
                            dr["trackingperson"] = 氏名;
                        }
                    }
                }
                else {
                    if(MessageBox.Show("通常扱いに戻しますか？" + Environment.NewLine + "変更はすぐに他の画面に反映されます。", "緊急度変更", MessageBoxButtons.YesNo) == DialogResult.Yes) {
                        gr.Cells[e.ColumnIndex].Value = "";
                        DataRow dr = ((DataRowView)gr.DataBoundItem).Row;
                        if(dr["trackingperson"].ToString() != "") {
                            sendToServer("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                            sendToWatcher("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                            sendToTracker("replacecomment", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString());
                        }
                        else {
                            string guid = System.Guid.NewGuid().ToString();
                            sendToServer("putdocumentinfo", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString(), guid);
                            sendToWatcher("putdocumentinfo", folders[types.IndexOf(dr["dockind"].ToString())], dr["docfolder"].ToString(), dr["doccomment"].ToString(), dr["docpriority"].ToString(), guid);
                            dr["trackingperson"] = 氏名;
                        }
                    }
                }
                タスクバー編集(((DataSet)dataGridView2.DataSource).Tables[0]);
            }
            else if(dataGridView2.Columns[e.ColumnIndex].Name == "updatetime") {
                //更新時刻強調解除
                gr.Cells["updatetime"].Style.ForeColor = Color.Empty;
                gr.Cells["updatetime"].Value = gr.Cells["updatetime"].Value.ToString().Replace("_", " ");
                dataGridView2.CurrentCell = null;
            }
        }

        //！付き文書種類は色付けする
        private void dataGridView2_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) {
            string 文書種類 = dataGridView2.Rows[e.RowIndex].Cells["dockind"].Value.ToString();
            if(文書種類.StartsWith("!") || 文書種類.StartsWith("！")) {
                dataGridView2.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Silver;
            }
        }

        //ソート時に再度色付する
        private void dataGridView2_Sorted(object sender, EventArgs e) {
            行に色付け();
        }

        internal void 行に色付け() {
            foreach(DataGridViewRow gr in dataGridView2.Rows) {
                //行を灰色に
                string 文書種類 = gr.Cells["dockind"].Value.ToString();
                string メモ = gr.Cells["memo"].Value.ToString();
                if(文書種類.StartsWith("!") || 文書種類.StartsWith("！") || メモ != "") {
                    gr.DefaultCellStyle.BackColor = Color.Silver;
                }
                else {
                    gr.DefaultCellStyle.BackColor = Color.Empty;
                }
                //時刻を青字に
                if(gr.Cells["updatetime"].Value.ToString().Contains("_")) {
                    gr.Cells["updatetime"].Style.ForeColor = Color.Blue;
                }

            }
            dataGridView2.CurrentCell = null;
        }

        private void normalFont(string txt) {
            this.textBoxIn.AppendText(txt);
            textBoxIn.SelectionStart = textBoxIn.TextLength;
            textBoxIn.ScrollToCaret();
            this.textBoxIn.AppendText("\r");
        }

        private void colorFont(string txt) {
            textBoxIn.SelectionColor = Color.Red;
            this.textBoxIn.AppendText(txt);
            textBoxIn.SelectionColor = Color.Empty;
            textBoxIn.SelectionStart = textBoxIn.TextLength;
            textBoxIn.ScrollToCaret();
            this.textBoxIn.AppendText("\r");
        }

        private void dataGridView2_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
            if(dataGridView2.Columns[e.ColumnIndex].Name == "docfolder") {
                if(e.Button == MouseButtons.Right) {
                    //MessageBox.Show("rightclick");
                }
            }
        }
    }
    delegate void DelegateFileSystemEvent(object source, FileSystemEventArgs e);  //デリゲート定義
    delegate void DelegateRenamedEvent(object source, RenamedEventArgs e);  //デリゲート定義

}