using ProtoBuf;
using Sandbox.ModAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UIFun.Interface;
using VRage.Utils;
using VRageMath;

namespace UIFun.Definition
{
	public class UIDefinition : iTextHUDAPI
	{
		enum sides : int
		{
			left,
			top,
			right,
			bottom
		}
		enum parts : int
		{
			top_left,
			bottom_left,
			top_right,
			bottom_right,
			fill
		}

		enum BoxUIDefinitionMembers : int
		{
			Definition = 0,
			Min
		}

		public class uipart
		{
			public MyStringId material;
			public int materialSize = 1;
			public bool tile = false;
			public bool HasValue = false;
			public int ux = 0;
			public int uy = 0;
			public int usizex = 0;
			public int usizey = 0;
		}

		public class uifill : uipart
		{

		}

		public class uicorner : uipart
		{


		}

		public class uiside : uipart
		{
			public int margin = 0;
			public int padding = 0;
		}

		[ProtoContract]
		public struct BoxUIDefinitionData
		{
			[ProtoMember(1)]
			public MyStringId Material;
			[ProtoMember(2)]
			public int imagesize;
			[ProtoMember(3)]
			public int topwidthpx;
			[ProtoMember(4)]
			public int leftwidthpx;
			[ProtoMember(5)]
			public int bottomwidthpx;
			[ProtoMember(6)]
			public int rightwidthpx;
			[ProtoMember(7)]
			public int margin;
			[ProtoMember(8)]
			public int padding;
		}

		public uiside top, right, left, bottom;
		public uicorner top_right, top_left, bottom_left, bottom_right;
		public uifill fill;
		public string DefinitionName;
		public bool readOnly = false;

		public void SetMember(int MemberEnum, object Value)
		{
			switch ((BoxUIDefinitionMembers)MemberEnum)
            {
				case BoxUIDefinitionMembers.Definition:
					var data = MyAPIGateway.Utilities.SerializeFromBinary<BoxUIDefinitionData>((byte[])Value);
					SetDefinition(data.Material, data.imagesize, data.topwidthpx, data.leftwidthpx, data.bottomwidthpx, data.rightwidthpx, data.margin, data.padding);
					return;
				case BoxUIDefinitionMembers.Min:
					return;
				default:
					return;
			}
		}

		public object GetMember(int MemberEnum)
		{
			switch((BoxUIDefinitionMembers)MemberEnum)
			{
				case BoxUIDefinitionMembers.Definition:
					return null;
				case BoxUIDefinitionMembers.Min:
					return Min;
				default:
					return null;
			}
		}

		public UIDefinition()
		{
			top = new uiside() { HasValue = false, margin = 0, padding = 0, usizex = 0, usizey = 0 };
			right = new uiside() { HasValue = false, margin = 0, padding = 0, usizex = 0, usizey = 0 };
			left = new uiside() { HasValue = false, margin = 0, padding = 0, usizex = 0, usizey = 0 };
			bottom = new uiside() { HasValue = false, margin = 0, padding = 0, usizex = 0, usizey = 0 };

			top_right = new uicorner() { HasValue = false };
			top_left = new uicorner() { HasValue = false };
			bottom_left = new uicorner() { HasValue = false };
			bottom_right = new uicorner() { HasValue = false };

			fill = new uifill() { HasValue = false };

		}
		public void SetDefinition(MyStringId Material, int imagesize, int topwidthpx, int leftwidthpx, int bottomwidthpx, int rightwidthpx, int margin = 0, int padding = 0)
		{
			if (readOnly)
				return;
			top = new uiside();
			top.HasValue = true;
			top.material = Material;
			top.materialSize = imagesize;
			top.tile = false;
			top.padding = padding;
			top.margin = margin;
			top.ux = leftwidthpx;
			top.uy = 0;
			top.usizex = imagesize - leftwidthpx - rightwidthpx;
			top.usizey = topwidthpx;

			left = new uiside();
			left.HasValue = true;
			left.material = Material;
			left.materialSize = imagesize;
			left.tile = false;
			left.padding = padding;
			left.margin = margin;
			left.ux = 0;
			left.uy = topwidthpx;
			left.usizex = leftwidthpx;
			left.usizey = imagesize - topwidthpx - bottomwidthpx;

			bottom = new uiside();
			bottom.HasValue = true;
			bottom.material = Material;
			bottom.materialSize = imagesize;
			bottom.tile = false;
			bottom.padding = padding;
			bottom.margin = margin;
			bottom.ux = leftwidthpx;
			bottom.uy = imagesize - bottomwidthpx;
			bottom.usizex = imagesize - leftwidthpx - rightwidthpx;
			bottom.usizey = bottomwidthpx;

			right = new uiside();
			right.HasValue = true;
			right.material = Material;
			right.materialSize = imagesize;
			right.tile = false;
			right.padding = padding;
			right.margin = margin;
			right.ux = imagesize - rightwidthpx;
			right.uy = topwidthpx;
			right.usizex = rightwidthpx;
			right.usizey = imagesize - topwidthpx - bottomwidthpx;

			fill = new uifill();
			fill.HasValue = true;
			fill.material = Material;
			fill.materialSize = imagesize;
			fill.tile = false;
			fill.ux = leftwidthpx;
			fill.uy = topwidthpx;
			fill.usizex = imagesize - leftwidthpx - rightwidthpx;
			fill.usizey = imagesize - topwidthpx - bottomwidthpx;

			top_left = new uicorner();
			top_left.HasValue = true;
			top_left.material = Material;
			top_left.materialSize = imagesize;
			top_left.tile = false;
			top_left.ux = 0;
			top_left.uy = 0;
			top_left.usizex = leftwidthpx;
			top_left.usizey = topwidthpx;

			top_right = new uicorner();
			top_right.HasValue = true;
			top_right.material = Material;
			top_right.materialSize = imagesize;
			top_right.tile = false;
			top_right.ux = imagesize - rightwidthpx;
			top_right.uy = 0;
			top_right.usizex = rightwidthpx;
			top_right.usizey = topwidthpx;

			bottom_left = new uicorner();
			bottom_left.HasValue = true;
			bottom_left.material = Material;
			bottom_left.materialSize = imagesize;
			bottom_left.tile = false;
			bottom_left.ux = 0;
			bottom_left.uy = imagesize - bottomwidthpx;
			bottom_left.usizex = leftwidthpx;
			bottom_left.usizey = bottomwidthpx;

			bottom_right = new uicorner();
			bottom_right.HasValue = true;
			bottom_right.material = Material;
			bottom_right.materialSize = imagesize;
			bottom_right.tile = false;
			bottom_right.ux = imagesize - rightwidthpx;
			bottom_right.uy = imagesize - bottomwidthpx;
			bottom_right.usizex = rightwidthpx;
			bottom_right.usizey = bottomwidthpx;
		}



		public UIDefinition(MyStringId Material, int imagesize, int topwidthpx, int leftwidthpx, int bottomwidthpx, int rightwidthpx, int margin = 0, int padding = 0, bool readOnly = false)
		{

			SetDefinition(Material, imagesize, topwidthpx, leftwidthpx, bottomwidthpx, rightwidthpx, margin, padding);
			this.readOnly = readOnly;
		}

		public Vector2I Min
		{
			get
			{
				return new Vector2I(MinX, MinY);
			}
		}

		public int MinX
		{
			get
			{
				return right.margin + Math.Max(top_left.usizex, bottom_left.usizex)  + right.padding + left.margin + Math.Max(top_right.usizex, bottom_right.usizex)  + left.padding;
			}
		}

		public int MinY
		{
			get
			{
				return top.margin + top.padding + Math.Max(top_left.usizey, top_right.usizey)  + bottom.margin + Math.Max(bottom_left.usizey, bottom_right.usizey) + bottom.padding;
			}
		}
	}
}
