using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XPrint.Image
{
    #region 参数解析
    public class Options
    {
        public List<string> InputFiles { get; set; } = new List<string>();
        public string OutputPattern { get; set; } = "{0}.svg";
        public int? Cores { get; set; }
        public int? Colors { get; set; }
        public string Quantization { get; set; } = "mc";
        public string Dither { get; set; }
        public string Remap { get; set; }
        public bool Stack { get; set; }
        public float Prescale { get; set; } = 1.0f;
        public int Despeckle { get; set; } = 2;
        public float SmoothCorners { get; set; } = 1.0f;
        public float OptimizePaths { get; set; } = 0.2f;
        public bool Background { get; set; }
        public string Width { get; set; }
        public string Height { get; set; }
        public bool Verbose { get; set; }
    }


    public class MainOptions
    {
        public static Options ParseArguments(string[] args)
        {
            Options options = new Options();
            int i = 0;

            while (i < args.Length)
            {
                string arg = args[i];
                switch (arg.ToLower())
                {
                    case "-i":
                    case "--input":
                        if (i + 1 >= args.Length)
                            return null;
                        i++;
                        while (i < args.Length && !args[i].StartsWith("-"))
                        {
                            options.InputFiles.Add(args[i]);
                            i++;
                        }
                        break;

                    case "-o":
                    case "--output":
                        if (i + 1 >= args.Length)
                            return null;
                        options.OutputPattern = args[i + 1];
                        i += 2;
                        break;

                    case "-C":
                    case "--cores":
                        if (i + 1 >= args.Length || !int.TryParse(args[i + 1], out int cores) || cores <= 0)
                            return null;
                        options.Cores = cores;
                        i += 2;
                        break;

                    case "-c":
                    case "--colors":
                        if (i + 1 >= args.Length || !int.TryParse(args[i + 1], out int colors) || colors < 0 || colors > 256)
                            return null;
                        options.Colors = colors;
                        i += 2;
                        break;

                    case "-q":
                    case "--quantization":
                        if (i + 1 >= args.Length || !new[] { "mc", "as", "nq" }.Contains(args[i + 1].ToLower()))
                            return null;
                        options.Quantization = args[i + 1].ToLower();
                        i += 2;
                        break;

                    case "-fs":
                    case "--floydsteinberg":
                        options.Dither = "floydsteinberg";
                        i++;
                        break;

                    case "-ri":
                    case "--riemersma":
                        options.Dither = "riemersma";
                        i++;
                        break;

                    case "-r":
                    case "--remap":
                        if (i + 1 >= args.Length)
                            return null;
                        options.Remap = args[i + 1];
                        i += 2;
                        break;

                    case "-s":
                    case "--stack":
                        options.Stack = true;
                        i++;
                        break;

                    case "-p":
                    case "--prescale":
                        if (i + 1 >= args.Length || !float.TryParse(args[i + 1], out float prescale) || prescale <= 0)
                            return null;
                        options.Prescale = prescale;
                        i += 2;
                        break;

                    case "-d":
                    case "--despeckle":
                        if (i + 1 >= args.Length || !int.TryParse(args[i + 1], out int despeckle) || despeckle < 0)
                            return null;
                        options.Despeckle = despeckle;
                        i += 2;
                        break;

                    case "-sc":
                    case "--smoothcorners":
                        if (i + 1 >= args.Length || !float.TryParse(args[i + 1], out float smooth) || smooth < 0 || smooth > 1.334)
                            return null;
                        options.SmoothCorners = smooth;
                        i += 2;
                        break;

                    case "-op":
                    case "--optimizepaths":
                        if (i + 1 >= args.Length || !float.TryParse(args[i + 1], out float optimize) || optimize < 0 || optimize > 5)
                            return null;
                        options.OptimizePaths = optimize;
                        i += 2;
                        break;

                    case "-bg":
                    case "--background":
                        options.Background = true;
                        i++;
                        break;

                    case "--width":
                        if (i + 1 >= args.Length)
                            return null;
                        options.Width = args[i + 1];
                        i += 2;
                        break;

                    case "--height":
                        if (i + 1 >= args.Length)
                            return null;
                        options.Height = args[i + 1];
                        i += 2;
                        break;

                    case "-v":
                    case "--verbose":
                        options.Verbose = true;
                        i++;
                        break;

                    case "-h":
                    case "--help":
                        return null;

                    default:
                        // 未知参数
                        return null;
                }
            }

            // 验证必要参数
            if (!options.InputFiles.Any())
                return null;

            if (options.Colors == null && string.IsNullOrEmpty(options.Remap))
                return null;

            return options;
        }

        public static void ShowHelp()
        {
            Console.WriteLine("ColorPotrace - 使用potrace将位图转换为彩色SVG");
            Console.WriteLine("用法: ColorPotrace [选项]");
            Console.WriteLine();
            Console.WriteLine("必选参数:");
            Console.WriteLine("  -i, --input <文件>     输入文件，支持通配符");
            Console.WriteLine("  必须指定以下之一:");
            Console.WriteLine("  -n, --colors <数量>    缩减到的颜色数量 (0-256)");
            Console.WriteLine("  -r, --remap <文件>     使用指定的调色板图像");
            Console.WriteLine();
            Console.WriteLine("可选参数:");
            Console.WriteLine("  -o, --output <模式>    输出文件模式，使用{0}表示文件名 (默认: {0}.svg)");
            Console.WriteLine("  -c, --cores <数量>     使用的进程数量 (默认: CPU核心数)");
            Console.WriteLine("  -q, --quantization <算法> 颜色量化算法: mc, as, nq (默认: mc)");
            Console.WriteLine("  -fs, --floydsteinberg  使用Floyd-Steinberg拟色");
            Console.WriteLine("  -ri, --riemersma       使用Riemersma拟色");
            Console.WriteLine("  -s, --stack            启用堆栈描摹");
            Console.WriteLine("  -p, --prescale <比例>  预缩放比例 (默认: 1.0)");
            Console.WriteLine("  -d, --despeckle <大小> 抑制斑点大小 (默认: 2)");
            Console.WriteLine("  -S, --smoothcorners <值> 转角平滑度 (0-1.334, 默认: 1.0)");
            Console.WriteLine("  -O, --optimizepaths <值> 路径优化 (0-5, 默认: 0.2)");
            Console.WriteLine("  -bg, --background      将第一个颜色作为背景");
            Console.WriteLine("  --width <尺寸>         输出宽度 (例如: 100pt)");
            Console.WriteLine("  --height <尺寸>        输出高度 (例如: 100pt)");
            Console.WriteLine("  -v, --verbose          显示详细信息");
            Console.WriteLine("  -h, --help             显示帮助信息");
        }
        #endregion      
    }
}
