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

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

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

        public SimpleLevels(int min, int max)
            : this()
        {
            Max = max;
            Min = min;

        }

        public float Max
        {
            set;
            get;
        }

        public float Min
        {
            set;
            get;
        }

        public override Bitmap Do(Bitmap bmp)
        {
            double aParam = 256 / (Max - Min);
            double bParam = -256 / (Max - Min) * Min;

            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 color = wrapperIn.GetPixel(x, y);


                    int red = (int)Math.Min(aParam * color.R + bParam, 255);
                    int green = (int)Math.Min(aParam * color.G + bParam, 255);
                    int blue = (int) Math.Min(aParam * color.B + bParam, 255);

                    red = Math.Max(red, 0);
                    green = Math.Max(green, 0);
                    blue = Math.Max(blue, 0);

                    color = Color.FromArgb(red, green, blue);

                    wrapperOut.SetPixel(color, x, y);
                }

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

            return newimg;

        }

        public override XmlNode ToXml(XmlDocument xmlDoc)
        {
            XmlElement simpleLevels = xmlDoc.CreateElement(OperationName);

            XmlElement min = XmlOperation.FloatToXml("min", Min, xmlDoc);
            XmlElement max = XmlOperation.FloatToXml("max", Max, xmlDoc);

            simpleLevels.AppendChild(min);
            simpleLevels.AppendChild(max);

            return simpleLevels;
        }

        public override void FromXml(XmlNode node)
        {
            Min = XmlOperation.FloatFromXml(node["min"]);
            Max = XmlOperation.FloatFromXml(node["max"]);
        }

        public override string GetFormattedName()
        {
            return "Contrast Stretch";
        }


        public override string GetInfo()
        {
            return "Minimum: " + Min + " Maximum: " + Max;
        }
    }
}
