using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace QC.QMSCT;

public class ProgressBarManager
{
	private enum ProgressBarState
	{
		Waiting,
		Running,
		Failed,
		Success
	}

	private const int PERCENTAGE_CAP = 98;

	private const double TEST_COUNT_MULTIPLIER = 1.1;

	private const int UPDATE_FREQUENCY = 300;

	private const int DEFAULT_NUMBER_OF_TESTS = 25;

	private ProgressBar progressBar;

	private System.Threading.Timer updateTimer;

	private double averageTime;

	private int numberOfCompletions;

	private int appxNumTests;

	private ProgressBarState currentState;

	private DateTime testTreeStartTime;

	private int currentTestNumber;

	private int recordProgressOnFailure;

	public ProgressBarManager(ProgressBar ProgressBarToManage, int numTests = 25)
	{
		SetApproximateNumberOfTests(numTests);
		progressBar = ProgressBarToManage;
	}

	public void StartRunning()
	{
		if (currentState != ProgressBarState.Running)
		{
			currentState = ProgressBarState.Running;
			SetProgressBarColor(Color.Green);
			currentTestNumber = 1;
			testTreeStartTime = DateTime.Now;
			updateTimer = new System.Threading.Timer(UpdateProgressBar, new AutoResetEvent(initialState: false), 0, 300);
		}
	}

	public void TestCompleted()
	{
		if (currentState == ProgressBarState.Running)
		{
			currentTestNumber++;
		}
	}

	public void Fail()
	{
		recordProgressOnFailure = EstimatePercentComplete();
		currentState = ProgressBarState.Failed;
		SetProgressBarColor(Color.Red);
		UpdateProgressBar(null);
	}

	public void Success()
	{
		if (currentState == ProgressBarState.Running)
		{
			currentState = ProgressBarState.Success;
			averageTime = ((double)numberOfCompletions * averageTime + DateTime.Now.Subtract(testTreeStartTime).TotalSeconds) / (double)(numberOfCompletions + 1);
			numberOfCompletions++;
		}
	}

	public void Wait()
	{
		currentState = ProgressBarState.Waiting;
	}

	public int EstimatePercentComplete()
	{
		switch (currentState)
		{
		case ProgressBarState.Waiting:
			return 0;
		case ProgressBarState.Failed:
			return recordProgressOnFailure;
		case ProgressBarState.Success:
			return 100;
		case ProgressBarState.Running:
		{
			if (numberOfCompletions == 0)
			{
				double num = Convert.ToDouble((double)currentTestNumber - 1.0) / (double)appxNumTests;
				return Math.Min(98, Convert.ToInt32(num * 98.0));
			}
			double num2 = DateTime.Now.Subtract(testTreeStartTime).TotalSeconds / averageTime;
			return Math.Min(98, Convert.ToInt32(num2 * 98.0));
		}
		default:
			return 0;
		}
	}

	private void UpdateProgressBar(object stateInfo)
	{
		try
		{
			progressBar.Invoke((MethodInvoker)delegate
			{
				progressBar.Value = EstimatePercentComplete();
			});
		}
		catch
		{
		}
	}

	public void SetApproximateNumberOfTests(int appxNumber)
	{
		if (appxNumber > 0)
		{
			appxNumTests = Convert.ToInt32((double)appxNumber * 1.1);
		}
	}

	private void SetProgressBarColor(Color color)
	{
		try
		{
			progressBar.Invoke((MethodInvoker)delegate
			{
				progressBar.Style = ProgressBarStyle.Continuous;
				progressBar.ForeColor = color;
			});
		}
		catch
		{
		}
	}
}
