using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace IronIntel.Contractor
{
    public class ConvertFormat
    {
        /// <summary>
        /// 本函数将c#格式转换为excel格式，在转换时只允许一个格式中出现{0}或{0:xxx}之类的一次，多余的抛弃。
        /// </summary>
        /// <param name="csharpFormat"></param>
        /// <returns></returns>
        public static string ConvertFormatFromCSharpToExcel(string csharpFormat, CellDataType DataType)
        {
            if (string.IsNullOrEmpty(csharpFormat)) return "";

            #region 验证格式是否合格。
            switch (DataType)
            {
                case CellDataType.Bool:
                    if (!string.IsNullOrEmpty(csharpFormat))
                    {
                        string[] fors = csharpFormat.Split(';');
                        csharpFormat = "\"" + string.Join("\";\"", fors.ToArray()) + "\"";
                        if (fors.Length == 2)
                        {
                            csharpFormat = csharpFormat + ";" + "\"" + fors[1] + "\"";
                        }
                    }
                    break;
                case CellDataType.Date:
                    try
                    {
                        string.Format(csharpFormat, DateTime.Now);
                    }
                    catch
                    {
                        csharpFormat = "";
                    }
                    break;
                case CellDataType.Guid:
                    break;
                case CellDataType.Integer:
                    try
                    {
                        string.Format(csharpFormat, 1234);
                    }
                    catch
                    {
                        csharpFormat = "";
                    }
                    break;
                case CellDataType.Float:
                    try
                    {
                        string.Format(csharpFormat, 1234.567890);
                    }
                    catch
                    {
                        csharpFormat = "";
                    }
                    break;
                default:
                    break;
            }
            #endregion

            string cshxp = csharpFormat;
            string excelFormat = "";
            string pattern = @"\{0\}|\{0:[^\}]+\}";
            Regex reg = new Regex(pattern);
            MatchCollection mc = reg.Matches(csharpFormat);
            if (mc.Count > 0)
            {
                //将多余的格式串去掉。
                for (int i = 1; i < mc.Count; i++)
                {
                    cshxp = cshxp.Replace(mc[i].Value, "");
                }

                if (string.Equals(mc[0].Value, "{0}", StringComparison.OrdinalIgnoreCase))
                {
                    int first = cshxp.IndexOf(mc[0].Value);

                    //当格式为｛0｝时，设置FIC需要的默认格式。
                    string ft = "General";
                    if (DataType == CellDataType.Float)
                    {
                        ft = "0.00";
                    }
                    else if (DataType == CellDataType.Integer)
                    {
                        ft = "0";
                    }
                    else if (DataType == CellDataType.Date)
                    {
                        ft = "M-d-yyyy";
                    }
                    else if (DataType == CellDataType.Bool)
                    {
                        ft = "True\";\"False\";\"False";
                    }

                    excelFormat = "\"" + cshxp.Substring(0, first) + "\"" + ft + "\"" + cshxp.Substring(first + 3) + "\"";
                }
                else
                {
                    int first = cshxp.IndexOf(mc[0].Value);
                    string format = mc[0].Value.Replace("{0:", "");
                    format = format.Replace("}", "");

                    string[] strs = format.Split(';');
                    string preText = cshxp.Substring(0, first);
                    string postText = cshxp.Substring(first + mc[0].Value.Length);

                    string str2 = "";
                    foreach (string str in strs)
                    {
                        str2 = str;
                        if (DataType == CellDataType.Date)
                        {
                            str2 = ConvertSpecialDateFormat(str);
                        }
                        if (string.IsNullOrEmpty(excelFormat))
                        {
                            excelFormat = "\"" + preText + "\"" + str2 + "\"" + postText + "\"";
                        }
                        else
                        {
                            string tmpFormat = "\"" + preText + "\"" + str2 + "\"" + postText + "\"";
                            excelFormat = excelFormat + ";" + tmpFormat;
                        }
                    }
                }
            }
            else
            {
                excelFormat = cshxp;
            }

            return excelFormat;
        }

        private static string ConvertSpecialDateFormat(string format)
        {
            string result = format;
            //AM/PM:tt
            result = result.Replace("tt", "AM/PM");

            //fff:
            string pattern = @"\.f+";
            Regex reg = new Regex(pattern);
            MatchCollection mc = reg.Matches(result);
            foreach (Match mt in mc)
            {
                if (mt.Value == null) continue;

                string x0 = "";
                int num = mt.Value.Substring(1).Length;
                while (num > 0)
                {
                    x0 += "0";
                    num--;
                }
                result = result.Replace(mt.Value, "." + x0);
            }

            return result;
        }

        private static bool CheckIfCSharpFormatIsValid(string format)
        {
            bool result = false;
            try
            {
                FormatDouble(format);
                return true; ;
            }
            catch { }

            try
            {
                FormatDateTime(format);
                return true; ;
            }
            catch { }

            return result;
        }

        private static void FormatDouble(string format)
        {
            double x = 12345.7890;
            try
            {
                string.Format(format, x);
            }
            catch
            {
                x.ToString(format);
            }
        }

        private static void FormatDateTime(string format)
        {
            DateTime now = DateTime.Now;
            try
            {
                string.Format(format, now);
            }
            catch
            {
                now.ToString(format);
            }
        }
    }
}
