using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nlgp1.StageEditor.Notifies;
using Nlgp1.StageEditor.Controls;
using System.Windows.Forms;
using Nlgp1.StageEditor.Controls.Events;

namespace Nlgp1.StageEditor.Instances
{
	public static class LayerInstance
	{
		private class LayerData
		{
			public LayerNotify layer;
			public LayerSettingNotify viewerSetting;
			public LayerTabPage layerTabPage;
		}

		private static StageEditorForm stageEditor;
		private static StageNotify stage;
		private static EditorNotify editor;
		private static Dictionary<LayerNotify, LayerData> layerDataTable;

		public static void Initialize(StageEditorForm stageEditor, EditorNotify editor, StageNotify stage)
		{
			LayerInstance.stageEditor = stageEditor;
			LayerInstance.stage = stage;
			LayerInstance.editor = editor;
			LayerInstance.layerDataTable = new Dictionary<LayerNotify, LayerData>();
		}

		public static void LoadImage(LayerNotify layer, string path)
		{
			layer.LoadLayerImage(path);
		}

		public static LayerNotify Add(string name)
		{
			var layer = stage.CreateLayer(name);
			var viewerSetting = editor.CreateLayerSetting();
			var layerTabPage = stageEditor.LayersetControl.CreateLayer(name);
			LayerTabPageEvent.Initialize(layerTabPage, layer, viewerSetting);

			stageEditor.LayersetControl.AddLayer(layerTabPage);
			stage.AddLayer(layer);
			editor.AddLayer(layer, viewerSetting);

			layer.PropertyChanged += stageEditor.MapControl.ChipGridData_PropertyChanged;
			layer.PropertyChanged += stageEditor.LayerChipControl.ChipGridData_PropertyChanged;
			layer.PropertyChanged += stageEditor.LayerChipsetControl.ChipGridData_PropertyChanged;
			layer.PropertyChanged += stageEditor.LayersetControl.ChipGridData_PropertyChanged;
			viewerSetting.PropertyChanged += stageEditor.MapControl.ViewSettingData_PropertyChanged;

			var data = new LayerData();
			data.layer = layer;
			data.viewerSetting = viewerSetting;
			data.layerTabPage = layerTabPage;
			layerDataTable[layer] = data;

			return layer;
		}

		public static void Remove(LayerNotify layer)
		{
			var data = layerDataTable[layer];
			stageEditor.LayersetControl.RemoveLayer(data.layerTabPage);
			if (editor.CurrentLayer == layer)
			{
				var prev = stage.GetPreviousLayer(layer);
				SetCurrentLayer(prev);
			}
			stage.RemoveLayer(data.layer);
			editor.RemoveLayer(data.layer);

			layerDataTable.Remove(layer);
		}

		public static void MoveUp(LayerNotify layer)
		{
			var isCurrent = editor.CurrentLayer == layer;
			var data = layerDataTable[layer];
			stage.MoveUpLayer(data.layer);
			stageEditor.LayersetControl.MoveUpLayer(data.layerTabPage);

			if (isCurrent)
			{
				SetCurrentLayer(layer);
			}
		}

		public static void MoveDown(LayerNotify layer)
		{
			var isCurrent = editor.CurrentLayer == layer;
			var data = layerDataTable[layer];
			stage.MoveDownLayer(data.layer);
			stageEditor.LayersetControl.MoveDownLayer(data.layerTabPage);

			if (isCurrent)
			{
				SetCurrentLayer(layer);
			}
		}

		public static void SetChip(LayerNotify layer, LayerChipNotify chip, int row, int column)
		{
			layer.SetChip(chip, row, column);
		}

		public static void SetChipIndex(LayerNotify layer, int chipIndex, int row, int column)
		{
			layer.SetChip(chipIndex, row, column);
		}


		public static int GetChipIndex(LayerNotify layer, int row, int column)
		{
   		return layer.GetChipIndex(row, column);
		}

		public static void SetMap(LayerNotify layer, LayerChipNotify[,] map)
		{
			layer.SetMap(map);
		}

		public static void ShiftLeft(LayerNotify layer)
		{
			layer.ShiftLeft();
		}

		public static void ShiftRight(LayerNotify layer)
		{
			layer.ShiftRight();
		}

		public static void ShiftUp(LayerNotify layer)
		{
			layer.ShiftUp();
		}

		public static void ShiftDown(LayerNotify layer)
		{
			layer.ShiftDown();
		}

		public static void SetCurrentLayer(LayerNotify layer)
		{
			editor.CurrentLayer = layer;
			if (layer != LayerNotify.None)
			{
				var index = stage.LayerList.IndexOf(layer);
				stageEditor.LayersetControl.SelectedTabIndex = index;
			}
			editor.CurrentChip = editor.GetCurrentChip(layer);
		}

		public static void SetCurrentLayer(int index)
		{
			var layer = LayerNotify.None;
			if (index >= 0 && index < stage.LayerList.Count)
			{
				layer = stage.LayerList[index];
			}
			SetCurrentLayer(layer);
		}
	}
}