﻿using System;
using CalculatorsLibrary.Enumeration;

namespace CalculatorsLibrary.Formulas.Milling
{
	public class MillingHighFeed : Milling, IMillingHighFeed
	{
		/// <summary>
		/// Calculates the actual cutting diameter using <paramref name="diameter"/>, <paramref name="entryAngle"/> and <paramref name="axialDepthOfCut"/> [Coromant Technical Guide, p. I7].
		/// </summary>
		public double DiameterCutting(double diameter, double entryAngle, double axialDepthOfCut)
		{
			return (diameter - ((2 * axialDepthOfCut) / Tangent(entryAngle)));
		}

		/// <summary>
		/// Calculates the feed per tooth based on the <paramref name="millingStrategy"/>, <paramref name="entryAngle"/>, <paramref name="radialCuttingDepth"/>, <paramref name="maximumChipThickness"/> and <paramref name="diameterCutting"/>  [Coromant Technical Guide, p. I7].
		/// This formula is using the <paramref name="millingStrategy"/> and is based on the input of the <paramref name="maximumChipThickness"/>.
		/// </summary>
		public double FeedPerToothMaximumChipThickness(MillingStrategy millingStrategy, double entryAngle, double radialCuttingDepth, double maximumChipThickness, double diameterCutting)
		{
			switch (millingStrategy)
			{
				case MillingStrategy.SideMilling:
					return (maximumChipThickness * diameterCutting) / (2 * Sinus(entryAngle) * Math.Sqrt(diameterCutting * radialCuttingDepth - Math.Pow(radialCuttingDepth, 2)));
				case MillingStrategy.CentralMilling:
					return (maximumChipThickness / Sinus(entryAngle));
				default:
					if (radialCuttingDepth < (diameterCutting / 2))
					{
						goto case MillingStrategy.SideMilling;
					}
					else
					{
						goto case MillingStrategy.CentralMilling;
					}
			}
		}

		/// <summary>
		/// Calculates maximum chipthickness based on the <paramref name="millingStrategy"/>, <paramref name="entryAngle"/>, <paramref name="radialCuttingDepth"/>, <paramref name="feedPerTooth"/> and the <paramref name="diameterCutting"/> [Coromant Technical Guide, p. I7].
		/// This formula is using the <paramref name="millingStrategy"/> and is based on the input of the <paramref name="feedPerTooth"/>
		/// </summary>
		public double MaximumChipThicknessFeedPerTooth(MillingStrategy millingStrategy, double entryAngle, double radialCuttingDepth, double feedPerTooth, double diameterCutting)
		{
			switch (millingStrategy)
			{
				case MillingStrategy.SideMilling:
					return (feedPerTooth * 2 * Sinus(entryAngle) * Math.Sqrt(diameterCutting * radialCuttingDepth - Math.Pow(radialCuttingDepth, 2))) / (diameterCutting);
				case MillingStrategy.CentralMilling:
					return feedPerTooth * Sinus(entryAngle);
				default:
					if (radialCuttingDepth < (diameterCutting / 2))
					{
						goto case MillingStrategy.SideMilling;
					}
					else
					{
						goto case MillingStrategy.CentralMilling;
					}
			}
		}
	}
}
