/*
 * +================================================================================+
 *      __  ___  ______________  __  __  ______________   ____
 *     / / / / |/ /  _/_  __/\ \/ / / / / /_  __/  _/ /  / __/
 *    / /_/ /    // /  / /    \  / / /_/ / / / _/ // /___\ \
 *    \____/_/|_/___/ /_/     /_/  \____/ /_/ /___/____/___/
 *
 * +================================================================================+
 *
 *    "THE BEER-WARE LICENSE"
 *    -----------------------
 *
 *    As long as you retain this notice you can do whatever you want with this
 *    stuff. However it is expressly forbidden to sell or commercially distribute
 *    Unity Utils or parts of it apart from your games.
 *    If you meet any of the authors some day, and you think this stuff is
 *    worth it, you can buy them a beer in return.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *    THE SOFTWARE.
 *
 * +================================================================================+
 *
 *    Authors:
 *    David Krummenacher (dave@timbookedtwo.com)
 *
 */

using UnityEngine;

namespace Utils {

	/// <summary>
	/// Helper methods for game math stuff.
	/// </summary>
	public abstract class GameMath {
		
		/// <summary>
		/// Get the result of a dice roll.
		/// </summary>
		/// <returns>The result of the roll.</returns>
		/// <param name="amountOfDices">Amount of dices.</param>
		/// <param name="sides">Sides per dice.</param>
		public static int DiceRoll(int amountOfDices = 1, int sides = 6) {
			if (sides < 2) {
				Debug.LogWarning("Dice cannot have less than 2 sides. Returning 1.");
				return 1;
			}
			
			int result = 0;
			for (int i = 0; i < amountOfDices; i++) result += Random.Range(0, sides) + 1;
			return result;
		}
		
		/// <summary>
		/// Returns wether a something is true or false based on a chance expressed in percent.
		/// This function is accurate to two decimal places (eg. 99.99%).
		/// </summary>
		/// <returns>The result of the roll.</returns>
		/// <param name="percent">Percent of chance.</param>
		/// <param name="fraction">If set to <c>true</c> uses fractions instead of full values (eg. 0.5 instead of 50%).</param>
		public static bool Chance(float percent, bool fraction = false) {
			return (fraction) ? Random.Range(0, 10000) < percent * 10000f : Random.Range(0, 10000) < percent * 100f;
		}
		
		/// <summary>
		/// Returns the percent based on percentage and base value.
		/// </summary>
		/// <returns>The percent.</returns>
		/// <param name="percentage">Percentage value.</param>
		/// <param name="baseValue">Base value.</param>
		/// <param name="fraction">If set to <c>true</c> uses fractions instead of full values (eg. 0.5 instead of 50%).</param>
		public static float Percent(float percentage, float baseValue, bool fraction = false) {
			return (fraction) ? percentage / baseValue : percentage / baseValue * 100f;
		}
		
		/// <summary>
		/// Returns the percentage value based on percent and base value.
		/// </summary>
		/// <returns>The percentage value.</returns>
		/// <param name="baseValue">Base value.</param>
		/// <param name="percent">Percent.</param>
		/// <param name="fraction">If set to <c>true</c> uses fractions instead of full values (eg. 0.5 instead of 50%).</param>
		public static float PercentPercentage(float baseValue, float percent, bool fraction = false) {
			return (fraction) ? baseValue * percent : baseValue * percent / 100f;
		}
		
		/// <summary>
		/// Returns the base value based on percentage value and percent.
		/// </summary>
		/// <returns>The base value.</returns>
		/// <param name="percentage">Percentage value.</param>
		/// <param name="percent">Percent.</param>
		/// <param name="fraction">If set to <c>true</c> uses fractions instead of full values (eg. 0.5 instead of 50%).</param>
		public static float PercentBaseValue(float percentage, float percent, bool fraction = false) {
			return (fraction) ? percentage / percent : percentage / percent * 100f;
		}
		
		/// <summary>
		/// Returns the digit sum of an integer.
		/// </summary>
		/// <returns>The digit sum.</returns>
		/// <param name="i">The integer.</param>
		public static int DigitSum(int i) {
			int sum = 0;
			for (int n = Mathf.Abs(i); n > 0; sum += n % 10, n /= 10);
			return sum;
		}
	}
}
