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

namespace Framefield.Core.ID185b06cd_15c6_4ff3_b69c_eca395b14ad5
{
    public class Class_CubeMap : OperatorPart.Function
    {
        //>>> _inputids
        private enum InputId
        {
            Image = 0
        }
        //<<< _inputids


        public override void Dispose()
        {
            Utilities.DisposeObj(ref _textureCube);
        }

        private bool BuildTextureArray(OperatorPartContext context, Texture2D origImage)
        {
        
            int texWidth=origImage.Description.Width/4;
            int texHeight=origImage.Description.Height/3;
            
           
            
            var uavVisuDesc = new Texture2DDescription
            {
                BindFlags = BindFlags.ShaderResource,
                Format = origImage.Description.Format,
                Width = texWidth,
                Height = texHeight,
                MipLevels = 1,//origImage.Description.MipLevels,
                SampleDescription = new SampleDescription(1, 0),
                Usage = ResourceUsage.Default,
                OptionFlags = ResourceOptionFlags.TextureCube,
                CpuAccessFlags = CpuAccessFlags.None,
                ArraySize = 6
            };
            Utilities.DisposeObj(ref _textureCube);
            _textureCube = new Texture2D(D3DDevice.Device, uavVisuDesc);


            
            int[,]  mapPositions={ {2,1},{0,1},{1,0},{1,2},{1,1},{3,1} }; // Right Left  top   Bot  front Back

            var dxContext = context.D3DDevice.ImmediateContext;
            for (int arraySlice = 0; arraySlice < 6; ++arraySlice)
            {
                ResourceRegion region = new ResourceRegion(
                    mapPositions[arraySlice,0]*texWidth,
                    mapPositions[arraySlice,1]*texHeight,
                    0,
                    mapPositions[arraySlice,0]*texWidth+texWidth,
                    mapPositions[arraySlice,1]*texHeight+texHeight,
                    1);

                for (int mipSlice = 0; mipSlice < origImage.Description.MipLevels; ++mipSlice)
                {
                    int mipSize;
                    int idx = _textureCube.CalculateSubResourceIndex(mipSlice, arraySlice, out mipSize);
                    dxContext.CopySubresourceRegion(origImage, mipSlice, region, _textureCube, idx);
                }
            }

            return true;
        }
        
        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;
            //<<< _params

            if (Changed)
            {
                Dispose();
                BuildTextureArray(context, Image);
                Changed = false;
            }

            if (_textureCube != null)
                context.Image = _textureCube;

            return context;
        }

        private Texture2D _textureCube;
        private Texture2D[] _lastImages = new Texture2D[6];
    }
}

