#define ENABLE_TRAY_NOTIFICATIONS

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Net.Security;
using System.Text.RegularExpressions;
using System.Security.Cryptography.X509Certificates;
using System.Security.Authentication;
using System.Windows.Forms;
using System.Diagnostics;

namespace StarTrinity
{
    public delegate void Action();
    public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
    public class Tuple<T1, T2>
    {
        public Tuple()
        {
        }
        public Tuple(T1 item1, T2 item2)
        {
            Item1 = item1;
            Item2 = item2;
        }
        public T1 Item1 { get; set; }
        public T2 Item2 { get; set; }
    }


	class DistributedProxyProgram
	{
		public static string BaseDirectory
		{
			get
			{
				Uri dllURI = new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
				return System.IO.Path.GetDirectoryName(dllURI.LocalPath);
			}
		}
		static NotifyIcon appIcon;
		static DistributedProxyMainWindow wnd;
        static DistributedProxy dp = null;
		static void Main(string[] args)
		{
			if (!SingleInstanceUtility.IsItASingleInstance("StarTrinity", () =>
				{
#if ENABLE_TRAY_NOTIFICATIONS
					if (appIcon != null)
						appIcon.ShowBalloonTip(1000, "StarTrinity", "StarTrinity Service is already started", ToolTipIcon.Info);
#endif
				}))
				return;

			try
			{
				appIcon = new NotifyIcon();
				appIcon.Icon = new System.Drawing.Icon(Path.Combine(BaseDirectory, "StarTrinity.DistributedProxy.ico"));
                appIcon.Text = "Past 24/hrs: $0.00\nPast Month: $0.00\nTotal Earnings: $0.00";
				appIcon.Visible = true;
#if ENABLE_TRAY_NOTIFICATIONS
				appIcon.ShowBalloonTip(1000, "StarTrinity", "StarTrinity Service " + DistributedProxy.AssemblyVersion + " started", ToolTipIcon.Info);
#endif
				appIcon.DoubleClick += new EventHandler(showItem_Click);

				ContextMenu contextMenu = new ContextMenu();
				var exitItem = contextMenu.MenuItems.Add("E&xit");
				exitItem.Click += new EventHandler(exitItem_Click);
				var showItem = contextMenu.MenuItems.Add("&Settings");
				showItem.Click += new EventHandler(showItem_Click);
				appIcon.ContextMenu = contextMenu;

				DistributedProxySettings settings = new DistributedProxySettings();
				
				wnd = new DistributedProxyMainWindow(settings, () =>
				{
					dp = new DistributedProxy(settings);
					dp.StatusChanged += new Action<string>(dp_StatusChanged);
                    dp.MoneyInfoLoaded += new Action<string, string, string>(dp_MoneyInfoLoaded);
				});
				try
				{
					Application.Run(wnd);
				}
				finally
				{
					if (dp != null) dp.Dispose();
				}

				appIcon.Dispose();
				appIcon = null;
			}
			catch (Exception exc)
			{
				MessageBox.Show("error: " + exc.ToString());		
			}
		}
        static void dp_MoneyInfoLoaded(string daily, string monthly, string total)
        {
            if (appIcon != null && wnd != null)
            {
                wnd.Invoke(new Action(() =>
                {
                    appIcon.Text = String.Format("Past 24/hrs: ${0}\nPast Month: ${1}\nTotal Earnings: ${2}", daily, monthly, total);

                }));
            }
        }
		static void dp_StatusChanged(string status)
		{
			if (appIcon != null && wnd != null)
			{
				wnd.Invoke(new Action(() =>
				{
#if ENABLE_TRAY_NOTIFICATIONS
                    appIcon.ShowBalloonTip(1000, "StarTrinity " + DistributedProxy.AssemblyVersion, status, ToolTipIcon.Info);
#endif
				}));
			}
		}
		static void exitItem_Click(object sender, EventArgs e)
        {
            if (dp != null) dp.log.WriteInfo(null, null, ">> exitItem_Click()");
			wnd.Close();

            try
            {
                var processes = Process.GetProcessesByName("StarTrinity.DistributedProxy.Controller");
                if (processes.Length > 0) processes[0].Kill();
            }
            catch
            {
            }
       
		}
		static void showItem_Click(object sender, EventArgs e)
		{
            if (dp != null) dp.log.WriteInfo(null, null, ">> showItem_Click()");
			wnd.Show();
			wnd.WindowState = FormWindowState.Normal;
			wnd.Activate();
		}
	}
}
