using System;
using JetBrains.Annotations;
using NaughtyAttributes;
using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
namespace EscapeRoomEngine.Station46.Runtime
{
public enum ButtonEventType
{
Pressed, Released, Activated, Deactivated
}
public static class ButtonEventExtensions
{
public static string Description(this ButtonEventType type, Button button)
{
var action = type switch
{
ButtonEventType.Pressed => "pressed",
ButtonEventType.Released => "released",
ButtonEventType.Activated => "activated",
ButtonEventType.Deactivated => "deactivated",
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
return $"{button} was {action}";
}
}
public delegate void ButtonEventHandler(Button source, ButtonEventType e);
///
/// A general component for buttons that handles button events.
///
public class Button : MonoBehaviour
{
public event ButtonEventHandler ButtonEvent;
///
/// Whether this button accepts input.
///
[ShowNativeProperty]
protected bool Active
{
get => _active;
set
{
var previous = _active;
_active = value;
if (previous != _active)
{
OnButtonEvent(_active ? ButtonEventType.Activated : ButtonEventType.Deactivated);
}
}
}
///
/// Whether this button is currently pressed.
///
[ShowNativeProperty]
protected bool Pressed
{
get => _pressed;
set
{
var previous = _pressed;
_pressed = Active && value;
if (previous != _pressed)
{
OnButtonEvent(_pressed ? ButtonEventType.Pressed : ButtonEventType.Released);
}
}
}
private bool _active = true, _pressed;
protected virtual void Start()
{
ButtonEvent += (_, type) =>
{
if (type == ButtonEventType.Deactivated)
{
Pressed = false; // release button if it is deactivated
}
};
}
private void OnButtonEvent(ButtonEventType type)
{
Logger.Log(type.Description(this), LogType.PuzzleDetail);
ButtonEvent?.Invoke(this, type);
}
#region Debug Buttons
[Button(enabledMode: EButtonEnableMode.Playmode)]
public void Enable() => Active = true;
[Button(enabledMode: EButtonEnableMode.Playmode)]
public void Disable() => Active = false;
[Button(enabledMode: EButtonEnableMode.Playmode)]
public void Press() => Pressed = true;
[Button(enabledMode: EButtonEnableMode.Playmode)]
public void Release() => Pressed = false;
[UsedImplicitly]
[Button(enabledMode: EButtonEnableMode.Playmode)]
public void PressAndRelease()
{
Press();
Release();
}
#endregion
public override string ToString()
{
return name;
}
}
}