//>>> _using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.Windows;
//<<< _using
using SharpDX.DXGI;

namespace Framefield.Core.IDe3fbabf6_2fc8_4e85_89fd_31fb5bd9e9e6
{
    public class Class_CountPixels : OperatorPart.Function
    {
        public override void Dispose()
        {   
            Utilities.DisposeObj(ref _imageWithCPUAccess);
        }
    
        //>>> _inputids
        private enum InputId
        {
            Image = 0,
            ThresholdColorR = 1,
            ThresholdColorG = 2,
            ThresholdColorB = 3,
            ThresholdColorA = 4
        }
        //<<< _inputids

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) 
        {
            //>>> _params
            var Image = inputs[(int)InputId.Image].Eval(context).Image; if (Image == null) return context;
            var ThresholdColorR = inputs[(int)InputId.ThresholdColorR].Eval(context).Value;
            var ThresholdColorG = inputs[(int)InputId.ThresholdColorG].Eval(context).Value;
            var ThresholdColorB = inputs[(int)InputId.ThresholdColorB].Eval(context).Value;
            var ThresholdColorA = inputs[(int)InputId.ThresholdColorA].Eval(context).Value;
            var ThresholdColor = new Color4(ThresholdColorR, ThresholdColorG, ThresholdColorB, ThresholdColorA);
            //<<< _params

            var immediateContext = D3DDevice.Device.ImmediateContext;
            if (_imageWithCPUAccess == null ||
                _imageWithCPUAccess.Description.Format != Image.Description.Format ||
                _imageWithCPUAccess.Description.Width != Image.Description.Width ||
                _imageWithCPUAccess.Description.Height != Image.Description.Height ||
                _imageWithCPUAccess.Description.MipLevels != Image.Description.MipLevels)
            {
                var desc = new Texture2DDescription()
                               {
                                   BindFlags = BindFlags.None,
                                   Format = Image.Description.Format,
                                   Width = Image.Description.Width,
                                   Height = Image.Description.Height,
                                   MipLevels = Image.Description.MipLevels,
                                   SampleDescription = new SampleDescription(1, 0),
                                   Usage = ResourceUsage.Staging,
                                   OptionFlags = ResourceOptionFlags.None,
                                   CpuAccessFlags = CpuAccessFlags.Read,
                                   ArraySize = 1
                               };
                Utilities.DisposeObj(ref _imageWithCPUAccess);
                _imageWithCPUAccess = new Texture2D(D3DDevice.Device, desc);
            }

            long countedPixel = 0;
            if (Changed)
            {
                immediateContext.CopyResource(Image, _imageWithCPUAccess);
                DataStream imageStream = null;
                DataBox dataBox = immediateContext.MapSubresource(_imageWithCPUAccess, 0, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out imageStream);

                using (imageStream)
                {
                    imageStream.Position = 0;
                    var desc = Image.Description;
                    for (int y = 0; y < desc.Height; ++y)
                    {
                        for (int x = 0; x < desc.Width; ++x)
                        {
                            Color4 currentC = new Color4(imageStream.Read<Int32>());
                            if (currentC.Red >= ThresholdColor.Red &&
                                currentC.Green >= ThresholdColor.Green &&
                                currentC.Blue >= ThresholdColor.Blue &&
                                currentC.Alpha >= ThresholdColor.Alpha)
                            {
                                ++countedPixel;
                            }
                        }
                        imageStream.Position += dataBox.RowPitch - desc.Width*4;
                    }
        
                    immediateContext.UnmapSubresource(_imageWithCPUAccess, 0);
                }
            }
            context.Value = (float)countedPixel;
            Changed = false;
            return context;
        }
        Texture2D _imageWithCPUAccess;
    }
}

