using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

using MindFusion.Mapping;
using MindFusion.Mapping.WinForms;
using Point=System.Drawing.Point;


namespace Palette
{
	public partial class MainForm : Form
	{
		public MainForm()
		{
			InitializeComponent();
		}

		private void MainForm_Load(object sender, EventArgs e)
		{
			var usMap = mapView.BaseMap = Map.FromFile(
				FindMap("United States of America.shp"), true, "");

			// hide the Alaska and Hawaii parts
			usMap.BoundingBox.XMin = -125;
			usMap.BoundingBox.YMin = 23;
			usMap.BoundingBox.YMax = 48;
			
			mapView.Invalidate();

			// load images
			var imgFolder = new DirectoryInfo("Images");
			var imgList = lvImages.LargeImageList = new ImageList();
			imgList.ImageSize = new Size(32, 32);
			foreach (var imgFile in imgFolder.GetFiles())
			{
				if (imgFile.Name.Contains("100") ||
					imgFile.Name.Contains("_") ||
					!imgFile.Name.EndsWith(".png"))
					continue;

				var image = Image.FromFile(imgFile.FullName);
				images.Add(image);

				var item = new ListViewItem(
					Capitalize(Path.GetFileNameWithoutExtension(imgFile.Name)),
					imgList.Images.Count);
				imgList.Images.Add(image);
				lvImages.Items.Add(item);
			}
			lvImages.View = View.Tile;

			decorationLayer = new DecorationLayer(usMap.BoundingBox);
			mapView.Layers.Add(decorationLayer);

			mapView.Layers[0].FillColors = new Color[] { Color.Moccasin };
			mapView.Focus();
		}

		private void miFileLoadMap_Click(object sender, EventArgs e)
		{
			var openDialog = new OpenFileDialog
			{
				Filter = "Shapefile map|*.shp",
				Title = "Open map"
			};

			if (openDialog.ShowDialog() == DialogResult.OK)
			{
				mapView.BaseMap = new Map();
				mapView.BaseMap.LoadFromFile(openDialog.FileName);
				mapView.Invalidate();
			}
		}

		private void miFileExit_Click(object sender, EventArgs e)
		{
			Close();
		}

		private string FindMap(string fileName)
		{
			string testDir = @"..\Maps\countries_level_1\";
			for (int i = 0; i < 10; i++)
			{
				if (Directory.Exists(testDir))
					break;
				testDir = @"..\" + testDir;
			}
			
			var testFile = testDir + fileName;
			if (File.Exists(testFile))
				return testFile;

			return "";
		}

		private string Capitalize(string s)
		{
			return char.ToUpper(s[0]) + s.Substring(1);
		}

		List<Image> images = new List<Image>();

		private void mapView_MapElementHover(object sender, MapEventArgs e)
		{
			var state = e.MapElement as Shape;
			if (state != null)
			{
				if (toolTip != null)
					toolTip.Dispose();

				var name = state.DatabaseRow["NAME_1"];
				var point = mapView.PointToClient(MousePosition);

				toolTip = new ToolTip();
				toolTip.Show(name, mapView, point.X, point.Y + 20, 1000);
			}
		}

		private void lvImages_ItemDrag(object sender, ItemDragEventArgs e)
		{
			DoDragDrop(lvImages.SelectedIndices[0], DragDropEffects.Copy);
		}

		private void mapView_DragOver(object sender, DragEventArgs e)
		{
			var clientPoint = mapView.PointToClient(new Point(e.X, e.Y));
			var geoLocation = mapView.ClientToMap(clientPoint);
			var state = mapView.BaseMap.HitTest(geoLocation);

			e.Effect = state != null ? DragDropEffects.Copy : DragDropEffects.None;
		}

		private void mapView_DragDrop(object sender, DragEventArgs e)
		{
			var clientPoint = mapView.PointToClient(new Point(e.X, e.Y));
			var geoLocation = mapView.ClientToMap(clientPoint);
			var state = mapView.BaseMap.HitTest(geoLocation);

			e.Effect = state != null ? DragDropEffects.Copy : DragDropEffects.None;

			if (state != null)
			{
				int index = (int)e.Data.GetData(typeof(Int32));
				var decoration = new DecorationImage(
					images[index], geoLocation.Y, geoLocation.X);
				decoration.Label = new MindFusion.Mapping.Label(lvImages.Items[index].Text +
					" in " + state.DatabaseRow["NAME_1"]);
				decorationLayer.Decorations.Add(decoration);
				mapView.Invalidate();
			}
		}

		DecorationLayer decorationLayer;
		ToolTip toolTip = new ToolTip();
	}
}