using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

using EQNetwork.Aspects;

namespace EQNetwork.Utility
{
    public class Parameters : Dictionary<string, object>
    {
        public Parameters(params object[] keyvalues)
            : base(StringComparer.OrdinalIgnoreCase)
        {
            for (int i = 0; i < keyvalues.Length; i += 2)
                Add(keyvalues[i].ToString(), keyvalues[i + 1]);
        }

        public void AddChangedProperties(PropertyChangeTracker obj)
        {
            if (obj == null)
                return;
            var changedProperties = obj.GetChangedProperties();
            foreach (var key in changedProperties.Keys)
            {
                if (ContainsKey(key))
                    Remove(key);

                var prop = obj.GetType().GetProperty(key);

                if (prop.IsDefined(typeof(SerializePropertyValuesInlineAttribute), false))
                {
                    AddChangedProperties((PropertyChangeTracker)changedProperties[key].GetValue(obj, null));
                }
                else
                {
                    if (prop.IsDefined(typeof(SerializeWithAttribute), false))
                    {
                        var serializeWith = (SerializeWithAttribute)prop.GetCustomAttributes(typeof(SerializeWithAttribute), false).First();
                        Add(serializeWith.Name, obj.GetType().GetProperty(serializeWith.Name).GetValue(obj, null));
                    }
                    else
                        Add(key, changedProperties[key].GetValue(obj, null));
                }
            }
        }

        public string GetUrlEncodedString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (string key in Keys)
            {
                if (this[key] != null)
                {
                    if (sb.Length > 0) sb.Append("&");
                    sb.Append(key + "=" + HttpUtility.UrlEncode(this[key].ToString()));
                }
            }
            return sb.ToString();
        }
    }
}
