using Microsoft.Xna.Framework;
using System;
using System.Linq;
namespace OpenVIII
{
///
/// Root class all menu objects can grow from.
///
public abstract class Menu_Base
{
#region Fields
protected Rectangle _pos;
#endregion Fields
#region Properties
///
/// Focus scales and centers the menu.
///
public static Matrix Focus { get; protected set; }
///
/// Adjusted mouse location used to determine if mouse is highlighting a button.
///
public static Point MouseLocation => InputMouse.Location.Transform(Focus);
public static Point ScreenBottomLeft => new Point(0, Memory.Graphics.GraphicsDevice.Viewport.Height).Transform(Focus);
public static Point ScreenBottomRight => new Point(Memory.Graphics.GraphicsDevice.Viewport.Width, Memory.Graphics.GraphicsDevice.Viewport.Height).Transform(Focus);
public static Point ScreenTopLeft => new Point(0, 0).Transform(Focus);
public static Point ScreenTopRight => new Point(Memory.Graphics.GraphicsDevice.Viewport.Width, 0).Transform(Focus);
public Menu_Base CONTAINER { get; set; }
public Cursor_Status Cursor_Status { get; set; } = Cursor_Status.Disabled;
///
/// Characters/Enemies/GF
///
public virtual Damageable Damageable { get; protected set; }
///
/// If enabled the menu is Visible and all functionality works. Else everything is hidden and
/// nothing functions.
///
public bool Enabled { get; private set; } = true;
public virtual int Height { get => _pos.Height; set => _pos.Height = value; }
public OffsetAnchor OffsetAnchor { get; set; }
///
/// Position of party member 0,1,2. If -1 at the time of setting the character wasn't in the party.
///
public sbyte PartyPos { get; protected set; } = sbyte.MaxValue;
///
/// Where to draw this item.
///
public virtual Rectangle Pos { get => _pos; set => _pos = value; }
public virtual int Width { get => _pos.Width; set => _pos.Width = value; }
public virtual int X { get => _pos.X; set => _pos.X = value; }
public virtual int Y { get => _pos.Y; set => _pos.Y = value; }
#endregion Properties
#region Methods
public static implicit operator Rectangle(Menu_Base v) => v.Pos;
public abstract void Draw();
///
/// Hide object prevents drawing, update, inputs.
///
public virtual void Hide() => Enabled = false;
public virtual void HideChildren()
{
}
public abstract bool Inputs();
public virtual void ModeChangeEvent(object sender, Enum e)
{
}
///
/// Things that change rarely. Like a party member changes or Laguna dream happens.
///
public virtual void Refresh() => RefreshChild();
///
/// by default null damageable won't propogate to children. resets to false after refresh.
///
public bool ForceNullDamageable { get; set; } = false;
///
/// Update set characters and then refresh.
///
///
///
public virtual void Refresh(Damageable damageable)
{
SetDamageable(damageable, null);
Refresh();
}
public bool Battle { get; protected set; } = false;
public void SetDamageable(Damageable damageable, sbyte? partypos = null, bool forcenull = false)
{
if ((Damageable != damageable) || (partypos.HasValue && partypos.Value != PartyPos))
{
if (partypos != null)
{
Damageable = damageable;
PartyPos = partypos.Value;
if (Damageable == null)
{
if (PartyPos >= 0 && Memory.State?.PartyData != null && PartyPos < Memory.State.PartyData.Count)
Damageable = Memory.State[Memory.State.PartyData[PartyPos]];
else
{
var enemypos = (0 - PartyPos) - 1;
if (PartyPos < 0 && Enemy.Party != null && enemypos < Enemy.Party.Count)
{
Damageable = Enemy.Party[enemypos];
}
}
}
}
else if (damageable != null)
{
Damageable = damageable;
if (Damageable.GetCharacterData(out var c))
{
PartyPos = (sbyte)(Memory.State?.Party?.Where(x => !x.Equals(Characters.Blank)).ToList().FindIndex(x => x.Equals(c.ID)) ?? -1);
}
else if (Damageable is Enemy)
{
PartyPos = checked((sbyte)(0 - Enemy.Party.FindIndex(x => x.Equals(Damageable)) - 1));
}
else PartyPos = sbyte.MaxValue;
}
else if(ForceNullDamageable || forcenull)
{
ForceNullDamageable = true;
Damageable = null;
PartyPos = sbyte.MaxValue;
}
}
}
///
/// Plan is to use this to reset values to a default state if done.
///
public virtual void Reset() { }
///
/// Show object enables drawing, update, inputs.
///
public virtual void Show() => Enabled = true;
public abstract bool Update();
protected abstract void Init();
///
/// For child items.
///
protected virtual void RefreshChild()
{
}
#endregion Methods
}
public class OffsetAnchor
{
#region Fields
private Vector2 v = Vector2.Zero;
#endregion Fields
#region Constructors
public OffsetAnchor(Vector2 pos) => this.v = pos;
public OffsetAnchor(Point pos) => this.v = pos.ToVector2();
public OffsetAnchor()
{
}
#endregion Constructors
#region Properties
public Point pPos { get => v.ToPoint(); set => v = value.ToVector2(); }
public Vector2 vPos { get => v; set => v = value; }
public float X { get => v.X; set => v.X = value; }
public float Y { get => v.Y; set => v.Y = value; }
#endregion Properties
#region Methods
public static explicit operator Point(OffsetAnchor a) => a.v.ToPoint();
public static implicit operator OffsetAnchor(Vector2 a) => new OffsetAnchor(a);
public static implicit operator OffsetAnchor(Point a) => new OffsetAnchor(a);
public static implicit operator Vector2(OffsetAnchor a) => a.v;
public OffsetAnchor Offset(float x, float y)
{
v.X += x;
v.Y += y;
return this;
}
public OffsetAnchor Offset(Vector2 _v)
{
v += _v;
return this;
}
internal void Set(Vector2 vector2) => v = vector2;
#endregion Methods
}
}