//>>> _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.ID47371b55_ddce_4d9a_b1d3_9aa9b8bb5448
{
    public class Class_CubeMap6Paths : OperatorPart.Function
    {
        //>>> _inputids
        private enum InputId
        {
            RightImagePath = 0,
            LeftImagePath = 1,
            TopImagePath = 2,
            BottomImagePath = 3,
            FrontImagePath = 4,
            BackImagePath = 5
        }
        //<<< _inputids

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

        private bool BuildTextureArray(OperatorPartContext context, string[] imagePaths)
        {
            Dispose();

            var singleTextures = new List<Texture2D>();
            foreach (var path in imagePaths)
            {
                if (File.Exists(path))
                    singleTextures.Add(SharpDX.Direct3D11.Resource.FromFile<Texture2D>(D3DDevice.Device, path));
            }

            if (singleTextures.Count() != 6)
            {
                foreach (var textur in singleTextures)
                    textur.Dispose();
                return false;
            }

            var uavVisuDesc = new Texture2DDescription
                                  {
                                      BindFlags = BindFlags.ShaderResource,
                                      Format = singleTextures[0].Description.Format,
                                      Width = singleTextures[0].Description.Width,
                                      Height = singleTextures[0].Description.Height,
                                      MipLevels = singleTextures[0].Description.MipLevels,
                                      SampleDescription = new SampleDescription(1, 0),
                                      Usage = ResourceUsage.Default,
                                      OptionFlags = ResourceOptionFlags.TextureCube,
                                      CpuAccessFlags = CpuAccessFlags.None,
                                      ArraySize = 6
                                  };
            _textureCube = new Texture2D(D3DDevice.Device, uavVisuDesc);


            var dxContext = context.D3DDevice.ImmediateContext;
            for (int arraySlice = 0; arraySlice < 6; ++arraySlice)
            {
                for (int mipSlice = 0; mipSlice < singleTextures[arraySlice].Description.MipLevels; ++mipSlice)
                {
                    int mipSize;
                    int idx = _textureCube.CalculateSubResourceIndex(mipSlice, arraySlice, out mipSize);
                    dxContext.CopySubresourceRegion(singleTextures[arraySlice], mipSlice, null, _textureCube, idx);
                }
            }

            foreach (var textur in singleTextures)
                textur.Dispose();

            return true;
        }
        
        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) 
        {
            //>>> _params
            var RightImagePath = inputs[(int)InputId.RightImagePath].Eval(context).Text;
            var LeftImagePath = inputs[(int)InputId.LeftImagePath].Eval(context).Text;
            var TopImagePath = inputs[(int)InputId.TopImagePath].Eval(context).Text;
            var BottomImagePath = inputs[(int)InputId.BottomImagePath].Eval(context).Text;
            var FrontImagePath = inputs[(int)InputId.FrontImagePath].Eval(context).Text;
            var BackImagePath = inputs[(int)InputId.BackImagePath].Eval(context).Text;
            //<<< _params

            var currentImages = new [] { RightImagePath, LeftImagePath, TopImagePath, BottomImagePath, FrontImagePath, BackImagePath };
            Changed = false;
            for (int i = 0; i < currentImages.Count(); ++i)
            {
                if (currentImages[i] != _lastImages[i])
                {
                    _lastImages = currentImages;
                    Changed = true;
                    break;
                }
            }

            if (Changed)
            {
                if (!BuildTextureArray(context, currentImages))
                    Logger.Error(this,"texture array could not created");
                Changed = false;
            }

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

            return context;
        }

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

