using System.Collections.Generic;
using Game.Shared;
using Mox.Shared.Renderer;
using Mox.Shared.UI;
using System.Threading.Tasks;

namespace Mox.Shared
{
	public enum EKey
	{
		Upgrade1,
		Upgrade2,
		Upgrade3,
		Upgrade4,
		Upgrade5,
		Deselect,
		Pause,
		CallNextWave,
		PlaceTower,
		SellTower
	}

	public abstract class ProgramBase
	{
		protected ProgramBase()
		{
			Instance = this;
			GameLoop = new GameLoop(this);
			UIRoot = new Root(c_iClientWidth, c_iClientHeight);
			UIRoot.OnPlaySound += s => PlaySound(s);
		}

		public abstract Task RegisterSound(string _sSoundId, string _sPath);

		public void PlaySound(string _sSoundId, bool _bLooped = false)
		{
			m_dSounds[_sSoundId].Play(_bLooped);
		}

		public void StopSound(string _sSoundId)
		{
			m_dSounds[_sSoundId].Stop();
		}

		protected virtual void Init()
		{
			UIRoot.MainControl.CalculateLayout();
		}

		protected virtual void Update(double _dDelta)
		{
			Renderer.BeginDraw();
			GameLoop.Update(_dDelta);
			Renderer.Render(UIRoot.MainControl);
			Renderer.EndDraw();
		}

		public abstract void ShowMessage(string _sMessage);

		protected void OnMouseDown(int _iX, int _iY)
		{
			if (!UIRoot.OnMouseDown(_iX, _iY))
			{
				GameLoop.OnMouseDown(_iX, _iY);
			}
		}

		protected void OnMouseMoved(int _iX, int _iY)
		{
			if (!UIRoot.OnMouseMoved(_iX, _iY))
			{
				GameLoop.OnMouseMoved(_iX, _iY);
			}
		}

		protected void OnMouseUp(int _iX, int _iY)
		{
			if (!UIRoot.OnMouseUp(_iX, _iY))
			{
				GameLoop.OnMouseUp(_iX, _iY);
			}
		}

		public abstract bool GetData(string _sKey, out string _sData);
		public abstract void SetData(string _sKey, string _sData);

		public static readonly Dictionary<int, EKey> s_dKeyCodes = new Dictionary<int, EKey>()
		{
			{
				13, EKey.CallNextWave
			},
			{
				32, EKey.Deselect
			},
			{
				49, EKey.Upgrade1
			},
			{
				50, EKey.Upgrade2
			},
			{
				51, EKey.Upgrade3
			},
			{
				52, EKey.Upgrade4
			},
			{
				53, EKey.Upgrade5
			},
			{
				80, EKey.Pause
			},
			{
				83, EKey.SellTower
			},
			{
				84, EKey.PlaceTower
			},
			{
				112, EKey.Pause
			},
			{
				115, EKey.SellTower
			},
			{
				116, EKey.PlaceTower
			}
		};

		public IGameLoop GameLoop
		{
			get;
			protected set;
		}

		public RendererBase Renderer
		{
			get;
			protected set;
		}

		public Root UIRoot
		{
			get;
			private set;
		}

		public static ProgramBase Instance
		{
			get;
			private set;
		}

		protected const int c_iClientWidth = 800;
		protected const int c_iClientHeight = 600;
		protected Dictionary<string, SoundBase> m_dSounds = new Dictionary<string, SoundBase>();
	}
}
