using ManagedCuda.VectorTypes;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ManagedCudaOpenGLCooperation
{
    class DataSlicer
    {
        public List<Slice> sliceList;

        public int lineSize;
        public int lineNumber;

        public int subLineNumber;

        public DataSlicer(int origLineNumber, int lineSize, long availableGPUMemn, float2[] lineIndex, int1[] lineEnd, float[] lineLength = null)
        {
            sliceList = new List<Slice>();
            lineNumber = origLineNumber;

            // Computing the subDatasetSize
            uint unitSliceSize = (2 * float2.SizeOf + uint4.SizeOf + float3.SizeOf + float2.SizeOf + float1.SizeOf * uint1.SizeOf) * (uint)lineSize;
            subLineNumber = Math.Min((int)(availableGPUMemn / unitSliceSize), origLineNumber);

            int sliceNumber = (int)Math.Ceiling((double)lineNumber / (double)subLineNumber);
            // Creating the slices
            for (int i = 0; i < sliceNumber; i++)
            {
                int tempLineNumber = Math.Min(subLineNumber, origLineNumber - i * subLineNumber);
                float2[] subLineIndex = new float2[subLineNumber * lineSize];
                int1[] subLineEnd = new int1[subLineNumber];
                Array.Copy(lineIndex, i * subLineNumber * lineSize, subLineIndex, 0, tempLineNumber * lineSize);
                Array.Copy(lineEnd, i * subLineNumber, subLineEnd, 0, tempLineNumber);

                float[] subLineLength = null;
                if (lineLength != null)
                {
                    subLineLength = new float[subLineNumber];
                    Array.Copy(lineLength, i * subLineNumber, subLineLength, 0, tempLineNumber);
                }

                Slice tmpSlice = new Slice(tempLineNumber, lineSize, subLineIndex, subLineEnd, subLineLength); //Math.Min(subLineNumber, origLineNumber - i * subLineNumber)
                sliceList.Add(tmpSlice);
            }

        }

        public void exportData()
        {
            string path = "./BundledLines.txt";
            CultureInfo myCultureInfo = new CultureInfo("en-US");
            if (File.Exists(path))
            {
                File.Delete(path);
            }
            using (StreamWriter sw = File.CreateText(path))
            {
                // Writing the text file
                //sw.WriteLine("#Id;#X;#Y;");
                int offset = 0;
                for (int i = 0; i < sliceList.Count; i++)
                {
                    offset += sliceList[i].exportSlice(sw, myCultureInfo, offset);
                }
            }
        }


        internal float2 getMinMax()
        {
            float min = float.MaxValue;
            float max = float.MinValue;
            foreach (Slice tmpSlice in sliceList)
            {
                float2 tmpMinMax = tmpSlice.getMinMaxWidth();
                min = Math.Min(min, tmpMinMax.x);
                max = Math.Max(max, tmpMinMax.y);
            }
            return new float2(min, max);
        }
    }
}
