using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Media;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.BZip2;
using System.Drawing.Imaging;

namespace WTD_Editor
{
    public partial class Form1 : Form
    {
        string version = "0.5";
        Map map;
        bool refresh;
        SoundPlayer splay;

        public Form1()
        {
            InitializeComponent();

            this.Text = this.Text + " v" + version;

            // new map
            map = new Map();
            map.version = version;

            /** set limits & init lists **/

            // misc infos
            textBox53.MaxLength = Map.AUTHOR_NAME_MAX;
            textBox54.MaxLength = Map.CONTACT_MAX;
            textBox55.MaxLength = Map.VERSION;

            // map tab
            textBox1.MaxLength = Map.MAP_NAME_MAX - 1;
            textBox2.MaxLength = Map.WELCOME_MAX - 1;
            textBox3.MaxLength = Map.PRESENTATION_MAX - 1;

            // round tab
            textBox15.MaxLength = Map.COMMENTS_MAX - 1;
            string[] mps_type = Enum.GetNames(typeof(Map.MPS_METHOD));
            comboBox18.DataSource = mps_type;
            string[] m_sr = Enum.GetNames(typeof(Map.SR));
            comboBox13.DataSource = m_sr;

            // monster tab
            textBox28.MaxLength = Map.NAME_MAX - 1;
            numericUpDown1.Maximum = 1;
            numericUpDown1.Minimum = 1;
            string[] imm_type = Enum.GetNames(typeof(Map.IMM));
            comboBox10.DataSource = imm_type;
            string[] anim_speeds = Enum.GetNames(typeof(Map.MA_SPEED));
            comboBox3.DataSource = anim_speeds;
            string[] walk_speeds = Enum.GetNames(typeof(Map.W_SPEED));
            comboBox2.DataSource = walk_speeds;
            comboBox12.DataSource = Map.MONSTERS_NAMES;
            string[] m_pals = Enum.GetNames(typeof(Map.M_PAL));
            comboBox14.DataSource = m_pals;

            // tower tab
            textBox43.MaxLength = Map.NAME_MAX - 1;
            textBox44.MaxLength = Map.DESC_MAX - 1;
            numericUpDown2.Maximum = 1;
            numericUpDown2.Minimum = 1;
            string[] att_type = Enum.GetNames(typeof(Map.ATTACKS));
            comboBox4.DataSource = att_type;
            comboBox5.DataSource = Map.SOUNDS_NAMES;
            string[] att_speed = Enum.GetNames(typeof(Map.A_SPEED));
            comboBox6.DataSource = att_speed;
            string[] att_range = Enum.GetNames(typeof(Map.A_RANGE));
            comboBox7.DataSource = att_range;
            string[] att_reload = Enum.GetNames(typeof(Map.A_RELOAD));
            comboBox8.DataSource = att_reload;
            string[] att_sp = Enum.GetNames(typeof(Map.SP));
            comboBox11.DataSource = att_sp;
            List<int> t_min_evo = new List<int>();
            for (int i = 0; i < Map.EVOLUTIONS_MAX; i++)
                t_min_evo.Add(i+1);
            comboBox9.DataSource = t_min_evo;

            // clan tab
            textBox45.MaxLength = Map.NAME_MAX - 1;
            textBox46.MaxLength = Map.INFO_MAX - 1;

            // evolution tab
            textBox47.MaxLength = Map.NAME_MAX - 1;
            textBox49.MaxLength = Map.INFO_MAX - 1;
            List<int> e_min_rnd = new List<int>();
            for (int i = 0; i < Map.ROUNDS_MAX; i++)
                e_min_rnd.Add(i + 1);
            comboBox16.DataSource = e_min_rnd;

            // refresh everything
            refreshAll();
            refresh = true;
        }

        private void refreshAll()
        {
            refreshValues();
            refreshProperties();
            refreshMonster();
            refreshTower();
            refreshRound();
            refreshClan();
            refreshEvolution();
            refreshDesign();
        }

        private void refreshProperties()
        {
            // properties tab
            textBox1.Text = map.name;
            textBox2.Text = map.welcome;
            textBox3.Text = map.presentation;
            checkBox1.Checked = map.simple_presentation;
            textBox5.Text = map.map_Width.ToString();
            textBox4.Text = map.map_Height.ToString();
            textBox6.Text = map.minimap_x_adjust.ToString();
            textBox7.Text = map.minimap_y_adjust.ToString();
            textBox8.Text = map.spawn_x.ToString();
            textBox9.Text = map.spawn_y.ToString();
            textBox10.Text = map.gold_start.ToString();
            textBox11.Text = map.lifes.ToString();
            textBox12.Text = map.sell_pct.ToString();
            textBox13.Text = map.max_towers_start.ToString();
            textBox14.Text = map.init_delay.ToString();
            checkBox3.Checked = map.timed_gold;
            textBox34.Text = map.initial_bonus.ToString();
            textBox33.Text = map.start_y.ToString();
            textBox17.Text = map.start_x.ToString();
            textBox53.Text = map.author;
            textBox54.Text = map.contact;
            textBox55.Text = map.map_version;
            checkBox9.Checked = map.w3_damage_style;
            checkBox12.Checked = map.use_fast_pathfinder;

            // other map options
            switch (map.minimap_colors)
            {
                case 0:
                    radioButton1.Checked = true;
                    break;
                case 1:
                    radioButton2.Checked = true;
                    break;
                case 2:
                    radioButton3.Checked = true;
                    break;
                case 3:
                    radioButton4.Checked = true;
                    break;
                default:
                    break;
            }
        }

        private void refreshMonster()
        {
            if (tabControl1.SelectedTab == tabPage4)
            {
                textBox21.Text = map.monsters.Count.ToString();
                if (listBox3.SelectedIndex >= 0 && map.monsters.Count > 0)
                {
                    if (!groupBox5.Visible)
                        groupBox5.Show();
                    groupBox5.Text = "Monster " + (listBox3.SelectedIndex + 1).ToString();

                    Monster mons = map.monsters[listBox3.SelectedIndex];
                    refresh = false;
                    textBox28.Text = mons.name;
                    checkBox2.Checked = mons.invisible;
                    checkBox10.Checked = mons.ghost;

                    if (mons.size == 1)
                        checkBox11.Checked = false;
                    else
                        checkBox11.Checked = true;

                    textBox26.Text = mons.gold_bonus.ToString();
                    textBox27.Text = mons.life.ToString();
                    textBox29.Text = mons.armor.ToString();
                    textBox25.Text = mons.immunes.Count.ToString();
                    comboBox12.SelectedIndex = mons.type;
                    comboBox14.Text = Enum.GetName(typeof(Map.M_PAL), mons.pal);
                    comboBox3.Text = Enum.GetName(typeof(Map.MA_SPEED), mons.anim_speed);
                    comboBox2.Text = Enum.GetName(typeof(Map.W_SPEED), mons.speed);
                    refresh = true;
                    pictureBox1.Image = Map.MONSTERS_GFX[mons.type];
                    pictureBox1.Location = new Point(0, -32);
                    switch (mons.pal)
                    {
                        case (int)Map.M_PAL.RED:
                            pictureBox1.Image.Palette = WTD_Editor.Properties.Resources.m_peon.Palette;
                            break;

                        case (int)Map.M_PAL.BLUE:
                            pictureBox1.Image.Palette = WTD_Editor.Properties.Resources.m_blue.Palette;
                            break;

                        case (int)Map.M_PAL.BLACK:
                            pictureBox1.Image.Palette = WTD_Editor.Properties.Resources.m_dark.Palette;
                            break;

                        case (int)Map.M_PAL.GREEN:
                            pictureBox1.Image.Palette = WTD_Editor.Properties.Resources.m_green.Palette;
                            break;
                    }

                    // immunes
                    if (mons.immunes.Count > 0)
                    {
                        refresh = false;
                        comboBox10.Enabled = true;
                        label35.Text = "Imm param1 :";
                        label36.Text = "Imm param2 :";
                        label37.Text = "Imm param3 :";
                        label60.Enabled = true;
                        label35.Enabled = false;
                        label36.Enabled = false;
                        label37.Enabled = false;
                        textBox30.Enabled = false;
                        textBox31.Enabled = false;
                        textBox32.Enabled = false;
                        numericUpDown1.Enabled = true;
                        numericUpDown1.Maximum = mons.immunes.Count;
                        if (numericUpDown1.Value < 1 || numericUpDown1.Value > mons.immunes.Count)
                            numericUpDown1.Value = 1;
                        comboBox10.Text = Enum.GetName(typeof(Map.IMM), mons.immunes[(int)numericUpDown1.Value - 1].type);
                        textBox30.Text = mons.immunes[(int)numericUpDown1.Value - 1].param1.ToString();
                        textBox31.Text = mons.immunes[(int)numericUpDown1.Value - 1].param2.ToString();
                        textBox32.Text = mons.immunes[(int)numericUpDown1.Value - 1].param3.ToString();
                        refresh = true;

                        switch (mons.immunes[(int)numericUpDown1.Value - 1].type)
                        {
                            case (int)Map.IMM.SLOW:
                                label35.Text = "Effect time malus (ms) :";
                                label36.Text = "Move delay malus (vbl) :";
                                label37.Text = "Effect delay bonus (vbl) :";
                                label35.Enabled = true;
                                label36.Enabled = true;
                                label37.Enabled = true;
                                textBox30.Enabled = true;
                                textBox31.Enabled = true;
                                textBox32.Enabled = true;
                                break;

                            case (int)Map.IMM.POISON:
                                label35.Text = "Effect time malus (ms) :";
                                label36.Text = "Poison resistance :";
                                label35.Enabled = true;
                                label36.Enabled = true;
                                textBox30.Enabled = true;
                                textBox31.Enabled = true;
                                break;

                            case (int)Map.IMM.FIRE:
                                label35.Text = "Fire resistance :";
                                label35.Enabled = true;
                                textBox30.Enabled = true;
                                break;

                            case (int)Map.IMM.WATER:
                                label35.Text = "Water resistance :";
                                label35.Enabled = true;
                                textBox30.Enabled = true;
                                break;

                            case (int)Map.IMM.LIGHTNING:
                                label35.Text = "Lightning resistance :";
                                label35.Enabled = true;
                                textBox30.Enabled = true;
                                break;

                            case (int)Map.IMM.WIND:
                                label35.Text = "Wind resistance :";
                                label35.Enabled = true;
                                textBox30.Enabled = true;
                                break;

                            case (int)Map.IMM.IM_NORMAL:
                                break;

                            case (int)Map.IMM.IM_PIERCE:
                                break;

                            case (int)Map.IMM.IM_MAGIC:
                                break;
                        }
                    }
                    else
                    {
                        label60.Enabled = false;
                        label35.Enabled = false;
                        label36.Enabled = false;
                        label37.Enabled = false;
                        comboBox10.Enabled = false;
                        textBox30.Enabled = false;
                        textBox31.Enabled = false;
                        textBox32.Enabled = false;
                        numericUpDown1.Enabled = false;
                    }

                }
                else
                {
                    groupBox5.Hide();
                }
            }

            // build
            checkBuild();
        }

        private void refreshTower()
        {
            if (tabControl1.SelectedTab == tabPage5)
            {
                textBox22.Text = map.towers.Count.ToString();
                if (listBox4.SelectedIndex >= 0 && map.towers.Count > 0)
                {
                    if (!groupBox7.Visible)
                        groupBox7.Show();
                    groupBox7.Text = "Tower " + (listBox4.SelectedIndex + 1).ToString();

                    Tower tow = map.towers[listBox4.SelectedIndex];
                    textBox43.Text = tow.name;
                    refresh = false;
                    comboBox9.SelectedIndex = tow.evo_min;
                    textBox44.Text = tow.desc;
                    checkBox4.Checked = tow.air;
                    checkBox5.Checked = tow.ground;
                    textBox42.Text = tow.price.ToString();
                    textBox41.Text = tow.min_damage.ToString();
                    textBox40.Text = tow.max_damage.ToString();
                    comboBox8.Text = tow.reload.ToString();
                    comboBox7.Text = tow.range.ToString();
                    comboBox6.Text = Enum.GetName(typeof(Map.A_SPEED), tow.speed);
                    comboBox4.SelectedIndex = tow.attack_type;
                    comboBox5.SelectedIndex = tow.sound;
                    textBox39.Text = tow.specials.Count.ToString();
                    refresh = true;

                    pictureBox3.Image = WTD_Editor.Properties.Resources.icons;
                    pictureBox3.Location = new Point(0, -16 * tow.icon_idx);

                    switch (tow.pal)
                    {
                        case (int)Map.T_PAL.NORMAL:
                            pictureBox2.Image = WTD_Editor.Properties.Resources.t_all_normal;
                            break;
//                        case (int)Map.T_PAL.DARK:
//                            pictureBox2.Image = WTD_Editor.Properties.Resources.t_all_dark;
//                            break;
                        case (int)Map.T_PAL.FROZEN:
                            pictureBox2.Image = WTD_Editor.Properties.Resources.t_all_frozen;
                            break;
                        case (int)Map.T_PAL.POISON:
                            pictureBox2.Image = WTD_Editor.Properties.Resources.t_all_poison;
                            break;
                    }
                    pictureBox2.Location = new Point(0, -32 * tow.gfx_idx);
                    pictureBox4.Image = Map.ATTACKS_GFX[tow.attack_type];

                    // special effects
                    if (tow.specials.Count > 0)
                    {
                        refresh = false;
                        comboBox11.Enabled = true;
                        label44.Text = "Sp param1 :";
                        label42.Text = "Sp param2 :";
                        label41.Text = "Sp param3 :";
                        label61.Enabled = true;
                        label44.Enabled = false;
                        label42.Enabled = false;
                        label41.Enabled = false;
                        textBox38.Enabled = false;
                        textBox37.Enabled = false;
                        textBox36.Enabled = false;
                        numericUpDown2.Enabled = true;
                        numericUpDown2.Maximum = tow.specials.Count;
                        if (numericUpDown2.Value < 1 || numericUpDown2.Value > tow.specials.Count)
                            numericUpDown2.Value = 1;
                        comboBox11.Text = Enum.GetName(typeof(Map.SP), tow.specials[(int)numericUpDown2.Value - 1].type);
                        textBox38.Text = tow.specials[(int)numericUpDown2.Value - 1].param1.ToString();
                        textBox37.Text = tow.specials[(int)numericUpDown2.Value - 1].param2.ToString();
                        textBox36.Text = tow.specials[(int)numericUpDown2.Value - 1].param3.ToString();
                        refresh = true;

                        switch (tow.specials[(int)numericUpDown2.Value - 1].type)
                        {
                            case (int)Map.SP.ADD_MAX_TOWERS:
                                label44.Text = "Max towers bonus :";
                                label44.Enabled = true;
                                textBox38.Enabled = true;
                                break;

                            case (int)Map.SP.SLOW:
                                label44.Text = "Effect time (ms) :";
                                label42.Text = "Move delay (vbl) :";
                                label41.Text = "Effect delay (vbl) :";
                                label44.Enabled = true;
                                label42.Enabled = true;
                                label41.Enabled = true;
                                textBox38.Enabled = true;
                                textBox37.Enabled = true;
                                textBox36.Enabled = true;
                                break;

                            case (int)Map.SP.POISON:
                                label44.Text = "Effect time (ms) :";
                                label42.Text = "Min. damage :";
                                label41.Text = "Max. damage :";
                                label44.Enabled = true;
                                label42.Enabled = true;
                                label41.Enabled = true;
                                textBox38.Enabled = true;
                                textBox37.Enabled = true;
                                textBox36.Enabled = true;
                                break;

                            case (int)Map.SP.CRITIC:
                                label44.Text = "% chance of dbl damage :";
                                label44.Enabled = true;
                                textBox38.Enabled = true;
                                break;

                            case (int)Map.SP.PIERCE:
                                label44.Text = "Armor malus :";
                                label44.Enabled = true;
                                textBox38.Enabled = true;
                                break;
                            
                            case (int)Map.SP.FIRE:
                                label44.Text = "Min. damage :";
                                label42.Text = "Max. damage :";
                                label44.Enabled = true;
                                label42.Enabled = true;
                                textBox38.Enabled = true;
                                textBox37.Enabled = true;
                                break;

                            case (int)Map.SP.WATER:
                                label44.Text = "Min. damage :";
                                label42.Text = "Max. damage :";
                                label44.Enabled = true;
                                label42.Enabled = true;
                                textBox38.Enabled = true;
                                textBox37.Enabled = true;
                                break;

                            case (int)Map.SP.LIGHTNING:
                                label44.Text = "Min. damage :";
                                label42.Text = "Max. damage :";
                                label44.Enabled = true;
                                label42.Enabled = true;
                                textBox38.Enabled = true;
                                textBox37.Enabled = true;
                                break;

                            case (int)Map.SP.WIND:
                                label44.Text = "Min. damage :";
                                label42.Text = "Max. damage :";
                                label44.Enabled = true;
                                label42.Enabled = true;
                                textBox38.Enabled = true;
                                textBox37.Enabled = true;
                                break;

                            case (int)Map.SP.SPLASH:
                                label44.Text = "Radius :";
                                label44.Enabled = true;
                                textBox38.Enabled = true;
                                break;

                            case (int)Map.SP.REVEAL:
                                label44.Text = "Radius :";
                                label44.Enabled = true;
                                textBox38.Enabled = true;
                                break;
                        }
                    }
                    else
                    {
                        label61.Enabled = false;
                        label44.Enabled = false;
                        label42.Enabled = false;
                        label41.Enabled = false;
                        comboBox11.Enabled = false;
                        textBox38.Enabled = false;
                        textBox37.Enabled = false;
                        textBox36.Enabled = false;
                        numericUpDown2.Enabled = false;
                    }
                }
                else
                {
                    groupBox7.Hide();
                }

            }

            // build
            checkBuild();
        }

        private void refreshRound()
        {
            textBox20.Text = map.rounds.Count.ToString();
            if (listBox2.SelectedIndex >= 0 && map.rounds.Count > 0)
            {
                if (!groupBox4.Visible)
                    groupBox4.Show();
                groupBox4.Text = "Round " + (listBox2.SelectedIndex + 1).ToString();
                Round rnd = map.rounds[listBox2.SelectedIndex];
                refresh = false;
                textBox15.Text = rnd.comment;
                textBox18.Text = rnd.nextround_delay.ToString();
                textBox19.Text = rnd.gold_bonus.ToString();
                comboBox1.DataSource = null;
                comboBox1.DataSource = map.monsters;
                comboBox1.SelectedIndex = map.monsters.IndexOf(rnd.type);
                textBox56.Text = map.num_paths.ToString();

                if (numericUpDown3.Value > map.num_paths || numericUpDown3.Value < 1)
                    numericUpDown3.Value = 1;

                if (numericUpDown3.Value == 1)
                {
                    textBox16.Text = rnd.number.ToString();
                    comboBox13.Text = Enum.GetName(typeof(Map.SR), rnd.spawn_rate);
                }
                else
                {
                    textBox16.Text = rnd.paths_number[(int)numericUpDown3.Value - 2].ToString();
                    comboBox13.Text = Enum.GetName(typeof(Map.SR), rnd.paths_spawn_rate[(int)numericUpDown3.Value - 2]);
                }

                comboBox18.Text = Enum.GetName(typeof(Map.MPS_METHOD), rnd.mps_method);
                refresh = true;
            }
            else
            {
                groupBox4.Hide();
            }

            // build
            if (map.waypoints.Count > 0 && map.rounds.Count > 0 && map.clans.Count > 0)
                button9.Enabled = true;
            else
                button9.Enabled = false;

            // build
            checkBuild();
        }

        private void refreshClan()
        {
            textBox23.Text = map.clans.Count.ToString();
            if (listBox6.SelectedIndex >= 0 && map.clans.Count > 0)
            {
                if (!groupBox10.Visible)
                    groupBox10.Show();
                groupBox10.Text = "Clan " + (listBox6.SelectedIndex + 1).ToString();
                Clan clan = map.clans[listBox6.SelectedIndex];
                refresh = false;
                textBox45.Text = clan.name;
                textBox46.Text = clan.info;
                pictureBox6.Image = WTD_Editor.Properties.Resources.icons;
                pictureBox6.Location = new Point(0, -16 * clan.icon_idx);
                textBox35.Text = clan.evolutions.Count.ToString();
                refresh = true;

                // evolutions
                listBox7.DataSource = null;
                listBox7.DataSource = clan.evolutions;

                List<Evolution> list_evo = new List<Evolution>(map.evolutions);
                foreach (Evolution e in clan.evolutions)
                    list_evo.Remove(e);

                if (list_evo.Count > 0)
                {
                    if (!comboBox17.Enabled)
                        comboBox17.Enabled = true;
                    comboBox17.DataSource = list_evo;
                }
                else
                {
                    comboBox17.SelectedIndex = -1;
                    comboBox17.Enabled = false;
                }
            }
            else
            {
                groupBox10.Hide();
            }

            // build
            checkBuild();
        }

        private void refreshEvolution()
        {
            textBox24.Text = map.evolutions.Count.ToString();
            if (listBox5.SelectedIndex >= 0 && map.evolutions.Count > 0)
            {
                if (!groupBox12.Visible)
                    groupBox12.Show();
                groupBox12.Text = "Evolution " + (listBox5.SelectedIndex + 1).ToString();
                Evolution evo = map.evolutions[listBox5.SelectedIndex];

                refresh = false;
                textBox47.Text = evo.name;
                textBox49.Text = evo.info;
                textBox50.Text = evo.price.ToString();
                textBox51.Text = evo.max_towers.ToString();
                comboBox16.SelectedIndex = evo.min_round;
                pictureBox7.Image = WTD_Editor.Properties.Resources.icons;
                pictureBox7.Location = new Point(0, -16 * evo.icon_idx);
                pictureBox8.Image = WTD_Editor.Properties.Resources.icons;
                pictureBox8.Location = new Point(0, -16 * evo.build_icon_idx);
                textBox48.Text = evo.towers.Count.ToString();
                refresh = true;

                // towers
                listBox8.DataSource = null;
                listBox8.DataSource = evo.towers;

                List<Tower> list_tow = new List<Tower>(map.towers);
                foreach (Tower to in evo.towers)
                    list_tow.Remove(to);

                if (list_tow.Count > 0)
                {
                    if (!comboBox15.Enabled)
                        comboBox15.Enabled = true;
                    comboBox15.DataSource = list_tow;
                }
                else
                {
                    comboBox15.SelectedIndex = -1;
                    comboBox15.Enabled = false;
                }
            }
            else
            {
                groupBox12.Hide();
            }

            // build
            checkBuild();
        }

        private void refreshDesign()
        {
            if (map.tilemap != null)
            {
                EditMap em = new EditMap(map);
                pictureBox10.Image = em.mapbuffer;
                map.gfxmap = em.mapbuffer;

                button33.Enabled = true;
                textBox52.Text = map.tilemap.width.ToString() + "x" + map.tilemap.height.ToString();

                Bitmap minimap = new Bitmap(Map.MINIMAP_WIDTH, Map.MINIMAP_HEIGHT);
                int wdth = Map.MINIMAP_WIDTH;
                int hght = Map.MINIMAP_HEIGHT;

                if (em.mapbuffer.Width > em.mapbuffer.Height)
                {
                    float ImgRatio = (float)em.mapbuffer.Width / (float)em.mapbuffer.Height;
                    hght = (int)Math.Round((float)Map.MINIMAP_WIDTH / ImgRatio, 0);
                }
                else
                {
                    float ImgRatio = (float)em.mapbuffer.Height / (float)em.mapbuffer.Width;
                    wdth = (int)Math.Round((float)Map.MINIMAP_HEIGHT / ImgRatio, 0);
                }

                Graphics gfx = Graphics.FromImage(minimap);
                gfx.FillRectangle(new SolidBrush(Color.FromArgb(255, 0, 0, 0)), new Rectangle(0, 0, Map.MINIMAP_WIDTH, Map.MINIMAP_HEIGHT));

                int x_offset = (Map.MINIMAP_WIDTH - wdth) / 2;
                int y_offset = (Map.MINIMAP_HEIGHT - hght) / 2;
                gfx.DrawImage(em.mapbuffer, new Rectangle(x_offset, y_offset, Map.MINIMAP_WIDTH - 2 * x_offset, Map.MINIMAP_HEIGHT - 2 * y_offset), new Rectangle(0, 0, em.mapbuffer.Width, em.mapbuffer.Height), GraphicsUnit.Pixel);
                gfx.Dispose();

                // reduce minimap colors to 256
                OctreeQuantizer quantizer = new OctreeQuantizer(255, 8);
                Bitmap q_minimap = quantizer.Quantize(minimap);
                minimap.Dispose();

                pictureBox9.Image = q_minimap;
                map.minimap = q_minimap;
                em.Dispose();

                if (x_offset < 0) x_offset = 0;
                if (y_offset < 0) y_offset = 0;

                map.minimap_x_adjust = x_offset;
                map.minimap_y_adjust = y_offset;
                map.map_Width = map.tilemap.width;
                map.map_Height = map.tilemap.height;

                if (map.waypoints.Count > 0)
                {
                    map.spawn_x = map.waypoints[0].x;
                    map.spawn_y = map.waypoints[0].y;
                }
            }
            else
            {
                textBox52.Text = "";
                if (pictureBox10.Image != null)
                    pictureBox10.Image = null;

                if (pictureBox9.Image != null)
                    pictureBox9.Image = null;

                button33.Enabled = false;
            }

            refreshProperties();

            // build
            checkBuild();
        }

        private void refreshValues()
        {
            /** refresh all boxes from initialized values **/

            // rounds tab
            Round.curr = 1;
            listBox2.DataSource = null;
            listBox2.DataSource = map.rounds;
            textBox20.Text = map.rounds.Count.ToString();

            // monsters tab
            listBox3.DataSource = null;
            listBox3.DataSource = map.monsters;
            textBox21.Text = map.monsters.Count.ToString();

            // towers tab
            listBox4.DataSource = null;
            listBox4.DataSource = map.towers;
            textBox22.Text = map.towers.Count.ToString();

            // clans tab
            listBox6.DataSource = null;
            listBox6.DataSource = map.clans;
            textBox23.Text = map.clans.Count.ToString();

            // evolutions tab
            listBox5.DataSource = null;
            listBox5.DataSource = map.evolutions;
            textBox24.Text = map.evolutions.Count.ToString();

            // build
            checkBuild();
        }

        private void checkBuild()
        {
            if (map.waypoints.Count > 1 && map.rounds.Count > 0 && map.clans.Count > 0 && map.tilemap != null)
                button9.Enabled = true;
            else
                button9.Enabled = false;

            if (map.tilemap == null)
                button4.Enabled = false;
            else
                button4.Enabled = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button27_Click(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            
            // tower upgrades
            Upgrades upg = new Upgrades(map, tow);
            if (upg.ShowDialog(this) == DialogResult.OK)
            {



            }
        }

        private void button22_Click(object sender, EventArgs e)
        {

        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            map.simple_presentation = checkBox1.Checked;
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {
            map.timed_gold = checkBox3.Checked;
        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox5.Text);
                if (num >= 0 && num <= Map.MAP_WIDTH_MAX)
                {
                    map.map_Width = num;
                }
                else if (num > Map.MAP_WIDTH_MAX)
                {
                    map.map_Width = Map.MAP_WIDTH_MAX;
                }
                textBox5.Text = map.map_Width.ToString();
            }
            catch(Exception)
            {
                textBox5.Text = map.map_Width.ToString();
            }
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox4.Text);
                if (num >= 0 && num <= Map.MAP_HEIGHT_MAX)
                {
                    map.map_Height = num;
                }
                else if (num > Map.MAP_HEIGHT_MAX)
                {
                    map.map_Height = Map.MAP_HEIGHT_MAX;
                }
                textBox4.Text = map.map_Height.ToString();
            }
            catch (Exception)
            {
                textBox4.Text = map.map_Height.ToString();
            }
        }

        private void textBox6_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox6.Text);
                map.minimap_x_adjust = num;
                textBox6.Text = map.minimap_x_adjust.ToString();
            }
            catch (Exception)
            {
                textBox6.Text = map.minimap_x_adjust.ToString();
            }
        }

        private void textBox7_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox7.Text);
                map.minimap_y_adjust = num;
                textBox7.Text = map.minimap_y_adjust.ToString();
            }
            catch (Exception)
            {
                textBox7.Text = map.minimap_y_adjust.ToString();
            }
        }

        private void textBox8_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox8.Text);
                if (num >= 0 && num <= Map.MAP_WIDTH_MAX)
                {
                    map.spawn_x = num;
                }
                else if (num > Map.MAP_WIDTH_MAX)
                {
                    map.spawn_x = Map.MAP_WIDTH_MAX;
                }
                textBox8.Text = map.spawn_x.ToString();
            }
            catch (Exception)
            {
                textBox8.Text = map.spawn_x.ToString();
            }
        }

        private void textBox9_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox9.Text);
                if (num >= 0 && num <= Map.MAP_HEIGHT_MAX)
                {
                    map.spawn_y = num;
                }
                else if (num > Map.MAP_HEIGHT_MAX)
                {
                    map.spawn_y = Map.MAP_HEIGHT_MAX;
                }
                textBox9.Text = map.spawn_y.ToString();
            }
            catch (Exception)
            {
                textBox9.Text = map.spawn_y.ToString();
            }
        }

        private void textBox34_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = (short)int.Parse(textBox34.Text);
                if(num >= 0)
                    map.initial_bonus = num;
                textBox34.Text = map.initial_bonus.ToString();
            }
            catch (Exception)
            {
                textBox34.Text = map.initial_bonus.ToString();
            }
        }

        private void textBox10_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = (short)int.Parse(textBox10.Text);
                if (num >= 0)
                    map.gold_start = num;
                textBox10.Text = map.gold_start.ToString();
            }
            catch (Exception)
            {
                textBox10.Text = map.gold_start.ToString();
            }
        }

        private void textBox11_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = (short)int.Parse(textBox11.Text);
                if (num >= 0)
                    map.lifes = num;
                textBox11.Text = map.lifes.ToString();
            }
            catch (Exception)
            {
                textBox11.Text = map.lifes.ToString();
            }
        }

        private void textBox12_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox12.Text);
                if (num >= 0 && num <= 100)
                {
                    map.sell_pct = num;
                }
                else if (num > 100)
                {
                    map.sell_pct = 100;
                }
                textBox12.Text = map.sell_pct.ToString();
            }
            catch (Exception)
            {
                textBox12.Text = map.sell_pct.ToString();
            }
        }

        private void textBox13_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox13.Text);
                if (num >= 0 && num <= Map.TOWERS_INST_MAX)
                {
                    map.max_towers_start = num;
                }
                else if (num > Map.TOWERS_INST_MAX)
                {
                    map.max_towers_start = Map.TOWERS_INST_MAX;
                }
                textBox13.Text = map.max_towers_start.ToString();
            }
            catch (Exception)
            {
                textBox13.Text = map.max_towers_start.ToString();
            }
        }

        private void textBox14_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = (short)int.Parse(textBox14.Text);
                if (num >= 0)
                    map.init_delay = num;
                textBox14.Text = map.init_delay.ToString();
            }
            catch (Exception)
            {
                textBox14.Text = map.init_delay.ToString();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            saveFileMap.ShowDialog();
        }

        private void button9_Click(object sender, EventArgs e)
        {
            saveFileBuild.ShowDialog();
        }

        private void saveFileMap_FileOk(object sender, CancelEventArgs e)
        {
            Stream File;
            if ((File = saveFileMap.OpenFile()) != null)
            {
                // Prepare objects
                map.fillIndexes();
                map.version = version;

                //Save
                BinaryWriter Writer = null;
                MemoryStream str = new MemoryStream();

                try
                {
                    System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(map.GetType());
                    xml.Serialize(str, map);
                    Writer = new BinaryWriter(File);
                    Writer.Write(str.ToArray());
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
                finally
                {
                    if (Writer != null)
                        Writer.Close();
                    if (File != null)
                        File.Close();
                }
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            map.name = textBox1.Text;
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (textBox2.Lines.GetLength(0) <= Map.LINES_WELCOME)
            {
                map.welcome = textBox2.Text;
            }
            else
            {
                textBox2.Text = map.welcome;
            }
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            if (textBox3.Lines.GetLength(0) <= Map.LINES_PRESENTATION)
            {
                map.presentation = textBox3.Text;
            }
            else
            {
                textBox3.Text = map.presentation;
            }
        }

        private void button11_Click(object sender, EventArgs e)
        {
            if (map.monsters.Count < Map.MONSTERS_MAX)
            {
                Monster mons = new Monster();
                mons.name = "Monster " + (map.monsters.Count + 1).ToString();
                map.monsters.Insert(listBox3.SelectedIndex + 1, mons);
                int sel = listBox3.SelectedIndex + 1;
                refresh = false;
                listBox3.DataSource = null;
                listBox3.DataSource = map.monsters;
                refresh = true;
                listBox3.SelectedIndex = sel;
            }
        }

        private void button10_Click(object sender, EventArgs e)
        {
            if (map.monsters.Count > 0 && listBox3.SelectedIndex >= 0)
            {
                Monster mons = map.monsters[listBox3.SelectedIndex];
                if (mons.usedby > 0)
                {
                    MessageBox.Show(this, "Cannot delete this monster !\nDelete the round that use it before.", "Error");
                }
                else
                {
                    map.monsters.RemoveAt(listBox3.SelectedIndex);
                    listBox3.DataSource = null;
                    listBox3.DataSource = map.monsters;
                    listBox3.SelectedIndex = -1;
                }
            }
        }

        private void listBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(refresh)
                refreshMonster();
        }

        private void textBox28_TextChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            mons.name = textBox28.Text;
            int sel = listBox3.SelectedIndex;
            refresh = false;
            listBox3.DataSource = null;
            listBox3.DataSource = map.monsters;
            refresh = true;
            listBox3.SelectedIndex = sel;

        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            mons.invisible = checkBox2.Checked;
        }

        private void openFileLoad_FileOk(object sender, CancelEventArgs e)
        {
            Stream File;
            TextReader reader = null;
            if ((File = openFileLoad.OpenFile()) != null)
            {
                // Load
                MemoryStream str = new MemoryStream();

                try
                {
                    MemoryStream zip = new MemoryStream();
                    FileInfo fi = new FileInfo(openFileLoad.FileName);
                    if (fi.Extension == ".tdm")
                    {
                        BinaryReader rd = new BinaryReader(File);

                        // check for header
/*                        char[] header = rd.ReadChars(Map.MAP_HEADER_SIZE);
                        if (new String(header) == Map.MAP_HEADER_V3)
                        {
                            // skip the rest of header + map name
                            rd.ReadBytes(8 + Map.MAP_NAME_MAX);
                            // skip built map size
                            int msize = rd.ReadInt32();
                            rd.ReadBytes(msize - Map.MAP_NAME_MAX - Map.MAP_FULL_HEADER_SIZE);
                        }
                        else*/
                        {
//                            File.Seek(0, SeekOrigin.Begin);
                            // skip map name
                            rd.ReadBytes(Map.MAP_NAME_MAX);
                            // skip built map size
                            int msize = rd.ReadInt32();
                            // skip built map
                            rd.ReadBytes(msize - Map.MAP_NAME_MAX);
                        }

                        BZip2InputStream zinput = new BZip2InputStream(rd.BaseStream);
                        MemoryStream mxml = new MemoryStream();

//                        ZipEntry entry = zinput.GetNextEntry();
//                        if (entry != null && entry.Name == "map.xml")
                        {
                            // decompress map
                            int size = 2048;
                            byte[] data = new byte[size];

                            while ((size = zinput.Read(data, 0, data.Length)) > 0)
                            {
                                mxml.Write(data, 0, size);
                            }
                            mxml.Flush();
                            mxml.Position = 0L;
                            reader = new StreamReader(mxml);
                        }
/*                        else
                        {
                            MessageBox.Show("Error, file corrupted.");
                            if (reader != null)
                                reader.Close();
                            if (File != null)
                                File.Close();
                            return;
                        }*/
                    }
                    else
                    {
                        reader = new StreamReader(File);
                    }

                    System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(map.GetType());
                    map = (Map)xml.Deserialize(reader);

                    // replace special characters
                    map.welcome = map.welcome.Replace("\n", "\r\n");
                    map.presentation = map.presentation.Replace("\n", "\r\n");

                    foreach (Tower tow in map.towers)
                    {
                        tow.desc = tow.desc.Replace("\n", "\r\n");
                        tow.upgrades.Clear();
                        foreach (int u in tow.upgrades_idx)
                            tow.upgrades.Add(map.towers[u]);
                    }

                    foreach (Round rnd in map.rounds)
                    {
                        rnd.comment = rnd.comment.Replace("\n", "\r\n");
                        rnd.type = map.monsters[rnd.type_idx];
                    }

                    foreach (Clan cln in map.clans)
                    {
                        cln.info = cln.info.Replace("\n", "\r\n");
                        cln.evolutions.Clear();
                        foreach (int ee in cln.evolutions_idx)
                            cln.evolutions.Add(map.evolutions[ee]);
                    }

                    foreach (Evolution evo in map.evolutions)
                    {
                        evo.info = evo.info.Replace("\n", "\r\n");
                        evo.towers.Clear();
                        foreach (int t in evo.towers_idx)
                            evo.towers.Add(map.towers[t]);
                    }

                    refreshAll();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
                finally
                {
                    if (reader != null)
                        reader.Close();
                    if (File != null)
                        File.Close();
                }
            }
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            openFileLoad.ShowDialog();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(this, "Unsaved data will be lost.\nSure ?", "Confirm new map", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                map = new Map();
                refreshAll();
            }
        }

        private void button18_Click(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            if (mons.immunes.Count < Map.IMMUNE_MAX)
            {
                Monster.Immune imm = new Monster.Immune();
                if (mons.immunes.Count > 0 && numericUpDown1.Value >= 1)
                {
                    mons.immunes.Insert((int)numericUpDown1.Value, imm);
                    numericUpDown1.Maximum++;
                    refresh = false;
                    numericUpDown1.Value++;
                    refresh = true;
                }
                else
                {
                    mons.immunes.Add(imm);
                    refresh = false;
                    numericUpDown1.Value = mons.immunes.Count;
                    refresh = true;
                }
                refreshMonster();
            }
        }

        private void comboBox10_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox3.SelectedIndex >= 0 && refresh)
            {
                Monster mons = map.monsters[listBox3.SelectedIndex];
                Monster.Immune imm = mons.immunes[(int)numericUpDown1.Value - 1];
                imm.type = (int)Enum.Parse(typeof(Map.IMM), comboBox10.Text);
                imm.param1 = 0;
                imm.param2 = 0;
                imm.param3 = 0;
                refreshMonster();
            }
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            if (refresh)
                 refreshMonster();
        }

        private void textBox26_TextChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox26.Text);
                if (num >= 0)
                    mons.gold_bonus = num;
                textBox26.Text = mons.gold_bonus.ToString();
            }
            catch (Exception)
            {
                textBox26.Text = mons.gold_bonus.ToString();
            }
        }

        private void textBox21_TextChanged(object sender, EventArgs e)
        {

        }

        private void button20_Click(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            if (mons.immunes.Count > 0 && (numericUpDown1.Value >= 1 && numericUpDown1.Value <= mons.immunes.Count))
            {
                if (mons.immunes.Count > 1)
                {
                    mons.immunes.RemoveAt((int)numericUpDown1.Value-1);
                    refresh = false;
                    if((int)numericUpDown1.Value != 1)
                        numericUpDown1.Value--;
                    refresh = true;
                    numericUpDown1.Maximum--;
                }
                else
                {
                    mons.immunes.RemoveAt((int)numericUpDown1.Value-1);
                }
                refreshMonster();
            }
        }

        private void textBox30_TextChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            Monster.Immune imm = mons.immunes[(int)numericUpDown1.Value - 1];
            try
            {
                int num = (short)int.Parse(textBox30.Text);
                if (num >= 0)
                    imm.param1 = num;
                textBox30.Text = imm.param1.ToString();
            }
            catch (Exception)
            {
                textBox30.Text = imm.param1.ToString();
            }
        }

        private void textBox31_TextChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            Monster.Immune imm = mons.immunes[(int)numericUpDown1.Value - 1];
            try
            {
                int num = (short)int.Parse(textBox31.Text);
                if (num >= 0)
                    imm.param2 = num;
                textBox31.Text = imm.param2.ToString();
            }
            catch (Exception)
            {
                textBox31.Text = imm.param2.ToString();
            }
        }

        private void textBox32_TextChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            Monster.Immune imm = mons.immunes[(int)numericUpDown1.Value - 1];
            try
            {
                int num = (short)int.Parse(textBox32.Text);
                if (num >= 0)
                    imm.param3 = num;
                textBox32.Text = imm.param3.ToString();
            }
            catch (Exception)
            {
                textBox32.Text = imm.param3.ToString();
            }
        }

        private void textBox27_TextChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            try
            {
                int num = int.Parse(textBox27.Text);
                if (num >= 0)
                    mons.life = num;
                textBox27.Text = mons.life.ToString();
            }
            catch (Exception)
            {
                textBox27.Text = mons.life.ToString();
            }
        }

        private void textBox29_TextChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox29.Text);
                if (num >= 0)
                    mons.armor = num;
                textBox29.Text = mons.armor.ToString();
            }
            catch (Exception)
            {
                textBox29.Text = mons.armor.ToString();
            }
        }

        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh && listBox3.SelectedIndex >= 0)
            {
                Monster mons = map.monsters[listBox3.SelectedIndex];
                mons.anim_speed = (int)Enum.Parse(typeof(Map.MA_SPEED), comboBox3.Text);
            }
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh && listBox3.SelectedIndex >= 0)
            {
                Monster mons = map.monsters[listBox3.SelectedIndex];
                mons.speed = (int)Enum.Parse(typeof(Map.W_SPEED), comboBox2.Text);
            }
        }

        private void comboBox12_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox3.SelectedIndex >= 0 && refresh)
            {
                Monster mons = map.monsters[listBox3.SelectedIndex];
                mons.type = comboBox12.SelectedIndex;
                refreshMonster();
            }
        }

        private void button23_Click(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            if (tow.specials.Count < Map.SPECIAL_MAX)
            {
                Tower.Special sp = new Tower.Special();
                if (tow.specials.Count > 0 && numericUpDown2.Value >= 1)
                {
                    tow.specials.Insert((int)numericUpDown2.Value, sp);
                    numericUpDown2.Maximum++;
                    refresh = false;
                    numericUpDown2.Value++;
                    refresh = true;
                }
                else
                {
                    tow.specials.Add(sp);
                    refresh = false;
                    numericUpDown2.Value = tow.specials.Count;
                    refresh = true;
                }
                refreshTower();
            }
        }

        private void textBox15_TextChanged(object sender, EventArgs e)
        {
            Round rnd = map.rounds[listBox2.SelectedIndex];
            if (textBox15.Lines.GetLength(0) <= Map.LINES_COMMENT)
            {
                rnd.comment = textBox15.Text;
            }
            else
            {
                textBox15.Text = rnd.comment;
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (map.rounds.Count < Map.ROUNDS_MAX)
            {
                if (map.monsters.Count == 0)
                {
                    MessageBox.Show(this, "Add at least 1 monster before\nadding rounds.", "Error");
                }
                else
                {
                    Round rnd = new Round(map.monsters[0]);
                    map.rounds.Insert(listBox2.SelectedIndex + 1, rnd);
                    int sel = listBox2.SelectedIndex + 1;
                    refresh = false;
                    Round.curr = 1;
                    listBox2.DataSource = null;
                    listBox2.DataSource = map.rounds;
                    refresh = true;
                    listBox2.SelectedIndex = sel;
                    map.monsters[map.monsters.IndexOf(rnd.type)].usedby++;
                }
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (map.rounds.Count > 0 && listBox2.SelectedIndex >= 0)
            {
                Round rnd = map.rounds[listBox2.SelectedIndex];
                map.monsters[map.monsters.IndexOf(rnd.type)].usedby--;
                map.rounds.RemoveAt(listBox2.SelectedIndex);
                Round.curr = 1;
                listBox2.DataSource = null;
                listBox2.DataSource = map.rounds;
                listBox2.SelectedIndex = -1;
            }
        }

        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
                refreshRound();
        }

        private void textBox17_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox17.Text);
                if (num >= 0 && num <= Map.MAP_WIDTH_MAX)
                {
                    map.start_x = num;
                }
                else if (num > Map.MAP_WIDTH_MAX)
                {
                    map.start_x = Map.MAP_WIDTH_MAX;
                }
                textBox17.Text = map.start_x.ToString();
            }
            catch (Exception)
            {
                textBox17.Text = map.start_x.ToString();
            }
        }

        private void textBox33_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = int.Parse(textBox33.Text);
                if (num >= 0 && num <= Map.MAP_WIDTH_MAX)
                {
                    map.start_y = num;
                }
                else if (num > Map.MAP_WIDTH_MAX)
                {
                    map.start_y = Map.MAP_WIDTH_MAX;
                }
                textBox33.Text = map.start_y.ToString();
            }
            catch (Exception)
            {
                textBox33.Text = map.start_y.ToString();
            }
        }

        private void comboBox14_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox3.SelectedIndex >= 0 && refresh)
            {
                Monster mons = map.monsters[listBox3.SelectedIndex];
                mons.pal = (int)Enum.Parse(typeof(Map.M_PAL), comboBox14.Text);
                refreshMonster();
            }
        }

        private void textBox16_TextChanged(object sender, EventArgs e)
        {
            Round rnd = map.rounds[listBox2.SelectedIndex];
            try
            {

                int num = int.Parse(textBox16.Text);
                if (num >= 0 && num <= Map.MONSTERS_SPAWN_MAX)
                {
                    if (numericUpDown3.Value == 1)
                        rnd.number = num;
                    else
                        rnd.paths_number[(int)numericUpDown3.Value - 2] = num;
                }
                else if (num > Map.MONSTERS_SPAWN_MAX)
                {
                    if (numericUpDown3.Value == 1)
                        rnd.number = Map.MONSTERS_SPAWN_MAX;
                    else
                        rnd.paths_number[(int)numericUpDown3.Value - 2] = Map.MONSTERS_SPAWN_MAX;
                }
                if (numericUpDown3.Value == 1)
                    textBox16.Text = rnd.number.ToString();
                else
                    textBox16.Text = rnd.paths_number[(int)numericUpDown3.Value - 2].ToString();
            }
            catch (Exception)
            {
                if (numericUpDown3.Value == 1)
                    textBox16.Text = rnd.number.ToString();
                else
                    textBox16.Text = rnd.paths_number[(int)numericUpDown3.Value - 2].ToString();
            }
        }

        private void textBox18_TextChanged(object sender, EventArgs e)
        {
            Round rnd = map.rounds[listBox2.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox18.Text);
                if (num >= 0)
                    rnd.nextround_delay = num;
                textBox18.Text = rnd.nextround_delay.ToString();
            }
            catch (Exception)
            {
                textBox18.Text = rnd.nextround_delay.ToString();
            }
        }

        private void comboBox13_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox2.SelectedIndex >= 0 && refresh)
            {
                Round rnd = map.rounds[listBox2.SelectedIndex];
                if (numericUpDown3.Value == 1)
                    rnd.spawn_rate = (int)Enum.Parse(typeof(Map.SR), comboBox13.Text);
                else
                    rnd.paths_spawn_rate[(int)numericUpDown3.Value - 2] = (int)Enum.Parse(typeof(Map.SR), comboBox13.Text);
                refreshRound();
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox2.SelectedIndex >= 0 && refresh && tabControl1.SelectedTab == tabPage3)
            {
                Round rnd = map.rounds[listBox2.SelectedIndex];
                map.monsters[map.monsters.IndexOf(rnd.type)].usedby--;
                rnd.type = map.monsters[comboBox1.SelectedIndex];
                map.monsters[comboBox1.SelectedIndex].usedby++;
                refreshRound();
            }
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            refreshAll();
        }

        private void button13_Click(object sender, EventArgs e)
        {
            if (map.towers.Count < Map.TOWERS_MAX)
            {
                Tower tow = new Tower();
                tow.name = "Tower " + (map.towers.Count + 1).ToString();
                map.towers.Insert(listBox4.SelectedIndex + 1, tow);
                int sel = listBox4.SelectedIndex + 1;
                refresh = false;
                listBox4.DataSource = null;
                listBox4.DataSource = map.towers;
                refresh = true;
                listBox4.SelectedIndex = sel;
            }
        }

        private void button12_Click(object sender, EventArgs e)
        {
            if (map.towers.Count > 0 && listBox4.SelectedIndex >= 0)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                if (tow.usedby > 0)
                {
                    MessageBox.Show(this, "Cannot delete this tower !\nDelete it from the upgrades or evolutions that use it before.", "Error");
                }
                else
                {
                    foreach (Tower t in tow.upgrades)
                        t.usedby--;
                    map.towers.RemoveAt(listBox4.SelectedIndex);
                    listBox4.DataSource = null;
                    listBox4.DataSource = map.towers;
                    listBox4.SelectedIndex = -1;
                }
            }
        }

        private void listBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
                refreshTower();
        }

        private void button26_Click(object sender, EventArgs e)
        {
            // choose icon
            Tower tow = map.towers[listBox4.SelectedIndex];
            ChooseIcon ci = new ChooseIcon(tow.icon_idx);
            if (ci.ShowDialog(this) == DialogResult.OK)
            {
                tow.icon_idx = ci.selected;
                refreshTower();
            }
            ci.Dispose();
        }

        private void button25_Click(object sender, EventArgs e)
        {
            // choose icon
            Tower tow = map.towers[listBox4.SelectedIndex];
            ChooseTower ct = new ChooseTower(tow.gfx_idx, tow.pal, tow.dark);
            if (ct.ShowDialog(this) == DialogResult.OK)
            {
                tow.gfx_idx = ct.selected;
                tow.pal = ct.pal;
                tow.dark = ct.dark;
                refreshTower();
            }
            ct.Dispose();
        }

        private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                tow.attack_type = comboBox4.SelectedIndex;
                pictureBox4.Image = Map.ATTACKS_GFX[tow.attack_type];
            }
        }

        private void textBox43_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            tow.name = textBox43.Text;
            int sel = listBox4.SelectedIndex;
            refresh = false;
            listBox4.DataSource = null;
            listBox4.DataSource = map.towers;
            refresh = true;
            listBox4.SelectedIndex = sel;
        }

        private void textBox44_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            if (textBox44.Lines.GetLength(0) <= Map.LINES_DESCRIPTION)
            {
                tow.desc = textBox44.Text;
            }
            else
            {
                textBox44.Text = tow.desc;
            } 
        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            tow.air = checkBox4.Checked;
        }

        private void checkBox5_CheckedChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            tow.ground = checkBox5.Checked;
        }

        private void textBox42_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox42.Text);
                if (num >= 0)
                    tow.price = num;
                textBox42.Text = tow.price.ToString();
            }
            catch (Exception)
            {
                textBox42.Text = tow.price.ToString();
            }
        }

        private void textBox41_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox41.Text);
                if (num >= 0)
                    tow.min_damage = num;
                textBox41.Text = tow.min_damage.ToString();
            }
            catch (Exception)
            {
                textBox41.Text = tow.min_damage.ToString();
            }
        }

        private void textBox40_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox40.Text);
                if (num >= 0)
                    tow.max_damage = num;
                textBox40.Text = tow.max_damage.ToString();
            }
            catch (Exception)
            {
                textBox40.Text = tow.max_damage.ToString();
            }
        }

        private void comboBox9_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                tow.evo_min = comboBox9.SelectedIndex;
            }
        }

        private void comboBox7_TextChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                try
                {
                    int num = (short)int.Parse(comboBox7.Text);
                    if (num >= 0)
                        tow.range = num;
                    comboBox7.Text = tow.range.ToString();
                }
                catch (Exception)
                {
                    comboBox7.Text = tow.range.ToString();
                }
            }
        }

        private void comboBox7_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh && comboBox7.SelectedIndex != -1)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                tow.range = (short)(int)Enum.Parse(typeof(Map.A_RANGE), comboBox7.Text);
                comboBox7.Text = tow.range.ToString();
            }
        }

        private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh && comboBox8.SelectedIndex != -1)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                tow.reload = (short)(int)Enum.Parse(typeof(Map.A_RELOAD), comboBox8.Text);
                comboBox8.Text = tow.reload.ToString();
            }
        }

        private void comboBox8_TextChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                try
                {
                    int num = (short)int.Parse(comboBox8.Text);
                    if (num >= 0)
                        tow.reload = num;
                    comboBox8.Text = tow.reload.ToString();
                }
                catch (Exception)
                {
                    comboBox8.Text = tow.reload.ToString();
                }
            }
        }

        private void comboBox5_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                tow.sound = comboBox5.SelectedIndex;
            }
        }

        private void comboBox6_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                tow.speed = (int)Enum.Parse(typeof(Map.A_SPEED), comboBox6.Text);
            }
        }

        private void button24_Click(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            if (tow.specials.Count > 0 && (numericUpDown2.Value >= 1 && numericUpDown2.Value <= tow.specials.Count))
            {
                if (tow.specials.Count > 1)
                {
                    tow.specials.RemoveAt((int)numericUpDown2.Value - 1);
                    refresh = false;
                    if ((int)numericUpDown2.Value != 1)
                        numericUpDown2.Value--;
                    refresh = true;
                    numericUpDown2.Maximum--;
                }
                else
                {
                    tow.specials.RemoveAt((int)numericUpDown2.Value - 1);
                }
                refreshTower();
            }
        }

        private void comboBox11_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox4.SelectedIndex >= 0 && refresh)
            {
                Tower tow = map.towers[listBox4.SelectedIndex];
                Tower.Special sp = tow.specials[(int)numericUpDown2.Value - 1];
                sp.type = (int)Enum.Parse(typeof(Map.SP), comboBox11.Text);
                sp.param1 = 0;
                sp.param2 = 0;
                sp.param3 = 0;
                refreshTower();
            }
        }

        private void textBox38_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            Tower.Special sp = tow.specials[(int)numericUpDown2.Value - 1];
            try
            {
                int num = (short)int.Parse(textBox38.Text);
                if (num >= 0)
                    sp.param1 = num;
                textBox38.Text = sp.param1.ToString();
            }
            catch (Exception)
            {
                textBox38.Text = sp.param1.ToString();
            }
        }

        private void textBox37_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            Tower.Special sp = tow.specials[(int)numericUpDown2.Value - 1];
            try
            {
                int num = (short)int.Parse(textBox37.Text);
                if (num >= 0)
                    sp.param2 = num;
                textBox37.Text = sp.param2.ToString();
            }
            catch (Exception)
            {
                textBox37.Text = sp.param2.ToString();
            }
        }

        private void textBox36_TextChanged(object sender, EventArgs e)
        {
            Tower tow = map.towers[listBox4.SelectedIndex];
            Tower.Special sp = tow.specials[(int)numericUpDown2.Value - 1];
            try
            {
                int num = (short)int.Parse(textBox36.Text);
                if (num >= 0)
                    sp.param3 = num;
                textBox36.Text = sp.param3.ToString();
            }
            catch (Exception)
            {
                textBox36.Text = sp.param3.ToString();
            }
        }

        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            if (refresh)
                refreshTower();
        }

        private void button17_Click(object sender, EventArgs e)
        {
            if (map.clans.Count < Map.CLANS_MAX)
            {
                Clan clan = new Clan();
                clan.name = "Clan " + (map.clans.Count + 1).ToString();
                map.clans.Insert(listBox6.SelectedIndex + 1, clan);
                int sel = listBox6.SelectedIndex + 1;
                refresh = false;
                listBox6.DataSource = null;
                listBox6.DataSource = map.clans;
                refresh = true;
                listBox6.SelectedIndex = sel;
            }
        }

        private void listBox6_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
                refreshClan();
        }

        private void button16_Click(object sender, EventArgs e)
        {
            if (map.clans.Count > 0 && listBox6.SelectedIndex >= 0)
            {
                Clan clan = map.clans[listBox6.SelectedIndex];
                map.clans.RemoveAt(listBox6.SelectedIndex);
                listBox6.DataSource = null;
                listBox6.DataSource = map.clans;
                listBox6.SelectedIndex = -1;
            }
        }

        private void textBox45_TextChanged(object sender, EventArgs e)
        {
            Clan clan = map.clans[listBox6.SelectedIndex];
            clan.name = textBox45.Text;
            int sel = listBox6.SelectedIndex;
            refresh = false;
            listBox6.DataSource = null;
            listBox6.DataSource = map.clans;
            refresh = true;
            listBox6.SelectedIndex = sel;
        }

        private void textBox46_TextChanged(object sender, EventArgs e)
        {
            Clan clan = map.clans[listBox6.SelectedIndex];
            if (textBox46.Lines.GetLength(0) <= Map.LINES_INFO)
            {
                clan.info = textBox46.Text;
            }
            else
            {
                textBox46.Text = clan.info;
            } 
        }

        private void button5_Click(object sender, EventArgs e)
        {
            Clan clan = map.clans[listBox6.SelectedIndex];
            if (comboBox17.SelectedIndex != -1 && comboBox17.Enabled && clan.evolutions.Count < Map.EVOLUTIONS_MAX)
            {
                Evolution evo = ((List<Evolution>)(comboBox17.DataSource))[comboBox17.SelectedIndex];
                evo.usedby++;
                clan.evolutions.Insert(listBox7.SelectedIndex + 1, evo);
                int sel = listBox7.SelectedIndex + 1;
                refreshClan();
                listBox7.SelectedIndex = sel;
            }
        }

        private void button19_Click(object sender, EventArgs e)
        {
            Clan clan = map.clans[listBox6.SelectedIndex];
            if (clan.evolutions.Count > 0 && listBox7.SelectedIndex >= 0)
            {
                Evolution evo = clan.evolutions[listBox7.SelectedIndex];
                evo.usedby--;
                clan.evolutions.RemoveAt(listBox7.SelectedIndex);
                refreshClan();
            }
        }

        private void button28_Click(object sender, EventArgs e)
        {
            // choose icon
            Clan clan = map.clans[listBox6.SelectedIndex];
            ChooseIcon ci = new ChooseIcon(clan.icon_idx);
            if (ci.ShowDialog(this) == DialogResult.OK)
            {
                clan.icon_idx = ci.selected;
                refreshClan();
            }
            ci.Dispose();
        }

        private void button15_Click(object sender, EventArgs e)
        {
            if (map.evolutions.Count < Map.EVOLUTIONS_MAX*Map.CLANS_MAX)
            {
                Evolution evo = new Evolution();
                evo.name = "Evolution " + (map.evolutions.Count + 1).ToString();
                map.evolutions.Insert(listBox5.SelectedIndex + 1, evo);
                int sel = listBox5.SelectedIndex + 1;
                refresh = false;
                listBox5.DataSource = null;
                listBox5.DataSource = map.evolutions;
                refresh = true;
                listBox5.SelectedIndex = sel;
                refreshClan();
            }
        }

        private void button14_Click(object sender, EventArgs e)
        {
            if (map.evolutions.Count > 0 && listBox5.SelectedIndex >= 0)
            {
                Evolution evo = map.evolutions[listBox5.SelectedIndex];
                if (evo.usedby > 0)
                {
                    MessageBox.Show(this, "Cannot delete this evolution !\nDelete it from the clan that use it before.", "Error");
                }
                else
                {
                    map.evolutions.RemoveAt(listBox5.SelectedIndex);
                    listBox5.DataSource = null;
                    listBox5.DataSource = map.evolutions;
                    listBox5.SelectedIndex = -1;
                    refreshClan();
                }
            }
        }

        private void listBox5_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
                refreshEvolution();
        }

        private void textBox47_TextChanged(object sender, EventArgs e)
        {
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            evo.name = textBox47.Text;
            int sel = listBox5.SelectedIndex;
            refresh = false;
            listBox5.DataSource = null;
            listBox5.DataSource = map.evolutions;
            refresh = true;
            listBox5.SelectedIndex = sel;
        }

        private void textBox49_TextChanged(object sender, EventArgs e)
        {
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            if (textBox49.Lines.GetLength(0) <= Map.LINES_INFO)
            {
                evo.info = textBox49.Text;
            }
            else
            {
                textBox49.Text = evo.info;
            } 
        }

        private void button29_Click(object sender, EventArgs e)
        {
            // choose icon
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            ChooseIcon ci = new ChooseIcon(evo.icon_idx);
            if (ci.ShowDialog(this) == DialogResult.OK)
            {
                evo.icon_idx = ci.selected;
                refreshEvolution();
            }
            ci.Dispose();
        }

        private void button30_Click(object sender, EventArgs e)
        {
            // choose icon
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            ChooseIcon ci = new ChooseIcon(evo.build_icon_idx);
            if (ci.ShowDialog(this) == DialogResult.OK)
            {
                evo.build_icon_idx = ci.selected;
                refreshEvolution();
            }
            ci.Dispose();
        }

        private void textBox50_TextChanged(object sender, EventArgs e)
        {
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox50.Text);
                if (num >= 0)
                    evo.price = num;
                textBox50.Text = evo.price.ToString();
            }
            catch (Exception)
            {
                textBox50.Text = evo.price.ToString();
            }
        }

        private void textBox51_TextChanged(object sender, EventArgs e)
        {
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            try
            {
                int num = (char)int.Parse(textBox51.Text);
                if (num >= 0)
                    evo.max_towers = num;
                textBox51.Text = evo.max_towers.ToString();
            }
            catch (Exception)
            {
                textBox51.Text = evo.max_towers.ToString();
            }
        }

        private void comboBox16_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                Evolution evo = map.evolutions[listBox5.SelectedIndex];
                evo.min_round = comboBox16.SelectedIndex;
            }
        }

        private void button21_Click(object sender, EventArgs e)
        {
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            if (comboBox15.SelectedIndex != -1 && comboBox15.Enabled && evo.towers.Count < Map.EVO_TOWERS)
            {
                Tower tow = ((List<Tower>)(comboBox15.DataSource))[comboBox15.SelectedIndex];
                tow.usedby++;
                evo.towers.Insert(listBox8.SelectedIndex + 1, tow);
                int sel = listBox8.SelectedIndex + 1;
                refreshEvolution();
                listBox8.SelectedIndex = sel;
            }
        }

        private void button22_Click_1(object sender, EventArgs e)
        {
            Evolution evo = map.evolutions[listBox5.SelectedIndex];
            if (evo.towers.Count > 0 && listBox8.SelectedIndex >= 0)
            {
                Tower tow = evo.towers[listBox8.SelectedIndex];
                tow.usedby--;
                evo.towers.RemoveAt(listBox8.SelectedIndex);
                refreshEvolution();
            }
        }

        private void button31_Click(object sender, EventArgs e)
        {
            if (map.tilemap == null)
            {
                ChooseSize cs = new ChooseSize(32, 32);
                if (cs.ShowDialog(this) == DialogResult.OK)
                {
                    map.tilemap = new TileMap(cs.width, cs.height);
                    // map design
                    EditMap em = new EditMap(map);
                    em.ShowDialog(this);
                    em.Dispose();
                    refreshDesign();
                }
                cs.Dispose();
            }
            else
            {
                // map design
                EditMap em = new EditMap(map);
                em.ShowDialog(this);
                em.Dispose();
                refreshDesign();
            }
        }

        private void saveFileBuild_FileOk(object sender, CancelEventArgs e)
        {
            Stream File;
            if ((File = saveFileBuild.OpenFile()) != null)
            {
                //Save
                BinaryWriter Writer = null;
                MemoryStream str = new MemoryStream();

                try
                {
                    // Write built map
                    Writer = new BinaryWriter(File);
                    Writer.Write(map.buildMap().ToArray());

                    // Convert map to xml
                    map.fillIndexes(); // prepare objectss
                    MemoryStream str2 = new MemoryStream();
                    System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(map.GetType());
                    xml.Serialize(str2, map);

                    // Zip the xml map
                    str2.Position = 0L;
                    MemoryStream zip = new MemoryStream();
                    BZip2OutputStream zipOStream = new BZip2OutputStream(zip);
//                    zipOStream.SetLevel(9); // best compression
//                    ZipEntry entry = new ZipEntry("map.xml");
//                    zipOStream.PutNextEntry(entry);
                    zipOStream.Write(str2.ToArray(), 0, str2.ToArray().GetLength(0));
                    // Close zip stream
//                    zipOStream.Finish();
                    zipOStream.Flush();
                    zipOStream.Close();
                    
                    // Append zipped xml map to file
                    Writer.Write(zip.ToArray());

                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
                finally
                {
                    if (Writer != null)
                        Writer.Close();
                    if (File != null)
                        File.Close();
                }
            }
        }

        private void button33_Click(object sender, EventArgs e)
        {
            ChooseSize cs = new ChooseSize(map.tilemap.width, map.tilemap.height);
            if (cs.ShowDialog(this) == DialogResult.OK)
            {
                bool can_resize = true;
                foreach (Waypoint wp in map.waypoints)
                {
                    if (wp.x >= cs.width || wp.y >= cs.height)
                    {
                        can_resize = false;
                        break;
                    }
                }

                if (can_resize)
                {
                    map.tilemap.changeSizeTo(cs.width, cs.height);
                    refreshDesign();
                }
                else
                {
                    MessageBox.Show(this, "Cannot resize the map !\nSome waypoints are out of range,\n delete them before resizing.", "Error");
                }
            }
            cs.Dispose();
        }

        private void pictureBox9_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (splay != null) {
                splay.Stop();
                splay.Dispose();
            }

            Map.SOUNDS_RES[comboBox5.SelectedIndex].Position = 0;
            splay = new SoundPlayer(Map.SOUNDS_RES[comboBox5.SelectedIndex]);

            splay.Play();
        }

        private void textBox19_TextChanged(object sender, EventArgs e)
        {
            Round rnd = map.rounds[listBox2.SelectedIndex];
            try
            {
                int num = (short)int.Parse(textBox19.Text);
                if (num >= 0)
                    rnd.gold_bonus = num;
                textBox19.Text = rnd.gold_bonus.ToString();
            }
            catch (Exception)
            {
                textBox19.Text = rnd.gold_bonus.ToString();
            }
        }

        private void textBox53_TextChanged(object sender, EventArgs e)
        {
            map.author = textBox53.Text;
        }

        private void textBox54_TextChanged(object sender, EventArgs e)
        {
            map.contact = textBox54.Text;
        }

        private void textBox55_TextChanged(object sender, EventArgs e)
        {
            map.map_version = textBox55.Text;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            saveFilePreview.ShowDialog();
        }

        private void saveFilePreview_FileOk(object sender, CancelEventArgs e)
        {
            Stream File;
            if ((File = saveFilePreview.OpenFile()) != null)
            {

                try
                {
                    // Generate preview image
//                    Image preview = pictureBox10.Image.GetThumbnailImage(Map.PREVIEW_WIDTH, Map.PREVIEW_HEIGHT, null, null);
                    EditMap em = new EditMap(map);

                    float ImgRatio = (float)em.mapbuffer.Width / (float)em.mapbuffer.Height;

                    Bitmap preview = new Bitmap(Map.PREVIEW_WIDTH, Map.PREVIEW_HEIGHT);
                    int wdth = Map.PREVIEW_WIDTH;
                    int hght = Map.PREVIEW_HEIGHT;

                    if (em.mapbuffer.Width > em.mapbuffer.Height)
                        hght = (int)Math.Round(Map.PREVIEW_WIDTH / ImgRatio, 0);
                    else
                        wdth = (int)Math.Round(Map.PREVIEW_HEIGHT * ImgRatio, 0);

                    Graphics gfx = Graphics.FromImage(preview);
                    gfx.FillRectangle(new SolidBrush(Color.FromArgb(255, 0, 0, 0)), new Rectangle(0, 0, Map.PREVIEW_WIDTH, Map.PREVIEW_HEIGHT));
                    int x_offset = (Map.PREVIEW_WIDTH - wdth) / 2;
                    int y_offset = (Map.PREVIEW_HEIGHT - hght) / 2;
                    gfx.DrawImage(em.mapbuffer, new Rectangle(x_offset, y_offset, Map.PREVIEW_WIDTH - 2 * x_offset, Map.PREVIEW_HEIGHT - 2 * y_offset), new Rectangle(0, 0, em.mapbuffer.Width, em.mapbuffer.Height), GraphicsUnit.Pixel);
                    gfx.Dispose();

                    // Save file
                    preview.Save(File, ImageFormat.Png);

                    // Copy map info for post in the clipboard
                    Clipboard.SetText("[img]http://noda.free.fr/wtd/img/" + Path.GetFileName(saveFilePreview.FileName) + "[/img]\r\n\r\n"
                        + "[size=18][url=http://noda.free.fr/wtd/ftp/maps/clean/" + Path.GetFileNameWithoutExtension(saveFilePreview.FileName) + ".tdm]Download[/url][/size]\r\n\r\n"
                        + "[b]Current version : [/b][i]" + map.map_version + "[/i]\r\n"
                        + "[b]Author : [/b][i]" + map.author + " (" + map.contact + ")" + "[/i]\r\n"
                        + "[b]Description : [/b][i]PUT_DESCRIPTION_HERE[/i]\r\n"
                        + "[b]Features : [/b][i]\r\n" + map.presentation + "[/i]\r\n\r\n"
                        + "[b]History : [/b]\r\n\r\n"
                        + "* Version " + map.map_version + "\r\n"
                        + "[i]- initial release[/i]");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
                finally
                {
                    if (File != null)
                        File.Close();
                }
            }
        }

        private void checkBox9_CheckedChanged(object sender, EventArgs e)
        {
            map.w3_damage_style = checkBox9.Checked;
        }

        private void checkBox10_CheckedChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            mons.ghost = checkBox10.Checked;
        }

        private void checkBox11_CheckedChanged(object sender, EventArgs e)
        {
            Monster mons = map.monsters[listBox3.SelectedIndex];
            if (checkBox11.Checked)
                mons.size = 2;
            else
                mons.size = 1;
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            map.minimap_colors = 0;
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            map.minimap_colors = 1;
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            map.minimap_colors = 2;
        }

        private void radioButton4_CheckedChanged(object sender, EventArgs e)
        {
            map.minimap_colors = 3;
        }

        private void numericUpDown3_ValueChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                if (numericUpDown3.Value > map.num_paths)
                    numericUpDown3.Value = map.num_paths;

                if (numericUpDown3.Value < 1)
                    numericUpDown3.Value = 1;

                refreshRound();
            }
        }

        private void comboBox18_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox2.SelectedIndex >= 0 && refresh)
            {
                Round rnd = map.rounds[listBox2.SelectedIndex];
                rnd.mps_method = (int)Enum.Parse(typeof(Map.MPS_METHOD), comboBox18.Text);
                refreshRound();
            }
        }

        private void checkBox12_CheckedChanged(object sender, EventArgs e)
        {
            map.use_fast_pathfinder = checkBox12.Checked;
        }

        



    }
}