using System;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
namespace DominionBase
{
[Serializable]
public class Currency : IDisposable
{
private static readonly Regex RegexParser = new Regex("((?\\d+))?((?\\d+))?((?\\d+))?");
public Currency() { }
public Currency(Currency currency)
: this(currency?.Coin, currency.Potion, currency.Debt)
{ }
public Currency(Cards.Cost cost)
: this(cost?.Coin, cost.Potion, cost.Debt)
{ }
public Currency(Currencies.Coin coin, Currencies.Potion potion = null, Currencies.Debt debt = null)
{
Contract.Requires(coin != default(Currencies.Coin), "coin cannot be null");
Coin.Value = coin.Value;
Coin.IsVariable = coin.IsVariable;
if (potion != null)
{
Potion.Value = potion.Value;
Potion.IsVariable = Potion.IsVariable;
}
if (debt != null)
{
Debt.Value = debt.Value;
Debt.IsVariable = Debt.IsVariable;
}
}
public Currency(int coin = 0, int potion = 0, int debt = 0)
{
Coin.Value = coin;
Potion.Value = potion;
Debt.Value = debt;
}
public Currency(string currency)
{
var matched = RegexParser.Match(currency);
if (!matched.Success)
throw new ArgumentException("Could not parse currency!");
if (matched.Groups["coinValue"].Success)
Coin.Value = int.Parse(matched.Groups["coinValue"].Value, CultureInfo.InvariantCulture);
if (matched.Groups["potionValue"].Success)
Potion.Value = int.Parse(matched.Groups["potionValue"].Value, CultureInfo.InvariantCulture);
if (matched.Groups["debtValue"].Success)
Debt.Value = int.Parse(matched.Groups["debtValue"].Value, CultureInfo.InvariantCulture);
}
#region IDisposable variables, properties, & methods
// Track whether Dispose has been called.
private bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!_disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
// Dispose managed resources.
Coin = null;
Potion = null;
Debt = null;
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
// Note disposing has been done.
_disposed = true;
}
}
~Currency()
{
Dispose(false);
}
#endregion
public Currencies.Coin Coin { get; set; } = new Currencies.Coin();
public Currencies.Potion Potion { get; set; } = new Currencies.Potion();
public Currencies.Debt Debt { get; set; } = new Currencies.Debt();
public bool IsVariable => Coin.IsVariable || Potion.IsVariable || Debt.IsVariable;
public bool IsBlank => Coin.Value == 0 && Potion.Value == 0 && Debt.Value == 0;
public Currency Clone()
{
return new Currency(this);
}
internal void Add(Currency currency)
{
Coin += currency.Coin;
Potion += currency.Potion;
Debt += currency.Debt;
}
public static Currency operator +(Currency x, Currency y)
{
Contract.Requires(y != default(Currency), "y cannot be null");
var newCurrency = new Currency(x);
newCurrency.Coin += y.Coin;
newCurrency.Potion += y.Potion;
newCurrency.Debt += y.Debt;
return newCurrency;
}
public static Currency operator +(Currency x, Cards.Cost y)
{
Contract.Requires(y != default(Cards.Cost), "y cannot be null");
var newCurrency = new Currency(x);
newCurrency.Coin += y.Coin;
newCurrency.Potion += y.Potion;
newCurrency.Debt += y.Debt;
return newCurrency;
}
public static Currency operator +(Currency x, Currencies.Coin y)
{
var newCurrency = new Currency(x);
newCurrency.Coin += y;
return newCurrency;
}
public static Currency operator +(Currency x, Currencies.Potion y)
{
var newCurrency = new Currency(x);
newCurrency.Potion += y;
return newCurrency;
}
public static Currency operator +(Currency x, Currencies.Debt y)
{
var newCurrency = new Currency(x);
newCurrency.Debt += y;
return newCurrency;
}
public static Currency operator -(Currency x, Currency y)
{
Contract.Requires(y != default(Currency), "y cannot be null");
var newCurrency = new Currency(x);
newCurrency.Coin -= y.Coin;
newCurrency.Potion -= y.Potion;
newCurrency.Debt -= y.Debt;
return newCurrency;
}
public static Currency Subtract(Currency left, Currency right) { return left - right; }
public static Currency operator -(Currency x, Cards.Cost y)
{
Contract.Requires(y != default(Cards.Cost), "y cannot be null");
var newCurrency = new Currency(x);
newCurrency.Coin -= y.Coin;
newCurrency.Potion -= y.Potion;
newCurrency.Debt -= y.Debt;
return newCurrency;
}
public static Currency operator -(Currency x, Currencies.Coin y)
{
var newCurrency = new Currency(x);
newCurrency.Coin -= y;
return newCurrency;
}
public static Currency operator -(Currency x, Currencies.Potion y)
{
var newCurrency = new Currency(x);
newCurrency.Potion -= y;
return newCurrency;
}
public static Currency operator -(Currency x, Currencies.Debt y)
{
var newCurrency = new Currency(x);
newCurrency.Debt -= y;
return newCurrency;
}
public static Currency operator -(Currency c)
{
Contract.Requires(c != default(Currency), "c cannot be null");
return new Currency(-c.Coin, -c.Potion, -c.Debt);
}
public static Currency Negate(Currency item) { return -item; }
public override int GetHashCode()
{
return Coin.GetHashCode() + 19 * Potion.GetHashCode() + 23 * Debt.GetHashCode();
}
public static bool operator ==(Currency x, Currency y)
{
if (ReferenceEquals(x, y))
return true;
// If one is null, but not both, return false.
if (x is null || y is null)
return false;
return x.Equals(y);
}
public static bool operator !=(Currency x, Currency y)
{
return !(x == y);
}
public static bool operator ==(Currency x, Cards.Cost y)
{
// If one is null, but not both, return false.
if (x is null || y is null)
return false;
return x.Equals(y);
}
public static bool operator !=(Currency x, Cards.Cost y)
{
return !(x == y);
}
public static bool operator <(Currency x, Currency y)
{
Contract.Requires(x != default(Currency), "x cannot be null");
Contract.Requires(y != default(Currency), "y cannot be null");
return (x.Coin < y.Coin && x.Potion == y.Potion && x.Debt == y.Debt)
|| (x.Coin == y.Coin && x.Potion < y.Potion && x.Debt == y.Debt)
|| (x.Coin == y.Coin && x.Potion == y.Potion && x.Debt < y.Debt)
|| (x.Coin < y.Coin && x.Potion < y.Potion && x.Debt == y.Debt)
|| (x.Coin < y.Coin && x.Potion == y.Potion && x.Debt < y.Debt)
|| (x.Coin == y.Coin && x.Potion < y.Potion && x.Debt < y.Debt)
|| (x.Coin < y.Coin && x.Potion < y.Potion && x.Debt < y.Debt);
}
public static bool operator >(Currency x, Currency y)
{
return (y < x);
}
public static bool operator <=(Currency x, Currency y)
{
return (x == y || x < y);
}
public static bool operator >=(Currency x, Currency y)
{
return (x == y || x > y);
}
public static bool operator <(Currency x, Cards.Cost y)
{
Contract.Requires(x != default(Currency), "x cannot be null");
Contract.Requires(y != default(Cards.Cost), "y cannot be null");
return (x.Coin < y.Coin && x.Potion == y.Potion && x.Debt == y.Debt)
|| (x.Coin == y.Coin && x.Potion < y.Potion && x.Debt == y.Debt)
|| (x.Coin == y.Coin && x.Potion == y.Potion && x.Debt < y.Debt)
|| (x.Coin < y.Coin && x.Potion < y.Potion && x.Debt == y.Debt)
|| (x.Coin < y.Coin && x.Potion == y.Potion && x.Debt < y.Debt)
|| (x.Coin == y.Coin && x.Potion < y.Potion && x.Debt < y.Debt)
|| (x.Coin < y.Coin && x.Potion < y.Potion && x.Debt < y.Debt);
}
public static bool operator >(Currency x, Cards.Cost y)
{
return (y < x);
}
public static bool operator <=(Currency x, Cards.Cost y)
{
return (x == y || x < y);
}
public static bool operator >=(Currency x, Cards.Cost y)
{
return (x == y || x > y);
}
public override bool Equals(object obj)
{
if (obj is Cards.Cost oCost)
return Coin.Equals(oCost.Coin) && Potion.Equals(oCost.Potion) && Debt.Equals(oCost.Debt);
if (obj is Currency oCurr)
return Coin.Equals(oCurr.Coin) && Potion.Equals(oCurr.Potion) && Debt.Equals(oCurr.Debt);
return false;
}
public int CompareTo(object o)
{
return CompareTo(o as Currency);
}
public int CompareTo(Currency other)
{
// Check for null
if (other is null)
return -1;
// Check for same reference
if (ReferenceEquals(this, other))
return 0;
if (this < other)
return -1;
if (this > other)
return 1;
if (this == other)
return 0;
// I... don't know if this is true??? Currency is weird
return 0;
}
public override string ToString()
{
var sb = new StringBuilder();
sb.AppendFormat("{0}", Coin.Value);
if (Potion.Value > 0)
sb.AppendFormat(", {0}", Potion.Value);
if (Debt.Value > 0)
sb.AppendFormat(", {0}", Debt.Value);
return sb.ToString();
}
public string ToStringInline()
{
var s = Coin.ToString();
if (Potion.Value > 0)
{
if (Coin.Value == 0)
s = string.Empty;
s += Potion.ToString();
}
if (Debt.Value > 0)
{
if (Coin.Value == 0)
s = string.Empty;
s += Debt.ToString();
}
return s;
}
}
}