using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Xml;
using ImageBlockz.Operations.InOut;
using ImageBlockz.Api;
using ImageBlockz.Core;

namespace ImageBlockz.Operations.Filters
{
    class ColorMapping : AbstractOperation
    {
        public static readonly string OperationName = typeof(ColorMapping).FullName;

        public ColorMapping()
            : base(OperationType.Filter)
        {
            
        }

        public ColorMapping(string cmType)
            : this()
        {
            CmType = cmType;
        }

        public string CmType
        {
            set;
            get;
        }

        public override Bitmap Do(Bitmap bmp)
        {
            int[,] colormap = CsvReader.ReadCsv(@"/ColorMaps/JET.csv");

            switch (CmType)
            {
                case "JET":
                    colormap = CsvReader.ReadCsv(@"/ColorMaps/JET.csv");
                    break;
                case "HSV":
                    colormap = CsvReader.ReadCsv(@"/ColorMaps/HSV.csv");
                    break;
                case "HOT":
                    colormap = CsvReader.ReadCsv(@"/ColorMaps/HOT.csv");
                    break;
                case "COOL":
                    colormap = CsvReader.ReadCsv(@"/ColorMaps/COOL.csv");
                    break;
                case "LINES":
                    colormap = CsvReader.ReadCsv(@"/ColorMaps/LINES.csv");
                    break;
                default:
                    Console.WriteLine("Invalid Colormap, using default /JET/.");
                    break;
            }

            Color color = new Color();
            int bwcolor, R, G, B;

            PixelFormat format = PixelFormat.Format24bppRgb;

            Bitmap newimg = new Bitmap(bmp.Width, bmp.Height, format);

            BitmapWrapper wrapperIn = new BitmapWrapper(bmp);
            BitmapWrapper wrapperOut = new BitmapWrapper(newimg);

            wrapperIn.Lock();
            wrapperOut.Lock();


            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    color = wrapperIn.GetPixel(x, y);
                    bwcolor = (int)Math.Round((color.R + color.G + color.B) / 3.0);
                    R = colormap[bwcolor, 0];
                    G = colormap[bwcolor, 1];
                    B = colormap[bwcolor, 2];
                    color = Color.FromArgb(R, G, B);
                    wrapperOut.SetPixel(color, x, y);
                }
            }

            wrapperIn.Unlock();
            wrapperOut.Unlock();

            return newimg;
        }

        public override XmlNode ToXml(XmlDocument xmlDoc)
        {
            XmlElement colorMapping = xmlDoc.CreateElement(OperationName);
         
            XmlElement colormap = XmlOperation.StringToXml("colormap", CmType, xmlDoc);

            colorMapping.AppendChild(colormap);
          
            return colorMapping;
        }

        public override void FromXml(XmlNode node)
        {
            CmType = XmlOperation.StringFromXml(node["colormap"]);
        }

        public override string GetFormattedName()
        {
            return "Color Mapping";
        }


        public override string GetInfo()
        {
            return CmType.ToString();
        }
    }
}
