view api/Factories/Xml/WarFoundryXmlLimitParser.cs @ 266:a3c1bf57fd3f

Re #279: Create composite limit * Ignore XPath and go for all child nodes, since we want to warn in future if an unsupported limit is ignored * Make the "any" option in the limit choice group a singular instead of 0+ to ensure we get a choice when we use the group
author IBBoard <dev@ibboard.co.uk>
date Sat, 05 Jun 2010 18:57:46 +0000
parents 6fe0cb1bf74f
children d8e4eeb761c7
line wrap: on
line source

//  This file (WarFoundryXmlLimitParser.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2010 IBBoard
// 
//  The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
using System.Collections.Generic;
using System.Xml;
using IBBoard.Limits;
using IBBoard.Xml;

namespace IBBoard.WarFoundry.API.Factories.Xml
{
	public class WarFoundryXmlLimitParser
	{
		public ILimit GetMinLimit(XmlElement elem)
		{
			XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:minLimit/*[1]");
			return GetLimitFromElement(limitElem);
		}

		public ILimit GetMaxLimit(XmlElement equipSlot)
		{
			XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(equipSlot, "race:maxLimit/*[1]");
			return GetLimitFromElement(limitElem);
		}

		public ILimit GetLimitFromElement(XmlElement limitElem)
		{
			ILimit limit = null;
			
			if (limitElem != null)
			{
				switch (limitElem.LocalName)
				{
					case "percentageLimit":
						double limitPercent = XmlTools.GetDoubleValueFromAttribute(limitElem, "limit");
						bool roundUp = limitElem.GetAttribute("round").Equals("up");
						limit = new SimpleRoundedPercentageLimit(limitPercent, roundUp);
						break;
					case "sizeConstrainedLimit":
						limit = new NumericSizeConstrainedLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit"));
						break;
					case "absoluteLimit":
						limit = new AbsoluteNumericLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit"));
						break;
					case "unitSizeLimit":
						limit = new SimpleRoundedPercentageLimit(100);
						break;
					case "compositeMaxLimit":
						ICollection<ILimit> maxSubLimits = GetSubLimits(limitElem);
						limit = new CompositeMaximumLimit(maxSubLimits);
						break;
					case "compositeMinLimit":
						ICollection<ILimit> minSubLimits = GetSubLimits(limitElem);
						limit = new CompositeMinimumLimit(minSubLimits);
						break;
					default:
						//TODO: Warn of missing handler for when we've extended the limit list
						break;
				}
			}
			
			return limit;
		}

		private ICollection<ILimit> GetSubLimits(XmlElement limitElem)
		{
			System.Console.WriteLine("Getting sub limits");
			XmlNodeList subLimitNodes = GetSubLimitElements(limitElem);
			ICollection<ILimit> limits = new List<ILimit>();
			
			foreach (XmlNode node in subLimitNodes)
			{
				System.Console.WriteLine("Getting limit for "+node.LocalName);
				if (node is XmlElement)
				{
					ILimit limit = GetLimitFromElement((XmlElement)node);
					System.Console.WriteLine("Limit was "+(limit == null ? "null" : limit.GetType().Name));
					if (limit != null)
					{
						limits.Add(limit);
					}
				}
			}
			
			return limits;
		}

		private XmlNodeList GetSubLimitElements(XmlElement limitElem)
		{
			return limitElem.ChildNodes;
		}
	}
}