using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using everdrive3x.Hardware;
using everdrive3x.Rom;

namespace everdrive3x
{
    public partial class Form1 : Form
    {

        ToolBox tool_box;
        Dump dump;
        Prog prog;
        delegate void consoleDlg(String str);
        delegate void lockInterfaceDlg(bool state, bool lock_stop);
        delegate void stateUpdateDlg(int percent, String speed, String time, String traffic);
        

        public Form1()
        {
            InitializeComponent();
            dump = new Dump(this);
            prog = new Prog(this);
            tool_box = new ToolBox(this);
            Text = "everdrie v"+ Application.ProductVersion;
            comboBox_dump_size.SelectedItem = "auto";
            addToConsole("everdrive program tool v" + Application.ProductVersion + " (c)2009 Igor Golubovskiy");
            addToConsole("homepage: http://krikzz.com");
            comboBox_region_sega.SelectedItem = "default";
            openFileDialog_hex.Filter = "hex files (*.hex)|*.hex|All files (*.*)|*.*";
            saveFileDialog_hex.Filter = "hex files (*.hex)|*.hex";
            openFileDialog1.Filter = "All files (*.*)|*.*|SEGA (*.bin;*.smd;*.gen)|*.bin;*.smd;*.gen|N64 (*.v64;*.z64;*.rom)|*.v64;*.z64;*.rom|SNES (*.smc)|*.smc";
            lockInterface(false);
                        
        }

       

        public void addToConsole(String str)
        {
            if (IsDisposed) return;
            if (richTextBox_console.InvokeRequired)
            {
                this.Invoke(new consoleDlg(addToConsole), new object[] { str });
            }
            else
            {
                if (str.Length > 64) str = str.Substring(0, 64);
                richTextBox_console.AppendText(str + "\r\n");
            }
        }

        private void richTextBox_console_TextChanged(object sender, EventArgs e)
        {
            richTextBox_console.ScrollToCaret();
        }


        public void lockInterface(bool state)
        {
            lockInterface(state, !state);
        }

        public void lockInterface(bool state, bool stop_state)
        {
            if (IsDisposed) return;
            if (comboBox_region_sega.InvokeRequired)
            {
                this.Invoke(new lockInterfaceDlg(lockInterface), new object[] { state, stop_state });
            }
            else
            {
                state = !state;
                stop_state = !stop_state;
                button_detect.Enabled = state;
                button_dump.Enabled = state;
                button_prog.Enabled = state;
                button_stop.Enabled = stop_state;
                comboBox_region_sega.Enabled = state;
                comboBox_dump_size.Enabled = state;
                button_clean.Enabled = state;
                button_read_header.Enabled = state;
                button_read_eeprom.Enabled = state;
                button_clean_console.Enabled = state;
                button_erase_flash.Enabled = state;
                button_reset_device.Enabled = state;
                button_read_firmware.Enabled = state;
                button_update_firmware.Enabled = state;
            }
            
            
        }

        private void button_stop_Click(object sender, EventArgs e)
        {
            dump.stop();
            prog.stop();
            lockInterface(false);
            progressBar1.Value = 0;
        }

        public void stateUpdate(int progress, String speed, String time, String traffic)
        {
            if (IsDisposed) return;
            if (progressBar1.InvokeRequired)
            {
                this.Invoke(new stateUpdateDlg(stateUpdate), new object[] { progress, speed, time, traffic });
            }
            else
            {
                progressBar1.Value = progress;
                textBox_speed.Text = speed;
                textBox_time.Text = time;
                textBox_traf.Text = traffic;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

            dump.stop();
            prog.stop();
            dump = null;
            prog = null;
            
         }

        private void button_dump_Click(object sender, EventArgs e)
        {
            try
            {
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    String size = (String)comboBox_dump_size.SelectedItem;
                    if (size == null) size = (String)comboBox_dump_size.Text;
                    dump.start(saveFileDialog1.FileName, size);
                }
            }
            catch (Exception x)
            {
                addToConsole("ERROR: " + x);
            }

        }

        private void button_prog_Click(object sender, EventArgs e)
        {
            try
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    prog.start(openFileDialog1.FileName);
                }
            }
            catch (Exception x)
            {
                addToConsole("ERROR: " + x);
            }
        }




        private void button_clean_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(tool_box.cleadPort);
            t.Start();
        }

        private void button_read_header_Click(object sender, EventArgs e)
        {
           Thread t = new Thread(tool_box.readHeader);
           t.Start();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(tool_box.detectDevice);
            t.Start();
        }

        private void button_clean_console_Click(object sender, EventArgs e)
        {
            richTextBox_console.Text = "";
        }

        private void button_read_eeprom_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(tool_box.readEeprom);
            t.Start();
        }

        private void button_erase_flash_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(tool_box.eraseFlash);
            t.Start();
        }

        private void button_reset_device_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(tool_box.resetDevice);
            t.Start();
        }

        private void button_update_firmware_Click(object sender, EventArgs e)
        {

            if (openFileDialog_hex.ShowDialog() == DialogResult.OK)
            {
                Thread t = new Thread(tool_box.updateFirmware);
                t.Start();
            }

        }

        private void button_read_firmware_Click(object sender, EventArgs e)
        {

            if (saveFileDialog_hex.ShowDialog() == DialogResult.OK)
            {
                Thread t = new Thread(tool_box.readFirmware);
                t.Start();
            }
        }

        
    }
}
