view FrmMain.cs @ 0:7dd160dacb60

Initial commit of WarFoundry code
author IBBoard <dev@ibboard.co.uk>
date Fri, 19 Dec 2008 15:57:51 +0000
parents
children 42cf06b8f897
line wrap: on
line source

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Threading;
using IBBoard;
using IBBoard.CustomMath;
using IBBoard.Commands;
using IBBoard.IO;
using IBBoard.Lang;
using IBBoard.WarFoundry.API;
using IBBoard.WarFoundry.API.Commands;
using IBBoard.Windows.Forms;
using IBBoard.Xml;
using log4net;

namespace IBBoard.WarFoundry
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class FrmMain : System.Windows.Forms.Form
	{
		private static readonly string AppTitle = "WarFoundry";

        private Preferences preferences;
        protected readonly ILog logger = LogManager.GetLogger(typeof(WarFoundryFactory));

		private CommandStack commandStack;
		private ToolBarButton[] categoryButtons;
        private Type factoryType = typeof(WarFoundryXmlFactory);

		public ObjectAddDelegate UnitAddedMethod;
		public ObjectRemoveDelegate UnitRemovedMethod;
		public DoubleValChangedDelegate PointsValueChangedMethod;
		//public FailedUnitRequirementDelegate FailedUnitRequirementMethod;

		private FrmArmyTree armyTree;
		private FrmDebugOutput debugWindow;

		private IBBoard.Windows.Forms.ColorableStatusBar statusBar;
		private System.Windows.Forms.ToolBar toolBar;
		private System.Windows.Forms.MainMenu mainMenu;
		private IBBoard.Windows.Forms.IBBMenuItem menuFile;
		private IBBoard.Windows.Forms.IBBMenuItem menuHelp;
		private IBBoard.Windows.Forms.IBBToolBarButton bttnNewArmy;
		private System.Windows.Forms.ImageList buttonIcons;
		private IBBoard.Windows.Forms.IBBToolBarButton bttnSaveArmy;
		private System.Windows.Forms.OpenFileDialog openArmyDialog;
		private System.Windows.Forms.SaveFileDialog saveArmyDialog;
		private IBBoard.Windows.Forms.IBBMenuItem miExit;
		private IBBoard.Windows.Forms.IBBToolBarButton bttnOpenArmy;
		private IBBoard.Windows.Forms.IBBMenuItem miAbout;
		private System.ComponentModel.IContainer components;
		private IBBoard.Windows.Forms.IBBMenuItem miNewArmy;
		private IBBoard.Windows.Forms.IBBMenuItem miOpenArmy;
		private IBBoard.Windows.Forms.IBBMenuItem miCloseArmy;
		private IBBoard.Windows.Forms.IBBMenuItem miSaveArmy;
		private IBBoard.Windows.Forms.IBBMenuItem miSaveArmyAs;
		private IBBoard.Windows.Forms.IBBMenuItem miChangeSystem;
		private IBBoard.Windows.Forms.IBBToolBarButton bttnSep1;
		private IBBoard.Windows.Forms.IBBToolBarButton bttnUndo;
		private IBBoard.Windows.Forms.IBBToolBarButton bttnRedo;
		private IBBoard.Windows.Forms.IBBMenuItem menuEdit;
		private IBBoard.Windows.Forms.IBBMenuItem miUndo;
		private IBBoard.Windows.Forms.IBBMenuItem miRedo;
		private IBBoard.Windows.Forms.IBBMenuItem miDebugWindow;
		private System.Windows.Forms.MenuItem miSep1;
		private System.Windows.Forms.MenuItem miSep2;
		private System.Windows.Forms.MenuItem miSep3;
		private IBBoard.Windows.Forms.ColorableStatusBarPanel sbMainPanel;
		private IBBoard.Windows.Forms.ColorableStatusBarPanel sbErrorPanel;
		private IBBoard.Windows.Forms.ColorableStatusBarPanel sbPointsPanel;
		private System.Windows.Forms.ContextMenu undoMenu;
		private System.Windows.Forms.ContextMenu redoMenu;
		private IBBoard.Windows.Forms.IBBMenuItem miReloadFiles;
		private System.Windows.Forms.Timer statusBarTimer;
		private System.Windows.Forms.Panel pnlRight;

		public FrmMain(string[] args)
		{
			this.Closing+=new CancelEventHandler(FrmMain_Closing);
			CommandStack.CommandStackUpdated+=new MethodInvoker(commandStack_CommandStackUpdated);

			InitializeComponent();

            Preferences = new Preferences("WarFoundry");
            Translation.InitialiseTranslations(Constants.ExecutablePath, Preferences["language"].ToString());

			//pnlRight.Left = ClientSize.Width - pnlRight.Width - 2;
			//pnlRight.Top = toolBar.Height + 5;
			//pnlRight.Height = ClientRectangle.Bottom - statusBar.Height - pnlRight.Top - 3;

			foreach (Control ctrl in Controls)
			{
				Translation.TranslateControl(ctrl);
			}

			foreach(Component comp in components.Components)
			{
				Translation.TranslateComponent(comp);
			}

			foreach (IBBMenuItem mi in Menu.MenuItems)
			{
				Translation.TranslateComponent(mi);
			}

			Translation.TranslateComponent(openArmyDialog);
			Translation.TranslateComponent(saveArmyDialog);

			WarFoundryCore.GameSystemChanged+= new GameSystemChangedDelegate(FrmMain_GameSystemChanged);
            WarFoundryCore.ArmyChanged += new ArmyChangedDelegate(FrmMain_ArmyChanged);
			UnitAddedMethod = new ObjectAddDelegate(FrmMain_UnitAddedMethod);
			UnitRemovedMethod = new ObjectRemoveDelegate(FrmMain_UnitRemovedMethod);
			PointsValueChangedMethod = new DoubleValChangedDelegate(FrmMain_PointsValueChangedMethod);
			//FailedUnitRequirementMethod = new FailedUnitRequirementDelegate(FrmMain_FailedUnitRequirement);

			sbErrorPanel.Color = Color.Red;

			armyTree = new FrmArmyTree(CommandStack);
			armyTree.MdiParent = this;
			armyTree.Show();
			armyTree.StartPosition = FormStartPosition.Manual;
			armyTree.Location = new Point(this.DisplayRectangle.Width - armyTree.Width - 10, 10);
			Translation.TranslateControl(armyTree);

            if (args.Length == 1)
			{
				logger.Debug("Attempting to load from file");				
				FileInfo file = new FileInfo(args[0]);
				
				try
				{
					if (file.Extension.Equals("."+Factory.GetArmyFileExtension()))
					{
						WarFoundryCore.CurrentArmy = Factory.CreateArmyFromFile(file);
						logger.InfoFormat("Loaded army from {0}", file.FullName);
					}
					else if (file.Extension.Equals("."+Factory.GetSystemFileExtension()))
					{
						WarFoundryCore.CurrentGameSystem = Factory.CreateGameSystemFromFile(file);
						logger.InfoFormat("Loaded game system from {0}", file.FullName);
					}
				}
				catch (InvalidFileException ex)
				{
					MessageBox.Show(Translation.GetTranslation("InvalidFileLoadError", "The file loaded ({0}) was not a valid WarFoundry file", file.FullName), Translation.GetTranslation("InvalidFileLoadTitle", "Invalid data file", null), MessageBoxButtons.OK, MessageBoxIcon.Error);
					logger.Error(ex);
				}
			}
			else
			{
				string gameSystemID = Preferences.GetStringProperty("currSystem");

				if (gameSystemID!=null && !"".Equals(gameSystemID))
				{
					logger.Debug("Attempting to load current game system from properties");
					GameSystem sys = Factory.GetGameSystem(gameSystemID);
					
					if (sys!=null)
					{
						WarFoundryCore.CurrentGameSystem = sys;
						logger.InfoFormat("Loaded game system {0} from properties", gameSystemID);
					}
				}
			}
		}

		public static string DataPath
		{
			get { return Constants.ExecutablePath+Constants.DirectoryChar+"data"; }
		}

		public static String ArmiesPath
		{
			get { return Constants.UserDataPath+Constants.DirectoryChar+"armies"; }
        }

        public Preferences Preferences
        {
            get { return preferences; }
            set { preferences = value; }
        }

		public CommandStack CommandStack
		{
			get 
			{
				if (commandStack == null)
				{					
					commandStack = new CommandStack();
				}

				return commandStack; 
			}
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain));
            this.statusBar = new IBBoard.Windows.Forms.ColorableStatusBar();
            this.sbMainPanel = new IBBoard.Windows.Forms.ColorableStatusBarPanel();
            this.sbErrorPanel = new IBBoard.Windows.Forms.ColorableStatusBarPanel();
            this.sbPointsPanel = new IBBoard.Windows.Forms.ColorableStatusBarPanel();
            this.toolBar = new System.Windows.Forms.ToolBar();
            this.bttnNewArmy = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.bttnOpenArmy = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.bttnSaveArmy = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.bttnSep1 = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.bttnUndo = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.undoMenu = new System.Windows.Forms.ContextMenu();
            this.bttnRedo = new IBBoard.Windows.Forms.IBBToolBarButton();
            this.redoMenu = new System.Windows.Forms.ContextMenu();
            this.buttonIcons = new System.Windows.Forms.ImageList(this.components);
            this.mainMenu = new System.Windows.Forms.MainMenu(this.components);
            this.menuFile = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miNewArmy = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miOpenArmy = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miSaveArmy = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miSaveArmyAs = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miCloseArmy = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miSep1 = new System.Windows.Forms.MenuItem();
            this.miChangeSystem = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miSep2 = new System.Windows.Forms.MenuItem();
            this.miReloadFiles = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miSep3 = new System.Windows.Forms.MenuItem();
            this.miExit = new IBBoard.Windows.Forms.IBBMenuItem();
            this.menuEdit = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miUndo = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miRedo = new IBBoard.Windows.Forms.IBBMenuItem();
            this.menuHelp = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miAbout = new IBBoard.Windows.Forms.IBBMenuItem();
            this.miDebugWindow = new IBBoard.Windows.Forms.IBBMenuItem();
            this.openArmyDialog = new System.Windows.Forms.OpenFileDialog();
            this.saveArmyDialog = new System.Windows.Forms.SaveFileDialog();
            this.pnlRight = new System.Windows.Forms.Panel();
            this.statusBarTimer = new System.Windows.Forms.Timer(this.components);
            ((System.ComponentModel.ISupportInitialize)(this.sbMainPanel)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.sbErrorPanel)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.sbPointsPanel)).BeginInit();
            this.SuspendLayout();
            // 
            // statusBar
            // 
            this.statusBar.Location = new System.Drawing.Point(0, 548);
            this.statusBar.Name = "statusBar";
            this.statusBar.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
            this.sbMainPanel,
            this.sbErrorPanel,
            this.sbPointsPanel});
            this.statusBar.ShowPanels = true;
            this.statusBar.Size = new System.Drawing.Size(792, 22);
            this.statusBar.TabIndex = 1;
            this.statusBar.PanelClick += new System.Windows.Forms.StatusBarPanelClickEventHandler(this.statusBar_PanelClick);
            this.statusBar.DrawItem += new System.Windows.Forms.StatusBarDrawItemEventHandler(this.statusBar_DrawItem);
            // 
            // sbMainPanel
            // 
            this.sbMainPanel.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
            this.sbMainPanel.Color = System.Drawing.SystemColors.WindowText;
            this.sbMainPanel.Name = "sbMainPanel";
            this.sbMainPanel.Style = System.Windows.Forms.StatusBarPanelStyle.OwnerDraw;
            this.sbMainPanel.Width = 475;
            // 
            // sbErrorPanel
            // 
            this.sbErrorPanel.Color = System.Drawing.SystemColors.WindowText;
            this.sbErrorPanel.Name = "sbErrorPanel";
            this.sbErrorPanel.Style = System.Windows.Forms.StatusBarPanelStyle.OwnerDraw;
            this.sbErrorPanel.Width = 150;
            // 
            // sbPointsPanel
            // 
            this.sbPointsPanel.Color = System.Drawing.SystemColors.WindowText;
            this.sbPointsPanel.Name = "sbPointsPanel";
            this.sbPointsPanel.Style = System.Windows.Forms.StatusBarPanelStyle.OwnerDraw;
            this.sbPointsPanel.ToolTipText = "Current Points Total";
            this.sbPointsPanel.Width = 150;
            // 
            // toolBar
            // 
            this.toolBar.Appearance = System.Windows.Forms.ToolBarAppearance.Flat;
            this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
            this.bttnNewArmy,
            this.bttnOpenArmy,
            this.bttnSaveArmy,
            this.bttnSep1,
            this.bttnUndo,
            this.bttnRedo});
            this.toolBar.ButtonSize = new System.Drawing.Size(16, 16);
            this.toolBar.DropDownArrows = true;
            this.toolBar.ImageList = this.buttonIcons;
            this.toolBar.Location = new System.Drawing.Point(0, 0);
            this.toolBar.Name = "toolBar";
            this.toolBar.ShowToolTips = true;
            this.toolBar.Size = new System.Drawing.Size(792, 28);
            this.toolBar.TabIndex = 2;
            this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
            // 
            // bttnNewArmy
            // 
            this.bttnNewArmy.Enabled = false;
            this.bttnNewArmy.ImageIndex = 0;
            this.bttnNewArmy.Name = "";
            // 
            // bttnOpenArmy
            // 
            this.bttnOpenArmy.ImageIndex = 2;
            this.bttnOpenArmy.Name = "";
            // 
            // bttnSaveArmy
            // 
            this.bttnSaveArmy.Enabled = false;
            this.bttnSaveArmy.ImageIndex = 1;
            this.bttnSaveArmy.Name = "";
            // 
            // bttnSep1
            // 
            this.bttnSep1.Name = "";
            this.bttnSep1.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
            // 
            // bttnUndo
            // 
            this.bttnUndo.DropDownMenu = this.undoMenu;
            this.bttnUndo.Enabled = false;
            this.bttnUndo.ImageIndex = 3;
            this.bttnUndo.Name = "";
            this.bttnUndo.Style = System.Windows.Forms.ToolBarButtonStyle.DropDownButton;
            // 
            // bttnRedo
            // 
            this.bttnRedo.DropDownMenu = this.redoMenu;
            this.bttnRedo.Enabled = false;
            this.bttnRedo.ImageIndex = 4;
            this.bttnRedo.Name = "";
            this.bttnRedo.Style = System.Windows.Forms.ToolBarButtonStyle.DropDownButton;
            // 
            // buttonIcons
            // 
            this.buttonIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("buttonIcons.ImageStream")));
            this.buttonIcons.TransparentColor = System.Drawing.Color.Transparent;
            this.buttonIcons.Images.SetKeyName(0, "");
            this.buttonIcons.Images.SetKeyName(1, "");
            this.buttonIcons.Images.SetKeyName(2, "");
            this.buttonIcons.Images.SetKeyName(3, "");
            this.buttonIcons.Images.SetKeyName(4, "");
            this.buttonIcons.Images.SetKeyName(5, "");
            this.buttonIcons.Images.SetKeyName(6, "");
            // 
            // mainMenu
            // 
            this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuFile,
            this.menuEdit,
            this.menuHelp});
            // 
            // menuFile
            // 
            this.menuFile.Index = 0;
            this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.miNewArmy,
            this.miOpenArmy,
            this.miSaveArmy,
            this.miSaveArmyAs,
            this.miCloseArmy,
            this.miSep1,
            this.miChangeSystem,
            this.miSep2,
            this.miReloadFiles,
            this.miSep3,
            this.miExit});
            this.menuFile.Text = "&file";
            // 
            // miNewArmy
            // 
            this.miNewArmy.Index = 0;
            this.miNewArmy.Text = "&new army";
            this.miNewArmy.Click += new System.EventHandler(this.miNewArmy_Click);
            // 
            // miOpenArmy
            // 
            this.miOpenArmy.Index = 1;
            this.miOpenArmy.Text = "&open army";
            this.miOpenArmy.Click += new System.EventHandler(this.miOpenArmy_Click);
            // 
            // miSaveArmy
            // 
            this.miSaveArmy.Enabled = false;
            this.miSaveArmy.Index = 2;
            this.miSaveArmy.Text = "&save army";
            this.miSaveArmy.Click += new System.EventHandler(this.miSaveArmy_Click);
            // 
            // miSaveArmyAs
            // 
            this.miSaveArmyAs.Enabled = false;
            this.miSaveArmyAs.Index = 3;
            this.miSaveArmyAs.Text = "save army &as...";
            this.miSaveArmyAs.Click += new System.EventHandler(this.miSaveArmyAs_Click);
            // 
            // miCloseArmy
            // 
            this.miCloseArmy.Enabled = false;
            this.miCloseArmy.Index = 4;
            this.miCloseArmy.Text = "&close army";
            this.miCloseArmy.Click += new System.EventHandler(this.miCloseArmy_Click);
            // 
            // miSep1
            // 
            this.miSep1.Index = 5;
            this.miSep1.Text = "-";
            // 
            // miChangeSystem
            // 
            this.miChangeSystem.Index = 6;
            this.miChangeSystem.Text = "change &game system";
            this.miChangeSystem.Click += new System.EventHandler(this.miChangeSystem_Click);
            // 
            // miSep2
            // 
            this.miSep2.Index = 7;
            this.miSep2.Text = "-";
            // 
            // miReloadFiles
            // 
            this.miReloadFiles.Index = 8;
            this.miReloadFiles.Text = "&reload files";
            this.miReloadFiles.Click += new System.EventHandler(this.miReloadFiles_Click);
            // 
            // miSep3
            // 
            this.miSep3.Index = 9;
            this.miSep3.Text = "-";
            // 
            // miExit
            // 
            this.miExit.Index = 10;
            this.miExit.Text = "e&xit";
            this.miExit.Click += new System.EventHandler(this.miExit_Click);
            // 
            // menuEdit
            // 
            this.menuEdit.Index = 1;
            this.menuEdit.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.miUndo,
            this.miRedo});
            this.menuEdit.Text = "&edit";
            // 
            // miUndo
            // 
            this.miUndo.Enabled = false;
            this.miUndo.Index = 0;
            this.miUndo.Text = "&undo";
            this.miUndo.Click += new System.EventHandler(this.miUndo_Click);
            // 
            // miRedo
            // 
            this.miRedo.Enabled = false;
            this.miRedo.Index = 1;
            this.miRedo.Text = "&redo";
            this.miRedo.Click += new System.EventHandler(this.miRedo_Click);
            // 
            // menuHelp
            // 
            this.menuHelp.Index = 2;
            this.menuHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.miAbout,
            this.miDebugWindow});
            this.menuHelp.Text = "&help";
            // 
            // miAbout
            // 
            this.miAbout.Enabled = false;
            this.miAbout.Index = 0;
            this.miAbout.Text = "&about";
            // 
            // miDebugWindow
            // 
            this.miDebugWindow.Index = 1;
            this.miDebugWindow.Text = "&debug";
            this.miDebugWindow.Click += new System.EventHandler(this.miDebugWindow_Click);
            // 
            // saveArmyDialog
            // 
            this.saveArmyDialog.Title = "Translatable:saveArmyDialog";
            // 
            // pnlRight
            // 
            this.pnlRight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.pnlRight.BackColor = System.Drawing.SystemColors.AppWorkspace;
            this.pnlRight.Location = new System.Drawing.Point(726, 30);
            this.pnlRight.Name = "pnlRight";
            this.pnlRight.Size = new System.Drawing.Size(64, 516);
            this.pnlRight.TabIndex = 4;
            this.pnlRight.Visible = false;
            this.pnlRight.Paint += new System.Windows.Forms.PaintEventHandler(this.pnlRight_Paint);
            // 
            // statusBarTimer
            // 
            this.statusBarTimer.Interval = 5000;
            this.statusBarTimer.Tick += new System.EventHandler(this.statusBarTimer_Tick);
            // 
            // FrmMain
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(792, 570);
            this.Controls.Add(this.pnlRight);
            this.Controls.Add(this.toolBar);
            this.Controls.Add(this.statusBar);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.IsMdiContainer = true;
            this.Menu = this.mainMenu;
            this.Name = "FrmMain";
            this.Text = "WarFoundry";
            ((System.ComponentModel.ISupportInitialize)(this.sbMainPanel)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.sbErrorPanel)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.sbPointsPanel)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args) 
		{
			try
			{
				///TODO: Work out how to auto-embed the Manifest file so that we can have visual styles without having a .manifest file floating around
				//and without using the line below, which causes the toolbar buttons to lose their icons
				//Application.EnableVisualStyles();
				Application.Run(new FrmMain(args));
			}
			catch(Exception ex)
			{
                   LogManager.GetLogger(typeof(FrmMain)).Fatal(ex);
				MessageBox.Show(null, "A major, unexpected and fatal error ocurred while starting the application: \r\n\r\n"+ex.Message+"\r\n\r\n"+ex.StackTrace, "Fatal error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

        public WarFoundryFactory Factory
        {
            get { return WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(Constants.ExecutablePath, factoryType); }
        }

		private void miExit_Click(object sender, System.EventArgs e)
		{
			Application.Exit();
		}

		private void miNewArmy_Click(object sender, System.EventArgs e)
		{
			createNewArmy();
		}

		private void createNewArmy()
		{
			if (closeCurrentArmy())
			{
				FrmNewArmy newArmy = new FrmNewArmy(CurrentGameSystem, Factory);
				DialogResult dr = newArmy.ShowDialog();

				if (dr == DialogResult.OK)
				{
                    CurrentArmy = new Army(newArmy.SelectedRace, newArmy.ArmyName, newArmy.ArmySize, Factory);
				}
			}
		}

		private bool openArmy()
		{
			if (closeCurrentArmy())
			{
				if (openArmyDialog.Filter=="")
				{
					string savePath = ArmiesPath;
				
					if (!Directory.Exists(savePath))
					{
						Directory.CreateDirectory(savePath);
					}

					openArmyDialog.InitialDirectory = savePath;
					openArmyDialog.Filter = Translation.GetTranslation("armyFileFilter")+"|*.army";
					openArmyDialog.Title = Translation.GetTranslation("openArmyDialog");

				}

				DialogResult dr = openArmyDialog.ShowDialog(this);

				if (dr == DialogResult.OK)
				{
					try
					{
						CurrentArmy = Factory.LoadArmy(openArmyDialog.FileName);
						return true;					
					}
					catch (InvalidFileException ex)
					{
						logger.Error(ex);
						MessageBox.Show(this, ex.Message, Translation.GetTranslation("InvalidFileBoxTitle", "Invalid data file"), MessageBoxButtons.OK, MessageBoxIcon.Error);
						return false;
					}
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}

		private bool closeCurrentArmy()
		{
			if (CurrentArmy!=null)
			{
				bool canClose = false;

				if (CommandStack.IsDirty())
				{
					DialogResult dr = MessageBox.Show(this, "The army \""+CurrentArmy.Name+"\" has been modified.\r\nSave changes before closing army?", "Unsaved changes", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3);

					if (dr == DialogResult.Yes)
					{
						canClose = saveCurrentArmyOrSaveAs();
					}
					else if (dr == DialogResult.No)
					{
						canClose = true;
					}
					//else they said cancel and we default to "canClose = false" so do nothing
				}
				else
				{
					canClose = true;
				}

				if (canClose)
				{
					//do close
					disableCategoryButtons();
					CurrentArmy = null;
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				disableCategoryButtons();
				//pretend we succeeded
				return true;
			}
		}

		private void undoLastAction()
		{
			if (commandStack.CanUndo())
			{
				commandStack.Undo();
			}
		}

		private void redoAction()
		{
			if (commandStack.CanRedo())
			{
				commandStack.Redo();
			}
		}

		private bool saveCurrentArmyOrSaveAs()
		{
			if (WarFoundrySaver.GetSaver().CanSave(CurrentArmy))
			{
				return saveCurrentArmy();
			}
			else 
			{
				return saveCurrentArmyAs();
			}
		}

		private bool saveCurrentArmy()
		{
            if (WarFoundrySaver.GetSaver().CanSave(CurrentArmy))
			{
                if (WarFoundrySaver.GetSaver().Save(CurrentArmy))
				{
					miSaveArmy.Enabled = false;
					bttnSaveArmy.Enabled = false;
					CommandStack.setCleanMark();
					return true;
				}
				else
				{
					MessageBox.Show(this, Translation.GetTranslation("SaveFailed"), Translation.GetTranslation("SaveFailedTitle"), MessageBoxButtons.OK, MessageBoxIcon.Error);
					return false;
				}
			}
			else
			{
				return false;
			}
		}

		private bool saveCurrentArmyAs()
		{
			if (saveArmyDialog.Filter == "")
			{
				string savePath = ArmiesPath;
				
				if (!Directory.Exists(savePath))
				{
					Directory.CreateDirectory(savePath);
				}

				saveArmyDialog.InitialDirectory = savePath;
				saveArmyDialog.Filter = Translation.GetTranslation("armyFileFilter")+"|*.army";
				saveArmyDialog.Title = Translation.GetTranslation("saveArmyDialog");
			}

			DialogResult dr = saveArmyDialog.ShowDialog(this);

			if (dr == DialogResult.OK)
			{
				if (WarFoundrySaver.GetSaver().SaveAs(CurrentArmy, saveArmyDialog.FileName))
				{
					miSaveArmy.Enabled = false;
					bttnSaveArmy.Enabled = false;
					CommandStack.setCleanMark();
					return true;
				}
				else
				{
					MessageBox.Show(this, Translation.GetTranslation("SaveFailed"), Translation.GetTranslation("SaveFailedTitle"), MessageBoxButtons.OK, MessageBoxIcon.Error);
					return false;
				}
			}
			else
			{
				return false;
			}
		}

		private void toolBar_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			if (e.Button == bttnUndo)
			{
				undoLastAction();
			}
			else if (e.Button == bttnRedo)
			{
				redoAction();
			}
			else if (e.Button == bttnNewArmy)
			{
				createNewArmy();
			}
			else if (e.Button == bttnOpenArmy)
			{
				openArmy();
			}
			else if (e.Button == bttnSaveArmy)
			{
				saveCurrentArmyOrSaveAs();
			}
			else
			{
				//it must be one of our extra buttons for the categories
				addUnitFromCategory((Category)e.Button.Tag);
			}
		}

		private GameSystem CurrentGameSystem
		{
			get { return WarFoundryCore.CurrentGameSystem; }
            set { WarFoundryCore.CurrentGameSystem = value; }
		}

		private static Army CurrentArmy
		{
			get { return WarFoundryCore.CurrentArmy; }
			set { WarFoundryCore.CurrentArmy = value; }
		}

		private void SelectGameSystem()
		{
			FrmSelectSystem selectSystem = new FrmSelectSystem(Factory);
			DialogResult dr = selectSystem.ShowDialog(this);

			if (dr==DialogResult.OK)
			{
				closeCurrentArmy();
				CurrentGameSystem = selectSystem.GameSystem;
			}
		}

		private void miChangeSystem_Click(object sender, System.EventArgs e)
		{
			SelectGameSystem();
		}

		private void FrmMain_GameSystemChanged(GameSystem oldSystem, GameSystem newSystem)
		{
            miNewArmy.Enabled = newSystem != null;
            bttnNewArmy.Enabled = newSystem != null;
			setAppTitle();
			removeCategoryButtons();
			addCategoryButtons();
		}

		private void FrmMain_ArmyChanged(Army oldArmy, Army newArmy)
		{		
			setAppTitle();

            if (oldArmy != null)
            {
                oldArmy.UnitAdded += UnitAddedMethod;
                oldArmy.UnitRemoved += UnitRemovedMethod;
                oldArmy.PointsValueChanged += PointsValueChangedMethod;
            }

			if (CurrentArmy==null)
			{
				miSaveArmyAs.Enabled = false;
				miCloseArmy.Enabled = false;
				disableCategoryButtons();
			}
			else
			{
                newArmy.UnitAdded += UnitAddedMethod;
                newArmy.UnitRemoved += UnitRemovedMethod;
                newArmy.PointsValueChanged += PointsValueChangedMethod;
				//TODO: Clear all buttons
				miSaveArmyAs.Enabled = true;
				miCloseArmy.Enabled = true;
				enableCategoryButtons();

                if (newArmy.Race.HasCategoryOverrides())
				{
					removeCategoryButtons();
                    addCategoryButtons(newArmy.Race.Categories);
				}
			}

			CommandStack.Reset();

			miSaveArmy.Enabled = false;
			bttnSaveArmy.Enabled = false;

			setPointsPanelText();
		}

		private void addCategoryButtons()
		{
			if (CurrentGameSystem!=null)
			{
				addCategoryButtons(CurrentGameSystem.Categories);
			}
		}

		private void addCategoryButtons(Category[] cats)
		{
			int catCount = cats.Length;
			Category cat;
			categoryButtons = new ToolBarButton[catCount+1];

			ToolBarButton sep = new ToolBarButton();
			sep.Style = ToolBarButtonStyle.Separator;
			categoryButtons[0] = sep;

			IBBToolBarButton button;

			for (int i = 0; i<catCount; i++)
			{
				cat = cats[i];
				button = new IBBToolBarButton();
				///button.Name = "bttnAddCategory" + cat.Name[0].ToString();
				button.Text = cat.Name.ToString();//String.Format(Translation.GetTranslation("bttnAddCategory"), cat.Name);
				button.Tag = cat;
				button.ImageIndex = 6;
				button.Enabled = false;
				categoryButtons[i+1] = button;
			}

			this.Invoke(new ToolBarButtonRangeDelegate(toolBar.Buttons.AddRange), new object[]{categoryButtons});
		}

		private void removeCategoryButtons()
		{
			if (categoryButtons!=null)
			{
				for (int i = 0; i<categoryButtons.Length; i++)
				{
					this.Invoke(new ToolBarButtonDelegate(toolBar.Buttons.Remove), new object[]{categoryButtons[i]});
				}
			}
		}

		private void enableCategoryButtons()
		{
			setCategoryButtonState(true);
		}

		private void disableCategoryButtons()
		{
			setCategoryButtonState(false);
		}

		private void setCategoryButtonState(bool state)
		{
			if (categoryButtons!=null)
			{
				for (int i = 0; i<categoryButtons.Length; i++)
				{
					categoryButtons[i].Enabled = state;
				}
			}
		}

		private void miSaveArmyAs_Click(object sender, System.EventArgs e)
		{
			saveCurrentArmyAs();
		}

		private void commandStack_CommandStackUpdated()
		{
			bttnUndo.Enabled = commandStack.CanUndo();
			miUndo.Enabled = bttnUndo.Enabled;
			bttnRedo.Enabled = commandStack.CanRedo();
			miRedo.Enabled = bttnRedo.Enabled;
			MenuItem[] menuItems = null;
			int redoLength = commandStack.RedoLength;
			int maxRedo = Math.Min(10, redoLength);
			
			if (redoLength > 0)
			{
				menuItems = new MenuItem[maxRedo];
				Command com;
				MenuItem mi;

				for (int i = 0; i < maxRedo; i++)
				{
					com = commandStack.PeekRedoCommand(i+1);

					if (com == null)
					{
						break; 
					}

					mi = new MenuItem(com.Description);
					mi.Click+=new EventHandler(redoMenu_Click);
					menuItems[i] = mi;
				}
			}

			redoMenu.MenuItems.Clear();

			if (menuItems!=null && menuItems[0]!=null)
			{
				bttnRedo.ToolTipText = menuItems[0].Text;
				redoMenu.MenuItems.AddRange(menuItems);
			}

			int undoLength = commandStack.UndoLength;
			int maxUndo = Math.Min(10, undoLength);
			MenuItem[] menuItemsUndo = null;
			
			if (undoLength > 0)
			{
				menuItemsUndo = new MenuItem[maxUndo];
				Command com;
				MenuItem mi;

				for (int i = 0; i < maxUndo; i++)
				{
					com = commandStack.PeekUndoCommand(i+1);

					if (com == null)
					{
						break; 
					}

					mi = new MenuItem(com.UndoDescription);
					mi.Click+=new EventHandler(undoMenu_Click);
					menuItemsUndo[i] = mi;
				}
			}

			undoMenu.MenuItems.Clear();

			if (menuItemsUndo!=null && menuItemsUndo[0]!=null)
			{
				bttnUndo.ToolTipText = menuItemsUndo[0].Text;
				undoMenu.MenuItems.AddRange(menuItemsUndo);
			}

            bool canSave = WarFoundrySaver.GetSaver().CanSave(CurrentArmy);
			bttnSaveArmy.Enabled = commandStack.IsDirty() && CurrentArmy!=null && canSave;
			miSaveArmy.Enabled = commandStack.IsDirty() && CurrentArmy!=null && canSave;
		}

		private void miSaveArmy_Click(object sender, System.EventArgs e)
		{
			//we should only be saving when the army can be saved (i.e. it has been opened from a file or Save As-ed)
			//so use the "just save" version
			saveCurrentArmy();
		}

		private void setAppTitle()
		{
			string str = AppTitle;

			if (CurrentGameSystem!=null)
			{
				str+= " - "+CurrentGameSystem.Name;
			}

			if (CurrentArmy!=null)
			{
				str+= " - "+CurrentArmy.Name;
			}

			this.Text = str;
		}

		private void addUnitFromCategory(Category cat)
		{
			FrmNewUnit newUnit = new FrmNewUnit(CurrentArmy.Race, cat, CurrentArmy);
			DialogResult dr = newUnit.ShowDialog(this);

			if (dr == DialogResult.OK)
			{
                CreateAndAddUnitCommand cmd = new CreateAndAddUnitCommand(newUnit.SelectedUnit, cat, CurrentArmy, Factory);
				commandStack.Execute(cmd);
			}
		}

		private void FrmMain_UnitAddedMethod(object unitObj)
		{
			if (unitObj is Unit)
			{
				Unit unit = (Unit)unitObj;
				sbErrorPanel.Text = "";
			}
		}

		private void FrmMain_UnitRemovedMethod(object unitObj)
		{
			if (unitObj is Unit)
			{
				Unit unit = (Unit)unitObj;
				sbErrorPanel.Text = "";

				//check if window is open, and close it if it is
				foreach (Form frm in this.MdiChildren)
				{
					if (frm is FrmUnit)
					{
						if (((FrmUnit)frm).Unit == unit)
						{
							frm.Close();
							break;
						}
					}
				}
			}
		}

		/*private void FrmMain_FailedUnitRequirement(FailedUnitRequirement failedRequirement)
		{
			sbErrorPanel.Text = Translation.GetTranslation("UnitRequirementFailed", "Unit Requirement Failed");
			sbErrorPanel.Tag = failedRequirement.Description;
		}*/

		/*public void MdiChildMoved()
		{
			Point mouseAt = PointToClient(ActiveMdiChild.Location);

			if (Comparisons.ValueWithinAmount(pnlRight.Right, ActiveMdiChild.Right, 10))
			{
				pnlRight.Visible = true;
				//pnlRight.Container.Add(ActiveMdiChild);
			}
			else
			{
				pnlRight.Visible = false;
			}
		}*/

		public void pnlRight_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
		{
			HatchBrush dockCueBrush = new HatchBrush(HatchStyle.LightDownwardDiagonal, Color.White, Color.Gray);
			Pen dockCuePen = new Pen(dockCueBrush, 10);
			e.Graphics.DrawRectangle(dockCuePen, new Rectangle(pnlRight.Left, pnlRight.Top, pnlRight.Width, pnlRight.Height));
		}

		private void miUndo_Click(object sender, System.EventArgs e)
		{
			undoLastAction();
		}

		private void miRedo_Click(object sender, System.EventArgs e)
		{
			redoAction();
		}

		private void miCloseArmy_Click(object sender, EventArgs e)
		{
			closeCurrentArmy();
		}

		private void miOpenArmy_Click(object sender, EventArgs e)
		{
			openArmy();
		}

		private void FrmMain_PointsValueChangedMethod(WarFoundryObject obj, double oldVal, double newVal)
		{
			if (obj is Army)
			{
				setPointsPanelText();
			}
		}

		private void setPointsPanelText()
		{	
			if (CurrentArmy==null)
			{
				sbPointsPanel.Text = "";
				sbPointsPanel.ResetColor();
			}
			else 
			{
				sbPointsPanel.Text = String.Format(Translation.GetTranslation("statusPanelPoints"), CurrentArmy.PointsTotal, CurrentArmy.MaxPoints);

				if (CurrentArmy.PointsTotal>CurrentArmy.MaxPoints)
				{
					sbPointsPanel.Color = Color.Red;
				}
				else
				{
					sbPointsPanel.ResetColor();
				}
			}
		}

		private void redoMenu_Click(object sender, EventArgs e)
		{
			if (sender is MenuItem)
			{
				MenuItem mi = (MenuItem)sender;

				if (mi.Parent == redoMenu)
				{
					//we know it's an redo menu item so find it's index and redo everything					
					int max = mi.Index;

					for (int i = 0; i <= max; i++)
					{
						commandStack.Redo();
					}
				}
			}
		}

		private void undoMenu_Click(object sender, EventArgs e)
		{
			if (sender is MenuItem)
			{
				MenuItem mi = (MenuItem)sender;

				if (mi.Parent == undoMenu)
				{
					//we know it's an undo menu item so find it's index and undo everything
					int max = mi.Index;
					for (int i = 0; i <= max; i++)
					{
						commandStack.Undo();
					}
				}
			}
		}

		private void statusBar_DrawItem(object sender, System.Windows.Forms.StatusBarDrawItemEventArgs sbdevent)
		{
			statusBar.ColorableStatusBarDrawItem(sender, sbdevent);
		}

		private void miDebugWindow_Click(object sender, EventArgs e)
		{
			if (debugWindow == null || debugWindow.IsDisposed)
			{
				debugWindow = new FrmDebugOutput();
			}

			debugWindow.Show();
			debugWindow.Focus();
		}

		private void FrmMain_Closing(object sender, CancelEventArgs e)
		{
			if (!closeCurrentArmy())
			{
				e.Cancel = true;
			}
		}

		private void miReloadFiles_Click(object sender, System.EventArgs e)
		{
			Factory.LoadAllGameSystems();
			sbMainPanel.Text = Translation.GetTranslation("GameSystemFilesReloaded", "Game system and race files reloaded");
			statusBarTimer.Enabled = true;
		}

		private void statusBarTimer_Tick(object sender, System.EventArgs e)
		{
			sbMainPanel.Text = "";
			statusBarTimer.Enabled = false;
		}

		private void statusBar_PanelClick(object sender, StatusBarPanelClickEventArgs e)
		{
			if (e.StatusBarPanel == sbErrorPanel && sbErrorPanel.Text!="")
			{
				MessageBox.Show(this, sbErrorPanel.TagString, Translation.GetTranslation("FailedRequirementMessage"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
			}
		}
	}
}