using CefSharp;
using CefSharp.WinForms;
using System;
using System.Windows.Forms;

namespace CefSharpWrap
{
    public abstract class CefSharpWrapBrowserBase : IDisposable
    {
        protected readonly ChromiumWebBrowser Underlying;
        public bool IsReady { get; private set; }

        public event EventHandler Ready;

        protected internal CefSharpWrapBrowserBase(string url)
        {
            Underlying = new ChromiumWebBrowser(url) { Dock = DockStyle.Fill };
            Underlying.LoadingStateChanged += Underlying_LoadingStateChanged;
        }

        private void Underlying_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
        {
            IsReady = true;
            OnReady();
            Underlying.LoadingStateChanged -= Underlying_LoadingStateChanged;
        }

        public void FillToControl(Control to) => to.Controls.Add(Underlying);

        public void ShowF12() => Underlying.ShowDevTools();

        public void ExecuteJsAsync(string js)
        {
            if (false == IsReady) return;
            if (Underlying.IsLoading) Underlying.ExecuteScriptAsyncWhenPageLoaded(js);
            else Underlying.ExecuteScriptAsync(js);
        }

        public string GetHtml()
        {
            var task = Underlying.GetBrowser().MainFrame.GetSourceAsync();
            task.Wait();
            return task.Result;
        }

        public void ExportAsPdf(string path, CefSharpWrapPdfExportSetting setting)
        {
            Underlying.PrintToPdfAsync(path, setting.ToCefSharpSetting()).Wait();
        }

        protected virtual void OnReady()
        {
            Ready?.Invoke(this, EventArgs.Empty);
        }

        public void Dispose()
        {
            if (false == Underlying.IsDisposed) Underlying.Dispose();
        }
    }
}