using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Xml;
using ZionGraphics.Filtering;
using ZionVault.Basic;

namespace ZionGraphics.Profiling
{
    public class Profile : ZionVault.Util.Xml, IDisposable
    {
        private const string MAINTAG = @"Profile";
        private string  path;

        public List<ZionGraphics.Filtering.IFilter> Filters;
        public List<ZionVault.Basic.Location> Regions;

        public Bitmap LatestBitmap;

        public string Path { get { return path; } }

        public Profile()
        {
            Filters = new List<IFilter>();
            Regions = new List<Location>();
        }
        public Profile(List<IFilter> filters, List<Location> regions)
        {
            Filters = filters;
            Regions = regions;
        }

        public Profile(string path)
        {
            Filters = new List<IFilter>();
            Regions = new List<Location>();

            if (!System.IO.File.Exists(path))
                throw new ArgumentException("File not found");

            this.path = path;
            this.Load(this.path, MAINTAG);

            foreach (XmlNode filter in this.SelectNodes(@"Profile/Filters/Filter"))
            {
                Filters.Add(IFilter.build(filter));
            }

            foreach (XmlNode region in this.SelectNodes(@"Profile/Regions/Area"))
            {
                Regions.Add(new Location(region));
            }
        }

        public void Dispose()
        {
            Filters.Clear();
            Regions.Clear();
            GC.Collect();
        }

        public void Set(ZionGraphics.Filtering.IFilter step)
        {
            if (Filters.Count > 0 && step.GetType() == Filters.Last().GetType())
            {
                Filters.Remove(Filters.Last());
            }

            Filters.Add(step);
        }

        public void Save(string path, bool encripty = true)
        {
            string current = System.DateTime.Now.ToString();
            this.AppendChild(this.CreateXmlDeclaration("1.0", @"UTF-8", @"yes"));

            XmlElement root = this.CreateElement(MAINTAG);

            XmlElement filters = this.CreateElement(@"Filters");
            Filters.ForEach(filter => {
                filter.AppendTo(this, filters);
            });


            XmlElement regions = this.CreateElement(@"Regions");
            Regions.ForEach(region => {
                region.AppendTo(this, regions);
            });

            root.AppendChild(filters);
            root.AppendChild(regions);
            this.AppendChild(root);

            base.Save(path, "Profile", encripty, false);
        }

        public List<Bitmap> Apply(Bitmap bitmap)
        {
            List<Bitmap> bitmaps = new List<Bitmap>();
            Bitmap map = (Bitmap)bitmap.Clone();

            Filters.ForEach(filter => {
                map = filter.Apply(map);
            });

            Regions.ForEach(region => {
                bitmaps.Add(
                    map.Clone(
                       new Rectangle(
                         (int)((region.Left / 100.00) * bitmap.Width),
                         (int)((region.Top / 100.00) * bitmap.Height),
                         (int)(((region.Right / 100.00) - (region.Left / 100.00)) * bitmap.Width),
                         (int)(((region.Bottom / 100.00) - (region.Top / 100.00)) * bitmap.Height)
                         ), bitmap.PixelFormat));
            });

            if (bitmaps.Count == 0)
                bitmaps.Add(map);

            return bitmaps;
        }
    }
}
