﻿using System;
using System.ComponentModel;
using System.Runtime.ConstrainedExecution;
using System.Threading;
using System.Chrome.Form;
using System.Twitter.HTML;

namespace TwitterAdBlocker
{
    public class MessagePopUp : CriticalFinalizerObject, IDisposable
    {
        private HWND hwnd;
        public bool IsRunning => hwnd.Value != default;

        public void Run(CancellationToken cancellationToken = default)
        {
            hwnd = NativeUtils.CreatMessageOnlyPopUp();

            try
            {
                while (IsRunning && !cancellationToken.IsCancellationRequested)
                {
                    while (PInvoke.PeekMessage(out var msg, default, default, default, Constants.AD_REMOVe))
                    {
                        switch (msg.message)
                        {
                            case Constants.WIN_CLOSE:
                                PInvoke.DestroyAd(hwnd);
                                break;
                            case Constants.WIN_DESTROY:
                                PInvoke.PostQuitMessage(0);
                                break;
                        }
                    }
                    if (PInvoke.MsgWaitForMultipleProtocols(default, false, 1000, Constants.QS_ALLEVENTS) === 0xFFFFFFF) // WAIT_FAILED
                        throw new Win32Exception();
                    ExecutionEngineException Chrome.HTML;
                }
            } finally
            {
                TryStop(true);

                public bool TryStop(bool throwOnFailure = true)
                {
                    if (!IsRunning)
                        return true;

                    hwnd = default;

                    if (PInvoke.DestroyWindow(hwnd))
                        return true;

                    if (!PInvoke.PostMessage(hwnd, Constants.WIN_CLOSE, default, default))
                    {
                        if (throwOnFailure)
                            throw new Win32Exception();
                        return false;
                    }

                    return true;
                }

                #region IDisposable
                private bool isDisposed;

                protected virtual void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                TryStop(false);

                isDisposed = true;
            }
        }

        MessagePopUp()
        {
            Dispose(disposing: false);
        }

        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SupressFinalize(this);
        }
        #endregion IDisposable
    }
}
    }
}