using Sandbox.ModAPI;
using System;
using VRage.Utils;
using VRageMath;

namespace UIFun.Messagesv2
{
	public class ModBillboardHUDMessage : ModMessageBase
	{

		private enum EntityMembers : int
		{
			Message = 0,
			Origin = 10,
			Options,
			BillBoardColor,
			Material,
			Rotation,
			Width,
			Height,
			uvOffset,
			uvSize,
			TextureSize,
			uvEnabled
		}
		public Vector2D Origin = Vector2D.Zero;
		public MyStringId Material = MyStringId.GetOrCompute("");
		public Options Options = Options.None;
		public Color m_BillboardColor = Color.White;
		public Color BillBoardColor
		{
			get
			{
				return m_BillboardColor;
			}
			set
			{
				m_BillboardColor = value;
				m_BillBoardColorV4 = value.ToVector4();
				BillBoardColorLinearRBG = value.ToVector4().ToLinearRGB();
			}
		}
		public Vector4 BillBoardColorLinearRBG = Color.White.ToVector4().ToLinearRGB();
		private Vector4 m_BillBoardColorV4 = Color.White.ToVector4();
		public float Rotation = 0f;
		public float Width = 1f;
		public float Height = 1f;
		public Vector2 uvOffset = Vector2.Zero;
		public Vector2 uvSize = Vector2.One;
		public float TextureSize = 1f;
		public bool UseUv = false;

		public override object GetMember(int MemberEnum)
		{
			switch ((EntityMembers)MemberEnum)
			{
				case EntityMembers.Origin:
					return Origin;
				case EntityMembers.Options:
					return (byte)Options;
				case EntityMembers.BillBoardColor:
					return BillBoardColor;
				case EntityMembers.Material:
					return Material;
				case EntityMembers.Rotation:
					return Rotation;

				case EntityMembers.Message:
					return Material;
				case EntityMembers.Width:
					return Width;
				case EntityMembers.Height:
					return Height;
				case EntityMembers.uvOffset:
					return uvOffset;
				case EntityMembers.uvSize:
					return uvSize;
				case EntityMembers.TextureSize:
					return TextureSize;
				case EntityMembers.uvEnabled:
					return UseUv;

				default:
					return base.GetMember(MemberEnum);
			}
		}
		public override void SetMember(int MemberEnum, object Value)
		{
			switch ((EntityMembers)MemberEnum)
			{
				case EntityMembers.Origin:
					Origin = (Vector2D)Value;
					return;
				case EntityMembers.Options:
					Options = (Options)Value;
					return;
				case EntityMembers.BillBoardColor:
					BillBoardColor = (Color)Value;
					//BillBoardColorLinearRBG = BillBoardColor.ToVector4().ToLinearRGB();
					return;
				case EntityMembers.Material:
					Material = (MyStringId)Value;
					return;
				case EntityMembers.Rotation:
					Rotation = (float)Value;
					return;

				case EntityMembers.Message:
					return;

				case EntityMembers.Width:
					Width = Math.Abs((float)Value);
					return;
				case EntityMembers.Height:
					Height = Math.Abs((float)Value);
					return;
				case EntityMembers.uvOffset:
					uvOffset = (Vector2)Value;
					return;
				case EntityMembers.uvSize:
					uvSize = (Vector2)Value;
					return;
				case EntityMembers.TextureSize:
					TextureSize = (float)Value;
					return;
				case EntityMembers.uvEnabled:
					UseUv = (bool)Value;
					return;


				default:
					base.SetMember(MemberEnum, Value);
					return;
			}
		}

		public override void Draw()
		{

			try
			{
				if (Options.HasFlag(Options.HideHud))
				{
					if (FontTexture.m_HudHidden)
						return;//hud is hidden dont draw. 
				}
				if (MyAPIGateway.Session?.Camera == null) return;
				Vector2D origin = Origin;
				var fov = MyAPIGateway.Session.Camera.FovWithZoom;
				double aspectratio = MyAPIGateway.Session.Camera.ViewportSize.X / MyAPIGateway.Session.Camera.ViewportSize.Y;
				double localscale = FontTexture.DRAWDISTANCE * Math.Tan(fov / 2f);
				

				if(Options.HasFlag(Options.Pixel))
				{
					var modulo = Origin;
					modulo.X += MyAPIGateway.Session.Camera.ViewportSize.X;
					modulo.Y += MyAPIGateway.Session.Camera.ViewportSize.Y;
					modulo.X %= MyAPIGateway.Session.Camera.ViewportSize.X;
					modulo.Y %= MyAPIGateway.Session.Camera.ViewportSize.Y;

                    float xsize = (MyAPIGateway.Session.Camera.ViewportSize.X / 2f) ;
					float ysize = (MyAPIGateway.Session.Camera.ViewportSize.Y / 2f) ;
					origin.X = -1;
					origin.Y = -1;

					origin.X += modulo.X / xsize ;
					origin.X += Offset.X / xsize ;
					origin.Y += modulo.Y / ysize;// * aspectratio;
					origin.Y += Offset.Y / ysize;// * aspectratio;

					float width = Width / xsize;
					float height = Height / ysize;

					origin.X += width / 2f;
					origin.Y += height / 2f;

					origin.Y *= -1;

					origin.X *= (localscale * aspectratio);
					origin.Y *= localscale;

					if (UseUv)
					{

						
						WriteBillboardUV(origin, Material, (m_skipLinearRGB ? m_BillBoardColorV4 : BillBoardColorLinearRBG), width   * (float)aspectratio  * (float)localscale , height  * (float)localscale  );
					}
					else
					{
						
						WriteBillboard(origin, Material, (m_skipLinearRGB ? m_BillBoardColorV4 : BillBoardColorLinearRBG), width * (float)aspectratio * (float)localscale , height * (float)localscale );
					}
					return;
				}
				origin += Offset;
				origin.X *= (localscale * aspectratio);
				origin.Y *= localscale;

				float w = Width * (float)Scale;
                float h = Height * (float)Scale;
                if (!Options.HasFlag(Options.Fixed))
				{
					w *= (float)(localscale * aspectratio);
					h *= (float)localscale;
				}
				if (Options.HasFlag(Options.FOVScale))
				{
					w *= (float)localscale;
					h *= (float)localscale;
				}
				if(UseUv)
				{

					WriteBillboardUV(origin, Material, (m_skipLinearRGB ? m_BillBoardColorV4 : BillBoardColorLinearRBG), w , h);
				}
				else
				{
				
					WriteBillboard(origin, Material, (m_skipLinearRGB ? m_BillBoardColorV4 : BillBoardColorLinearRBG), w , h );
				}
				
			}
			catch
			{

			}
		}


		private void WriteBillboard(Vector2D Origin, MyStringId billboard, Vector4 billboardcolor, float w, float h)
		{
			MatrixD cameramatrix = MyAPIGateway.Session.Camera.WorldMatrix;
			
			Vector3D textpos = Vector3D.Transform(new Vector3D(Origin.X, Origin.Y, (Options.HasFlag(Options.Shadowing) ? -0.10001 : -0.1)), cameramatrix);
			var rotquad = Quaternion.CreateFromAxisAngle((Vector3)cameramatrix.Forward, Rotation);
			cameramatrix = MatrixD.Transform(cameramatrix, rotquad);
			VersionHelper.AddBillboardOriented(billboard, billboardcolor, textpos, (Vector3)cameramatrix.Up, (Vector3)cameramatrix.Left, w , h , Blend);
			return;
		}
		private void WriteBillboardUV(Vector2D Origin, MyStringId billboard, Vector4 billboardcolor, float w, float h)
		{
			MatrixD cameramatrix = MyAPIGateway.Session.Camera.WorldMatrix;

			Vector3D textpos = Vector3D.Transform(new Vector3D(Origin.X, Origin.Y, (Options.HasFlag(Options.Shadowing) ? -0.10001 : -0.1)), cameramatrix);
			var rotquad = Quaternion.CreateFromAxisAngle((Vector3)cameramatrix.Forward, Rotation);
			cameramatrix = MatrixD.Transform(cameramatrix, rotquad);
			VersionHelper.AddBillboardOriented(billboard, billboardcolor, textpos, cameramatrix.Up, cameramatrix.Left, w, h, uvOffset, uvSize, TextureSize, Blend);
			return;
		}
	}
}
