/*
 * @license Private Source License v1.0.0
 * @copyright 2023 Reinhardt Weyers
 *
 * @author Reinhardt Weyers
 *
 * @version 0.1.0
 * 
 * Created On: 04/12/25
 * Last edited: 04/12/25
 */

using UnityEngine;
using System.Collections.Generic;

namespace RetroDev.Controller
{
    /// <summary>
    /// Static class for managing game controller input and button mappings.
    /// </summary>
    public static class Controller
    {
        /// <summary>
        /// Enumeration representing different types of controllers.
        /// </summary>
        public enum ControllerType
        {
            PlayStation,
            Xbox,
            Generic
        }

        /// <summary>
        /// Dictionary to store button mappings.
        /// </summary>
        private static Dictionary<string, string> buttonMappings = new Dictionary<string, string>();

        /// <summary>
        /// Detects connected game controllers and initializes button mappings accordingly.
        /// </summary>
        /// <returns>True if any controller is connected, false otherwise.</returns>
        public static bool DetectConnectedController()
        {
            // Get an array of connected joystick names
            string[] joystickNames = Input.GetJoystickNames();

            // Iterate through the joystick names
            foreach (string name in joystickNames)
            {
                string productName = name.ToLower();

                // Check if the name contains "playstation"
                if (productName.Contains("playstation"))
                {
                    // Initialize button mappings for PlayStation controller
                    InitializeButtonMappings(ControllerType.PlayStation);
                    return true; // PlayStation controller detected
                }
                // Check if the name contains "xbox"
                else if (productName.Contains("xbox"))
                {
                    // Initialize button mappings for Xbox controller
                    InitializeButtonMappings(ControllerType.Xbox);
                    return true; // Xbox controller detected
                }
            }

            // Default to generic controller
            InitializeButtonMappings(ControllerType.Generic);
            return joystickNames.Length > 0; // Return true if any controller is connected, false otherwise
        }

        /// <summary>
        /// Initializes button mappings based on the specified controller type.
        /// </summary>
        /// <param name="controllerType">Type of the controller.</param>
        private static void InitializeButtonMappings(ControllerType controllerType)
        {
            switch (controllerType)
            {
                case ControllerType.PlayStation:
                    // Initialize PlayStation button mappings
                    PlayStation.InitializeButtons();
                    break;
                case ControllerType.Xbox:
                    // Initialize Xbox button mappings
                    Xbox.InitializeButtons();
                    break;
                case ControllerType.Generic:
                    // Initialize Generic button mappings
                    Generic.InitializeButtons();
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Gets the input name of the specified button.
        /// </summary>
        /// <param name="button">Name of the button.</param>
        /// <returns>The input name of the button.</returns>
        public static string GetButtonName(string button)
        {
            string buttonName;
            if (buttonMappings.TryGetValue(button, out buttonName))
            {
                return buttonName; // Return the input name if button is found in mappings
            }
            else
            {
                // Log a warning if button mapping is not found
                UnityEngine.Debug.LogWarning("Button mapping not found for " + button);
                return null;
            }
        }
    }


    /// <summary>
    /// Static class containing button mappings for PlayStation controller.
    /// </summary>
    public static class PlayStation
    {
        /// <summary>
        /// Input name for the Cross button.
        /// </summary>
        public static string Cross { get; set; } = "joystick button 1";

        /// <summary>
        /// Input name for the Circle button.
        /// </summary>
        public static string Circle { get; set; } = "joystick button 2";

        /// <summary>
        /// Input name for the Square button.
        /// </summary>
        public static string Square { get; set; } = "joystick button 0";

        /// <summary>
        /// Input name for the Triangle button.
        /// </summary>
        public static string Triangle { get; set; } = "joystick button 3";

        /// <summary>
        /// Input name for the L1 button.
        /// </summary>
        public static string L1 { get; set; } = "joystick button 4";

        /// <summary>
        /// Input name for the R1 button.
        /// </summary>
        public static string R1 { get; set; } = "joystick button 5";

        /// <summary>
        /// Input name for the L2 button.
        /// </summary>
        public static string L2 { get; set; } = "joystick button 6";

        /// <summary>
        /// Input name for the R2 button.
        /// </summary>
        public static string R2 { get; set; } = "joystick button 7";

        /// <summary>
        /// Input name for the L3 button.
        /// </summary>
        public static string L3 { get; set; } = "joystick button 8";

        /// <summary>
        /// Input name for the R3 button.
        /// </summary>
        public static string R3 { get; set; } = "joystick button 9";

        /// <summary>
        /// Input name for the Share button.
        /// </summary>
        public static string Share { get; set; } = "joystick button 10";

        /// <summary>
        /// Input name for the Options button.
        /// </summary>
        public static string Options { get; set; } = "joystick button 11";

        /// <summary>
        /// Input name for the PS button.
        /// </summary>
        public static string PSButton { get; set; } = "joystick button 12";

        /// <summary>
        /// Initializes the button mappings for the PlayStation controller.
        /// </summary>
        public static void InitializeButtons()
        {
            Cross = "joystick button 1";
            Circle = "joystick button 2";
            Square = "joystick button 0";
            Triangle = "joystick button 3";
            L1 = "joystick button 4";
            R1 = "joystick button 5";
            L2 = "joystick button 6";
            R2 = "joystick button 7";
            L3 = "joystick button 8";
            R3 = "joystick button 9";
            Share = "joystick button 10";
            Options = "joystick button 11";
            PSButton = "joystick button 12";
        }
    }

    /// <summary>
    /// Static class containing button mappings for Xbox controller.
    /// </summary>
    public static class Xbox
    {
        /// <summary>
        /// Input name for the A button.
        /// </summary>
        public static string A { get; set; } = "joystick button 0";

        /// <summary>
        /// Input name for the B button.
        /// </summary>
        public static string B { get; set; } = "joystick button 1";

        /// <summary>
        /// Input name for the X button.
        /// </summary>
        public static string X { get; set; } = "joystick button 2";

        /// <summary>
        /// Input name for the Y button.
        /// </summary>
        public static string Y { get; set; } = "joystick button 3";

        /// <summary>
        /// Input name for the LB button.
        /// </summary>
        public static string LB { get; set; } = "joystick button 4";

        /// <summary>
        /// Input name for the RB button.
        /// </summary>
        public static string RB { get; set; } = "joystick button 5";

        /// <summary>
        /// Input name for the LT button.
        /// </summary>
        public static string LT { get; set; } = "joystick button 6";

        /// <summary>
        /// Input name for the RT button.
        /// </summary>
        public static string RT { get; set; } = "joystick button 7";

        /// <summary>
        /// Input name for the Left Stick button.
        /// </summary>
        public static string LeftStick { get; set; } = "joystick button 8";

        /// <summary>
        /// Input name for the Right Stick button.
        /// </summary>
        public static string RightStick { get; set; } = "joystick button 9";

        /// <summary>
        /// Input name for the Back button.
        /// </summary>
        public static string Back { get; set; } = "joystick button 10";

        /// <summary>
        /// Input name for the Start button.
        /// </summary>
        public static string Start { get; set; } = "joystick button 11";

        /// <summary>
        /// Input name for the Xbox button.
        /// </summary>
        public static string XboxButton { get; set; } = "joystick button 12";

        /// <summary>
        /// Initializes the button mappings for the Xbox controller.
        /// </summary>
        public static void InitializeButtons()
        {
            A = "joystick button 0";
            B = "joystick button 1";
            X = "joystick button 2";
            Y = "joystick button 3";
            LB = "joystick button 4";
            RB = "joystick button 5";
            LT = "joystick button 6";
            RT = "joystick button 7";
            LeftStick = "joystick button 8";
            RightStick = "joystick button 9";
            Back = "joystick button 10";
            Start = "joystick button 11";
            XboxButton = "joystick button 12";
        }
    }

    /// <summary>
    /// Static class containing button mappings for generic controller.
    /// </summary>
    public static class Generic
    {
        /// <summary>
        /// Input name for the A button.
        /// </summary>
        public static string A { get; set; } = "joystick button 0";

        /// <summary>
        /// Input name for the B button.
        /// </summary>
        public static string B { get; set; } = "joystick button 1";

        /// <summary>
        /// Input name for the X button.
        /// </summary>
        public static string X { get; set; } = "joystick button 2";

        /// <summary>
        /// Input name for the Y button.
        /// </summary>
        public static string Y { get; set; } = "joystick button 3";

        /// <summary>
        /// Input name for the LB button.
        /// </summary>
        public static string LB { get; set; } = "joystick button 4";

        /// <summary>
        /// Input name for the RB button.
        /// </summary>
        public static string RB { get; set; } = "joystick button 5";

        /// <summary>
        /// Input name for the LT button.
        /// </summary>
        public static string LT { get; set; } = "joystick button 6";

        /// <summary>
        /// Input name for the RT button.
        /// </summary>
        public static string RT { get; set; } = "joystick button 7";

        /// <summary>
        /// Input name for the Left Stick button.
        /// </summary>
        public static string LeftStick { get; set; } = "joystick button 8";

        /// <summary>
        /// Input name for the Right Stick button.
        /// </summary>
        public static string RightStick { get; set; } = "joystick button 9";

        /// <summary>
        /// Input name for the Back button.
        /// </summary>
        public static string Back { get; set; } = "joystick button 10";

        /// <summary>
        /// Input name for the Start button.
        /// </summary>
        public static string Start { get; set; } = "joystick button 11";

        /// <summary>
        /// Input name for the Menu button.
        /// </summary>
        public static string Menu { get; set; } = "joystick button 12";

        /// <summary>
        /// Initializes the button mappings for the generic controller.
        /// </summary>
        public static void InitializeButtons()
        {
            A = "joystick button 0";
            B = "joystick button 1";
            X = "joystick button 2";
            Y = "joystick button 3";
            LB = "joystick button 4";
            RB = "joystick button 5";
            LT = "joystick button 6";
            RT = "joystick button 7";
            LeftStick = "joystick button 8";
            RightStick = "joystick button 9";
            Back = "joystick button 10";
            Start = "joystick button 11";
            Menu = "joystick button 12";
        }
    }
}



