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

namespace UIFun.Messagesv2
{
	public class ModBillboardTriHUDMessage : ModMessageBase
	{

		private enum EntityMembers : int
		{
			Message = 0,
			Origin = 10,
			Options,
			BillBoardColor,
			Material,
			Rotation,
			Width,
			Height,
			p0,
			p1,
			p2
		}
		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 uvP0;
		public Vector2 uvP1;
		public Vector2 uvP2;



		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.p0:
					return uvP0;
				case EntityMembers.p1:
					return uvP1;
				case EntityMembers.p2:
					return uvP2;
				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;
					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.p0:
					uvP0 = (Vector2)Value;
					return;
				case EntityMembers.p1:
					uvP1 = (Vector2)Value;
					return;
				case EntityMembers.p2:
					uvP2 = (Vector2)Value;
					return;

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

		public override void Draw()
		{

			try
			{
				if (Options.HasFlag(Options.HideHud))
				{
					if (FontTexture.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;
					origin.Y += height;

					origin.Y *= -1;

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

					WriteBillboardUV(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;

				//origin.X *= (FontTexture.localscale * FontTexture.aspectRatio);
				//origin.Y *= FontTexture.localscale;

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

					//w *= (float)(FontTexture.localscale * FontTexture.aspectRatio);
					//h *= (float)FontTexture.localscale;

				}
				if (Options.HasFlag(Options.FOVScale))
				{
					w *= (float)localscale;
					h *= (float)localscale;

					//w *= (float)FontTexture.localscale;
					//h *= (float)FontTexture.localscale;

				}

				WriteBillboardUV(origin, Material, (m_skipLinearRGB ? m_BillBoardColorV4 : BillBoardColorLinearRBG), w , h);

				
			}
			catch
			{

			}
		}

		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.AddBillboardOrientedTri(billboard, billboardcolor, textpos, uvP0, uvP1, uvP2, cameramatrix.Up, cameramatrix.Left, w, h, Blend);
			return;
		}
	}
}
