using System;
using System.IO;
using System.Text;
using System.Threading;

namespace WindowsFormsApp1
{
    public delegate void ThreadCallBack(DateTime StartTime, DateTime FinishTime, TimeSpan DifferenceTime, double[] x, double[] y, double[,] z, string mass);

    public class ThreadWithState
    {
        private ThreadCallBack tcall;
        private int sNN, sTH;
        private double sMaxX, sMinX, sMaxY, sMinY, sShagX, sShagY;
        private double[] sXT, sYT;
        private double[,] sZT;
        private string LineS1;
        private int I, J;
        public DateTime BT1, FT1;
        public TimeSpan ST1;

        public ThreadWithState(int zNN, double zMinX, double zMaxX, double zMinY, double zMaxY, int zTH, ThreadCallBack tcallD)
        {
            sNN = zNN;
            sMinX = zMinX;
            sMaxX = zMaxX;
            sMinY = zMinY;
            sMaxY = zMaxY;
            tcall = tcallD;
            sTH = zTH;
            sXT = new double[sNN];
            sYT = new double[sNN];
            sZT = new double[sNN, sNN];
        }

        public void ThreadDoWork()
        {
            BT1 = DateTime.Now;
            InitializeArrays();
            CalculateFunctionValues();
            FT1 = DateTime.Now;
            ST1 = FT1 - BT1;

            string results = GenerateResultsString();

            tcall(BT1, FT1, ST1, sXT, sYT, sZT, results);
            WriteResultsToFile();
        }

        private void InitializeArrays()
        {
            sXT = new double[sNN];
            sYT = new double[sNN];
            sZT = new double[sNN, sNN];
            sShagX = (sMaxX - sMinX) / (sNN - 1);
            sShagY = (sMaxY - sMinY) / (sNN - 1);
            sXT[0] = sMinX;
            sYT[0] = sMinY;

            for (I = 1; I < sNN; I++)
            {
                sXT[I] = sXT[I - 1] + sShagX;
                sYT[I] = sYT[I - 1] + sShagY;
            }
        }

        private void CalculateFunctionValues()
        {
            for (I = 0; I < sNN; I++)
            {
                for (J = 0; J < sNN; J++)
                {
                    sZT[I, J] = 4 * Math.Sin(sXT[I]) * Math.Cos(Math.Pow(sXT[I], 3)) -
                                Math.Sin(12 * sYT[J]) * Math.Cos(Math.Pow(sXT[I], 3)) -
                                3 * Math.Sin(4 * sYT[J]) * Math.Cos(Math.Pow(sXT[I], 3));
                }
            }
        }

        private string GenerateResultsString()
        {
            StringBuilder resultBuilder = new StringBuilder();

            resultBuilder.AppendLine($"Дата: {BT1.ToShortDateString()}");
            resultBuilder.AppendLine($"Время начала: {BT1.TimeOfDay}");
            resultBuilder.AppendLine($"Время окончания: {FT1.TimeOfDay}");
            resultBuilder.AppendLine($"Продолжительность: {ST1}");

            resultBuilder.AppendLine("PXT: ");
            foreach (var x in sXT)
            {
                resultBuilder.Append($"{x}; ");
            }
            resultBuilder.AppendLine();

            for (I = 0; I < sNN; I++)
            {
                resultBuilder.Append("PZT: ");
                for (J = 0; J < sNN; J++)
                {
                    resultBuilder.Append($"{sZT[I, J]}; ");
                }
                resultBuilder.AppendLine();
            }

            return resultBuilder.ToString();
        }

        private void WriteResultsToFile()
        {
            string fileName = $"D://A_T_{sTH}.txt";

            using (StreamWriter writer = new StreamWriter(fileName, false, Encoding.Default))
            {
                writer.WriteLine(GenerateResultsString());
            }
        }
    }
}