using CommonAI.RTS.Manhattan;
using CommonAI.Zone;
using CommonAI.Zone.Helper;
using CommonAI.Zone.ZoneEditor;
using CommonAI.ZoneClient;
using CommonLang;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XmdsCommon.ZoneClient;

namespace XmdsCommon.Plugin
{

    public class XmdsZoneFactoryBot : XmdsZoneFactory
    {
        public static bool SaveMemory
        {
            get { return s_save_memory; }
            set
            {
                s_save_memory = value;
                lock (s_maps)
                {
                    if (value == false)
                    {
                        s_maps.Clear();
                    }
                }
            }
        }
        private static HashMap<int, BotMapInfo> s_maps = new HashMap<int, BotMapInfo>();
        private static bool s_save_memory = false;


        public override ZoneLayer CreateClientZoneLayer(EditorTemplates templates, ILayerClient listener)
        {
            return new BotZoneLayer(templates, listener);
        }
        class BotZoneLayer : HZZoneLayer
        {

            public BotZoneLayer(EditorTemplates dataroot, ILayerClient client)
                : base(dataroot, client)
            {
            }
            protected override void InitTerrain(ClientEnterScene msg, out ZoneManhattanMap terrain_data, out AstarManhattan path_finder, out ManhattanMapAreaGenerator area_gen)
            {
                if (SaveMemory)
                {
                    BotMapInfo minfo = null;
                    lock (s_maps)
                    {
                        minfo = s_maps.Get(this.Data.ID);
                        if (minfo == null)
                        {
                            minfo = new BotMapInfo(base.TerrainSrc.Clone() as ZoneInfo, base.Templates);
                            s_maps.Add(this.Data.ID, minfo);
                        }
                    }
                    terrain_data = minfo.terrain_data;
                    path_finder = minfo.path_finder;
                    area_gen = minfo.area_gen;
                    //Data.Terrain = null;
                    this.IsShareTerrain = true;
                    this.IsIgnoreTerrainTouch = true;
                }
                else
                {
                    base.InitTerrain(msg, out terrain_data, out path_finder, out area_gen);
                }
            }
            protected override void DisposeTerrain()
            {
                if (SaveMemory)
                {
                }
                else
                {
                    base.DisposeTerrain();
                }
            }
        }

        class BotMapInfo
        {
            public readonly BotLayerManhattanMap terrain_data;
            public readonly AstarManhattan path_finder;
            public readonly ManhattanMapAreaGenerator area_gen;
            public BotMapInfo(ZoneInfo data, TemplateManager templates)
            {
                this.terrain_data = new BotLayerManhattanMap(templates, data);
                this.path_finder = new AstarManhattan(data.TemplateID, terrain_data, true, 0);
                this.area_gen = new ManhattanMapAreaGenerator(terrain_data.Data);
            }
        }

        class BotLayerManhattanMap : ZoneManhattanMap
        {
            public BotLayerManhattanMap(TemplateManager templates, ZoneInfo info)
                : base(info, templates.TerrainDefinition)
            {
            }
            public override bool SetValue(int bx, int by, int value)
            {
                return false;
            }
        }
    }
}