view api/Objects/ArmyCategory.cs @ 101:f7b9423c2a5a

Big mess of updates, breaking our rules on "commit little and often" because the code was so ugly. This revision will be broken for the WinForms UI, but as MonoDevelop/eSVN don't have a way of committing multiple projects in one go it can't be helped (Eclipse's Team Sync view could handle it) Fixes #122: Make usage of percentage or ratio common * All usage of ratio amounts for equipment items should now assume percentage * Properly calculate number taken for ratio selection (divide by 0 now we're using percentages) Fixes #118: Allow equipment amounts of "ratio" equipment to be define as absolute or ratio amounts * Added extra commands that differentiate between ratio and absolute amounts Fixes #120: Numeric limit equipment items show large percentages * Now made formatting treat ratios as percentages (don't multiply by 100) * Move string formatting to UnitEquipmentItem...Selection classes * Add method to Unit to say whether an equipment item is a numeric or ratio amount
author IBBoard <dev@ibboard.co.uk>
date Thu, 13 Aug 2009 21:09:20 +0000
parents cb3759c3ea19
children 2f3cafb69799
line wrap: on
line source

// This file (ArmyCategory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard.
//
// The file and the library/program it is in are licensed under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license.

using System;
using System.Collections.Generic;
using IBBoard.WarFoundry.API.Requirements;

namespace IBBoard.WarFoundry.API.Objects
{
	/// <summary>
	/// Summary description for ArmyCategory.
	/// </summary>
	public class ArmyCategory : WarFoundryObject
	{
		private Category category;
		private Army parentArmy;
		private double pointsTotal;
		private List<Unit> units;
		private Dictionary<string, int> unitTypes;
		private DoubleValChangedDelegate PointsValueChangedMethod;
		public event DoubleValChangedDelegate PointsValueChanged;
		public event ObjectAddDelegate UnitAdded;
		public event ObjectRemoveDelegate UnitRemoved;
		public event FailedUnitRequirementDelegate FailedRequirement;

		public ArmyCategory(Army army, Category cat) : base()
		{
			parentArmy = army;
			category = cat;
			cat.NameChanged+=new StringValChangedDelegate(cat_NameChanged);
			PointsValueChangedMethod = new DoubleValChangedDelegate(PointsValueChangedHandler);
			units = new List<Unit>();
			unitTypes = new Dictionary<string,int>();
		}

		public Category Category
		{
			get { return category; }
		}

		public Army ParentArmy
		{
			get { return parentArmy; }
		}

		public override string ID
		{
			get
			{
				return Category.ID;
			}
			set
			{
				Category.ID = value;
			}
		}

		public override string Name
		{
			get { return category.Name; }
			set 
			{
				category.Name = value;
			}
		}

		internal void AddUnit(Unit unit)
		{
			List<FailedUnitRequirement> failedReqs = ParentArmy.CanAddUnit(unit);
			units.Add(unit);
			unit.Category = this;
			unit.PointsValueChanged+= PointsValueChangedMethod;
			int unitTypeCount;
			unitTypes.TryGetValue(unit.UnitType.ID, out unitTypeCount);
			unitTypes[unit.UnitType.ID] = (int)unitTypeCount + 1;
			TotalPoints+= unit.PointsValue;
			OnUnitAdded(unit, failedReqs);
		}

		internal void RemoveUnit(Unit unit)
		{
			List<FailedUnitRequirement> failedReqs = ParentArmy.CanRemoveUnit(unit);
			units.Remove(unit);
			unitTypes[unit.UnitType.ID] = ((int)unitTypes[unit.UnitType.ID])-1;
			TotalPoints-= unit.PointsValue;
			unit.PointsValueChanged-= PointsValueChangedMethod;
			OnUnitRemoved(unit, failedReqs);
		}

		public int GetUnitTypeCount(UnitType unitType)
		{
			return unitTypes.ContainsKey(unitType.ID) ? (int)unitTypes[unitType.ID] : 0;
		}

		public Unit[] GetUnits()
		{
			return units.ToArray();
		}

		private double TotalPoints
		{
			get { return pointsTotal; }
			set 
			{
				double oldVal = pointsTotal;
				pointsTotal = value;

				if (oldVal!=pointsTotal)
				{
					OnPointsValueChanged(oldVal, pointsTotal);
				}
			}
		}

		public double PointsTotal
		{
			get { return TotalPoints; }
		}

		private void PointsValueChangedHandler(WarFoundryObject obj, double oldVal, double newVal)
		{
			if (obj is Unit)
			{
				double diff = newVal - oldVal;
				TotalPoints+= diff;
			}
		}

		protected void OnUnitAdded(Unit unit)
		{
			OnUnitAdded(unit, null);
		}

		protected void OnUnitAdded(Unit unit, List<FailedUnitRequirement> failedReqs)
		{
			if (UnitAdded != null)
			{
				UnitAdded(unit);
			}

			if (FailedRequirement != null && failedReqs != null && failedReqs.Count > 0)
			{
				FailedRequirement(failedReqs);
			}
		}

		protected void OnUnitRemoved(Unit unit)
		{
			OnUnitRemoved(unit, null);
		}

		protected void OnUnitRemoved(Unit unit, List<FailedUnitRequirement> failedReqs)
		{
			if (UnitRemoved != null)
			{
				UnitRemoved(unit);
			}

			if (FailedRequirement != null && failedReqs != null && failedReqs.Count > 0)
			{
				FailedRequirement(failedReqs);
			}
		}

		protected virtual void OnPointsValueChanged(double oldValue, double newValue)
		{
			if (PointsValueChanged!=null)
			{
				PointsValueChanged(this, oldValue, newValue);
			}
		}

		protected void cat_NameChanged(WarFoundryObject obj, string oldValue, string newValue)
		{
			OnNameChanged(oldValue, newValue);
		}
				
		public int GetPointsPercentage()
		{
			return (int)Math.Round((PointsTotal / ParentArmy.MaxPoints) * 100, 0);
		}
	}
}