using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace DXGfxLib
{
    /// <summary>
    /// At the moment this class is only use to control that we load a MeshRessource only once. This is not completely fnished yet,
    /// for example there is no usage ref count. This will be implemented once I have decided if the library will start managing
    /// ressources or if these should always be managed by the calling code and that the library should remain only a scene graph
    /// libary. This is still undecided.
    /// </summary>
    public class RessourceManager
    {
        /// <summary>
        /// At the moment we want only one instance of the RessourceManager class per AppDomain so we keep a ref to the first
        /// instance created here. When the constructore is called if this static member variable is not null we just throw an
        /// exception.
        /// </summary>
        protected static RessourceManager globalInstance = null;

        /// <summary>
        /// A hashtable to keep track of the MeshRessources whe have already loaded.
        /// </summary>
        Hashtable loadedMeshRessources = null;

        /// <summary>
        /// Default constructor. The constructor check if the member variable globalInstance is already different of null.
        /// If it is the constructor will throw an exception to notify the calling code!!
        /// </summary>
        public RessourceManager()
        {
            if (globalInstance != null)
            {
                throw new Exception("This is wrong only one instance of the RessourceManager can be created per process and there is already one!");
            }
            loadedMeshRessources = new Hashtable();
            globalInstance = this;
        }

        /// <summary>
        /// This static method will always return a reference to the sole instance of this class. If the constructor has not been
        /// called yet and that we don't have any instance of the RessourceManager class we throw an exception.
        /// </summary>
        /// <returns></returns>
        public RessourceManager GetGlobalInstance()
        {
            if (globalInstance == null)
            {
                throw new NullReferenceException("There is no instance of RessourceManager class in this AppDomain. It is wrong to call this method now!");
            }
            return globalInstance;
        }
        
        /// <summary>
        /// This method will check if the specified filename has already been loaded in a MeshRessource. If it has we get
        /// its reference and return that to the calling code. If it has not been loaded yet the method is going to load it
        /// now and add the fileName and a ref to the MeshRessource to the HAshtable loadedMeshRessources.
        /// If one day MeshRessource or a base Ressource class do implement a usage counter ala COM ref count then this method
        /// will have to increase the ref count if the ressource is already loaded and that a ref to the already existing
        /// MeshRessource is return to the calling code.
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public MeshRessource GetMeshRessource(string filename)
        {
            MeshRessource preloaded = loadedMeshRessources[filename] as MeshRessource;

            if (preloaded == null)
            {
                preloaded = new MeshRessource(filename);
            }

            return preloaded;
        }
    }
}
