context: using UnityEngine;
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Xml.Serialization;
  using Frontiers.World.WIScripts;
  
  namespace Frontiers.World
  {
  	[Serializable]
  	public class Bank : IBank
  	{
  		public Bank ()
  		{
  			//TEMP
  			//Randomize (100);
  			//TEMP
  		}
  
  		[XmlIgnore]
  		public Action RefreshAction { get; set; }
  
  		[XmlIgnore]
  		public Action OnMoneyAdded;
  		[XmlIgnore]
  		public Action OnMoneyRemoved;
  
  		public void AddBaseCurrencyOfType (float numBaseCurrency, WICurrencyType type)
  		{
  			AddBaseCurrencyOfType (Mathf.FloorToInt (numBaseCurrency), type);
  		}
  
  		public void AddBaseCurrencyOfType (int numBaseCurrency, WICurrencyType type)
  		{
  			if (numBaseCurrency == 0 || type == WICurrencyType.None) {
  				return;
  			}
  	
  			int numActualCurrency = Currency.ConvertFromBaseCurrency (numBaseCurrency, type);
  			Add (numActualCurrency, type);
  		}
  
  		public void MakeChange (int baseCurrencyValue, IBank bankToTransferTo)
  		{
  			if (baseCurrencyValue <= 0 || bankToTransferTo == this) {
  				return;
  			}
  
  			int lumensTransferred = 0;
  			int goldTransferred = 0;
  			int warlockTransferred = 0;
  			int silverTransferred = 0;
  			int bronzeTransferred = 0;
  			//probably a better way to do this but whatever
  			while (mLumen > 0 && baseCurrencyValue >= (mLumen * Globals.BaseValueLumen)) {
  				mLumen--;
  				lumensTransferred++;
  				baseCurrencyValue -= Globals.BaseValueLumen;
  			}
  
  			while (mGold > 0 && baseCurrencyValue >= (mGold * Globals.BaseValueGold)) {
  				mGold--;
  				goldTransferred++;
  				baseCurrencyValue -= Globals.BaseValueGold;
  			}
  
  			while (mWarlock > 0 && baseCurrencyValue >= (mWarlock * Globals.BaseValueWarlock)) {
  				mWarlock--;
  				warlockTransferred++;
  				baseCurrencyValue -= Globals.BaseValueWarlock;
  			}
  
  			while (mSilver > 0 && baseCurrencyValue >= (mSilver * Globals.BaseValueSilver)) {
  				mSilver--;
  				silverTransferred++;
  				baseCurrencyValue -= Globals.BaseValueSilver;
  			}
  
  			//if we still have something left
  			if (baseCurrencyValue > 0) {
  				if (mBronze >= baseCurrencyValue) {
  					//transfer everything
  					mBronze -= baseCurrencyValue;
  					bronzeTransferred = baseCurrencyValue;
  					baseCurrencyValue = 0;
  				} else {
  					//transfer what we can
  					bronzeTransferred = mBronze;
  					baseCurrencyValue -= Bronze;
  					mBronze = 0;
  				}
  			}
  
  			bankToTransferTo.Add (bronzeTransferred, WICurrencyType.A_Bronze);
  			bankToTransferTo.Add (silverTransferred, WICurrencyType.B_Silver);
  			bankToTransferTo.Add (goldTransferred, WICurrencyType.C_Gold);
  			bankToTransferTo.Add (lumensTransferred, WICurrencyType.D_Luminite);
  			bankToTransferTo.Add (warlockTransferred, WICurrencyType.E_Warlock);
  
  			RefreshAction.SafeInvoke ();
  			OnMoneyAdded.SafeInvoke ();
  		}
  
  		public void Add (int numCurrency, WICurrencyType type)
  		{
  			if (numCurrency < 0) {
  				//can't add negative currency
  				return;
  			}
  			
  			switch (type) {
  			case WICurrencyType.A_Bronze:
  			default:
  				Bronze += numCurrency;
  				break;
  				
  			case WICurrencyType.B_Silver:
  				Silver += numCurrency;
  				break;
  				
  			case WICurrencyType.C_Gold:
  				Gold += numCurrency;
  				break;
  				
  			case WICurrencyType.D_Luminite:
  				Lumen += numCurrency;
  				break;
  				
  			case WICurrencyType.E_Warlock:
  				Warlock += numCurrency;
  				break;
  			}
  			//Debug.Log ("Added " + numCurrency.ToString () + " currency of type " + type.ToString () + ", refresh action null? " + (RefreshAction == null).ToString ());
  			RefreshAction.SafeInvoke ();
  			OnMoneyAdded.SafeInvoke ();
  		}
  
  		public void Absorb (IBank otherBank)
  		{
  			Bronze += otherBank.Bronze;
  			Silver += otherBank.Silver;
  			Gold += otherBank.Gold;
  			Lumen += otherBank.Lumen;
  			Warlock += otherBank.Warlock;
  
  			otherBank.Clear ();
  
  			RefreshAction.SafeInvoke ();
  			OnMoneyAdded.SafeInvoke ();
  		}
  
  		public bool CanAfford (int numBaseCurrency)
  		{
  			return BaseCurrencyValue >= numBaseCurrency;
  		}
  
  		public bool CanAfford (int numCurrency, WICurrencyType currencyType)
  		{
  			if (numCurrency <= 0) {
  				return true;
  			}
  			return BaseCurrencyValue >= Currency.ConvertToBaseCurrency (numCurrency, currencyType);
  		}
  
  		public bool HasExactChange (int numCurrency, WICurrencyType type)
  		{
  			return false;
  		}
  
  		public static void FillWithRandomCurrency (IBank bank, int wealth)
  		{
  			int totalBaseCurrency = 0;
  			//TODO make this random value based on global seed
  			float randomValue = Mathf.Max (0.25f, UnityEngine.Random.value);
  
  			switch (wealth) {
  			case 0://poor
  				totalBaseCurrency = Globals.WealthLevelPoorBaseCurrency;
  				break;
  
  			case 1://middle class
  				totalBaseCurrency = Globals.WealthLevelMiddleClassBaseCurrency;
  				break;
  
  			case 2://wealthy
  				totalBaseCurrency = Globals.WealthLevelWealthyBaseCurrency;
  				break;
  
  			case 3://aristocracy
  				totalBaseCurrency = Globals.WealthLevelAristocracyBaseCurrency;
  				break;
  			}
  
  			totalBaseCurrency = (int)(totalBaseCurrency * randomValue);
  
  			//split into various currencies
  			//TODO use mod operator, this is inefficient as hell
  			while (totalBaseCurrency > Globals.BaseValueLumen) {
  				bank.Lumen += Globals.BaseValueLumen;
  				totalBaseCurrency -= Globals.BaseValueLumen;
  			}
  
  			while (totalBaseCurrency > Globals.BaseValueGold) {
  				bank.Gold += Globals.BaseValueGold;
  				totalBaseCurrency -= Globals.BaseValueGold;
  			}
  
  			while (totalBaseCurrency > Globals.BaseValueSilver) {
  				bank.Silver += Globals.BaseValueSilver;
  				totalBaseCurrency -= Globals.BaseValueSilver;
  			}
  			bank.Bronze += totalBaseCurrency;
  			bank.RefreshAction.SafeInvoke ();
  		}
  
  		public bool TryToRemove (int numToRemove, WICurrencyType type)
  		{
  			return TryToRemove (numToRemove, type, true);
  		}
  
  		public bool TryToRemove (int numToRemove, WICurrencyType type, bool makeChange)
  		{	
  			if (makeChange) {
  				return TryToRemove (Currency.ConvertToBaseCurrency (numToRemove, type));
  			} else if (numToRemove == 0) {
  				return true;
  			} else {
  				bool result = false;
  				switch (type) {
  				case WICurrencyType.A_Bronze:
  				default:
  					if (mBronze >= numToRemove) {
  						mBronze -= numToRemove;
  						result = true;
  					}
  					break;
  
  				case WICurrencyType.B_Silver:
  					if (mSilver >= numToRemove) {
  						mSilver -= numToRemove;
  						result = true;
  					}
  					break;
  
  				case WICurrencyType.C_Gold:
  					if (mGold >= numToRemove) {
  						mGold -= numToRemove;
  						result = true;
  					}
  					break;
  
  				case WICurrencyType.D_Luminite:
  					if (mLumen >= numToRemove) {
  						mLumen -= numToRemove;
  						result = true;
  					}
  					break;
  
  				case WICurrencyType.E_Warlock:
  					if (mWarlock >= numToRemove) {
  
gt: 						mWarlock -= numToRemove;