Newer
Older
TheVengeance-Project-IADE-Unity2D / Assets / UI / Inventory / DynamicInventoryUI.cs
using MyCollections.Interfaces;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class DynamicInventoryUI : MonoBehaviour, IReceiver<int, int>
{
    [Header("Inventory Grid Settings: ")]
    [SerializeField] private GameObject UIslot;
    [SerializeField] private GameObject buttonOptions;
    [SerializeField] private GameObject insertPanel;
    [SerializeField] private float gridSpacingX, gridSpacingY; //the space between each tile of the matrix
    [SerializeField] private int columns = 5;  // Number of columns in the inventory grid

    private GameManager gameManager;
    private GameObject currentButtonOptions = null;
    private GameObject currentInsertPanel = null;
    [SerializeField] private InventoryManager inventoryManager;
    private Inventory inventory;

    //UI Inventory Matrix Size
    GameObject[,] inventorySlots = null;

    void Awake()
    {
        gameManager = GameManager.Instance;
    }

    // Start is called before the first frame update
    void Start()
    {
        inventoryManager = gameManager.PlayerController.GetComponentInChildren<InventoryManager>();

        if (inventoryManager != null)
        {
            inventory = inventoryManager.Inventory;

            // Subscribe to inventory changes when the UI is active
            inventory.InventoryChanged += UpdateUI;
            CreateInventoryGrid();
        }

        else
        {
            Debug.LogError($"Component not found: {nameof(InventoryManager)}");
        }
    }

    private void UpdateUI()
    {
        if(inventorySlots != null)
        {
            ClearInventoryGrid();
            CreateInventoryGrid();
        }
    }
    private void CreateInventoryGrid()
    {
        // Get the inventory size from the player
        int inventorySize = inventory.Capacity;

        // Calculate number of rows needed based on the inventory size and number of columns
        int rows = Mathf.CeilToInt((float)inventorySize / columns);

        // Initialize the 2D array based on rows and columns
        inventorySlots = new GameObject[rows, columns];

        // Calculate total width and height of the grid
        float gridWidth = columns * gridSpacingX;
        float gridHeight = rows * gridSpacingY;

        // Calculate the starting position for centering the grid
        Vector3 startPosition = new Vector3(-gridWidth / 2 + gridSpacingX / 2, gridHeight / 2 - gridSpacingY / 2, 0);

        // Start drawing the inventory grid
        for (int row = 0; row < rows; row++)
        {
            for (int col = 0; col < columns; col++)
            {
                // Calculate the slot index (linear inventory index)
                int index = row * columns + col;

                // Ensure we don't create extra slots beyond the inventory size
                if (index >= inventorySize) break;

                // Calculate the position for each slot based on row, column, and spacing
                Vector3 position = startPosition + new Vector3(col * gridSpacingX, -row * gridSpacingY, 0);

                // Instantiate the slot at the calculated position
                GameObject slot = Instantiate(UIslot, transform);
                slot.GetComponent<RectTransform>().anchoredPosition = position;

                // Store the slot reference in the array
                inventorySlots[row, col] = slot;

                // Display the item in this slot
                DisplayItemUIInfo(index, slot);
            }
        }
    }

    private void ClearInventoryGrid()
    {
        // Ensure that the inventorySlots array exists
        if (inventorySlots != null)
        {
            // Iterate through all rows and columns, destroy the slot GameObjects
            for (int row = 0; row < inventorySlots.GetLength(0); row++)
            {
                for (int col = 0; col < inventorySlots.GetLength(1); col++)
                {
                    if (inventorySlots[row, col] != null)
                    {
                        Destroy(inventorySlots[row, col]);
                    }
                }
            }

            // Reset the inventorySlots array
            inventorySlots = null;
        }
    }

    private void ClearSlotOptions()
    {
        if (currentButtonOptions != null)
            Destroy(currentButtonOptions);
    }

    //private void SetButtonListeners(InventorySlot slot, int index)
    //{
    //    if (slot.gameObject.TryGetComponent(out InventoryButton button))
    //    {
    //        slot
    //        button.ButtonInit(slot, index);
    //    }
    //}

    public void DisplayButtonOptions(Vector3 position, int index)
    {
        if(currentButtonOptions != null)
            Destroy(currentButtonOptions);

        currentButtonOptions = Instantiate(buttonOptions, position, Quaternion.identity, gameObject.transform);
        Button[] buttons = currentButtonOptions.GetComponentsInChildren<Button>();

        buttons[0].onClick.AddListener(delegate
        {
            SplitItemStack(index);
            Destroy(currentButtonOptions);
        });

        buttons[1].onClick.AddListener(delegate
        {
            CreateInsertPanel(index);
            Destroy(currentButtonOptions);
        });

        buttons[2].onClick.AddListener(delegate
        {
            //Discard the item
            DiscardItem(index);
            Destroy(currentButtonOptions);
        });
    }

    private void CreateInsertPanel(int index)
    {
        InventorySlot slot = inventory.GetSlot(index);

        if (slot == null)
            return;

        int amount = slot.Amount;

        if (currentInsertPanel != null)
        {
            Destroy(currentInsertPanel);
        }

        currentInsertPanel = Instantiate(insertPanel, gameObject.transform);

        if (currentInsertPanel.TryGetComponent(out AmountInserter inserter))
        {
            inserter.Init(gameObject, amount, index);
        }

    }

    private void DisplayItemUIInfo(int index, GameObject slot)
    {
        // Get item from inventory list
        if (index < inventory.Count)
        {
            InventorySlot inventorySlot = inventory.InventorySlot(index);

            if (inventorySlot != null)
            {
                //SetButtonListeners(slot, index);
                // Assign item sprite to the UI slot image
                Image[] images = slot.GetComponentsInChildren<Image>();
                TextMeshProUGUI tmp = slot.GetComponentInChildren<TextMeshProUGUI>();

                if (images != null)
                {
                    foreach (Image image in images)
                    {
                        if (image.gameObject.transform.childCount == 0)
                        {
                            image.color = Color.white;
                            image.sprite = inventorySlot.Item.ItemImage;
                            tmp.text = inventorySlot.Amount > 1 ? inventorySlot.Amount.ToString() : string.Empty;
                        }
                    }
                    //tmp.text = slot
                    Debug.Log($"Changed Sprite at index: {index}");
                    return;
                }
            }

            Debug.LogWarning("Item is NUll");
        }
    }

    private void Update()
    {

        if (Input.GetKeyDown(InputManager.GetKey(InputAction.SplitItemStack)))
        {
            //Activate 
        }
    }
    private void OnEnable()
    {   
        if (inventory != null)
        {
            // Subscribe to inventory changes when the UI is active
            inventory.InventoryChanged += UpdateUI;
            CreateInventoryGrid();
        }
    }

    private void OnDisable()
    {
        ClearInventoryGrid();
        inventory.InventoryChanged -= UpdateUI;
    }

    public void SplitItemStack(int index) => inventory.SplitSlot(index);

    public void DiscardItem(int index) => inventory.RemoveItem(index);

    public void Receive(int value, int index) => inventoryManager.DropItem(index, value);
}