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

namespace AtlasGenerator
{
    public struct Arguments
    {
        public string m_sTargetPath;
        public string m_sRootPath;
        public uint m_iAtlasSize;
        public uint m_iAlignment;
        public uint m_iMargin;
    }
    
    static class SanitizeCommandlineInputs
    {
        static uint s_iDefaultAtlasSize = 4096;
        static uint s_iDefaultAlignment = 4;
        static uint s_iDefaultMargin = 2;
        
        static void PrintHelp()
        {
            Console.WriteLine("Tool for converting pngs into atlases\n\n" +
                                "Usage: " + Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location) + " rootpath targetpath [/size=n] [/alignment=n] [/margin=n] \n\n" +
                                "\trootPath: the root path of the art asset folder, needs to exist \n" +
                                "\ttargetpath: the path where the generated atlas files are to be placed \n" +
                                "\t/size=n: intended size for the atlases, n must be a power of 2. Optional, defaults to " + s_iDefaultAtlasSize + "\n" +
                                "\t/alignment=n: intended alignment of the pictures inside the atlas. Optional, defaults to " + s_iDefaultAlignment + "\n" +
                                "\t/margin=n: intended minimum margin from the border for all pictures inside the atlas. Optional, defaults to " + s_iDefaultMargin + "\n");

            Environment.Exit(1);
        }

        private static bool IsPowerOfTwo(uint x)
        {
            return (x != 0) && ((x & (x - 1)) == 0);
        }

        public static Arguments SanitizeInput(String[] args)
        {
            Arguments retVal = new Arguments();
            retVal.m_iAtlasSize = s_iDefaultAtlasSize;
            retVal.m_iAlignment = s_iDefaultAlignment;
            retVal.m_iMargin = s_iDefaultMargin;

            if (args.Length < 2 || args.Any(arg => arg == "/?" || arg == "-?" || arg == "--help" || arg == "-help"))
            {
                PrintHelp();
            }
            else
            {
                retVal.m_sRootPath = args[0];
                retVal.m_sTargetPath = args[1];

                foreach (var arg in args.Take(2))
                {
                    if (arg.StartsWith("/size=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var size = arg.Substring(6);
                        if (!uint.TryParse(size, out retVal.m_iAtlasSize) || !IsPowerOfTwo(retVal.m_iAtlasSize))
                        {
                            throw new Exception("Could not parse string for size to power of 2 uint : " + size);
                        }
                    }
                    else if (arg.StartsWith("/alignment=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var alignment = arg.Substring(11);
                        if (!uint.TryParse(alignment, out retVal.m_iAlignment) || !IsPowerOfTwo(retVal.m_iAlignment))
                        {
                            throw new Exception("Could not parse string for alignment to uint: " + alignment);
                        }
                    }
                    else if (arg.StartsWith("/margin=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var margin = arg.Substring(8);
                        if (!uint.TryParse(margin, out retVal.m_iMargin) || !IsPowerOfTwo(retVal.m_iMargin))
                        {
                            throw new Exception("Could not parse string for margin to uint: " + margin);
                        }
                    }
                }
            }

            return retVal;
        }
    }
}
