using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using NMeCab;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Linq;

using MecInfoDll;

namespace nispi
{
    [Serializable]
    public class MecInfo
    {
        public MeCabTagger t;
        public List<MecWordList> mecWords;

        List<MecWord> pqbdHumanList;
        List<MecWord> pqbdSocietryList;
        List<MecWord> pqbdOtherList;
        List<MecWord> humanLastNameList;
        List<MecWord> humanFirstNameList;
        List<MecWord> societryList;
        List<MecWord> areaList;
        List<MecWord> otherList;

        List<string> pqbdHumanStrList;
        List<string> pqbdSocietyStrList;
        List<string> pqbdOtherStrList;
        List<string> humanFirstNameStrList;
        List<string> humanLastNameStrList;
        List<string> societyStrList;
        List<string> areaStrList;
        List<string> otherStrList;

        public MecInfo()
        {
            t = MeCabTagger.Create();

            mecWords = new List<MecWordList>();
            
            pqbdHumanList = new List<MecWord>();
            pqbdSocietryList = new List<MecWord>();
            pqbdOtherList = new List<MecWord>();
            humanLastNameList = new List<MecWord>();
            humanFirstNameList = new List<MecWord>();
            societryList = new List<MecWord>();
            areaList = new List<MecWord>();
            otherList = new List<MecWord>();

            pqbdHumanStrList = new List<string>();
            pqbdSocietyStrList = new List<string>();
            pqbdOtherStrList = new List<string>();
            humanFirstNameStrList = new List<string>();
            humanLastNameStrList = new List<string>();
            societyStrList = new List<string>();
            areaStrList = new List<string>();
            otherStrList = new List<string>();
        }

        public List<MecWordList> GetMecWord(List<Comment> comments)
        {
            try
            {
                ClearData(pqbdHumanList);
                ClearData(pqbdSocietryList);
                ClearData(pqbdOtherList);
                ClearData(humanLastNameList);
                ClearData(humanFirstNameList);
                ClearData(societryList);
                ClearData(areaList);
                ClearData(otherList);

                pqbdHumanStrList.Clear();
                pqbdSocietyStrList.Clear();
                pqbdOtherStrList.Clear();
                humanFirstNameStrList.Clear();
                humanLastNameStrList.Clear();
                societyStrList.Clear();
                areaStrList.Clear();
                otherStrList.Clear();
                mecWords.Clear();
            }
            catch
            {
                //return null;
            }
            
            GetAnalysisData(comments);

            MecWordList mcList = new MecWordList("人名(フルネーム)", pqbdHumanList);
            mecWords.Add(mcList);
            mcList = new MecWordList("組織１", pqbdSocietryList);
            mecWords.Add(mcList);
            mcList = new MecWordList("その他１",pqbdOtherList);
            mecWords.Add(mcList);
            mcList = new MecWordList("名前(苗字)",humanFirstNameList);
            mecWords.Add(mcList);
            mcList = new MecWordList("名前(下の名前)",humanLastNameList);
            mecWords.Add(mcList);
            mcList = new MecWordList("組織２",societryList);
            mecWords.Add(mcList);
            mcList = new MecWordList("地域", areaList);
            mecWords.Add(mcList);
            mcList = new MecWordList("その他２",otherList);
            mecWords.Add(mcList);

            return mecWords;
        }
        private void ClearData(List<MecWord> mecWords)
        {
            try
            {
                foreach (MecWord m in mecWords)
                {
                    m.list.Clear();
                }
                mecWords.Clear();
            }
            catch { ;}
        }
        public void GetAnalysisData(List<Comment> comments)
        {

 

            foreach (Comment comment in comments)
            {
                int num = 0;
                //チェック開始

                //単語のリストを得る
                Nmecab(comment.body);
                //単語一つ一つをチェックする
                CheckAndAddList(pqbdHumanList, pqbdHumanStrList, comment.num);
                CheckAndAddList(pqbdSocietryList, pqbdSocietyStrList, comment.num);
                CheckAndAddList(pqbdOtherList, pqbdOtherStrList, comment.num);
                CheckAndAddList(humanLastNameList, humanLastNameStrList, comment.num);
                CheckAndAddList(humanFirstNameList, humanFirstNameStrList, comment.num);
                CheckAndAddList(societryList, societyStrList, comment.num);
                CheckAndAddList(areaList, areaStrList, comment.num);
                CheckAndAddList(otherList, otherStrList, comment.num);

                pqbdHumanStrList.Clear();
                pqbdSocietyStrList.Clear();
                pqbdOtherStrList.Clear();
                humanFirstNameStrList.Clear();
                humanLastNameStrList.Clear();
                societyStrList.Clear();
                areaStrList.Clear();
                otherStrList.Clear();
                mecWords.Clear();
            }
        }
        void CheckAndAddList(List<MecWord> mecList, List<string> strList, string numStr)
        {
            int num;
            foreach (string word in strList)
            {
                num = 0;
                
                //ループ中にmecword自体が書き換わってしまうのでエラーが起きる。
                foreach (MecWord mc in mecList)
                {
                    num += 1;
                    //リストに存在する場合
                    if (mc.mecword.CompareTo(word) == 0)
                    {
                        if (mc.list.Contains(numStr) == false)
                            mc.list.Add(numStr);
                        break;
                    }
                    else
                    {
                        //リストに存在しない上に、最後までループした場合
                        if (num == mecList.Count)
                        {
                            MecWord item = new MecWord(word, numStr);
                            mecList.Add(item);
                            break;
                        }
                    }
                }
                //最初にリストが存在しない場合は
                if (num == 0)
                {
                    MecWord item = new MecWord(word, numStr);
                    mecList.Add(item);
                }
            }
        }

        public void Nmecab(string str)
        {
            //List<string> wordlist = new List<string>();
            // NMeCab はクラス名が変更されている

            MeCabNode node = t.ParseToNode(str);
            node = node.Next;
            while (node != null)
            {

                //固有名詞・一般
                if (node.RCAttr == 1288)
                {
                    if ((node.Surface.Length > 1) &&
                        (false == node.Surface.Contains("www")) &&
                        (false == node.Surface.Contains("ｗｗｗ"))&&
                        (false == node.Surface.Contains("WWW")) &&
                        (false == node.Surface.Contains("ＷＷＷ")))
                    otherStrList.Add(node.Surface);
                }
                //人名（フルネーム）
                else if (node.RCAttr == 1289)
                {
                    if (node.Feature.EndsWith("pqbd人物") == true)
                        pqbdHumanStrList.Add(node.Surface);
                    //フルネームでは通常のリストに加えない
                    //else
                    //    humanStrList.Add(node.Surface);
                }
                //人名（名前
                else if (node.RCAttr == 1290)
                {
                    humanFirstNameStrList.Add(node.Surface);
                }
                //人名（苗字
                else if (node.RCAttr == 1291)
                {
                    humanLastNameStrList.Add(node.Surface);
                }
                //未知語,組織
                else if (node.RCAttr == 1292)
                {
                    if (node.Surface.Length > 1)
                    {
                        //独自辞書
                        if (node.Feature.EndsWith("pqbd組織") == true)
                            pqbdSocietyStrList.Add(node.Surface);
                        //独自辞書
                        else if (node.Feature.EndsWith("pqbdその他") == true)
                            pqbdOtherStrList.Add(node.Surface);
                        //ipadic
                        else
                        {
                            if ((node.Surface.Length > 1) &&
                                (false == node.Surface.Contains("www")) &&
                                (false == node.Surface.Contains("ｗｗｗ")) &&
                                (false == node.Surface.Contains("WWW")) &&
                                (false == node.Surface.Contains("ＷＷＷ")))
                                societyStrList.Add(node.Surface);
                        }
                    }
                }
                //地域
                else if (node.RCAttr == 1293)
                {
                    areaStrList.Add(node.Surface);
                }
                node = node.Next;
            }
        }
    }
}