﻿using IcingDX.EntityComponentModel.Managers;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace IcingDX.EntityComponentModel
{
    public class EntityContext
    {
        private readonly Dictionary<int, Entity> entities;
       
        private bool initialized = false;

        public EntityContext()
        {
            entities = new Dictionary<int, Entity>();
            Configure();
            initialized = true;
        }

        internal IIdManager IdManager { get; private set;}
        public IGroupManager GroupManager { get; private set; }
        public INameManager NameManager { get; private set; }



       
        protected void SetIdManager(IIdManager idManager)
        {
            if (idManager == null)
                throw new ArgumentNullException("idManager");

            GuardConfiguration();

            IdManager = idManager;
        }

        protected void SetGroupManager(IGroupManager groupManager)
        {
            if (groupManager == null)
                throw new ArgumentNullException("groupManager");

            GuardConfiguration();

            GroupManager = groupManager;
        }

        protected void SetNameManager(INameManager nameManager)
        {
            if (nameManager == null)
                throw new ArgumentNullException("nameManager");

            GuardConfiguration();

            NameManager = nameManager;
        }

        private void GuardConfiguration()
        {
            if (initialized)
                throw new InvalidOperationException("Configuration already completed.");
        }

        public virtual void OverrideConfiguration() { }

        private void Configure()
        {
            OverrideConfiguration();

            if (IdManager == null) IdManager = new DefaultIdManager();
            if (GroupManager == null) GroupManager = new DefaultGroupManager();
            if (NameManager == null) NameManager = new DefaultNameManager();
        }

        internal void OnEntityCreated(Entity entity)
        {
            lock (entities)
            {
                if (entities.ContainsKey(entity.Id))
                    return;               
               
                entities.Add(entity.Id, entity);   
            }
        }       

        internal protected virtual void OnEntityDestroyed(Entity entity)
        {            
            lock (entities)
            {
                if(entities.Remove(entity.Id))
                {
                    GroupManager.OnEntityDestroyed(entity);
                    NameManager.OnEntityDestroyed(entity);
                }
            }
        }

        internal protected void OnComponentAdded(Entity entity, ComponentKey componentKey)
        {
            
        }

        internal protected void OnComponentRemoved(Entity entity, ComponentKey componentKey)
        {
            
        }
    }
}
