using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;

namespace App语言包处理工具
{
    public partial class LanguageDealerForm : Form
    {
        public LanguageDealerForm()
        {
            InitializeComponent();
        }

        private Dictionary<string, string> srcLangDic = new Dictionary<string, string>();
        private DataTable destExcelDt = new DataTable();
        private Platform srcLangPlatform = Platform.iOS;
        private Platform srcLangAnotherPlatform = Platform.iOS;
        private DataTable srcExcelDt = new DataTable();

        private enum Platform : int
        {
            Android = 1,
            iOS = 2,
        }

        //加载语言包原文件
        private void buttonGetSrcLangFilePath_Click(object sender, EventArgs e)
        {
            //获取文件路径
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            openFileDialog.Title = "请选择原始语言包文件";
            openFileDialog.Filter = "安卓文件(*.xml)|*.xml|iOS文件(*.txt)|*.txt";
            if (openFileDialog.ShowDialog() != DialogResult.OK)
            {
                //未选择文件
                return;
            }
            
            //处理语言文件
            bool isOK = false;
            int readedLineCnt = 0;
            if(Path.GetExtension(openFileDialog.FileName) ==".xml")
            {
                //Android
                readedLineCnt = DealWithAndroidLangSrcFile(openFileDialog.FileName);
                isOK = readedLineCnt != 0 ? true : false;
                srcLangPlatform = Platform.Android;
                srcLangAnotherPlatform = Platform.iOS;

            }
            else if(Path.GetExtension(openFileDialog.FileName) == ".txt")
            {
                //ios
                readedLineCnt = DealWithIOSLangSrcFile(openFileDialog.FileName);
                isOK = readedLineCnt != 0 ? true : false;
                srcLangPlatform = Platform.iOS;
                srcLangAnotherPlatform = Platform.Android;
            }
            else
            {
                textBoxStatus.Text = "！！！ 文件扩展名异常";
                return;
            }

            //显示提示信息
            if(isOK)
            {
                textBoxSrcLangFilePath.Text = openFileDialog.FileName;
                textBoxStatus.Text = "原始语言包读取完成,已读取【"+ readedLineCnt + "】行";
            }
            else
            {
                textBoxStatus.Text = "！！！ 原始语言包读取异常";
            }
        }

        //加载android语言包文件
        private int DealWithAndroidLangSrcFile(string filePath)
        {
            srcLangDic.Clear();
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(filePath);
                XmlNode root = xmlDoc.SelectSingleNode("resources");
                XmlNodeList nodeList = root.ChildNodes;
                //遍历所有子节点
                foreach (XmlNode xn in nodeList)
                {
                    XmlElement xe = null;
                    try
                    {
                        xe = (XmlElement)xn;
                    }
                    catch
                    {
                        continue;
                    }
                    string name = xe.GetAttribute("name");
                    string value = xe.InnerText;
                    if (name != null && name != "" && value != null && value != "")
                    {
                        srcLangDic.Add(name, value);
                    }
                }
                return srcLangDic.Count;
            }
            catch(Exception ex)
            {
                return 0;
            }
        }

        //加载ios语言包文件
        private int DealWithIOSLangSrcFile(string filePath)
        {
            System.IO.StreamReader file = null;
            string strline;
            int counter = 0;
            try
            {
                file = new System.IO.StreamReader(filePath);
                while ((strline = file.ReadLine()) != null)
                {
                    Regex keyRegex = new Regex("(?<=\").*?(?=(\" *=))");
                    MatchCollection keyMs = keyRegex.Matches(strline);
                    string key = "";
                    foreach (Match m in keyMs)
                    {
                        if (m.Success)
                        {
                            key = m.Groups[0].Value;
                        }
                    }

                    Regex valueRegex = new Regex("(?<=(= *\")).*?(?=(\" *;))");
                    MatchCollection valueMs = valueRegex.Matches(strline);
                    string value = "";
                    foreach (Match m in valueMs)
                    {
                        if (m.Success)
                        {
                            value = m.Groups[0].Value;
                        }
                    }

                    if(key!="" && value!="")
                    {
                        srcLangDic[key] = value;
                    }
                    counter++;
                }


                return srcLangDic.Count;
            }
            catch(Exception ex)
            {}
            finally
            {
                if(file!=null)
                {
                    file.Close();
                }
            }
            return 0;
        }

        //加载要写入的excel表格
        private void buttonGetDestExcelPath_Click(object sender, EventArgs e)
        {
            //打开文件
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            openFileDialog.Title = "请选择要保存的文件，如新建文件请复制Demo空表格再选择";
            openFileDialog.Filter = "Excel2003文件(*.xls)|*.xls";
            if (openFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            try
            {
                destExcelDt.Clear();

                using (XlsHelper destExcelHelper = new XlsHelper(openFileDialog.FileName))
                {
                    if (destExcelHelper == null)
                    {
                        textBoxStatus.Text = "！！！打开目标excel文件失败1";
                        return;
                    }
                    destExcelDt = destExcelHelper.ExcelToDataTable("语言包", true);
                    if (destExcelDt == null)
                    {
                        textBoxStatus.Text = "！！！目标excel文件格式错误，找不到指定的表";
                        return;
                    }

                    //判断列名
                    int columnCnt = destExcelDt.Columns.Count;
                    if (columnCnt < 3 ||
                       destExcelDt.Columns[0].ColumnName.ToLower() != "统一字段" ||
                       destExcelDt.Columns[1].ColumnName.ToLower() != "安卓字段" ||
                       destExcelDt.Columns[2].ColumnName.ToLower() != "ios字段"
                        )
                    {
                        textBoxStatus.Text = "！！！目标excel文件格式错误，找不到指定的列";
                        return;
                    }
                }

                textBoxDestExcelFilePath.Text = openFileDialog.FileName;
                textBoxStatus.Text = "打开目标excel文件成功 打开【"+ destExcelDt .Rows.Count+ "】行";

            }
            catch (Exception ex)
            {
                textBoxStatus.Text = "！！！打开目标excel文件失败3";
            }
        }

        private void LanguageDealerForm_Load(object sender, EventArgs e)
        {

        }

        private void LanguageDealerForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.ExitThread();
            Environment.Exit(0);
        }

        //保存excel表格
        private void buttonSaveDestExcelFile_Click(object sender, EventArgs e)
        {
            if (textBoxSrcLangFilePath.Text == "")
            {
                textBoxStatus.Text = "！！！请选择语言包文件";
                return;
            }
            if (textBoxDestExcelFilePath.Text == "")
            {
                textBoxStatus.Text = "！！！请选择要保存的excel文件";
                return;
            }
            if (textBoxLangName.Text == "")
            {
                textBoxStatus.Text = "！！！请输入语言包的语言名称";
                return;
            }

            DialogResult result = MessageBox.Show("字段和列名相同的语言值会被后写入的替换\r\n请确保新的语言文件后写入到excel文件中\r\n或者未不同平台使用不同的列名", "请注意:", MessageBoxButtons.OKCancel);
            if (result == DialogResult.Cancel)
            {
                return;
            }

            //获取要写入的列的index
            int columnsIndex = 0;
            int columnCnt = destExcelDt.Columns.Count;
            for (int i = 0; i < columnCnt; i++)
            {
                if (destExcelDt.Columns[i].ColumnName == textBoxLangName.Text)
                {
                    columnsIndex = i;
                }
            }
            //插入新列
            if (columnsIndex == 0)
            {
                DataColumn priceColumn = new DataColumn(textBoxLangName.Text, typeof(string));
                destExcelDt.Columns.Add(priceColumn);
                columnsIndex = columnCnt;
            }

            //遍历excel中的行
            for(int i= 0; i< destExcelDt.Rows.Count; i++)
            {
                string currentPlatformKey = "";
                try{currentPlatformKey = (string)destExcelDt.Rows[i][(int)srcLangPlatform];}
                catch{ }

                string anotherPlatformKey = "";
                try{anotherPlatformKey = (string)destExcelDt.Rows[i][(int)srcLangAnotherPlatform];}
                catch{ }

                string uniquePlatformKey = "";
                try{uniquePlatformKey = (string)destExcelDt.Rows[i][0];}
                catch{ }

                //存在当前平台的字段，修改当前语言
                if (srcLangDic.ContainsKey(currentPlatformKey))
                {
                    destExcelDt.Rows[i][columnsIndex] = srcLangDic[currentPlatformKey];
                    srcLangDic.Remove(currentPlatformKey);
                }
                //不存在当前平台字段，但存在其他平台字段，将字段改为统一字段
                //注意：这里会替换语言包内容，所以一定要后载入正确的语言包
                else if(srcLangDic.ContainsKey(anotherPlatformKey))
                {
                    destExcelDt.Rows[i][(int)srcLangAnotherPlatform] = "";
                    destExcelDt.Rows[i][0] = anotherPlatformKey;
                    destExcelDt.Rows[i][columnsIndex] = srcLangDic[anotherPlatformKey];
                    srcLangDic.Remove(anotherPlatformKey);
                }
                //存在在统一字段
                else if (srcLangDic.ContainsKey(uniquePlatformKey))
                {
                    destExcelDt.Rows[i][columnsIndex] = srcLangDic[uniquePlatformKey];
                    srcLangDic.Remove(uniquePlatformKey);
                }
            }

            //将剩余字典中的内容写入datatable
            foreach(KeyValuePair<string,string> item in srcLangDic)
            {
                DataRow dr = destExcelDt.NewRow();
                dr[(int)srcLangPlatform] = item.Key;
                dr[columnsIndex] = item.Value;
                destExcelDt.Rows.Add(dr);
            }

            //写入文件
            using (XlsHelper excelHelper = new XlsHelper(textBoxDestExcelFilePath.Text))
            {
                int count = excelHelper.DataTableToExcel(destExcelDt, "语言包", true);
                if (count <= 0)
                {
                    textBoxStatus.Text = "！！！Excel文件写入 失败";
                    return;
                }
            }

            textBoxSrcLangFilePath.Text = "";
            textBoxDestExcelFilePath.Text = "";
            textBoxStatus.Text = "Excel文件写入 成功";

        }

        //获取要读取的excel文件
        private void buttonGetSrcExcelFilePath_Click(object sender, EventArgs e)
        {
            //打开文件
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            openFileDialog.Title = "请选择要保存的文件，如新建文件请复制Demo空表格再选择";
            openFileDialog.Filter = "Excel2003文件(*.xls)|*.xls";
            if (openFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            try
            {
                srcExcelDt.Clear();
                comboBoxDestLangColumnName.Items.Clear();

                using (XlsHelper destExcelHelper = new XlsHelper(openFileDialog.FileName))
                {
                    if (destExcelHelper == null)
                    {
                        textBoxStatus.Text = "！！！打开目标excel文件失败1";
                        return;
                    }
                    srcExcelDt = destExcelHelper.ExcelToDataTable("语言包", true);
                    if (srcExcelDt == null)
                    {
                        textBoxStatus.Text = "！！！目标excel文件格式错误，找不到指定的表";
                        return;
                    }

                    //判断列名
                    int columnCnt = srcExcelDt.Columns.Count;
                    if (columnCnt < 3 ||
                       srcExcelDt.Columns[0].ColumnName.ToLower() != "统一字段" ||
                       srcExcelDt.Columns[1].ColumnName.ToLower() != "安卓字段" ||
                       srcExcelDt.Columns[2].ColumnName.ToLower() != "ios字段"
                        )
                    {
                        textBoxStatus.Text = "！！！目标excel文件格式错误，找不到指定的列";
                        return;
                    }

                    for(int i=3; i< srcExcelDt.Columns.Count; i++)
                    {
                        comboBoxDestLangColumnName.Items.Add(srcExcelDt.Columns[i].ColumnName);
                    }

                }

                textBoxSrcExelFilePath.Text = openFileDialog.FileName;
                textBoxStatus.Text = "打开目标excel文件成功 打开【" + srcExcelDt.Rows.Count + "】行";

            }
            catch (Exception ex)
            {
                textBoxStatus.Text = "！！！打开目标excel文件失败3";
            }
        }

        public class LangItem
        {
            public string key { get; set; }
            public string value { get; set; }

            public LangItem(string key, string value)
            {
                this.key = key;
                this.value = value;  
            }
        }
        List<LangItem> iosList = new List<LangItem>();
        List<LangItem> androidList = new List<LangItem>();

        //从excel文件导出为android和ios语言包
        private void buttonGetDestLangFiles_Click(object sender, EventArgs e)
        {
            if(textBoxSrcExelFilePath.Text == "")
            {
                textBoxStatus.Text = "！！！请选择excel语言包文件";
                return;
            }

            iosList.Clear();
            androidList.Clear();

            //获取要写入的列的index
            int columnsIndex = 3 + comboBoxDestLangColumnName.SelectedIndex;
            if(columnsIndex<3)
            {
                textBoxStatus.Text = "！！！请选择要生成语言包的列名";
                return;
            }

            //取list
            //遍历excel中的行
            for (int i = 0; i < srcExcelDt.Rows.Count; i++)
            {
                string iosPlatformKey = "";
                try { iosPlatformKey = (string)srcExcelDt.Rows[i][2]; }
                catch { }

                string androidPlatformKey = "";
                try { androidPlatformKey = (string)srcExcelDt.Rows[i][1]; }
                catch { }

                string uniquePlatformKey = "";
                try { uniquePlatformKey = (string)srcExcelDt.Rows[i][0]; }
                catch { }

                string value = "";
                try { value = (string)srcExcelDt.Rows[i][columnsIndex]; }
                catch { }

                if (checkBoxIsWriteWhileBlank.Checked || value != "")
                {
                    if (uniquePlatformKey != "")
                    {
                        //存在在统一字段
                        iosList.Add(new LangItem(uniquePlatformKey, value));
                        androidList.Add(new LangItem(uniquePlatformKey, value));
                    }
                    if (iosPlatformKey != "")
                    {
                        //存在在ios字段
                        iosList.Add(new LangItem(iosPlatformKey, value));
                    }
                    if (androidPlatformKey != "")
                    {
                        //存在在安卓字段
                        androidList.Add(new LangItem(androidPlatformKey, value));
                    }
                    if (uniquePlatformKey == "" && iosPlatformKey == "" && androidPlatformKey == "")
                    {
                        continue;
                    }
                }
            }

            string path = Path.GetDirectoryName(textBoxSrcExelFilePath.Text);
            string iosPath = path + "\\" + comboBoxDestLangColumnName.SelectedItem.ToString() + ".txt";
            string androidPath = path + "\\" + comboBoxDestLangColumnName.SelectedItem.ToString() + ".xml";

            WriteIOS(iosPath, iosList);
            WriteAndroid(androidPath, androidList);

            textBoxStatus.Text = "生成语言包成功";
            textBoxSrcExelFilePath.Text = "";
            comboBoxDestLangColumnName.Items.Clear();

        }

        //写ios语言包
        private void WriteIOS(string path, List<LangItem> list)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("/* \r\n  Localizable.strings\r\n*/\r\n\r\n");

            foreach (LangItem langitem in list)
            {
                sb.Append("\""+ langitem.key + "\"=\"" + langitem.value + "\";\r\n");
            }

            //文件已覆盖方式添加内容
            System.IO.StreamWriter file = new System.IO.StreamWriter(path, false);
            //保存数据到文件
            file.Write(sb.ToString());
            //关闭文件
            file.Close();
            file.Dispose();
        }

        //写android语言包
        private void WriteAndroid(string path, List<LangItem> list)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n\r\n");

            foreach(LangItem langitem in list)
            {
                sb.Append("    <string name=\"" + langitem.key + "\">" + langitem.value + "</string>\r\n");
            }
            sb.Append("\r\n</resources>");

            //文件已覆盖方式添加内容
            System.IO.StreamWriter file = new System.IO.StreamWriter(path, false);
            //保存数据到文件
            file.Write(sb.ToString());
            //关闭文件
            file.Close();
            file.Dispose();
        }
    }
}
