﻿using System.Collections.Generic;
using JLGames.RocketDriver.CSharp.Languages.Lua;

#if !OVERRIDE_LUA

namespace JLGames.RocketDriver.Actions.Languages.Lua
{
    public class LuaTableWrapper
    {
        private readonly LuaTable m_LuaTable = null;

        /// <summary>
        /// Get Lua table
        /// 获取Lua表
        /// </summary>
        public LuaTable LuaTable => m_LuaTable;

        /// <summary>
        /// Verify that the Lua table is valid
        /// 验证Lua表是否有效
        /// </summary>
        public bool IsValid => m_LuaTable != null;

        /// <summary>
        /// Get the data size of the Lua table
        /// 取Lua表的数据大小
        /// </summary>
        public int Size
        {
            get
            {
                if (!IsValid) return 0;
                return m_LuaTable.Length > m_LuaTable.Count ? m_LuaTable.Length : m_LuaTable.Count;
            }
        }

        public LuaTableWrapper(LuaTable luaTable)
        {
            m_LuaTable = luaTable;
        }

        /// <summary>
        /// Get value from Lua table
        /// 从Lua表中取值
        /// </summary>
        /// <param name="key"></param>
        public object this[string key] => GetValue(key);

        /// <summary>
        /// Get value from Lua table
        /// 从Lua表中取值
        /// </summary>
        /// <param name="key"></param>
        public object this[int key] => GetValue(key);

        /// <summary>
        /// Get value from Lua table
        /// 从Lua表中取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object GetValue(string key)
        {
            LuaValue value = LuaNil.Nil;
            if (m_LuaTable.Count > 0)
            {
                value = m_LuaTable.GetValue(key);
            }

            if (LuaNil.Nil == value && m_LuaTable.Length > 0)
            {
                var index = LuaValueUtils.StringToInt(key);
                if (index != 0)
                    value = m_LuaTable.GetValue(index);
            }

            return ConvertValue(value);
        }

        /// <summary>
        /// Get value from Lua table
        /// 从Lua表中取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object GetValue(int key)
        {
            LuaValue value = LuaNil.Nil;
            if (m_LuaTable.Length > 0)
            {
                value = m_LuaTable.GetValue(key);
            }
            else
            {
                value = m_LuaTable.GetValue(key.ToString());
            }

            return ConvertValue(value);
        }

        /// <summary>
        /// Traverse to get all the values in the Lua table
        /// 遍历取出Lua表中的全部值
        /// </summary>
        public IEnumerable<object> Values
        {
            get
            {
                if (null == m_LuaTable) yield break;
                if (m_LuaTable.Length > 0)
                {
                    foreach (var value in m_LuaTable.ListValues)
                    {
                        yield return ConvertValue(value);
                    }
                }
                else if (m_LuaTable.Count > 0)
                {
                    foreach (var kv in m_LuaTable.KeyValuePairs)
                    {
                        yield return ConvertValue(kv.Value);
                    }
                }
            }
        }

        /// <summary>
        /// Get all values from Lua table
        /// 从Lua表中取出全部值
        /// </summary>
        /// <returns></returns>
        public object[] GeValues()
        {
            if (null == m_LuaTable) return null;
            if (m_LuaTable.Length > 0)
            {
                var rs = new object[m_LuaTable.Length];
                var index = 0;
                foreach (var value in m_LuaTable.ListValues)
                {
                    rs[index] = ConvertValue(value);
                    index += 1;
                }

                return rs;
            }
            else if (m_LuaTable.Count > 0)
            {
                var rs = new object[m_LuaTable.Length];
                var index = 0;
                foreach (var kv in m_LuaTable.KeyValuePairs)
                {
                    rs[index] = ConvertValue(kv.Value);
                    index += 1;
                }
            }

            return null;
        }

        /// <summary>
        /// Convert LuaValue data to C# data
        /// 把LuaValue数据转换为C#数据
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public object ConvertValue(LuaValue value)
        {
            if (LuaNil.Nil == value) return null;
            if (value is LuaTable)
                return new LuaTableWrapper(value as LuaTable);
            else
                return LuaValueUtils.LuaValueToObject(value);
        }
    }
}
#endif