using CommonAI.Zone.ZoneEditor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XmdsServerEdgeJS
{
    //--------------------------------------------------------------------------------------------------------
    #region Exceptions

    /// <summary>
    /// 副本不存在异常
    /// </summary>
    public class InstanceNotExistException : Exception
    {
        private string instanceId;
        private string type;
        public string InstanceId { get { return instanceId; } }
        public string Type { get { return type; } }
        public InstanceNotExistException(string instanceId)
        {
            this.type = "InstanceNotExist";
            this.instanceId = instanceId;
        }
    }

    /// <summary>
    /// 玩家不存在异常
    /// </summary>
    public class PlayerNotExistException : Exception
    {
        private string playerId;
        private string type;
        public string PlayerId { get { return playerId; } }
        public string Type { get { return type; } }
        public PlayerNotExistException(string playerId)
        {
            this.type = "PlayerNotExist";
            this.playerId = playerId;
        }
    }


    /// <summary>
    /// 玩家已经存在异常
    /// </summary>
    public class PlayerHasExistException : Exception
    {
        private string playerId;
        private string type;
        public string PlayerId { get { return playerId; } }
        public string Type { get { return type; } }
        public PlayerHasExistException(string playerId)
        {
            this.type = "PlayerHasExist";
            this.playerId = playerId;
        }
    }

    #endregion
    //--------------------------------------------------------------------------------------------------------


    public enum EventType
    {
        /// <summary>
        /// 玩家发送消息
        /// </summary>
        playerSended,
        /// <summary>
        /// 场景事件
        /// </summary>
        areaEvent,
        /// <summary>
        /// 角色事件
        /// </summary>
        playerEvent,
        /// <summary>
        /// 任务事件
        /// </summary>
        taskEvent,
        
    }


    public class UnitInfo
    {
        public string type;
        public uint ObjectId;
        public int force;
        public int templateId;
        public string playerId;
        public float x;
        public float y;
        public string unitType;
        public string name;
    }

    public class XmdsPlayerEnter : XmdsServerNode.Node.PlayerEnterRoomS2R
    {

    }

    //public class ZoneConfig
    //{
    //    /// <summary>
    //    /// 启动路径
    //    /// </summary>        
    //    public string startPath;
    //    /// <summary>
    //    /// 资源路径
    //    /// </summary>
    //    public string assetPath;
    //    /// <summary>
    //    /// fastStream 端口
    //    /// </summary>
    //    public int fastStreamPort;    
    //}
    //--------------------------------------------------------------------------------------------------------
    #region EdgeData

    public class EdgeAbilityData
    {
        public string Name;
        public string Type;
        public EdgeAbilityData(AbilityData ad)
        {
            Name = ad.Name;
            Type = ad.GetType().Name;
        }
    }

    public class EdgePlayerStartAbilityData : EdgeAbilityData
    {
        public int START_Force;
        public int TestActorTemplateID;
        public int TestActorLevel;
        public EdgePlayerStartAbilityData(AbilityData ad)
            : base(ad)
        {
            PlayerStartAbilityData data = ad as PlayerStartAbilityData;
            START_Force = data.START_Force;
            TestActorTemplateID = data.TestActorTemplateID;
            TestActorLevel = data.TestActorLevel;
        }
    }

    public class EdgeSpawnUnitAbilityData : EdgeAbilityData
    {
        public List<SpawnUnitAbilityData.SpawnUnit> UnitTemplates;
        public List<int> UnitTemplatesID;
        public int UnitLevel;
        public int StartTimeDelayMS;
        public int IntervalMS = 5000;
        public int OnceCount = 5;
        public int TotalLimit;
        public int AliveLimit;
        public bool WithoutAlive;
        public int Force;
        public string UnitTag;
        public string UnitName;
        public string StartPointName;
        public EdgeSpawnUnitAbilityData(AbilityData ad)
        : base(ad)
        {
            SpawnUnitAbilityData data = ad as SpawnUnitAbilityData;
            UnitTemplates = new List<SpawnUnitAbilityData.SpawnUnit>(data.UnitTemplates);
            UnitTemplatesID = new List<int>(data.UnitTemplatesID);
            UnitLevel = data.UnitLevel;
            StartTimeDelayMS = data.StartTimeDelayMS;
            IntervalMS = data.IntervalMS;
            OnceCount = data.OnceCount;
            TotalLimit = data.TotalLimit;
            AliveLimit = data.AliveLimit;
            WithoutAlive = data.WithoutAlive;
            Force = data.GetForce();
            UnitTag = data.UnitTag;
            UnitName = data.UnitName;
            StartPointName = data.StartPointName;

        }
    }


    public class EdgeUnitTransportAbilityData : EdgeAbilityData
    {
        public string NextPosition;
        public int AcceptUnitType;
        public bool AcceptUnitTypeForAll;
        public int AcceptForce;
        public bool AcceptForceForAll;

        public EdgeUnitTransportAbilityData(AbilityData ad)
            : base(ad)
        {
            UnitTransportAbilityData data = ad as UnitTransportAbilityData;
            NextPosition = data.NextPosition;
            AcceptUnitType = (int)data.AcceptUnitType;
            AcceptUnitTypeForAll = data.AcceptUnitTypeForAll;
            AcceptForce = data.AcceptForce;
            AcceptForceForAll = data.AcceptForceForAll;
        }

    }

    public class EdgeSceneTransportAbilityData : EdgeAbilityData
    {
        public int NextSceneID;
        public string NextScenePosition;
        public EdgeSceneTransportAbilityData(AbilityData ad)
            : base(ad)
        {
            SceneTransportAbilityData data = ad as SceneTransportAbilityData;
            NextSceneID = data.NextSceneID;
            NextScenePosition = data.NextScenePosition;
        }
    }


    public class EdgeSpawnItemAbilityData : EdgeAbilityData
    {

        public List<SpawnItemAbilityData.SpawnItem> ItemTemplates;
        public int StartTimeDelayMS;
        public int IntervalMS;
        public int OnceCount;
        public int TotalLimit;
        public int AliveLimit;
        public bool WithoutAlive;
        public int Force;
        public string UnitTag;
        public string UnitName;
        public EdgeSpawnItemAbilityData(AbilityData ad)
            : base(ad)
        {
            SpawnItemAbilityData data = ad as SpawnItemAbilityData;
            ItemTemplates = new List<SpawnItemAbilityData.SpawnItem>(data.ItemTemplates);
            StartTimeDelayMS = data.StartTimeDelayMS;
            IntervalMS = data.IntervalMS;
            OnceCount = data.OnceCount;
            TotalLimit = data.TotalLimit;
            AliveLimit = data.AliveLimit;
            WithoutAlive = data.WithoutAlive;
            Force = data.Force;
            UnitTag = data.UnitTag;
            UnitName = data.UnitName;
        }

    }

    public class EdgeSceneObjectData
    {
        public string Name;
        public string Alias;
        public float X;
        public float Y;
        public string SavePath;
        public int Color;
        public List<EdgeAbilityData> Abilities = new List<EdgeAbilityData>();
        public List<string> Attributes;
        public bool Enable;
        public string Script;
        public EdgeSceneObjectData(SceneObjectData data)
        {
            Name = data.Name;
            Alias = data.Alias;
            X = data.X;
            Y = data.Y;
            SavePath = data.SavePath;
            Color = data.Color;
            foreach (AbilityData ad in data.GetAbilities())
            {
                EdgeAbilityData edgeAd = EdgeSceneData.ConvertToEdgeAbilityData(ad);
                if (edgeAd != null)
                {
                    Abilities.Add(edgeAd);
                }
            }
            if (data.Attributes != null)
            {
                Attributes = new List<string>(data.Attributes);
            }
            else
            {
                Attributes = new List<string>();
            }
            Enable = data.Enable;
            Script = data.Script;
        }
    }

    public class EdgeRegionData : EdgeSceneObjectData
    {
        public int RegionType;
        public float W;
        public float H;
        public EdgeRegionData(RegionData data)
        : base(data)
        {
            RegionType = (int)data.RegionType;
            W = data.W;
            H = data.H;
        }
    }

    public class EdgePointData : EdgeSceneObjectData
    {
        public List<string> NextNames;
        public EdgePointData(PointData data)
        : base(data)
        {
            NextNames = new List<string>(data.NextNames);
        }
    }


    public class EdgeDecorationData : EdgeSceneObjectData
    {
        public string AnimName;
        public bool Blockable;
        public int BlockValue;
        public float Direction;
        public float GridSizeH;
        public float GridSizeW;
        public float H;
        public float Height;
        public int RegionType;
        public string ResourceID;
        public string ResourceID_Disabled;
        public string ResourceID_Enabled;
        public float Scale;
        public string SoundAmbient;
        public float W;
        public EdgeDecorationData(DecorationData data)
            : base(data)
        {
            AnimName = data.AnimName;
            Blockable = data.Blockable;
            BlockValue = data.BlockValue;
            Direction = data.Direction;
            GridSizeH = data.GridSizeH;
            GridSizeW = data.GridSizeW;
            H = data.H;
            Height = data.Height;
            RegionType = (int)data.RegionType;
            ResourceID = data.ResourceID;
            ResourceID_Disabled = data.ResourceID_Disabled;
            ResourceID_Enabled = data.ResourceID_Enabled;
            Scale = data.Scale;
            SoundAmbient = data.SoundAmbient;
            W = data.W;
        }
    }


    public class EdgeUnitData : EdgeSceneObjectData
    {
        public float Direction;
        public byte Force;
        public float Scale;
        public string StartPointName;
        public int UnitLevel;
        public string UnitTag;
        public int UnitTemplateID;
        public EdgeUnitData(UnitData data)
            : base(data)
        {

            Direction = data.Direction;
            Force = data.Force;
            Scale = data.Scale;
            StartPointName = data.StartPointName;
            UnitLevel = data.UnitLevel;
            UnitTag = data.UnitTag;
            UnitTemplateID = data.UnitTemplateID;
        }
    }

    public class EdgeItemData : EdgeSceneObjectData
    {
        public float Direction;
        public byte Force;
        public int ItemTemplateID;
        public EdgeItemData(ItemData data)
            : base(data)
        {
            Direction = data.Direction;
            Force = data.Force;
            ItemTemplateID = data.ItemTemplateID;
        }
    }

    public class EdgeSceneData
    {
        public int TemplateID;
        public int ID;
        public string FileName;
        public string BGM;
        public int TotalTimeLimitSEC;
        public string ResourceProperty;
        public string Name;
        public string Desc;
        public List<string> Attributes;
        public int MaxPlayer;
        public int MaxUnit;
        public int DefaultUnitLevel;
        public List<EdgePointData> Points = new List<EdgePointData>();
        public List<EdgeRegionData> Regions = new List<EdgeRegionData>();

        public List<EdgeDecorationData> Decorations = new List<EdgeDecorationData>();
        public List<EdgeUnitData> Units = new List<EdgeUnitData>();
        public List<EdgeItemData> Items = new List<EdgeItemData>();

        public List<EdgeAbilityData> Abilities = new List<EdgeAbilityData>();
        public static EdgeAbilityData ConvertToEdgeAbilityData(AbilityData ad)
        {
            EdgeAbilityData edgeAd = null;
            if (ad is PlayerStartAbilityData)
            {
                edgeAd = new EdgePlayerStartAbilityData(ad);
            }
            else if (ad is SpawnUnitAbilityData)
            {
                edgeAd = new EdgeSpawnUnitAbilityData(ad);
            }
            else if (ad is UnitTransportAbilityData)
            {
                edgeAd = new EdgeUnitTransportAbilityData(ad);
            }
            else if (ad is SceneTransportAbilityData)
            {
                edgeAd = new EdgeSceneTransportAbilityData(ad);
            }
            else if (ad is SpawnItemAbilityData)
            {
                edgeAd = new EdgeSpawnItemAbilityData(ad);
            }
            return edgeAd;
        }
        public EdgeSceneData(SceneData data)
        {
            TemplateID = data.TemplateID;
            ID = data.ID;
            FileName = data.FileName;
            BGM = data.BGM;
            TotalTimeLimitSEC = data.TotalTimeLimitSEC;
            ResourceProperty = data.ResourceProperty;
            Name = data.Name;
            Desc = data.Desc;
            if (data.Attributes != null)
            {
                Attributes = new List<string>(data.Attributes);
            }
            else
            {
                Attributes = new List<string>();
            }
            MaxPlayer = data.MaxPlayer;
            MaxUnit = data.MaxUnit;
            DefaultUnitLevel = data.DefaultUnitLevel;
            foreach (PointData pd in data.Points)
            {
                Points.Add(new EdgePointData(pd));
            }
            foreach (RegionData rd in data.Regions)
            {
                Regions.Add(new EdgeRegionData(rd));
            }

            foreach (DecorationData rd in data.Decorations)
            {
                Decorations.Add(new EdgeDecorationData(rd));
            }
            foreach (UnitData rd in data.Units)
            {
                Units.Add(new EdgeUnitData(rd));
            }
            foreach (ItemData rd in data.Items)
            {
                Items.Add(new EdgeItemData(rd));
            }

            foreach (AbilityData ad in data.Abilities)
            {
                EdgeAbilityData edgeAd = ConvertToEdgeAbilityData(ad);
                if (edgeAd != null)
                {
                    Abilities.Add(edgeAd);
                }
            }

        }
        #endregion
        //--------------------------------------------------------------------------------------------------------
    }
}