using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace VBoxDebugMgr
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            ReloadVMList();
        }

        void ReloadVMList()
        {
            try
            {
                listView1.Items.Clear();
                var vbox = new VirtualBox.VirtualBox();
                foreach (VirtualBox.IMachine machine in vbox.Machines)
                {
                    AddVM(machine);
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void AddVM(VirtualBox.IMachine machine)
        {
            var item = listView1.Items.Add(machine.Name);
            int port;
            bool dbg = IsDebuggerEnabled(machine, out port);
            if (dbg)
                item.SubItems.Add(port.ToString());
            else
                item.SubItems.Add("disabled");
            item.SubItems.Add(machine.SettingsFilePath);
            item.Tag = machine;
        }

        void UpdateCurrentVM()
        {
            if (listView1.SelectedItems.Count < 1)
                return;
            var machine = listView1.SelectedItems[0].Tag as VirtualBox.IMachine;
            if (machine == null)
                return;
            int port;
            bool dbg = IsDebuggerEnabled(machine, out port);
            if (dbg)
                listView1.SelectedItems[0].SubItems[1].Text = port.ToString();
            else
                listView1.SelectedItems[0].SubItems[1].Text = "disabled";
        }


        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            numericUpDown1.Enabled = checkBox1.Checked;
            var machine = SelectedMachine;
            if (!_IgnoreDbgChange && machine != null)
            {
                try
                {
                    machine.SetExtraData("VBoxInternal/DBGC/Enabled", checkBox1.Checked ? "1" : "0");
                    if (checkBox1.Checked)
                        machine.SetExtraData("VBoxInternal/DBGC/Port", numericUpDown1.Value.ToString());
                    UpdateCurrentVM();
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        VirtualBox.IMachine SelectedMachine
        {
            get
            {
                if (listView1.SelectedItems.Count < 1)
                    return null;
                return listView1.SelectedItems[0].Tag as VirtualBox.IMachine;
            }
        }

        bool IsDebuggerEnabled(VirtualBox.IMachine machine, out int port)
        {
            string str = machine.GetExtraData(@"VBoxInternal/DBGC/Port");
            int.TryParse(str, out port);
            str = machine.GetExtraData(@"VBoxInternal/DBGC/Enabled");
            return str == "1";
        }

        bool _IgnoreDbgChange;

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var machine = SelectedMachine;
            if (machine == null)
                return;
            int port;
            try
            {
                _IgnoreDbgChange = true;
                checkBox1.Checked = IsDebuggerEnabled(machine, out port);
                if (port == 0)
                    port = 7000;
                numericUpDown1.Value = port;
            }
            finally
            {
                _IgnoreDbgChange = false;
            }
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            var machine = SelectedMachine;
            if (!_IgnoreDbgChange && machine != null)
            {
                try
                {
                    machine.SetExtraData("VBoxInternal/DBGC/Port", numericUpDown1.Value.ToString());
                    UpdateCurrentVM();
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ReloadVMList();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    var vbox = new VirtualBox.VirtualBox();
                    var vm = vbox.OpenMachine(openFileDialog1.FileName);
                    AddVM(vm);
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
    }
}
