using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ImageBlockz.Api;

namespace ImageBlockz.Core
{
    /// <summary>
    /// This class provides automatic creating  of instances of OperationControl from all plugins.
    /// </summary>
    public class ControlFactory
    {
        private static ControlFactory factory;

        /// <summary>
        /// This method returns default control factory if exist, otherwise creates new factory.
        /// </summary>
        /// <returns>Default control facotry.</returns>
        public static ControlFactory GetDefaultFactory()
        {
            if (factory == null)
            {
                factory = new ControlFactory();
            }

            return factory;
        }

        private List<OperationInfo> operationInfos = new List<OperationInfo>();

        private Dictionary<string, OperationControl> controls = new Dictionary<string, OperationControl>();
        
        /// <summary>
        /// This property provides List of <see cref="OperationInfo"/>.
        /// </summary>
        public List<OperationInfo> OperationInfos
        {
            get
            {
                return operationInfos;
            }
        }

        /// <summary>
        /// Creates new instance of <see cref="OperationControl"/> along <see cref="string"/> name.
        /// </summary>
        /// <param name="name">Name of Operation.</param>
        /// <returns>Instance of <see cref="OperationControl"/></returns>
        public OperationControl CreateControl(string name)
        {
            OperationControl control = null;

            controls.TryGetValue(name, out control);
            
            return control;
        }

        /// <summary>
        /// Add new <see cref="OperationInfo"/> to Control Factory.
        /// </summary>
        /// <param name="info"><see cref="OperationInfo"/></param>
        public void AddOperationInfo(OperationInfo info)
        {
            if (info.ControlType != null)
            {
                if (typeof(OperationControl).IsAssignableFrom(info.ControlType) == false)
                {
                    throw new ArgumentException(info.ControlType.FullName);
                }

                OperationControl control = (OperationControl)info.ControlType.GetConstructor(Type.EmptyTypes).Invoke(null);
                controls.Add(info.OperationId, control);
            }

            operationInfos.Add(info);
        }
    }
}
