/*
 * Program.cs --
 *
 * Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: $
 */

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Threading;
using System.Windows.Forms;
using Eagle._Components.Private;
using Eagle._Forms;

namespace Eagle._Tool
{
    [Guid("3fa71d89-21c4-49bd-b1ef-3f13371cf3e6")]
    internal static class Program
    {
        #region Private Data (Read-Only)
        private static readonly string TraceCategory = typeof(Program).Name;
        private static readonly Assembly assembly = Assembly.GetExecutingAssembly();
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Error Handling Methods
        public static void Fail(
            Configuration configuration,
            Assembly assembly,
            string message,
            string category
            )
        {
            TraceOps.ShowMessage(
                configuration, assembly, message, category,
                MessageBoxButtons.OK, MessageBoxIcon.Error);

            Environment.Exit(1);
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Entry Point Method
        [STAThread] /* WinForms */
        private static int Main(
            string[] args
            )
        {
            Configuration configuration = null;
            string error = null;

            if (Configuration.TryCreate(assembly, ref configuration, ref error) &&
                Configuration.FromFile(null, true, ref configuration, ref error) &&
                Configuration.FromArgs(args, true, ref configuration, ref error) &&
                Configuration.Process(args, configuration, false, ref error))
            {
                if (!configuration.IsValid)
                {
                    error = "Invalid configuration.";
                    goto error;
                }

                if (!configuration.IsSigned)
                {
                    error = "Self-check failed, cannot continue.";
                    goto error;
                }

                try
                {
                    using (Mutex.OpenExisting(configuration.MutexName,
                            MutexRights.Synchronize))
                    {
                        error = "Eagle is running, please close it and try again.";
                    }
                }
                catch (WaitHandleCannotBeOpenedException)
                {
                    try
                    {
                        Application.EnableVisualStyles();
                        Application.SetCompatibleTextRenderingDefault(false);

                        using (UpdateForm form = UpdateForm.Create(
                                configuration, ref error))
                        {
                            if (form != null)
                            {
                                Application.Run(form);
                                return 0; /* SUCCESS */
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        TraceOps.Trace(configuration, e, TraceCategory);

                        error = "User interface failed.";
                    }
                }
                catch (Exception e)
                {
                    TraceOps.Trace(configuration, e, TraceCategory);

                    error = "Running instance detection failed.";
                }
            }

        error:
            Fail(configuration, assembly, error, TraceCategory);
            return 1; /* NOT REACHED */
        }
        #endregion
    }
}
