using CefFlashBrowser.Data;
using CefFlashBrowser.FlashBrowser.Handlers;
using CefFlashBrowser.Models;
using CefFlashBrowser.Utils;
using CefSharp;
using SimpleMvvm.Messaging;
using System;
using System.ComponentModel;
using System.Windows;
using BrowserHandlers = CefFlashBrowser.Browser.Handlers;

namespace CefFlashBrowser.Views
{
    /// <summary>
    /// SwfPlayerWindow.xaml 的交互逻辑
    /// </summary>
    public partial class SwfPlayerWindow : Window
    {
        private class SwfPlayerLifeSpanHandler : LifeSpanHandler
        {
            private readonly SwfPlayerWindow window;

            public SwfPlayerLifeSpanHandler(SwfPlayerWindow window)
            {
                this.window = window;
            }

            public override bool DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
            {
                if (!window._isClosed
                    && (browser.IsDisposed || !browser.IsPopup))
                {
                    window.Dispatcher.Invoke(delegate
                    {
                        window._doClose = true;
                        window.Close();
                    });
                }
                return false;
            }

            public override bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
            {
                Application.Current.Dispatcher.Invoke(() => WindowManager.ShowBrowser(targetUrl));
                newBrowser = null;
                return true;
            }
        }

        private bool _doClose = false;
        private bool _isClosed = false;


        public string FileName
        {
            get { return (string)GetValue(FileNameProperty); }
            set { SetValue(FileNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FileName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FileNameProperty =
            DependencyProperty.Register("FileName", typeof(string), typeof(SwfPlayerWindow), new PropertyMetadata(string.Empty, OnFileNamePropertyChanged));

        private static void OnFileNamePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SwfPlayerWindow swfPlayerWindow)
            {
                if (swfPlayerWindow.browser.IsLoaded)
                    swfPlayerWindow.LoadSwf(e.NewValue as string);
            }
        }


        public SwfPlayerWindow()
        {
            InitializeComponent();
            WindowSizeInfo.Apply(GlobalData.Settings.SwfWindowSizeInfo, this);

            browser.DragHandler = new BrowserHandlers.DisableDragHandler();
            browser.MenuHandler = new BrowserHandlers.ContextMenuHandler();
            browser.JsDialogHandler = new BrowserHandlers.JsDialogHandler();
            browser.DownloadHandler = new BrowserHandlers.DownloadHandler();
            browser.LifeSpanHandler = new SwfPlayerLifeSpanHandler(this);

            browser.Address = GlobalData.SwfPlayerPath;

            Messenger.Global.Register(MessageTokens.CLOSE_ALL_BROWSERS, CloseBrowserHandler);
            Closed += delegate { Messenger.Global.Unregister(MessageTokens.CLOSE_ALL_BROWSERS, CloseBrowserHandler); };
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (browser.IsDisposed || _doClose)
            {
                GlobalData.Settings.SwfWindowSizeInfo = WindowSizeInfo.GetSizeInfo(this);
            }
            else
            {
                bool forceClose = GlobalData.Settings.DisableOnBeforeUnloadDialog;
                browser.GetBrowser().CloseBrowser(forceClose);
                e.Cancel = true;
            }
            base.OnClosing(e);
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            _isClosed = true;
        }

        private void LoadSwf(string fileName)
        {
            try { browser.ExecuteScriptAsync("loadSwf", fileName); }
            catch (Exception e) { LogHelper.LogError($"Failed to load swf file: {fileName}", e); }
        }

        private void OnBrowserFrameLoadEnd(object sender, FrameLoadEndEventArgs e)
        {
            LoadSwf(FileName);
        }

        private void CloseBrowserHandler(object msg)
        {
            ForceCloseWindow();
        }

        public void ForceCloseWindow()
        {
            if (!browser.IsDisposed)
            {
                browser.LifeSpanHandler = null;
                browser.CloseBrowser(true);
            }
            _doClose = true;
            Close();
        }
    }
}
