﻿using System;
using System.Collections.Generic;
using EnergyShell.Content.Generator;
using SFML.Graphics;

namespace EnergyShell.Content
{
    /// <summary>
    /// A content heap which contains projectile texture which are dynamically created.
    /// </summary>
    public sealed class DynamicProjectileTextureHeap
    {
        /// <summary>
        /// The content heap which stores all cached content.
        /// </summary>
        private readonly Dictionary<int, WeakReference> heap;

        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicProjectileTextureHeap" /> class.
        /// </summary>
        public DynamicProjectileTextureHeap()
        {
            this.heap = new Dictionary<int, WeakReference>();
        }

        /// <summary>
        /// Gets the texture.
        /// </summary>
        /// <param name="radius">The radius of the projectile.</param>
        /// <returns>The texture for a projectile which matches the given parameters.</returns>
        public Texture GetTexture(int radius)
        {
            WeakReference contentRef;

            if (this.heap.TryGetValue(radius, out contentRef))
            {
                Texture content = contentRef.Target as Texture;
                if (contentRef.IsAlive && content != null)
                {
                    return content;
                }
                // We didnt manage to find the object because it was either dead or null.
                this.heap.Remove(radius);
            }

            // Cached a new instance of the content object.
            return CacheContent(radius);
        }

        /// <summary>
        /// Caches new content.
        /// </summary>
        /// <param name="radius">The radius.</param>
        /// <returns>The texture for a projectile which matches the given parameters.</returns>
        private Texture CacheContent(int radius)
        {
            Texture texture = CircleDataTextureFactory.GenerateCircleWithEvenDiameter(radius);
            this.heap.Add(radius, new WeakReference(texture));
            return texture;
        }
    }
}
