using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Framework.ItemSystem
{
    /// <summary>
    /// Acts as a general store of item type identifiers so that item types can be easily
    /// identified. Other partial implementations of this class in this namespace should be made 
    /// in different parts of the project to add new stats to the system.
    /// </summary>
    public static partial class ItemType
    {
        public delegate Itemlike CreateItemHandler(ItemDefinitionlike definition, GameObject owner);

        public static readonly Id Example = Allocate((definition, owner) => {return new Item(definition, owner);}); 

        // TODO, Use string to hashed value rather than a number perhaps? Problems with multiplayer could occur if number allocation is not the same on all clients
        private static int id; // The current id number, incremented every time an id is allocated

        /// <summary>
        /// Call this method when setting up a new item type id, it will return
        /// a unique id number for that stat
        /// </summary>
        /// <returns></returns>
        private static Id Allocate(CreateItemHandler handler)
        {
            //return (Id)id++;
            return new Id(id++, handler);
        }

        /// <summary>
        /// Item ids use an inner class that defines how the id works,
        /// this is so that only item ids can be used to identify items.
        /// </summary>
        public struct Id
        {
            private int value;
            private CreateItemHandler createItemHandler;

            internal Id(int value, CreateItemHandler handler)
            {
                this.value = value;
                this.createItemHandler = handler;
            }

            /// <summary>
            /// Creates the item that matches this ItemType id by calling the
            /// handler attached to this id. 
            /// </summary>
            /// <param name="definition">The definition.</param>
            /// <param name="owner">The owner.</param>
            /// <returns></returns>
            public Itemlike CreateItem(ItemDefinitionlike definition, GameObject owner)
            {
                return createItemHandler(definition, owner);
            }

            public override string ToString()
            {
                return "" + value;
            }
        }
    }
}
