﻿/******************************************************************************
 プロジェクト: loxXmlUtils
 ライセンス: MIT License (http://opensource.org/licenses/mit-license.php)
   http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license
 *****************************************************************************/
/******************************************************************************
 Copyright (c) 2012-2015 synctam

 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
 the Software without restriction, including without limitation the rights to
 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 of the Software, and to permit persons to whom the Software is furnished to do
 so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *****************************************************************************/
//using Google.GData.Spreadsheets;
//using GoogleDocUtils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Uguu.IO.Csv;

namespace loxXmlUtils
{
    public class TJxFlashCard
    {
        public enum TConvertType
        {
            None,
            ProperNounJapanese, // 固有名詞日本語版にのみ適用
            Both,               // 固有名詞日本語版、固有名詞英語版ともに適用
        }

        public enum TConvertMode
        {
            ProperNounJapanese, // 固有名詞日本語版として処理する
            ProperNounEnglish,  // 固有名詞英語版として処理する
        }

        public class TJxProperNoun
        {
            public int CharacterLength = 0;
            public string Initial = null;
            public TConvertType FConvertType = TConvertType.None;
            public string Prefix = null;
            public string English = null;
            public string Japanese = null;
            public string Category = null;
            public string Comment = null;
            public string Other = null;
            public TConvertType ConvertType
            {
                get { return this.FConvertType; }
            }

            public TConvertType setConvertType(string value)
            {
                TConvertType result = TConvertType.None;
                switch (value) {
                    case "@":
                        result = TConvertType.ProperNounJapanese;
                        break;
                    case "#":
                        result = TConvertType.Both;
                        break;
                    default:
                        result = TConvertType.None;
                        break;
                }
                return result;
            }
        }

        private List<TJxProperNoun> FProperNounList = new List<TJxProperNoun>();
        public List<TJxProperNoun> ProperNounList { get { return this.FProperNounList; } }

        /// <summary>
        /// 固有名詞単語帳と読み込み単語帳リストを作成する
        /// </summary>
        /// <param name="FileName">CSVファイル名</param>
        /// <param name="encCSV">CSVファイル名の文字コード</param>
        public void loadFromCsv(string FileName, Encoding encCSV = null)
        {
            if (encCSV == null) encCSV = Encoding.UTF8;
            using (StreamReader reader = new StreamReader(FileName, encCSV)) {
                using (CsvReader csvReader = new CsvReader(reader, "\n", ",", false)) {
                    this.FProperNounList.Clear();
                    while (csvReader.Read()) {
                        if (csvReader[0].StartsWith("[[")) {
                            // 1行目は見出し行なのでスキップ
                        } else {
                            TJxProperNoun data = new TJxProperNoun();
                            data.CharacterLength = int.Parse(csvReader[0]);
                            data.Initial = csvReader[1];
                            data.FConvertType = data.setConvertType(csvReader[2]);
                            data.Prefix = csvReader[3];
                            data.English = csvReader[4];
                            data.Japanese = csvReader[5];
                            data.Category = csvReader[6];
                            data.Comment = csvReader[7];
                            data.Other = csvReader[8];
                            // [[変換対象(ConvertType)]]、[[英語]]、[[日本語]]に値がない場合は無視する。
                            if ((data.ConvertType == TConvertType.None) ||
                                (string.IsNullOrWhiteSpace(data.English)) ||
                                (string.IsNullOrWhiteSpace(data.Japanese))) {
                                continue;
                            } else {
                                this.FProperNounList.Add(data);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Googleスプレッドシートの固有名詞単語帳シートをネット経由で読み込み単語帳リストを作成する
        /// </summary>
        //internal void loadFromGoogle(string appName, string user, string ClientID, string ClientSecret, string BookName, string SheetName = null)
        //{
        //    if (string.IsNullOrWhiteSpace(BookName)) {
        //        BookName = TJxCommon.BOOK_NAME;
        //    }
        //    if (string.IsNullOrWhiteSpace(SheetName)) {
        //        SheetName = "固有名詞単語帳";
        //    }
        //    this.FProperNounList.Clear();
        //    try {
        //        JxGoogleSpreadsheet ggl = new JxGoogleSpreadsheet();
        //        ListFeed sheet = ggl.getTablebyBookAndSheet(appName, user, ClientID, ClientSecret, BookName, SheetName);
        //        foreach (ListEntry row in sheet.Entries) {
        //            TJxProperNoun data = new TJxProperNoun();
        //            data.CharacterLength = int.Parse(row.Elements[0].Value);
        //            data.Initial = row.Elements[1].Value;
        //            data.FConvertType = data.setConvertType(row.Elements[2].Value);
        //            data.Prefix = row.Elements[3].Value;
        //            data.English = row.Elements[4].Value;
        //            data.Japanese = row.Elements[5].Value;
        //            data.Category   = row.Elements[6].Value;
        //            data.Comment = row.Elements[7].Value;
        //            data.Other = row.Elements[8].Value;
        //            // [[変換対象(ConvertType)]]、[[英語]]、[[日本語]]に値がない場合は無視する。
        //            if ((data.ConvertType == TConvertType.None) ||
        //                (string.IsNullOrWhiteSpace(data.English)) ||
        //                (string.IsNullOrWhiteSpace(data.Japanese))) {
        //                continue;
        //            } else {
        //                this.FProperNounList.Add(data);
        //            }
        //        }
        //        Console.WriteLine("Googleスプレッドシート処理件数({0})：{1}", SheetName, this.FProperNounList.Count);
        //    }
        //    catch (ArgumentException ex) {
        //        Console.Error.WriteLine(ex.StackTrace);
        //        Console.Error.WriteLine(ex.Message);
        //        throw;
        //    }
        //}
        private delegate string DMakePrefix(string Prefix);

        public string Convert(string msg, TConvertMode ConvertMode)
        {
            DMakePrefix makePrefix = delegate(string Prefix)
            {
                if (string.IsNullOrWhiteSpace(Prefix)) {
                    return "";
                } else {
                    return Prefix + "_";
                }
            };

            // 置き換え対象文字が含まれない場合は何もしない。
            if (!msg.Contains("@")) {
                return msg;
            } else {
                foreach (TJxProperNoun proper in this.FProperNounList) {
                    string oldChar = null;
                    oldChar = string.Format("@{0}{1}@", makePrefix(proper.Prefix), proper.English);
                    if (msg.Contains("@")) {
                        if (ConvertMode == TConvertMode.ProperNounEnglish) { // 固有名詞英語版
                            if (proper.ConvertType == TConvertType.Both) {
                                msg = TJxCommon.StringReplace(msg, oldChar, proper.Japanese, -1, true);
                            } else if (proper.ConvertType == TConvertType.ProperNounJapanese) {
                                // 英語版の場合は日本語化せず前後の「@」のみ除去する。
                                msg = TJxCommon.StringReplace(msg, oldChar, proper.English, -1, true);
                            }
                        } else if (ConvertMode == TConvertMode.ProperNounJapanese) { // 固有名詞日本語版
                            msg = TJxCommon.StringReplace(msg, oldChar, proper.Japanese, -1, true);
                        }
                    }
                }
            }
            return msg;
        }
    }
}
