using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows;
using System.Windows.Media;

namespace OcadMapLibrary {

	public class OcadMap {

		public OcadMap() {
			UnloadMap();
		}

		private bool isLoaded;
		public bool IsLoaded {
			get {
				return isLoaded;
			}
			set {
				isLoaded = value;
			}
		}

		public bool LoadMap(string path) {
			UnloadMap();
			FileStream fs;
			try {
				fs = new FileStream(path, FileMode.Open);
			} catch (Exception) {
				return false;
			}
			BinaryReader br = new BinaryReader(fs);
			Int16 ocadMark = br.ReadInt16();
			if (ocadMark != 0x0cad) {
				return false;
			}
			Int16 ignore = br.ReadInt16();
			Int16 version = br.ReadInt16();
			fs.Seek(0, SeekOrigin.Begin);
			OcadBaseFileReader reader;
			if (version >= 6 && version <= 8) {
				reader = new Ocad8FileReader();
			} else if (version >= 9) {
				reader = new Ocad9FileReader();
			} else {
				return false;
			}
			if (!reader.LoadMap(fs)) {
				return false;
			}
			fs.Close();
			mapInfo = reader.GetMapInfo();
			mapColors = reader.GetColors();
			mapSymbols = reader.GetSymbols();
			mapObjects = reader.GetObjects();
			IsLoaded = true;
			return true;
		}

		public void UnloadMap() {
			IsLoaded = false;
			mapInfo = null;
			mapColors = null;
			mapSymbols = null;
			mapObjects = null;
		}

		MapInfo mapInfo;
		public MapInfo MapInfo {
			get {
				return mapInfo;
			}
		}

		List<MapColor> mapColors;
		public List<MapColor> MapColors {
			get {
				return mapColors;
			}
		}

		List<MapSymbol> mapSymbols;
		public List<MapSymbol> MapSymbols {
			get {
				return mapSymbols;
			}
		}

		List<MapObject> mapObjects;
		public List<MapObject> MapObjects {
			get {
				return mapObjects;
			}
		}

		public void DrawMap(DrawingContext drawingContext) {
			if (!IsLoaded) {
				return;
			}
			for (int i = 0; i < mapColors.Count; i++) {
				DrawObjects(drawingContext, mapColors[i]);
			}
		}

		void DrawObjects(DrawingContext drawingContext, MapColor mapColor) {
			for (int i = 0; i < mapObjects.Count; i++) {
				mapObjects[i].DrawObject(drawingContext, mapSymbols, mapColor);
			}
		}

		public Rect GetBoundingRect() {
			Rect rect = Rect.Empty;
			if (!IsLoaded) {
				return rect;
			}
			for (int i = 0; i < mapObjects.Count; i++) {
				rect.Union(mapObjects[i].GetBoundingRect(mapSymbols));
			}
			return rect;
		}

		public double MetersConversionFactor {
			get {
				if (mapInfo == null) {
					return -1;
				}
				return 2.54 / (96.0 * 100.0) * mapInfo.Scale;
			}
		}

	}

}
