using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
///
/// This class connects a grid view for buy state of the shop to a controller to manipulate the BuyModel via a ShopController
/// interface, it contains specific methods to setup and update a grid view, with the data from a BuyModel. If you want to display
/// informationoutside of the BuyModel, for example, the money amount from the player's inventory, then you need to either keep a
/// reference to all the related models, or make this class an observer/event subscriber of the related models.
///
public abstract class ShopView : MonoBehaviour, IShopModelObserver-
{
public ShopModel ShopModel => model; //A getter to access shopModel.
[SerializeField]
protected GameObject itemPrefab; //A prefab to display an item in the view
[SerializeField]
protected Button buyButton;
[SerializeField]
protected TextMeshProUGUI instructionText;
[SerializeField] protected LayoutGroup layoutGroup; // The layout group that represents this view visually
protected ShopModel model; // Model in MVC pattern
protected ShopModel other; // Other model in MVC pattern (our own inventory)
private ShopController shopController; //Controller in MVC pattern
// Set up the view's necessary stuff before the view is enabled
protected virtual void Awake()
{
model = new BuyModel(2f, 16, 500); //Right now use magic values to set up the shop
shopController = gameObject.AddComponent().Initialize(model);//Set the default controller to be the mouse controller
SetupItemIconView(); //Setup the grid view's properties
InitializeButtons(); //Connect the buttons to the controller
//model.Subscribe(this);
}
private void OnEnable()
{
PopulateItemIconView(); //Display items
}
private void OnDisable()
{
ClearIconView();
}
//------------------------------------------------------------------------------------------------------------------------
// SetupItemIconView()
//------------------------------------------------------------------------------------------------------------------------
//Setup the grid view according to the ViewConfig object's requirements, right now it just sets the constraint mode and column count,
//you can make cosmetic adjustments to the GridLayoutGroup by adding more configurations to ViewConfig and use them adjusting properties
//like cellSize, spacing, padding, etc.
protected abstract void SetupItemIconView();
//------------------------------------------------------------------------------------------------------------------------
// RepopulateItems()
//------------------------------------------------------------------------------------------------------------------------
//Clears the grid view and repopulates it with new icons (updates the visible icons)
private void RepopulateItemIconView() {
ClearIconView();
PopulateItemIconView();
}
//------------------------------------------------------------------------------------------------------------------------
// PopulateItems()
//------------------------------------------------------------------------------------------------------------------------
//Adds one icon for each item in the shop
private void PopulateItemIconView() {
foreach (Item item in model.inventory.GetItems()) {
AddItemToView(item);
}
}
//------------------------------------------------------------------------------------------------------------------------
// ClearIconView()
//------------------------------------------------------------------------------------------------------------------------
//Removes all existing icons in the gridview
protected abstract void ClearIconView();
//------------------------------------------------------------------------------------------------------------------------
// AddItemToView()
//------------------------------------------------------------------------------------------------------------------------
//Adds a new item container to the view, each view can have its way of displaying items
protected abstract void AddItemToView(Item item);
protected abstract void RemoveItemFromView(Item item);
//------------------------------------------------------------------------------------------------------------------------
// InitializeButtons()
//------------------------------------------------------------------------------------------------------------------------
//This method adds a listener to the 'Buy' button. They are forwarded to the controller. Since this is the confirm button of
//the buy view, it will just call the controller interface's ConfirmSelectedItem function, the controller will handle the rest.
private void InitializeButtons() {
buyButton.onClick.AddListener(
delegate {
shopController.ConfirmSelectedItem();
}
);
}
private void Update()
{
//RepopulateItemIconView();//Repopulate the view each frame, this is very inefficient and won't work in many scenarios and SHOULD NOT be in
//the final implementation, the view should be modified by the models via an observer or event queue pattern
//Switch between mouse and keyboard controllers
if (Input.GetKeyUp(KeyCode.K))
{
if (shopController is MouseController)
{
SwitchToKeyboardControl();
}
}
else if (Input.GetMouseButtonUp(0))
{
if (shopController is GridViewKeyboardController)
{
SwitchToMouseControl();
}
}
//Let the current controller handle input
shopController.HandleInput();
}
//------------------------------------------------------------------------------------------------------------------------
// SwitchToKeyboardControl()
//------------------------------------------------------------------------------------------------------------------------
private void SwitchToKeyboardControl()
{
Destroy(shopController);//Remove the current controller component
shopController = gameObject.AddComponent().Initialize(model);//Create and add a keyboard controller
instructionText.text = "The current control mode is: Keyboard Control, WASD to select item, press K to buy. Press left mouse button to switch to Mouse Control.";
buyButton.gameObject.SetActive(false);//Hide the buy button because we only use keyboard
}
//------------------------------------------------------------------------------------------------------------------------
// SwitchToMouseControl()
//------------------------------------------------------------------------------------------------------------------------
private void SwitchToMouseControl()
{
Destroy(shopController);//Remove the current controller component
shopController = gameObject.AddComponent().Initialize(model);//Create and add a mouse controller
instructionText.text = "The current control mode is: Mouse Control, press 'K' to switch to Keyboard Control.";
buyButton.gameObject.SetActive(true);//Show the buy button for the mouse controler
}
public void OnSelected(Item item)
{
Debug.Log("View selects item: " + item.name,this);
RepopulateItemIconView();
}
public void OnRemoved(Item item)
{
RemoveItemFromView(item);
}
public void OnAdded(Item item)
{
throw new NotImplementedException();
}
}