using Apewer.Internals;
using System;
using System.Collections.Generic;
#if !NET20
using System.Dynamic;
#endif

namespace Apewer
{

    /// <summary>对象字典模型。</summary>
    [Serializable]
    public class ObjectSet : ObjectSet<object>
    {

        /// <summary></summary>
        public ObjectSet(bool autotrim)
        {
            AutoTrim = autotrim;
        }

        /// <summary></summary>
        public ObjectSet() { }

    }

    /// <summary>字典模型。</summary>
    [Serializable]
    public partial class ObjectSet<T> // where T : class
    {

        [NonSerialized]
        private readonly T Default = default(T);

        private Dictionary<string, T> _origin;

        private bool _autotrim = false;

        private bool _locked = false;

        /// <summary>获取或设置字典内容。</summary>
        public T this[string key]
        {
            get { return Get(key); }
            set { Set(key, value); }
        }

        /// <summary>获取字典。</summary>
        internal Dictionary<string, T> Origin
        {
            get { return _origin; }
        }

        internal bool Locked { get { return _locked; } set { _locked = value; } }

        internal bool AutoTrim { get { return _autotrim; } set { _autotrim = value; } }

        /// <summary>构造函数。</summary>
        public ObjectSet()
        {
            _origin = new Dictionary<string, T>();
        }

        /// <summary>构造函数。</summary>
        public ObjectSet(bool autotrim)
        {
            _autotrim = autotrim;
            _origin = new Dictionary<string, T>();
        }

        private T Get(string key)
        {
            var contains = false;
            return Get(key, ref contains);
        }

        private T Get(string key, ref bool contains)
        {
            var value = default(T);
            if (key != null)
            {
                var k = _autotrim ? TextModifier.Trim(key) : key;
                lock (_origin)
                {
                    contains = _origin.ContainsKey(k);
                    if (contains) value = _origin[k];
                }
            }
            return value;
        }

        private bool Set(string key, T value)
        {
            if (_locked) return false;
            var success = false;
            if (key != null)
            {
                var k = _autotrim ? TextModifier.Trim(key) : key;
                lock (_origin)
                {
                    if (_origin.ContainsKey(k))
                    {
                        _origin[k] = value;
                    }
                    else
                    {
                        _origin.Add(k, value);
                    }
                    success = true;
                }
            }
            return success;
        }

    }

#if !NET20

    /// <summary>字典模型。</summary>
    public partial class ObjectSet<T> : DynamicObject
    {

        /// <summary></summary>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var contains = false;
            result = Get(binder.Name, ref contains);
            return contains;
        }

        /// <summary></summary>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            return Set(binder.Name, (T)value);
        }

    }

#endif

}