using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using VIZ.Package.Domain;

namespace VIZ.Package.Plugin
{
    /// <summary>
    /// 插件加载器
    /// </summary>
    public class PluginLoader : ContentControl
    {
        /// <summary>
        /// 日志
        /// </summary>
        private static readonly ILog log = LogManager.GetLogger(typeof(PluginLoader));

        static PluginLoader()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PluginLoader), new FrameworkPropertyMetadata(typeof(PluginLoader)));
        }

        #region ViewType -- 视图类型

        /// <summary>
        /// 视图类型
        /// </summary>
        public Type ViewType
        {
            get { return (Type)GetValue(ViewTypeProperty); }
            set { SetValue(ViewTypeProperty, value); }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for ViewType.  This enables animation, styling, binding, etc...
        /// </summary>        
        public static readonly DependencyProperty ViewTypeProperty =
            DependencyProperty.Register("ViewType", typeof(Type), typeof(PluginLoader), new PropertyMetadata(null, new PropertyChangedCallback((s, e) =>
            {
                (s as PluginLoader)?.ResetPluginView();
            })));

        #endregion

        /// <summary>
        /// 重置插件视图
        /// </summary>
        private void ResetPluginView()
        {
            try
            {
                IDisposable disposable = this.Content as IDisposable;
                this.Content = null;
                disposable?.Dispose();

                if (this.ViewType == null)
                    return;

                FrameworkElement view = this.ViewType.Assembly.CreateInstance(this.ViewType.FullName) as FrameworkElement;

                this.Content = view;

                PluginInfo info = this.DataContext as PluginInfo;
                if (info != null)
                {
                    info.View = new WeakReference<FrameworkElement>(view);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }
    }
}
