namespace UVTexIntegra.CustomControls
{
    internal class ExceptionCatcher : System.IDisposable
    {
        public ExceptionCatcher()
        {
            m_disposed = false;
            lock (g_lock)
            {
                if (g_lockCt == 0)
                {
                    System.AppDomain.CurrentDomain.UnhandledException += g_unhandledException;
                    System.Windows.Forms.Application.ThreadException += g_threadException;
                }
                g_lockCt++;
            }
        }

        ~ExceptionCatcher() { Dispose(false); }

        public void Dispose()
        {
            Dispose(true);
            System.GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool flag)
        {
            lock (g_lock)
            {
                if (m_disposed == false)
                {
                    g_lockCt--;
                    if (g_lockCt == 0)
                    {
                        System.AppDomain.CurrentDomain.UnhandledException -= g_unhandledException;
                        System.Windows.Forms.Application.ThreadException -= g_threadException;
                    }
                    m_disposed = true;
                }
            }
        }

        static ExceptionCatcher()
        {
            g_lock = new System.Object();
            g_lockCt = 0;
            g_unhandledException = new System.UnhandledExceptionEventHandler(ExceptionCatcher.UnhandledException);
            g_threadException = new System.Threading.ThreadExceptionEventHandler(ExceptionCatcher.ThreadException);
        }

        private static void UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
        {
            TextLogFile.AppendException(e.ExceptionObject);
        }

        private static void ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            TextLogFile.AppendException(e.Exception);
        }

        private static readonly System.Object g_lock;
        private static uint g_lockCt;
        private static System.UnhandledExceptionEventHandler g_unhandledException;
        private static System.Threading.ThreadExceptionEventHandler g_threadException;

        private bool m_disposed;
    }
}
