using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using System.Text;
using pcmp.Forms;

namespace pcmp
{
    static class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
            Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            // 2重起動のチェック
            if (CheckPrevProcess())
                Application.Run(new FormMain());
        }

        static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = e.ExceptionObject as Exception;
            if (ex != null)
            {
                FormExceptionMessageBox f = new FormExceptionMessageBox(ex.Message, ex.StackTrace);
                f.ShowDialog();
                f.Dispose();
            }
        }

        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            FormExceptionMessageBox f = new FormExceptionMessageBox(e.Exception.Message, e.Exception.StackTrace);
            f.ShowDialog();
            f.Dispose();
        }

        public static bool CheckPrevProcess()
        {
            Process hThisProcess = Process.GetCurrentProcess();
            Process[] hProcesses = Process.GetProcessesByName(hThisProcess.ProcessName);
            int iThisProcessId = hThisProcess.Id;
            int pid = 0;

            foreach (Process hProcess in hProcesses)
            {
                if (hProcess.Id != iThisProcessId)
                {
                    pid = hProcess.Id;
                }
            }

            if (pid == 0) return true;

            EnumWindowsProcDelegate proc = new EnumWindowsProcDelegate(EnumWindowsProc);
            Win32.EnumWindows(proc, pid);

            return false;          
        }

        static bool EnumWindowsProc(IntPtr hWnd, int lParam)
        {
            uint pid;
            Win32.GetWindowThreadProcessId(hWnd, out pid);
            StringBuilder sb = new StringBuilder(100);
            if (pid == lParam)
            {
                Win32.GetClassName(hWnd, sb, 100);
                if (sb.ToString().StartsWith("WindowsForms"))
                {
                    Win32.COPYDATASTRUCT cdStruct = new Win32.COPYDATASTRUCT();
                    cdStruct.dwData = 0;
                    cdStruct.cbData = Encoding.Unicode.GetByteCount(Common.CommandActivate);
                    cdStruct.lpData = Common.CommandActivate;
                    Win32.SendMessage(hWnd, (uint)WindowsMessages.WM_COPYDATA,
                        Process.GetCurrentProcess().MainWindowHandle, ref cdStruct); 
                }
            }

            return true;
        }
    }
}