view api/Objects/ArmyCategory.cs @ 83:89cc29b4c012

Re #90: Stop new units showing up twice * Hand all of unit adding/removing down to category * Refactor out OnFailedRequirement method in Army * Make Army listen to and propogate FailedRequirement events from Units * Add OnUnitAdded/Removed method to ArmyCategory that takes list of failures * Remove direct reference to Army from Unit and go via ArmyCategory instead
author IBBoard <dev@ibboard.co.uk>
date Sat, 27 Jun 2009 19:39:04 +0000
parents 3ea0ab04352b
children cb3759c3ea19
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);
		}
	}
}