// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
//
// Author: Kenneth James Pouncey

namespace Microsoft.Xna.Framework.Graphics
{
    public sealed partial class SamplerStateCollection
    {
        private int _d3dMaxDirty;
        private int _d3dDirty;

        partial void CalculateMaxDirty()
        {
            _d3dMaxDirty = 0;
            for (var i = 0; i < _actualSamplers.Length; i++)
            {
                _d3dMaxDirty |= 1 << i;
            }
        }

        private void PlatformSetSamplerState(int index)
        {
            _d3dDirty |= 1 << index;
        }

        private void PlatformClear()
        {
            _d3dDirty = _d3dMaxDirty;
        }

        private void PlatformDirty()
        {
            _d3dDirty = _d3dMaxDirty;
        }

        internal void PlatformSetSamplers(GraphicsDevice device)
        {
            if (_applyToVertexStage && !device.GraphicsCapabilities.SupportsVertexTextures)
                return;

            // Skip out if nothing has changed.
            if (_d3dDirty == 0)
                return;

            // NOTE: We make the assumption here that the caller has
            // locked the d3dContext for us to use.
            SharpDX.Direct3D11.CommonShaderStage shaderStage;
            if (_applyToVertexStage)
	            shaderStage = device._d3dContext.VertexShader;
            else
	            shaderStage = device._d3dContext.PixelShader;

            for (var i = 0; i < _actualSamplers.Length; i++)
            {
                var mask = 1 << i;
                if ((_d3dDirty & mask) == 0)
                    continue;

                var sampler = _actualSamplers[i];
                SharpDX.Direct3D11.SamplerState state = null;
                if (sampler != null)
                    state = sampler.GetState(device);

                shaderStage.SetSampler(i, state);

                _d3dDirty &= ~mask;
                if (_d3dDirty == 0)
                    break;
            }

            if (_d3dDirty != 0) { throw new System.Exception($"SamplerStateCollection still dirty ({_d3dDirty})"); }
            //_d3dDirty = 0;
        }
    }
}
