﻿#region License
/*****************************************************************************
 *
 *Copyright 2016 cathy33
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
 *
 *****************************************************************************/
#endregion

using Infinity.Core.Data;
using Infinity.Core.Interface;
using Infinity.Core.Variant;

namespace Infinity.Client
{
    partial class CKernel
    {
        public bool FindChild(PersistID pid, string container_name, PersistID child)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return false;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return false;
            }

            return container.GetSlot(child) != Constant.INVALID_SLOT;
        }

        public bool FindContainer(PersistID pid, string container_name)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return false;
            }

            return entity.FindContainer(container_name);
        }

        public int GetCapacity(PersistID pid, string container_name)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return Constant.INVALID_SLOT;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return Constant.INVALID_SLOT;
            }

            return container.Capacity;
        }

        public PersistID[] GetChildren(PersistID pid, string container_name)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return null;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return null;
            }

            return container.GetChildren();
        }

        public void AddChild(PersistID pid, string container_name, PersistID child)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return;
            }

            VariantList result;
            if (!container.TryAddChild(child, out result))
            {
                return;
            }

            _DataCallbackManager.CallContainerHandler(pid, container_name, ContainerEvent.AddChild, result);

            if (entity.OnEntry)
            {
                CallbackContainerData(pid, container_name, ContainerEvent.AddChild, result);
            }
        }

        public void AddChild(PersistID pid, string container_name, int slot, PersistID child)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return;
            }

            VariantList result;
            if (!container.TryAddChild(slot, child, out result))
            {
                return;
            }

            _DataCallbackManager.CallContainerHandler(pid, container_name, ContainerEvent.AddChild, result);

            if (entity.OnEntry)
            {
                CallbackContainerData(pid, container_name, ContainerEvent.AddChild, result);
            }
        }

        public void DelChild(PersistID pid, string container_name, int slot)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return;
            }

            VariantList result;
            if (!container.TryDelChild(slot, out result))
            {
                return;
            }

            _DataCallbackManager.CallContainerHandler(pid, container_name, ContainerEvent.DelChild, result);

            if (entity.OnEntry)
            {
                CallbackContainerData(pid, container_name, ContainerEvent.DelChild, result);
            }
        }

        public void DelChild(PersistID pid, string container_name, PersistID child)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return;
            }

            VariantList result;
            if (!container.TryDelChild(child, out result))
            {
                return;
            }

            _DataCallbackManager.CallContainerHandler(pid, container_name, ContainerEvent.DelChild, result);

            if (entity.OnEntry)
            {
                CallbackContainerData(pid, container_name, ContainerEvent.DelChild, result);
            }
        }

        public int GetSlot(PersistID pid, string container_name, PersistID child)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return Constant.INVALID_SLOT;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return Constant.INVALID_SLOT;
            }

            return container.GetSlot(child);
        }

        public PersistID GetChild(PersistID pid, string container_name, int slot)
        {
            IEntity entity = _EntityManager.GetEntity(pid);
            if (entity == null)
            {
                return PersistID.Empty;
            }

            IContainer container = entity.GetContainer(container_name);
            if (container == null)
            {
                return PersistID.Empty;
            }

            return container.GetChild(slot);
        }

        private void CallbackContainerData(PersistID pid, string container_name, 
            ContainerEvent container_event, VariantList result)
        {
            VariantList msg = VariantList.New();
            msg.Append(container_name).Append((byte)container_event).Append(result);
            _DataTypeCallbackManager.CallbackHandler(DataType.Container, this, pid, msg);
        }
    }
}
