/*
 * 由SharpDevelop创建。
 * 用户： Administrator
 * 日期: 2018-11-16
 * 时间: 9:22
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;
using Server.Config;
using Server.Pack;
using Server.Data;
using GameData;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
using System.Threading;
using Game.Player;
using MrWu.core;
using Debug = MrWu.Debug.Debug;

namespace Server
{
    /// <summary>
    /// 房间管理
    /// </summary>
    public abstract class RoomManager : IGameUtil, ICollection<TingManager>
    {

        #region ICollection

        /// <summary>
        /// 厅管理
        /// </summary>
        protected readonly TingManager[] tings;

        /// <summary>
        /// 只读的,不能添加删除
        /// </summary>
        public bool IsReadOnly {
            get {
                return true;
            }
        }

        /// <summary>
        /// 厅的数量
        /// </summary>
        public int Count {
            get;
            private set;
        }

        /// <summary>
        /// 接口实现,隐藏方法,不可添加删除
        /// </summary>
        /// <param name="item"></param>
        void ICollection<TingManager>.Add(TingManager item) { }

        /// <summary>
        /// 接口实现,隐藏方法,不可添加删除
        /// </summary>
        /// <param name="item"></param>
        bool ICollection<TingManager>.Remove(TingManager item) {
            return false;
        }

        /// <summary>
        /// 接口实现,隐藏方法,不可清楚数据
        /// </summary>
        void ICollection<TingManager>.Clear() { }

        /// <summary>
        /// 是否存在某个厅
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Contains(TingManager item) {
            if (item == null)
                return false;
            foreach (var it in this) {
                if (item == it)
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 厅数据拷贝到 array
        /// </summary>
        /// <param name="array"></param>
        /// <param name="arrayIndex">从第几个开始放</param>
        public void CopyTo(TingManager[] array, int arrayIndex) {
            if (array == null)
                throw new ArgumentNullException("array is null!");

            if (array.Length < Count + arrayIndex)
                throw new IndexOutOfRangeException($"array 数组太小了 array.Length:{array.Length},arrayIndex:{arrayIndex},Collection Count:{Count}");

            Array.Copy(tings, 0, array, arrayIndex, Count);
        }

        /// <summary>
        /// 迭代器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<TingManager> GetEnumerator() {
            return new ArrayEnumerator<TingManager>(tings);
        }

        /// <summary>
        /// 迭代器
        /// </summary>
        /// <returns></returns>
        IEnumerator IEnumerable.GetEnumerator() {
            return new ArrayEnumerator<TingManager>(tings);
        }

        #endregion

        /// <summary>
        /// 城堡配置
        /// </summary>
        public readonly Server.Config.CastlesConfig config;

        /// <summary>
        /// 玩家数量
        /// </summary>
        public int playerCount {
            get;
            private set;
        }

        /// <summary>
        /// 机器人数量
        /// </summary>
        public int robotCount {
            get;
            private set;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="config">配置</param>
        public RoomManager(int id, Server.Config.CastlesConfig config) {
            this.id = id;
            this.config = config;

            Count = config.Tings.Length;
            tings = new TingManager[Count];
        }

        /// <summary>
        /// 添加厅
        /// </summary>
        /// <param name="id"></param>
        /// <param name="ting"></param>
        public void AddTing(int id, TingManager ting) {
            tings[id] = ting;
        }

        /// <summary>
        /// 检查玩家是否可以在此房间中_金币场才有效
        /// </summary>
        /// <returns>0是可以进  -1表示前太少不能进入  1表示钱太多不能进入</returns>
        protected int CheckInRoom(PlayerDataAsyc pl) {
            if (!isFriend) {
                if (pl.money < config.MinMoney)
                    return -1;
                if (pl.money >= config.MaxMoney && config.MaxMoney<2000000000)
                    return 1;
                return 0;
            }
            return 0;
        }

        /// <summary>
        /// 是否存在某个厅
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool isExists(int id) {
            foreach (var ting in tings) {
                if (id == ting.id)
                    return true;
            }
            return false;
        }

        #region IGameUtil

        /// <summary>
        /// roomid
        /// </summary>
        public int id {
            get;
            private set;
        }

        /// <summary>
        /// 是否是朋友房城堡
        /// </summary>
        public abstract bool isFriend {
            get;
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Init() {

        }

        /// <summary>
        /// 获取房间字符串信息
        /// </summary>
        /// <param name="lx">类型</param>
        /// <returns></returns>
        public string GetStringValue(string lx) {
            switch (lx) {
                default:
                    Debug.Error("未解析的房间字符串信息:" + lx);
                    break;
            }
            return string.Empty;
        }

        /// <summary>
        /// 获取房间的整数型信息
        /// </summary>
        /// <param name="lx">类型</param>
        /// <returns></returns>
        public virtual int GetIntValue(string lx) {

            switch (lx) {
                case "0"://房间赔率
                    return config.BeiLv;

                case "1"://房间倍数 (赔率*倍数=限进金钱)
                    Debug.Error("房间倍数已取消，使用请修改baskdbas");
                    break;

                case "2"://房间模式 返回 0普通模式  1百家乐模式
                    return ServerConfigManager.Instance.GameMode;
                case "3"://收税
                    return config.Tax;
                case "4"://经验加成
                    return config.Exp;
                case "5"://改成整个服务器的输赢   怕值超过整形上限所以返回值是除以了1000的
                    return (int)(GameManager.instance.winmoney / 1000);
                case "6"://desk maxman
                    Debug.Error("转至厅解析bsakdbaskj");
                    break;
                case "7"://desk minfightman
                    Debug.Error("转至厅解析hasvbdajk");
                    break;
                case "8"://真数量
                    return playerCount;
                    break;
                case "9"://是否朋友房
                    Debug.Error("是否朋友房 转至桌子 / 或厅");
                    break;
                case "99": //整个服务器人数
                    return PlayerCollection.Instance.PlayerCnt;
                    break;
                default:
                    Debug.Error("未解析的房间整数型信息:" + lx);
                    break;
            }
            return -1;
        }

        /// <summary>
        /// 获取房间数据
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public virtual object GetData(string tag) {
            return null;
        }

        #endregion

        #region IGameWinMoney

        /// <summary>
        /// 赢的游戏币
        /// </summary>
        public Int64 winmoney {
            get;
            private set;
        }

        /// <summary>
        /// 增加税收的游戏币
        /// </summary>
        public Int64 taxmoney {
            get;
            private set;
        }

        /// <summary>
        /// 赢的游戏币
        /// </summary>
        /// <param name="money"></param>
        public void AddWinMoney(long money) {
            winmoney += money;
            GameManager.instance.AddWinMoney(money);
        }

        /// <summary>
        /// 添加税收的钱
        /// </summary>
        /// <param name="money"></param>
        public void AddTaxMoney(long money) {
            taxmoney += money;
            GameManager.instance.AddTaxMoney(money);
        }

        #endregion

        /// <summary>
        /// 设置房间的玩家数量
        /// </summary>
        /// <param name="pl">哪个玩家进入或退出房间</param>
        /// <param name="quitRoom">是否是退出房间</param>
        public void SetRoomPlayerCnt(PlayerDataAsyc pl, bool quitRoom = false) {
            if (quitRoom) {
                playerCount--;
                if (pl.isRobot)
                    robotCount--;
            } else {
                playerCount++;
                if (pl.isRobot)
                    robotCount++;
            }

            StackTrace stackTrace = new StackTrace();
            
            Debug.Info("房间中的玩家数量:" +  pl.userid + "," + playerCount + "," + id + "," + robotCount + "," + stackTrace.ToString());
        }

        /// <summary>
        /// 进入房间
        /// </summary>
        /// <param name="pl">想进入房间的玩家</param>
        /// <param name="tingid">进入房间的包</param>
        /// <param name="deskid">指定要进入的桌子 百家乐模式</param>
        /// <returns>是否成功进入</returns>
        public abstract bool InRoom(PlayerDataAsyc pl, int tingid, int deskid = -1);
        

        /// <summary>
        /// 退出房间
        /// </summary>
        /// <param name="pl"></param>
        public virtual bool Quit(PlayerDataAsyc pl) {

            if (pl.roomid != id) {
                Debug.Warning("ascnkjsadbnkjas");
                return false;
            }

            if (!isExists(pl.tingid)) {
                Debug.Error("玩家数据的厅数据与玩家状态不匹配userid:{0}", pl.userid);
                return false;
            }

            var ting = FindTing(pl.tingid);
            if (ting == null) {
                Debug.Error("找不到厅信息 tingid:{0}, userid:{1} ThreadId:{2}", pl.tingid, pl.userid,Thread.CurrentThread.ManagedThreadId);
                return false;
            }
            bool result = ting.QuitDesk(pl, true);

            return result;
        }

        /// <summary>
        /// 查找厅
        /// </summary>
        /// <param name="tingid"></param>
        /// <returns></returns>
        public TingManager FindTing(int tingid) {
            int len = tings.Length;
            for (int i = 0; i < len; i++) {
                if (tings[i].id == tingid)
                    return tings[i];
            }
            return null;
        }

        #region ITimerProcessor

        /// <summary>
        /// 游戏定时器
        /// </summary>
        public virtual void OnTime(int Interval) {

        }

        /// <summary>
        /// 秒级定时器
        /// </summary>
        public virtual void SecondTime() {

        }

        #endregion
    }
}
