view api/Exporters/WarFoundryHtmlExporter.cs @ 153:dd892567f054

Fixes #174: HTML output can add empty tables for stat lines * Check if table has rows before outputting it
author IBBoard <dev@ibboard.co.uk>
date Sat, 26 Sep 2009 19:57:06 +0000
parents 7f13ffcb8765
children 4a02c07278e7
line wrap: on
line source

// This file (WarFoundryHtmlExporter.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 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;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using IBBoard.Lang;
using IBBoard.WarFoundry.API.Objects;

namespace IBBoard.WarFoundry.API.Exporters
{
	/// <summary>
	/// Custom exporter that exports an army as a basic HTML file
	/// </summary>
	public class WarFoundryHtmlExporter : IWarFoundryExporter
	{
		private static WarFoundryHtmlExporter exporter;
		
		public static WarFoundryHtmlExporter GetDefault()
		{
			if (exporter == null)
			{
				exporter = new WarFoundryHtmlExporter();
			}
			
			return exporter;
		}
		
		private WarFoundryHtmlExporter()
		{
			//Hide constructor
		}
		
		public void ExportArmy(Army army, string path)
		{
			XmlDocument doc = new XmlDocument();
			doc.AppendChild(doc.CreateDocumentType("html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", null));
			XmlElement html = doc.CreateElement("html");
			doc.AppendChild(html);
			XmlElement head = doc.CreateElement("head");
			html.AppendChild(head);
			XmlElement title = doc.CreateElement("title");
			title.InnerXml = army.Name;
			head.AppendChild(title);
			XmlElement style = doc.CreateElement("style");
			style.InnerText = "table, th, td { border: 1px solid #000 }";
			head.AppendChild(style);
			XmlElement body = doc.CreateElement("body");
			html.AppendChild(body);
			XmlElement header = doc.CreateElement("h1");
			header.InnerText = Translation.GetTranslation("armyHtmlOutputBodyHeader", "{0} - {1}pts", army.Name, army.Points);
			body.AppendChild(header);
			
			foreach (XmlElement table in CreateTables(army, doc))
			{
				if (!IsTableOnlyHeader(table))
				{
					body.AppendChild(table);
				}
			}
			
			StreamWriter writer = new StreamWriter(path, false);
			
			try
			{
				writer.Write(doc.OuterXml);
			}
			finally
			{
				writer.Close();
			}
		}

		private bool IsTableOnlyHeader(XmlElement table)
		{
			return table.ChildNodes.Count == 1;
		}
		
		private XmlElement[] CreateTables(Army army, XmlDocument doc)
		{
			Dictionary<string, XmlElement> tables = new Dictionary<string, XmlElement>();
			
			foreach (SystemStats statSets in army.GameSystem.SystemStats)
			{
				tables[statSets.ID] = CreateTable(statSets, doc);
			}
			
			foreach (Unit unit in army.GetUnits())
			{
				tables[unit.UnitType.StatsID].AppendChild(CreateUnitRow(unit, doc));
			}
			
			return DictionaryUtils.ToArray(tables);
		}
		
		private XmlElement CreateTable(SystemStats stats, XmlDocument doc)
		{
			XmlElement table = doc.CreateElement("table");
			XmlElement headerRow = doc.CreateElement("tr");
			table.AppendChild(headerRow);
			XmlElement name = doc.CreateElement("th");
			name.InnerText = "Name";
			headerRow.AppendChild(name);
			
			foreach (StatSlot stat in stats.StatSlots)
			{
				XmlElement statHeader = doc.CreateElement("th");
				statHeader.InnerText = stat.Name;
				headerRow.AppendChild(statHeader);
			}
			
			XmlElement notes = doc.CreateElement("th");
			notes.InnerText = "Notes";
			headerRow.AppendChild(notes);
			
			XmlElement points = doc.CreateElement("th");
			points.InnerText = "Points";
			headerRow.AppendChild(points);
			
			return table;
		}
		
		private XmlElement CreateUnitRow(Unit unit, XmlDocument doc)
		{
			XmlElement row = doc.CreateElement("tr");
			XmlElement name = doc.CreateElement("td");
			name.InnerText = unit.Name;
			row.AppendChild(name);
			
			foreach (Stat stat in unit.UnitStatsArray)
			{
				XmlElement statCell = doc.CreateElement("td");
				statCell.InnerText = stat.SlotValueString;
				row.AppendChild(statCell);
			}

			StringBuilder sb = new StringBuilder();
			bool addSeparator = false;

			foreach (UnitEquipmentItem equip in unit.GetEquipment())
			{
				if (!addSeparator)
				{
					addSeparator = true;
				}
				else
				{
					sb.Append(", ");
				}

				sb.Append(Translation.GetTranslation("armyHtmlExportEquipAmountRatio", "{0} for {1}", equip.Name, unit.GetEquipmentAmountString(equip)));
			}
						
			XmlElement notes = doc.CreateElement("td");
			notes.InnerText = sb.ToString();
			row.AppendChild(notes);
			
			XmlElement points = doc.CreateElement("td");
			points.InnerText = unit.Points.ToString();
			row.AppendChild(points);
			
			return row;
		}
	}
}