using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using battle;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization.Formatters.Binary;

namespace Battlefield_Simulator_2019
{
    public partial class BattleField : Form
    {
        classBattleField battlefield;
        classBattle cLibBattle;
        classMapEditor cLibMapEditor;
        Random rnd = new Random();
        const int intVerticalOffset = 35;
        System.Windows.Forms.Timer tmrSizechange = new Timer();
        Label[] lblRedInvasionDirLabels;
        int intRedLaunchDirIndex;
        string[] strRedUnits = new string[classBattle.intMaxInvasionForce];
        string[] strBlueUnits = new string[classBattle.intMaxInvasionForce];
        Timer tmrLaunchDelay = new Timer();
        bool bolInit = false;
        System.Windows.Forms.Timer tmrIntro = new System.Windows.Forms.Timer();
        PictureBox picIntro = new PictureBox();
        string[] strMapFilenames;
        
        public class classReorderUnits
        {
            public string strUnitDescription;
            public int intValue;
        }

        public BattleField()
        {
            InitializeComponent();
            cLibBattle = new classBattle(this);
            SizeChanged += new EventHandler(BattleField_SizeChanged);
            tmrSizechange.Interval = 5;
            tmrSizechange.Tick += new EventHandler(tmrSizechange_Tick);

            btnBL_Go.Click += new EventHandler(btnBL_Go_Click);

            cmbLB_MapsAvailable.SelectedIndexChanged += new EventHandler(cmbLB_MapsAvailable_SelectedIndexChanged);
            lstLB_Units_Blue.Click += new EventHandler(lstLB_Units_Blue_Click);
            lstLB_Units_Red.Click += new EventHandler(lstLB_Units_Red_Click);

            LaunchBattle();
            tmrSizechange.Enabled = true;
            tmrLaunchDelay.Tick += new EventHandler(tmrLaunchDelay_Tick);
            tmrLaunchDelay.Interval = 1000;
            Activated += new EventHandler(BattleField_Activated);
            grbLaunchBattle.MouseEnter += new EventHandler(grbLaunchBattle_MouseEnter);
            cmbLB_MapsAvailable.GotFocus += new EventHandler(cmbLB_MapsAvailable_GotFocus);

            tmrIntro.Interval = 4000;
            tmrIntro.Tick += new EventHandler(tmrIntro_Tick);
            picIntro.Image = Battlefield_Simulator_2019.Resources.BattleField_Intro;
            picIntro.SizeMode = PictureBoxSizeMode.AutoSize;
            Controls.Add(picIntro);
            picIntro.BringToFront();
        }

        void cmbLB_MapsAvailable_GotFocus(object sender, EventArgs e) { testNeedToRebuildCmbLB_Maps(); }
        void grbLaunchBattle_MouseEnter(object sender, EventArgs e) { testNeedToRebuildCmbLB_Maps(); }

        void tmrIntro_Tick(object sender, EventArgs e)
        {
            tmrIntro.Enabled = false;
            picIntro.Visible = false;
        }

        void BattleField_Activated(object sender, EventArgs e)
        {
            if (!bolInit)
            {
                bolInit = true;
                Width = Screen.PrimaryScreen.WorkingArea.Width;
                Height = Screen.PrimaryScreen.WorkingArea.Height;
                Top = 0; Left = 0;
                Controls.Add(picIntro);
                picIntro.Top = (Height - picIntro.Height) / 2;
                picIntro.Left = (Width - picIntro.Width) / 2;
                picIntro.Visible = true;
                picIntro.BringToFront();
                tmrIntro.Enabled = true;

                mnuLoad_Click();
            }
        }

        
        void tmrSizechange_Tick(object sender, EventArgs e)
        {
            tmrSizechange.Enabled = false;
            Resize();
        }

        void BattleField_SizeChanged(object sender, EventArgs e) { tmrSizechange.Enabled = true; }

        void Resize()
        {
          // pnlLB_Map_Container.Visible = false;
            if (battlefield != null && !grbLaunchBattle.Visible)
            {
                battlefield.Width = Width;
                battlefield.Height = Height - intVerticalOffset;
                battlefield.Left = 0;
                battlefield.Top = 0;
                battlefield.displayMap(true);
            }
            pnlBattleContainer.Top = intVerticalOffset;
            pnlBattleContainer.Height = Height - intVerticalOffset;
            pnlBattleContainer.Left = 0;
            pnlBattleContainer.Width = Width;

            if (grbLaunchBattle.Visible)
            {
                
                grbLaunchBattle.Left = 5; grbLaunchBattle.Width = Width - 15;
                grbLaunchBattle.Top = intVerticalOffset; grbLaunchBattle.Height = Height - grbLaunchBattle.Top - intVerticalOffset;

                grbLB_Map.Top = lstLB_Units_Red.Top = lstLB_Units_Blue.Top = 15;
                lstLB_Units_Blue.Left = 5;
                lstLB_Units_Blue.Height = lstLB_Units_Red.Height = grbLaunchBattle.Height - grbLB_Units_Blue_Control.Height - 10;
                lstLB_Units_Red.Left = grbLaunchBattle.Width - lstLB_Units_Red.Width - 10;

                grbLB_Map.Left = lstLB_Units_Blue.Left + lstLB_Units_Blue.Width;
                grbLB_Map.Width = lstLB_Units_Red.Left - lstLB_Units_Blue.Left - lstLB_Units_Blue.Width ;
                grbLB_Map.Height = lstLB_Units_Blue.Height - 5;

                cmbLB_MapsAvailable.Left = 5; cmbLB_MapsAvailable.Top = 15;
                cmbLB_MapsAvailable.Width = grbLB_Map.Width - 10;

                pnlLB_Map_Container.Top = cmbLB_MapsAvailable.Top + cmbLB_MapsAvailable.Height + 5;
                pnlLB_Map_Container.Height = grbLB_Map.Height  - pnlLB_Map_Container.Top;
                pnlLB_Map_Container.Left = 5; pnlLB_Map_Container.Width = grbLB_Map.Width - 15;
             
                if (battlefield != null)
                {
                    battlefield.Left = 0; battlefield.Top = 0;
                    battlefield.Width = pnlLB_Map_Container.Width;
                    battlefield.Height = pnlLB_Map_Container.Height;
                }

                grbLB_Units_Blue_Control.Left = 5;
                grbLB_Units_Red_Control.Left = grbLaunchBattle.Width - grbLB_Units_Red_Control.Width - 15;
                grbLB_Units_Red_Control.Top = grbLB_Units_Blue_Control.Top = lstLB_Units_Blue.Top + lstLB_Units_Blue.Height + 5;

                btnBL_Go.Left = grbLB_Map.Left;
                btnBL_Go.Width = grbLB_Map.Width;
                btnBL_Go.Height = grbLB_Units_Blue_Control.Height;
                btnBL_Go.Top = grbLB_Units_Blue_Control.Top;

                grbLB_RedInvasionDirection.Top = grbLB_Units_Red_Control.Top;
                grbLB_RedInvasionDirection.Width = grbLB_Units_Red_Control.Width;
                grbLB_RedInvasionDirection.Left = grbLB_Units_Red_Control.Left - grbLB_RedInvasionDirection.Width;
                grbLB_RedInvasionDirection.Height = grbLB_Units_Red_Control.Height;
                resetInvasionDirectionControlLabels();
            }
        }

        private void resetInvasionDirectionControlLabels()
        {
            Point udrCenter = new Point();
            udrCenter.X = grbLB_RedInvasionDirection.Width / 2;
            udrCenter.Y = (grbLB_RedInvasionDirection.Height / 2)+5;

            double dblXRadius = udrCenter.X * .7;
            double dblYRadius = udrCenter.Y * .7;


            for (classBattle.enuInitialUnitLocDirIndices dirCounter = 0; dirCounter < classBattle.enuInitialUnitLocDirIndices._num_RedInitialLocIndices; dirCounter++)
            {
                double dblAngle = (double)dirCounter / 8.0 * Math.PI * 2.0;
                Point udrAbsLoc = new Point();
                udrAbsLoc.X = (int)(dblXRadius * Math.Sin(dblAngle));
                udrAbsLoc.Y = -(int)(dblYRadius * Math.Cos(dblAngle));
                lblRedInvasionDirLabels[(int)dirCounter].Top = (int)(udrCenter.Y + udrAbsLoc.Y - (double)lblRedInvasionDirLabels[(int)dirCounter].Height / 2.0);
                lblRedInvasionDirLabels[(int)dirCounter].Left = (int)(udrCenter.X + udrAbsLoc.X - (double)lblRedInvasionDirLabels[(int)dirCounter].Width / 2.0);
            }
        }

        private void mnuFile_Quit_Click(object sender, EventArgs e) { Dispose(); }

        private void mnuMapEditor_Click(object sender, EventArgs e)
        {
            if (cLibMapEditor != null)
            {
                cLibMapEditor.Visible = false;
                cLibMapEditor.formEditControls.Visible = false;
                cLibMapEditor.formEditControls.Dispose();
                cLibMapEditor.Dispose();
            }

            cLibMapEditor = new classMapEditor(cLibBattle, this);
            cLibMapEditor.Visible = true;
        }

        private void mnuLoad_Click()
        {
            string strCurrentDirectory = System.IO.Directory.GetCurrentDirectory();

            string[] strMapFilenames = System.IO.Directory.GetFiles(strCurrentDirectory, "*.map");

            cmbLB_MapsAvailable.Items.Clear();
            foreach (string strFilename in strMapFilenames)
                cmbLB_MapsAvailable.Items.Add(strFilename.Substring(0, strFilename.Length - ".map".Length).Replace(strCurrentDirectory + "\\", ""));

            rdbLB_Units_Blue_Control_Computer.Checked = true;
            rdbLB_Units_Red_Control_Player.Checked = true;

            grbLaunchBattle.Visible = true;
            Resize();
        }

        void addRedUnits(ref classBattleField battlefield)
        {
            classBattleUnit[] units = new classBattleUnit[classBattle.intMaxInvasionForce];

            for (int intUnitCounter = 0; intUnitCounter < lstLB_Units_Blue.Items.Count; intUnitCounter++)
            {
                try
                {
                    int intCutChr = lstLB_Units_Red.Items[intUnitCounter].ToString().IndexOf(",");
                    string strType = lstLB_Units_Red.Items[intUnitCounter].ToString().Substring(0, intCutChr).Trim();
                    string strRank = lstLB_Units_Red.Items[intUnitCounter].ToString().Substring(intCutChr + 1).Trim();

                    classBattle.enuUnitRanks unitRank = cLibBattle.getRankFromString(strRank);
                    classBattle.enuUnitTypes unitType = cLibBattle.getTypeFromString(strType);
                    units[intUnitCounter] = new classBattleUnit(unitType, classBattle.enuUnitColors.red, unitRank);
                }
                catch (Exception) { }
            }
            classBattle.enuInitialUnitLocDirIndices dirInvasion;
            if (true)
                dirInvasion = (classBattle.enuInitialUnitLocDirIndices)intRedLaunchDirIndex;
            else
                dirInvasion = (classBattle.enuInitialUnitLocDirIndices)((int)(rnd.NextDouble() * (int)classBattle.enuInitialUnitLocDirIndices._num_RedInitialLocIndices));

            battlefield.addUnitsToBattleGround(ref units, dirInvasion);
        }

        void addBlueUnits(ref classBattleField battlefield)
        {
            classBattleUnit[] units = new classBattleUnit[classBattle.intMaxInvasionForce];
            for (int intUnitCounter = 0; intUnitCounter < lstLB_Units_Blue.Items.Count; intUnitCounter++)
            {
                try
                {
                    int intCutChr = lstLB_Units_Blue.Items[intUnitCounter].ToString().IndexOf(",");
                    string strType = lstLB_Units_Blue.Items[intUnitCounter].ToString().Substring(0, intCutChr).Trim();
                    string strRank = lstLB_Units_Blue.Items[intUnitCounter].ToString().Substring(intCutChr + 1).Trim();

                    classBattle.enuUnitRanks unitRank = cLibBattle.getRankFromString(strRank);
                    classBattle.enuUnitTypes unitType = cLibBattle.getTypeFromString(strType);
                    units[intUnitCounter] = new classBattleUnit(unitType, classBattle.enuUnitColors.blue, unitRank);
                }
                catch (Exception) { }
            }
            battlefield.addUnitsToBattleGround(ref units);
        }

        private void mnuLaunchBattle_Click(object sender, EventArgs e) { LaunchBattle(); }

        public void testNeedToRebuildCmbLB_Maps()
        {
            string strCurrentDirectory = System.IO.Directory.GetCurrentDirectory();
            bool bolNeedToRebuildCmb = false;
            if (strMapFilenames == null)
            {
                strMapFilenames = System.IO.Directory.GetFiles(strCurrentDirectory, "*.map");
                bolNeedToRebuildCmb = true;
            }
            else
            {
                string[] strMapFilenames_Temp = System.IO.Directory.GetFiles(strCurrentDirectory, "*.map");
                if (strMapFilenames.Length != strMapFilenames_Temp.Length)
                {
                    strMapFilenames = strMapFilenames_Temp;
                    bolNeedToRebuildCmb = true;
                }
                else
                {
                    for (int intFilenameCounter = 0; intFilenameCounter < strMapFilenames.Length; intFilenameCounter++)
                        if (strMapFilenames[intFilenameCounter].CompareTo(strMapFilenames_Temp[intFilenameCounter]) != 0)
                        {
                            strMapFilenames = strMapFilenames_Temp;
                            bolNeedToRebuildCmb = true;
                        }
                }
            }

            if (bolNeedToRebuildCmb)
            {
                cmbLB_MapsAvailable.Items.Clear();
                foreach (string strFilename in strMapFilenames)
                    cmbLB_MapsAvailable.Items.Add(strFilename.Substring(0, strFilename.Length - ".map".Length).Replace(strCurrentDirectory + "\\", ""));
            }
        }

        private void LaunchBattle()
        {
            if (battlefield != null)
            {
                if (battlefield.Unit_Q[0] != null && battlefield.Unit_Q[0] != null)
                {
                    if (MessageBox.Show("Quit current battle?", "Are you sure?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        battlefield.killBattle();
                        battlefield.Visible = false;
                        battlefield = new classBattleField(cLibBattle, this);
                    }
                    else
                        return;
                }
                else
                {
                    battlefield.killBattle();
                    battlefield.Visible = false;
                    battlefield = new classBattleField(cLibBattle, this);
                }
            }
            else
                battlefield = new classBattleField(cLibBattle, this);

            battlefield.intMapGridSize = 29;

           
            testNeedToRebuildCmbLB_Maps();
            if (lstLB_Units_Blue.Items.Count <= 0 && lstLB_Units_Red.Items.Count <= 0)
            {
                classBattle.enuUnitTypes[] unittypes = { 
                                                           classBattle.enuUnitTypes.artillery,
                                                           classBattle.enuUnitTypes.artillery,
                                                           classBattle.enuUnitTypes.infantry,
                                                           classBattle.enuUnitTypes.infantry,
                                                           classBattle.enuUnitTypes.infantry,
                                                           classBattle.enuUnitTypes.infantry,
                                                           classBattle.enuUnitTypes.infantry,
                                                           classBattle.enuUnitTypes.cavalry,
                                                           classBattle.enuUnitTypes.cavalry,
                                                           classBattle.enuUnitTypes.cavalry
                                                       };

                classBattle.enuUnitRanks[] unitranks = {
                                                           classBattle.enuUnitRanks.captain,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant,
                                                           classBattle.enuUnitRanks.lieutenant
                                                       };
              
                for (int intUnitCounter = 0; intUnitCounter < classBattle.intMaxInvasionForce; intUnitCounter++)
                {
                    strBlueUnits[intUnitCounter] = unittypes[intUnitCounter].ToString() + ", " + unitranks[intUnitCounter].ToString();
                    strRedUnits[intUnitCounter] = unittypes[intUnitCounter].ToString() + ", " + unitranks[intUnitCounter].ToString();
                }

                reorderUnits(ref strBlueUnits);
                reorderUnits(ref strRedUnits);

                setLstUnits(ref lstLB_Units_Blue, strBlueUnits);
                setLstUnits(ref lstLB_Units_Red, strRedUnits);
            }

            grbLB_RedInvasionDirection.Width = grbLB_Units_Red_Control.Width;
            grbLB_RedInvasionDirection.Text = "Dir";
            grbLB_RedInvasionDirection.BackColor = Color.White;
            grbLB_RedInvasionDirection.Width = 80;
            grbLB_RedInvasionDirection.Height = grbLB_RedInvasionDirection.Width + 15;
            if (lblRedInvasionDirLabels == null)
            {
                lblRedInvasionDirLabels = new Label[(int)classBattle.enuInitialUnitLocDirIndices._num_RedInitialLocIndices];
                for (classBattle.enuInitialUnitLocDirIndices dirCounter = 0; dirCounter < classBattle.enuInitialUnitLocDirIndices._num_RedInitialLocIndices; dirCounter++)
                {
                    classDirLabel dirLabel = new classDirLabel();
                    grbLB_RedInvasionDirection.Controls.Add(dirLabel);
                    dirLabel.Visible = true;
                    dirLabel.AutoSize = true;
                    dirLabel.myDir = dirCounter;
                    dirLabel.Text = dirCounter.ToString().Replace("Red_", "");

                    dirLabel.BackColor = Color.Red;
                    dirLabel.Click += new EventHandler(dirLabel_Click);
                    dirLabel.MouseEnter += new EventHandler(dirLabel_MouseEnter);
                    dirLabel.MouseLeave += new EventHandler(dirLabel_MouseLeave);
                    lblRedInvasionDirLabels[(int)dirCounter] = dirLabel;
                }
            }

            resetInvasionDirectionControlLabels();
            if (cmbLB_MapsAvailable.Items.Count >0)
            cmbLB_MapsAvailable.SelectedIndex = 0;
            grbLaunchBattle.Visible = true;
            grbLaunchBattle.BringToFront();
            Resize();
        }

        void dirLabel_MouseLeave(object sender, EventArgs e)
        {  
            classDirLabel thisDirLabel = (classDirLabel)sender;
            if (thisDirLabel.myDir == (classBattle.enuInitialUnitLocDirIndices)intRedLaunchDirIndex)
            {
                thisDirLabel.BackColor = Color.Black;
                thisDirLabel.ForeColor = Color.Red;
            }
            else
            {
                thisDirLabel.BackColor = Color.Red;
                thisDirLabel.ForeColor = Color.Black;
            }  
        }

        void dirLabel_MouseEnter(object sender, EventArgs e)
        {
            classDirLabel thisDirLabel = (classDirLabel)sender;
            thisDirLabel.BackColor = Color.Black;
            thisDirLabel.ForeColor = Color.Purple;
        }

        void dirLabel_Click(object sender, EventArgs e)
        {
            lblRedInvasionDirLabels[intRedLaunchDirIndex].BackColor = Color.Red;
            lblRedInvasionDirLabels[intRedLaunchDirIndex].ForeColor = Color.Black;
            classDirLabel thisDirLabel = (classDirLabel)sender;
            intRedLaunchDirIndex = (int)thisDirLabel.myDir;
        }

        void cmbLB_MapsAvailable_SelectedIndexChanged(object sender, EventArgs e)
        {
            string strFilename = cmbLB_MapsAvailable.SelectedItem .ToString() + ".map";
            string strCurrentDirectory = System.IO.Directory.GetCurrentDirectory();
            string strFileAndDirectory = strCurrentDirectory + "\\" + strFilename;

            if (File.Exists(strFileAndDirectory))
            {
                battlefield.loadBattleField(strFilename);
                pnlLB_Map_Container.Controls.Add(battlefield);
                battlefield.btnDebug.Visible = false;
                battlefield.btnEndTurn.Visible = false;
                battlefield.Visible = true;
            }
        }

        void btnBL_Go_Click(object sender, EventArgs e)
        {
            battlefield.Control_Blue = (rdbLB_Units_Blue_Control_Computer.Checked == true)
                                           ? classBattle.enuColorControlledBy.computer
                                           : classBattle.enuColorControlledBy.player;

            battlefield.Control_Red = (rdbLB_Units_Red_Control_Computer.Checked == true)
                                           ? classBattle.enuColorControlledBy.computer
                                           : classBattle.enuColorControlledBy.player;

            addBlueUnits(ref battlefield);
            addRedUnits(ref battlefield);

            pnlBattleContainer.Controls.Add(battlefield);
           

            grbLaunchBattle.Visible = false;
            battlefield.intMapGridSize = 55;
            Resize();
            battlefield.setScrollBarLocations();
            battlefield.displayMap();
            battlefield.PlaceMap();
            
            tmrLaunchDelay.Enabled = true;
        }
        void tmrLaunchDelay_Tick(object sender, EventArgs e)
        {
            tmrLaunchDelay.Enabled = false;
            battlefield.launchBattle();            
        }
        
        //void copyLstToStringArray(ListBox lstBox, ref string[] strText)
        //{
        //    for (int intItemCounter = 0; intItemCounter < lstBox.Items.Count; intItemCounter++)
        //    {
        //        try { strText[intItemCounter] = lstBox.Items[intItemCounter].ToString(); }
        //        catch (Exception) { }
        //    }
        //}

        void lstLB_Units_Red_Click(object sender, EventArgs e)
        {
            //string[] strText = new string[lstLB_Units_Red.Items.Count];
            //copyLstToStringArray(lstLB_Units_Red, ref strText);
            int intSelectedIndex = lstLB_Units_Red.SelectedIndex;
            if ((intSelectedIndex < classBattle.intMaxInvasionForce && intSelectedIndex >= 0)
                || (intSelectedIndex<0 && lstLB_Units_Red.Items.Count < classBattle.intMaxInvasionForce))
            {
                editUnit(ref strRedUnits, intSelectedIndex);
                setLstUnits(ref lstLB_Units_Red, strRedUnits);
            }
        }

        void lstLB_Units_Blue_Click(object sender, EventArgs e)
        {
            //string[] strText = new string[lstLB_Units_Blue.Items.Count];
            //copyLstToStringArray(lstLB_Units_Red, ref strText);
            int intSelectedIndex = lstLB_Units_Blue.SelectedIndex;
            if ((intSelectedIndex < classBattle.intMaxInvasionForce && intSelectedIndex >= 0)
                || (intSelectedIndex < 0 && lstLB_Units_Blue.Items.Count < classBattle.intMaxInvasionForce))
            {
                editUnit(ref strBlueUnits, intSelectedIndex);
                setLstUnits(ref lstLB_Units_Blue, strBlueUnits);
            }
        }

        void setLstUnits(ref ListBox lstBox, string[] strText)
        {
            lstBox.Items.Clear();
            for (int intItemCounter = 0; intItemCounter < strText.Length; intItemCounter++)
                lstBox.Items.Add(strText[intItemCounter]);
        }

        void reorderUnits(ref string[] strText)
        {
            classReorderUnits[] udrUnits = new classReorderUnits[strText.Length];
            for (int intUnitCounter = 0; intUnitCounter < strText.Length; intUnitCounter++)
            {
                int intCutChr = strText[intUnitCounter].IndexOf(",");
                string strType = strText[intUnitCounter].Substring(0, intCutChr).Trim();
                string strRank = strText[intUnitCounter].Substring(intCutChr+1).Trim();
                udrUnits[intUnitCounter] = new classReorderUnits();
                udrUnits[intUnitCounter].strUnitDescription = strText[intUnitCounter];
                udrUnits[intUnitCounter].intValue = 100 * (int)cLibBattle.getTypeFromString(strType) + (int)cLibBattle.getRankFromString(strRank);
            }

            classReorderUnits udrTemp = new classReorderUnits();
            for (int intOuterLoop = 0; intOuterLoop < udrUnits.Length - 1; intOuterLoop++)
            {
                int intBestIndex = intOuterLoop;
                for (int intInnerLoop = intOuterLoop + 1; intInnerLoop < udrUnits.Length; intInnerLoop++)
                {
                    if (udrUnits[intInnerLoop].intValue > udrUnits[intBestIndex].intValue)
                        intBestIndex = intInnerLoop;
                }
                if (intOuterLoop != intBestIndex)
                {
                    udrTemp = udrUnits[intOuterLoop];
                    udrUnits[intOuterLoop] = udrUnits[intBestIndex];
                    udrUnits[intBestIndex] = udrTemp;
                }
            }

            for (int intUnitCounter = 0; intUnitCounter < udrUnits.Length; intUnitCounter++)
                strText[intUnitCounter] = udrUnits[intUnitCounter].strUnitDescription;
        }

        void editUnit(ref string[] strText, int intSelectedIndex)
        {
        startEditUnit:
            string[] strUnitTypes = new string[(int)classBattle.enuUnitTypes._num_UnitTypes];
            for (classBattle.enuUnitTypes unitType = (classBattle.enuUnitTypes)0; unitType < classBattle.enuUnitTypes._num_UnitTypes; unitType++)
                strUnitTypes[(int)unitType] = unitType.ToString();

            string[] strUnitRanks = new string[(int)classBattle.enuUnitRanks._numUnitRanks];
            for (classBattle.enuUnitRanks unitType = (classBattle.enuUnitRanks)0; unitType < classBattle.enuUnitRanks._numUnitRanks; unitType++)
                strUnitRanks[(int)unitType] = unitType.ToString();

            string strType = "", strRank = "";

            bool bolEdit = (intSelectedIndex < strText.Length && intSelectedIndex >=0);

            if (bolEdit)
            {
                string[] strEditDeleteButtons = {"Edit", "Delete", "Cancel" };
                using (classMessageBox msgBoxEditOrDelete = new classMessageBox("Edit :" + strText[intSelectedIndex],
                                                       "Do you want to edit or delete this unit?",
                                                       strEditDeleteButtons))
                {
                    int intMinWidth = 300;
                    msgBoxEditOrDelete.Owner = this;
                    msgBoxEditOrDelete.Width = (msgBoxEditOrDelete.Width < intMinWidth ? intMinWidth : msgBoxEditOrDelete.Width);
                    msgBoxEditOrDelete.ShowDialog();

                    switch (msgBoxEditOrDelete.Reply)
                    {
                        case "Delete":
                            for (int intUnitcounter = intSelectedIndex; intUnitcounter < strText.Length - 1; intUnitcounter++)
                                strText[intUnitcounter] = strText[intUnitcounter + 1];
                            Array.Resize<string>(ref strText, strText.Length - 1);
                        goto endEditUnit;

                        case "Cancel":
                        goto endEditUnit;
                    }
                }
            }

            using (classMessageBox msgBoxTypeUnit = new classMessageBox("current : " + (bolEdit ? strText[intSelectedIndex] : "new unit"),
                                                         "What type for this unit?",
                                                         strUnitTypes))
            {
                int intMinWidth = 300;
                msgBoxTypeUnit.Owner = this;
                msgBoxTypeUnit.Width = (msgBoxTypeUnit.Width < intMinWidth ? intMinWidth : msgBoxTypeUnit.Width);
                msgBoxTypeUnit.ShowDialog();

                strType = msgBoxTypeUnit.Reply;
            }

            using (classMessageBox msgBoxRankUnit = new classMessageBox("current : " + (bolEdit ? strText[intSelectedIndex] : "new unit"),
                                                                     "What Rank for this unit?",
                                                                     strUnitRanks))
            {
                int intMinWidth = 400;
                msgBoxRankUnit.Owner = this;
                msgBoxRankUnit.Width = (msgBoxRankUnit.Width < intMinWidth ? intMinWidth : msgBoxRankUnit.Width);
                msgBoxRankUnit.ShowDialog();

                strRank = msgBoxRankUnit.Reply;
            }

            if (cLibBattle.getTypeFromString(strType) != classBattle.enuUnitTypes._num_UnitTypes 
                && cLibBattle.getRankFromString(strRank) != classBattle.enuUnitRanks ._numUnitRanks)
            {

                string strNewUnitDescription = strType + ", " + strRank;
                string strMsgText = "", strMsgTitle = "";
                string[] strConfirmButtons = { "Yes", "No", "Cancel" };

                if (bolEdit)
                {
                    strMsgText = "Do you want to edit " + strText[intSelectedIndex] + " to " + strNewUnitDescription + "?";
                    strMsgTitle = "Edit Unit";
                }
                else
                {
                    strMsgText = "Do you want to create a new unit " + strNewUnitDescription + "?";
                    strMsgTitle = "Create new unit";
                }

                string strConfirmReply = "";
                using (classMessageBox msgBoxConfirm = new classMessageBox(strMsgTitle, strMsgText, strConfirmButtons))
                {
                    int intMinWidth = 300;
                    msgBoxConfirm.Owner = this;
                    msgBoxConfirm.Width = msgBoxConfirm.Width < intMinWidth ? intMinWidth : msgBoxConfirm.Width;
                    msgBoxConfirm.ShowDialog();
                    strConfirmReply = msgBoxConfirm.Reply;
                }

                switch (strConfirmReply.ToUpper())
                {
                    case "YES":
                        if (bolEdit)
                        {
                            strText[intSelectedIndex] = strNewUnitDescription;
                            goto endEditUnit;
                        }
                        else
                        {
                            Array.Resize<string>(ref strText, strText.Length + 1);
                            strText[strText.Length - 1] = strNewUnitDescription;
                            goto endEditUnit;
                        }

                    case "NO":
                        goto startEditUnit;

                    case "CANCEL":
                        // exit function
                        break;

                }
            }

        endEditUnit:
            reorderUnits(ref strText);
        }

        //private void InitializeComponent()
        //{
        //    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BattleField));
        //    this.SuspendLayout();
        //    // 
        //    // BattleField
        //    // 
        //    this.ClientSize = new System.Drawing.Size(284, 261);
        //    this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
        //    this.Name = "BattleField";
        //    this.ResumeLayout(false);

        //}
    }
}
