using System;
using System.Collections.Generic;
using System.Linq;
namespace Mustache
{
    /// 
    /// Associates parameters to their argument values.
    /// 
    internal sealed class ArgumentCollection
    {
        private readonly Dictionary _argumentLookup;
        /// 
        /// Initializes a new instance of an ArgumentCollection.
        /// 
        public ArgumentCollection()
        {
            _argumentLookup = new Dictionary();
        }
        /// 
        /// Associates the given parameter to the key placeholder.
        /// 
        /// The parameter to associate the key with.
        /// The argument.
        /// If the key is null, the default value of the parameter will be used.
        public void AddArgument(TagParameter parameter, IArgument argument)
        {
            _argumentLookup.Add(parameter, argument);
        }
        /// 
        /// Gets the key that will be used to find the substitute value.
        /// 
        /// The name of the parameter.
        public string GetKey(TagParameter parameter)
        {
            IArgument argument;
            if (_argumentLookup.TryGetValue(parameter, out argument) && argument != null)
            {
                return argument.GetKey();
            }
            else
            {
                return null;
            }
        }
        /// 
        /// Substitutes the key placeholders with their respective values.
        /// 
        /// The key/value pairs in the current lexical scope.
        /// The key/value pairs in current context.
        /// A dictionary associating the parameter name to the associated value.
        public Dictionary GetArguments(Scope keyScope, Scope contextScope)
        {
            Dictionary arguments = new Dictionary();
            foreach (KeyValuePair pair in _argumentLookup)
            {
                object value;
                if (pair.Value == null)
                {
                    value = pair.Key.DefaultValue;
                }
                else
                {
                    value = pair.Value.GetValue(keyScope, contextScope);
                }
                arguments.Add(pair.Key.Name, value);
            }
            return arguments;
        }
        public Dictionary GetArgumentKeyNames()
        {
            return _argumentLookup.ToDictionary(p => p.Key.Name, p => (object)GetKey(p.Key));
        }
    }
}