using SkiaSharp;

namespace omp
{
    using CalculationResults = Dictionary<string, double[,]>;

    public class Drawer
    {
        public static void DrawAll(Configurator conf, CalculationResults results)
        {
            Directory.CreateDirectory("output");
            foreach ((string name, double[,] matrix) in results)
            {
                Draw(conf, matrix, Path.Join("output", name + ".png"));
            }
        }

        public static void Draw(Configurator conf, double[,] matrix, string fileName)
        {
            (double min, double max) = matrix.MinMax();
            Console.WriteLine("{0}: {1}...{2}", fileName, min, max);

            var bitmap = new SKBitmap(conf.XSize, conf.YSize);

            for (int i = 0; i < conf.XSize; ++i)
            {
                for (int j = 0; j < conf.YSize; ++j)
                {
                    SKColor color;

                    if (double.IsNaN(matrix[i, j]))
                    {
                        color = SKColors.White;
                    }
                    else
                    {
                        double t = (matrix[i, j] - min) / (max - min);
                        color = Map2Color(t);
                    }

                    bitmap.SetPixel(i, j, color);
                }
            }

            using (var image = SKImage.FromBitmap(bitmap))
            using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
            using (var stream = File.OpenWrite(fileName))
            {
                data.SaveTo(stream);
            }
        }

        public static SKColor Map2Color(double t)
        {
            if (t < 0.25)
            {
                // Blue to cyan
                double localT = t / 0.25;
                return new SKColor(0, (byte)(255 * localT), 255);
            }
            else if (t < 0.5)
            {
                // Cyan to green
                double localT = (t - 0.25) / 0.25;
                return new SKColor(0, 255, (byte)(255 * (1 - localT)));
            }
            else if (t < 0.75)
            {
                // Green to yellow
                double localT = (t - 0.5) / 0.25;
                return new SKColor((byte)(255 * localT), 255, 0);
            }
            else
            {
                // Yellow to red
                double localT = (t - 0.75) / 0.25;
                return new SKColor(255, (byte)(255 * (1 - localT)), 0);
            }
        }
    }
}
