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.Drawing.Imaging;

namespace WTD_Editor
{
    public partial class EditMap : Form
    {
        Map map;
        TileMap tilemap;
        TileSet tileset;
        SolidBrush tileselect = new SolidBrush(Color.FromArgb(50, 255, 255, 255));
        SolidBrush black = new SolidBrush(Color.FromArgb(128, 0, 0, 0));
        Rectangle selectarea;
        Rectangle copyarea;
        int copy_x1, copy_x2, copy_y1, copy_y2;
        public Bitmap mapbuffer;
        TileMap copymap;
        Bitmap tilesetbuffer;
        List<Label> wp_box;
        int selected_tile;
        int pos_x;
        int pos_y;
        bool wp_exists;
        bool refresh;
        bool shift_down;
        bool start_sel;
        bool copy, paste;
        bool moved;
        byte brush_size;

        public EditMap(Map m)
        {
            InitializeComponent();
            map = m;
            tilemap = map.tilemap;

            if (tilemap.use_custom_tileset)
            {
                if (tilemap.custom_tileset_gif == null)
                {
                    try
                    {
                        Bitmap img = (Bitmap)Bitmap.FromFile(tilemap.custom_tileset_path);
                        tileset = new TileSet(img, "CUSTOM");
                        MemoryStream gif = new MemoryStream();
                        img.Save(gif, ImageFormat.Gif);
                        tilemap.custom_tileset_gif = gif.ToArray();
                        gif.Dispose();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error while opening custom tileset image: \n" + ex.Message);
                        tilemap.use_custom_tileset = false;
                        tileset = Map.TILESETS[map.tilemap.tileset];
                    }
                }
                else
                {
                    MemoryStream gif = new MemoryStream(tilemap.custom_tileset_gif);
                    Bitmap img = (Bitmap)Bitmap.FromStream(gif);
                    tileset = new TileSet(img, "CUSTOM");
                    gif.Dispose();
                }
            }
            else
            {
                tileset = Map.TILESETS[map.tilemap.tileset];
            }
            refresh = false;
            checkBox5.Checked = tilemap.use_custom_tileset;
            refresh = true;

            pos_x = 0;
            pos_y = 0;
            wp_exists = false;
            shift_down = false;
            wp_box = new List<Label>();

            brush_size = 1;
            moved = false;
            start_sel = false;
            copy = false;
            paste = false;
            copy_x1 = 0;
            copy_y1 = 0;
            copy_x2 = TileSet.TILE_WIDTH;
            copy_y2 = TileSet.TILE_HEIGHT;
            copyarea = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            copymap = new TileMap(tilemap);

            selectarea = new Rectangle();
            selectarea.Size = new Size(TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);

            mapbuffer = new Bitmap(tilemap.width * TileSet.TILE_WIDTH, tilemap.height * TileSet.TILE_HEIGHT);
            tilesetbuffer = new Bitmap(tileset.bmp);
            pictureBox9.Image = tilesetbuffer;
            pictureBox5.Image = mapbuffer;
            pictureBox7.Image = (Bitmap)mapbuffer.Clone();
            pictureBox8.Image = (Bitmap)mapbuffer.Clone();
            pictureBox7.Hide();
            pictureBox8.Hide();

            refresh = false;
            comboBox1.DataSource = Map.TILESETS;
            comboBox1.SelectedIndex = map.tilemap.tileset;

            numericUpDown1.Value = 1;
            textBox2.Text = map.num_paths.ToString();
            refresh = true;

            selected_tile = 0;
            pictureBox6.Image = new Bitmap(TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            pictureBox10.Image = new Bitmap(TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            redrawMaps();
            createWPBoxes();
            refreshAll();
            redrawSelector();
            redrawTileSelector();
            listBox1.SelectedIndex = map.waypoints.Count - 1;
            radioButton1.Checked = true;

            KeyPreview = true;
            KeyDown += new KeyEventHandler(KeyDownEvent);
            KeyUp += new KeyEventHandler(KeyUpEvent);
            
        }

        private void KeyDownEvent(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey)
            {
                shift_down = true;
            }
        }

        private void KeyUpEvent(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey)
            {
                shift_down = false;
            }
        }

        private void deleteWPBoxes()
        {
            for (int i = 0; i < wp_box.Count; i++)
                wp_box[i].Dispose();
        }

        private void createWPBoxes()
        {
            int numWP;
            List<Waypoint> currWP;
            if (numericUpDown1.Value == 1)
                currWP = map.waypoints;
            else
                currWP = map.paths[(int)numericUpDown1.Value - 2];
            numWP = currWP.Count;

            for (int i = 0; i < numWP; i++)
            {
                Label lwp = new Label();
                panel3.Controls.Add(lwp);
                lwp.BringToFront();
                lwp.AutoSize = false;
                lwp.Size = new Size(14, 14);
                lwp.TabIndex = 5;
                lwp.TextAlign = ContentAlignment.MiddleCenter;
                lwp.Location = new Point(currWP[i].x * TileSet.TILE_WIDTH + 1 - panel3.HorizontalScroll.Value, currWP[i].y * TileSet.TILE_HEIGHT + 1 - panel3.VerticalScroll.Value);
                lwp.Visible = true;
                lwp.BackColor = Color.FromArgb(255, 255, 255, 255);
                lwp.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseMove);
                lwp.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseMove);
                lwp.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseMove);
                lwp.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseRelease);
                wp_box.Insert(i, lwp);
            }
        }

        private void refreshAll()
        {
            Waypoint.curr = 1;
            listBox1.DataSource = null;
            if (numericUpDown1.Value == 1)
            {
                textBox1.Text = map.waypoints.Count.ToString();
                listBox1.DataSource = map.waypoints;
            }
            else
            {
                textBox1.Text = map.paths[(int)numericUpDown1.Value - 2].Count.ToString();
                listBox1.DataSource = map.paths[(int)numericUpDown1.Value - 2];
            }

            for (int i = 0; i < wp_box.Count; i++)
            {
                if (checkBox3.Checked)
                {
                    wp_box[i].Hide();
                }
                else
                {
                    if (!wp_box[i].Visible)
                        wp_box[i].Show();
                    wp_box[i].Text = (i + 1).ToString();
                    if (i > 8)
                        wp_box[i].Font = new Font("Microsoft Sans Serif", 5.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    else
                        wp_box[i].Font = new Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));

                }
            }
        }

        private void redrawMaps()
        {
            Rectangle source = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            Rectangle dest = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);

            for (int i = 0; i < tilemap.height; i++)
                for (int j = 0; j < tilemap.width; j++)
                {
                    Graphics g_draw = Graphics.FromImage(mapbuffer);
                    dest.X = (j * TileSet.TILE_WIDTH);
                    dest.Y = (i * TileSet.TILE_HEIGHT);
                    g_draw.DrawImage(tileset.tiles[tilemap.tilemap[j][i]], dest, source, GraphicsUnit.Pixel);
                    g_draw.Dispose();
                }

            pictureBox5.Invalidate();
            redrawCollisionsMaps();
        }

        private void redrawCollisionsMaps()
        {
            Rectangle source = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            Rectangle dest = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);

            pictureBox7.Image = (Bitmap)mapbuffer.Clone();
            pictureBox8.Image = (Bitmap)mapbuffer.Clone();

            for (int i = 0; i < tilemap.height; i++)
                for (int j = 0; j < tilemap.width; j++)
                {
                    Graphics g_draw = Graphics.FromImage(pictureBox7.Image);
                    dest.X = (j * TileSet.TILE_WIDTH);
                    dest.Y = (i * TileSet.TILE_HEIGHT);
                    if (tilemap.monster_map[j][i] == 1)
                        g_draw.FillRectangle(black, dest);
                    g_draw.Dispose();

                    g_draw = Graphics.FromImage(pictureBox8.Image);
                    dest.X = (j * TileSet.TILE_WIDTH);
                    dest.Y = (i * TileSet.TILE_HEIGHT);
                    if (tilemap.tower_map[j][i] == 1)
                        g_draw.FillRectangle(black, dest);
                    g_draw.Dispose();
                }

            pictureBox7.Invalidate();
            pictureBox8.Invalidate();
        }

        private void redrawTileSelector()
        {
            Rectangle dest = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            int posx = (selected_tile * TileSet.TILE_WIDTH) % 128;
            int posy = (((selected_tile * TileSet.TILE_WIDTH) / 128) * TileSet.TILE_HEIGHT);
            pictureBox10.Image.Dispose();
            pictureBox10.Image = new Bitmap(tileset.tiles[selected_tile]);
            Graphics g_draw = Graphics.FromImage(pictureBox10.Image);
            g_draw.FillRectangle(tileselect, dest);
            g_draw.Dispose();
            pictureBox10.Invalidate();
            pictureBox10.Location = new Point(pictureBox9.Location.X + posx, pictureBox9.Location.Y + posy);
        }

        private void redrawSelector()
        {
            int px = pos_x - ((brush_size - 1) / 2);
            int py = pos_y - ((brush_size - 1) / 2);

            pictureBox6.Size = new Size(TileSet.TILE_WIDTH * brush_size, TileSet.TILE_HEIGHT * brush_size);
            if (pictureBox6.Image.Size.Width != TileSet.TILE_WIDTH * brush_size || pictureBox6.Image.Size.Height != TileSet.TILE_HEIGHT)
            {
                pictureBox6.Image.Dispose();
                pictureBox6.Image = new Bitmap(TileSet.TILE_WIDTH * brush_size, TileSet.TILE_HEIGHT * brush_size);
            }

            Rectangle dest = new Rectangle(0, 0, TileSet.TILE_WIDTH * brush_size, TileSet.TILE_HEIGHT * brush_size);
            Rectangle dest2 = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            Graphics gfx = Graphics.FromImage(pictureBox6.Image);

            for (int j = py; j < py + brush_size; j++)
                for (int i = px; i < px + brush_size; i++)
                {
                    tileset.drawTile(gfx, tilemap, new Point(i, j), new Point(i - px, j - py));

                    if (i >= 0 && i < tilemap.width && j >= 0 && j < tilemap.height)
                    {
                        if (checkBox1.Checked && tilemap.monster_map[i][j] == 1)
                        {
                            dest2.X = (i - px) * TileSet.TILE_WIDTH;
                            dest2.Y = (j - py) * TileSet.TILE_HEIGHT;
                            gfx.FillRectangle(black, dest2);
                        }
                        else if (checkBox2.Checked && tilemap.tower_map[i][j] == 1)
                        {
                            dest2.X = (i - px) * TileSet.TILE_WIDTH;
                            dest2.Y = (j - py) * TileSet.TILE_HEIGHT;
                            gfx.FillRectangle(black, dest2);
                        }
                    }
                }

            gfx.FillRectangle(tileselect, dest);
            gfx.Dispose();
            pictureBox6.Invalidate();
            pictureBox6.Location = new Point(px * 16 - panel3.HorizontalScroll.Value, py * 16 - panel3.VerticalScroll.Value);

        }

        private void drawPaste(Graphics gfx, Rectangle rect)
        {
            int width = copyarea.Width / 16;
            int height = copyarea.Height / 16;
            int x, y;

            Rectangle src = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
            Rectangle dest = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);

            for(int j = rect.Top / 16; j < rect.Height / 16; j++)
                for (int i = rect.Left / 16; i < rect.Width / 16; i++)
                {
                    x = (i % width) + copyarea.Left / 16;
                    y = (j % height) + copyarea.Top / 16;
                    dest.X = (i * TileSet.TILE_WIDTH);
                    dest.Y = (j * TileSet.TILE_HEIGHT);
                    gfx.DrawImage(tileset.tiles[copymap.tilemap[x][y]], dest, src, GraphicsUnit.Pixel);
                }
        }

        private void pasteToSelection()
        {
            int min_x = Math.Min(copy_x1, copy_x2);
            int max_x = Math.Max(copy_x1, copy_x2);
            int min_y = Math.Min(copy_y1, copy_y2);
            int max_y = Math.Max(copy_y1, copy_y2);

            int width = copyarea.Width / 16;
            int height = copyarea.Height / 16;
            int x, y;
            Graphics g_draw;

            for (int j = 0; j < (max_y - min_y + 1); j++)
                for (int i = 0; i < (max_x - min_x + 1); i++)
                {
                    x = (i % width) + copyarea.Left / 16;
                    y = (j % height) + copyarea.Top / 16;
                    g_draw = Graphics.FromImage(pictureBox5.Image);
                    tileset.putAndDrawTile(g_draw, tilemap, new Point(i+min_x, j+min_y), copymap.tilemap[x][y]);
                }
            pictureBox5.Invalidate();
        }

        private void redrawCopySelector()
        {
            int min_x = Math.Min(copy_x1, copy_x2);
            int max_x = Math.Max(copy_x1, copy_x2);
            int min_y = Math.Min(copy_y1, copy_y2);
            int max_y = Math.Max(copy_y1, copy_y2);

            pictureBox6.Location = new Point(min_x * 16 - panel3.HorizontalScroll.Value, min_y * 16 - panel3.VerticalScroll.Value);
            pictureBox6.Size = new Size((max_x - min_x + 1) * 16, (max_y - min_y + 1) * 16);

            Rectangle dest = new Rectangle(0, 0, (max_x - min_x + 1) * 16, (max_y - min_y + 1) * 16);
            Rectangle src = new Rectangle();;

            pictureBox6.Image.Dispose();
            pictureBox6.Image = new Bitmap((max_x - min_x + 1) * 16, (max_y - min_y + 1) * 16);
            Graphics g_draw = Graphics.FromImage(pictureBox6.Image);
            
            if (copy)
            {
                src.Location = new Point(min_x * 16, min_y * 16);
                src.Size = new Size((max_x - min_x + 1) * 16, (max_y - min_y + 1) * 16);
                g_draw.DrawImage(mapbuffer, dest, src, GraphicsUnit.Pixel);
            }
            else //if (paste)
            {
                src.Location = copyarea.Location;
                src.Size = new Size((max_x - min_x + 1) * 16, (max_y - min_y + 1) * 16);
                drawPaste(g_draw, dest);
            }

            g_draw.FillRectangle(tileselect, dest);
            g_draw.Dispose();
            pictureBox6.Invalidate();
        }

        private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
        {
        }

        private void EditMap_Load(object sender, EventArgs e)
        {
        }

        private bool checkWayPoint(int x, int y)
        {
            List<Waypoint> currWP;
            if (numericUpDown1.Value == 1)
                currWP = map.waypoints;
            else
                currWP = map.paths[(int)numericUpDown1.Value - 2];

            foreach (Waypoint wp in currWP)
                if (wp.x == x && wp.y == y)
                    return true;
            return false;
        }

        private void mouseActions()
        {
            if (MouseButtons == MouseButtons.Left)
            {
                if (checkBox1.Checked)
                {
                    int px = pos_x - ((brush_size - 1) / 2);
                    int py = pos_y - ((brush_size - 1) / 2);
                    Graphics gfx = Graphics.FromImage(pictureBox7.Image);

                    for(int j = py; j < py + brush_size; j++)
                        for (int i = px; i < px + brush_size; i++)
                        {
                            if ((i >= 0 && i < tilemap.width && j >= 0 && j < tilemap.height) && (tilemap.monster_map[i][j] == 0))
                            {
                                Rectangle dest = new Rectangle(i * TileSet.TILE_WIDTH, j * TileSet.TILE_HEIGHT, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
                                gfx.FillRectangle(black, dest);
                                tilemap.monster_map[i][j] = 1;
                            }
                        }
                    pictureBox7.Invalidate();
                    redrawSelector();
                    gfx.Dispose();
                }
                else if (checkBox2.Checked)
                {
                    int px = pos_x - ((brush_size - 1) / 2);
                    int py = pos_y - ((brush_size - 1) / 2);
                    Graphics gfx = Graphics.FromImage(pictureBox8.Image);

                    for(int j = py; j < py + brush_size; j++)
                        for (int i = px; i < px + brush_size; i++)
                        {
                            if ((i >= 0 && i < tilemap.width && j >= 0 && j < tilemap.height) && (tilemap.tower_map[i][j] == 0))
                            {
                                Rectangle dest = new Rectangle(i * TileSet.TILE_WIDTH, j * TileSet.TILE_HEIGHT, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
                                gfx.FillRectangle(black, dest);
                                tilemap.tower_map[i][j] = 1;
                            }
                        }
                    pictureBox8.Invalidate();
                    redrawSelector();
                    gfx.Dispose();
                }
                else
                {
                    if (shift_down)
                    {
                        if (!start_sel)
                        {
                            copy_x1 = pos_x;
                            copy_y1 = pos_y;
                            start_sel = true;
                            paste = true;

                            copy_x2 = pos_x;
                            copy_y2 = pos_y;
                            redrawCopySelector();
                        }
                        if (moved)
                        {
                            copy_x2 = pos_x;
                            copy_y2 = pos_y;
                            redrawCopySelector();
                        }
                    }
                    else
                    {
                        int px = pos_x - ((brush_size - 1) / 2);
                        int py = pos_y - ((brush_size - 1) / 2);
                        Graphics gfx = Graphics.FromImage(pictureBox5.Image);

                        for (int j = py; j < py + brush_size; j++)
                            for (int i = px; i < px + brush_size; i++)
                            {
                                if (checkBox4.Checked && selected_tile < 24)
                                    tileset.putAndDrawRandomBaseTile(gfx, tilemap, new Point(i, j), selected_tile);
                                else
                                    tileset.putAndDrawTile(gfx, tilemap, new Point(i, j), selected_tile);
                            }

                        pictureBox5.Invalidate();
                        redrawSelector();
                        gfx.Dispose();
                    }
                }
            }
            else if (MouseButtons == MouseButtons.Right)
            {
                if (checkBox1.Checked)
                {
                    int px = pos_x - ((brush_size - 1) / 2);
                    int py = pos_y - ((brush_size - 1) / 2);
                    Graphics gfx = Graphics.FromImage(pictureBox7.Image);

                    for(int j = py; j < py + brush_size; j++)
                        for (int i = px; i < px + brush_size; i++)
                        {
                            if ((i >= 0 && i < tilemap.width && j >= 0 && j < tilemap.height) && (tilemap.monster_map[i][j] == 1))
                            {
                                Rectangle src = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
                                Rectangle dest = new Rectangle(i * TileSet.TILE_WIDTH, j * TileSet.TILE_HEIGHT, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
                                tilemap.monster_map[i][j] = 0;
                                tileset.drawTile(gfx, tilemap, new Point(i, j));
                            }
                        }

                    pictureBox7.Invalidate();
                    redrawSelector();
                    gfx.Dispose();
                }
                else if (checkBox2.Checked)
                {
                    int px = pos_x - ((brush_size - 1) / 2);
                    int py = pos_y - ((brush_size - 1) / 2);
                    Graphics gfx = Graphics.FromImage(pictureBox8.Image);

                    for(int j = py; j < py + brush_size; j++)
                        for (int i = px; i < px + brush_size; i++)
                        {
                            if ((i >= 0 && i < tilemap.width && j >= 0 && j < tilemap.height) && (tilemap.tower_map[i][j] == 1))
                            {
                                Rectangle src = new Rectangle(0, 0, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
                                Rectangle dest = new Rectangle(i * TileSet.TILE_WIDTH, j * TileSet.TILE_HEIGHT, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
                                tilemap.tower_map[i][j] = 0;
                                tileset.drawTile(gfx, tilemap, new Point(i, j));
                            }
                        }

                    pictureBox8.Invalidate();
                    redrawSelector();
                    gfx.Dispose();
                }
                else
                {
                    if (shift_down)
                    {
                        if (!start_sel)
                        {
                            copy_x1 = pos_x;
                            copy_y1 = pos_y;
                            start_sel = true;
                            copy = true;

                            copy_x2 = pos_x;
                            copy_y2 = pos_y;
                            redrawCopySelector();
                        }
                        if (moved)
                        {
                            copy_x2 = pos_x;
                            copy_y2 = pos_y;
                            redrawCopySelector();
                        }
                    }
                    else
                    {

                        if (checkWayPoint(pos_x, pos_y))
                        {
                            toolStripMenuItem1.Text = "Delete waypoint";
                            wp_exists = true;
                        }
                        else
                        {
                            toolStripMenuItem1.Text = "Add waypoint";
                            wp_exists = false;
                        }
                        if (selected_tile >= 24)
                            toolStripMenuItem2.Enabled = false;
                        else
                            toolStripMenuItem2.Enabled = true;
                        contextMenuStrip1.Show(Cursor.Position.X, Cursor.Position.Y);
                    }
                }
            }
        }

        private void pictureBox5_MouseRelease(object sender, MouseEventArgs e)
        {
            start_sel = false;
            if (copy)
            {
                int min_x = Math.Min(copy_x1, copy_x2);
                int max_x = Math.Max(copy_x1, copy_x2);
                int min_y = Math.Min(copy_y1, copy_y2);
                int max_y = Math.Max(copy_y1, copy_y2);

                copyarea.Location = new Point(min_x * 16, min_y * 16);
                copyarea.Size = new Size((max_x - min_x + 1) * 16, (max_y - min_y + 1) * 16);
                copy = false;
                copymap = new TileMap(tilemap);
            }
            else if (paste)
            {
                pasteToSelection();
                paste = false;
            }
            redrawSelector();
        }
            
        private void pictureBox5_MouseMove(object sender, MouseEventArgs e)
        {
            int newpos_x = (pictureBox5.PointToClient(Cursor.Position).X) / 16;
            int newpos_y = (pictureBox5.PointToClient(Cursor.Position).Y) / 16;
            if (newpos_x < 0) newpos_x = 0;
            if (newpos_y < 0) newpos_y = 0;
            if (newpos_x >= tilemap.width) newpos_x = tilemap.width - 1;
            if (newpos_y >= tilemap.height) newpos_y = tilemap.height - 1;
            moved = false;

            if (newpos_x != pos_x || newpos_y != pos_y)
            {
                pos_x = newpos_x;
                pos_y = newpos_y;

                label5.Text = pos_x.ToString() + ", " + pos_y.ToString();
                if (MouseButtons == MouseButtons.None)
                    redrawSelector();
                moved = true;
            }
            mouseActions();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                redrawCollisionsMaps();
                pictureBox7.Show();
            }
            else
                pictureBox7.Hide();

            if (checkBox1.Checked && checkBox2.Checked)
                checkBox2.Checked = false;

            redrawSelector();
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked)
            {
                redrawCollisionsMaps();
                pictureBox8.Show();
            }
            else
                pictureBox8.Hide();

            if (checkBox1.Checked && checkBox2.Checked)
                checkBox1.Checked = false;

            redrawSelector();
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            tilemap.fillWithTile(selected_tile);
            redrawMaps();
            redrawSelector();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            List<Waypoint> currWP;
            if (numericUpDown1.Value == 1)
                currWP = map.waypoints;
            else
                currWP = map.paths[(int)numericUpDown1.Value - 2];

            if (wp_exists)
            {
                Waypoint wp = null;
                foreach (Waypoint w in currWP)
                    if (w.x == pos_x && w.y == pos_y)
                    {
                        wp = w;
                        break;
                    }
                int idx = currWP.IndexOf(wp);
                panel3.Controls.Remove(wp_box[idx]);
                wp_box[idx].Dispose();
                wp_box.RemoveAt(idx);
                currWP.RemoveAt(idx);
                refreshAll();
                listBox1.SelectedIndex = idx - 1;
            }
            else
            {
                if (currWP.Count < 256)
                {
                    Waypoint wp = new Waypoint();
                    wp.x = pos_x;
                    wp.y = pos_y;
                    currWP.Insert(listBox1.SelectedIndex + 1, wp);
                    Label lwp = new Label();
                    panel3.Controls.Add(lwp);
                    lwp.BringToFront();
                    lwp.AutoSize = false;
                    lwp.Size = new Size(14, 14);
                    lwp.TabIndex = 5;
                    lwp.TextAlign = ContentAlignment.MiddleCenter;
                    lwp.Location = new Point(wp.x * TileSet.TILE_WIDTH + 1 - panel3.HorizontalScroll.Value, wp.y * TileSet.TILE_HEIGHT + 1 - panel3.VerticalScroll.Value);
                    lwp.Visible = true;
                    lwp.BackColor = Color.FromArgb(255, 255, 255, 255);
                    lwp.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseMove);
                    lwp.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseMove);
                    lwp.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseMove);
                    lwp.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox5_MouseRelease);
                    wp_box.Insert(listBox1.SelectedIndex + 1, lwp);
                    int sel = listBox1.SelectedIndex + 1;
                    refreshAll();
                    listBox1.SelectedIndex = sel;
                }
                else
                {
                    MessageBox.Show("Can't add waypoint, maximum is 256");
                }
            } 
        }

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

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (refresh)
            {
                map.tilemap.tileset = comboBox1.SelectedIndex;
                if (!tilemap.use_custom_tileset)
                {
                    tileset = Map.TILESETS[map.tilemap.tileset];
                    pictureBox9.Image.Dispose();
                    tilesetbuffer.Dispose();
                    tilesetbuffer = new Bitmap(tileset.bmp);
                    pictureBox9.Image = tilesetbuffer;
                    redrawTileSelector();
                    redrawSelector();
                    redrawMaps();
                }
            }
        }

        private void pictureBox9_Click(object sender, MouseEventArgs e)
        {
            if (MouseButtons == MouseButtons.Left)
            {
                int newpos_x = (pictureBox9.PointToClient(Cursor.Position).X) / 16;
                int newpos_y = (pictureBox9.PointToClient(Cursor.Position).Y) / 16;
                if (newpos_x < 0) newpos_x = 0;
                if (newpos_y < 0) newpos_y = 0;
                if (newpos_x >= 8) newpos_x = 7;
                if (newpos_y >= 16) newpos_y = 15;
                int new_selected_tile = newpos_x + newpos_y * 8;
                if (new_selected_tile != selected_tile)
                {
                    selected_tile = new_selected_tile;
                    redrawTileSelector();
                }
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            CommandsHelp ch = new CommandsHelp();
            ch.ShowDialog();
        }

        private void customTilesetDialog_FileOk(object sender, CancelEventArgs e)
        {
            Bitmap img;
            Stream File;
            if ((File = customTilesetDialog.OpenFile()) != null)
            {
                try 
                {
                    img = (Bitmap)Bitmap.FromFile(customTilesetDialog.FileName);
                    if (img.Width != 128 || img.Height != 256 || img.PixelFormat != System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
                    {
                        throw new Exception("The image must be in a 128x256, 256 colors format.");
                    }
                    tilemap.custom_tileset_path = customTilesetDialog.FileName;
                    tilemap.use_custom_tileset = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                    tilemap.use_custom_tileset = false;
                    refresh = false;
                    checkBox5.Checked = false;
                    refresh = true;
                }
                finally
                {
                    if (File != null)
                        File.Close();
                }
            }

        }

        private void checkBox5_CheckedChanged(object sender, EventArgs e)
        {
            if (tilemap.use_custom_tileset != checkBox5.Checked && refresh)
            {
                if (checkBox5.Checked)
                {
                    if (customTilesetDialog.ShowDialog() != DialogResult.OK)
                    {
                        refresh = false;
                        checkBox5.Checked = false;
                        refresh = true;
                    }
                }
                else
                {
                    tilemap.use_custom_tileset = false;
                }

                if (tilemap.use_custom_tileset)
                {
                    try
                    {
                        Bitmap img = (Bitmap)Bitmap.FromFile(tilemap.custom_tileset_path);
                        tileset = new TileSet(img, "CUSTOM");
                        MemoryStream gif = new MemoryStream();
                        img.Save(gif, ImageFormat.Gif);
                        tilemap.custom_tileset_gif = gif.ToArray();
                        gif.Dispose();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error while opening custom tileset image: \n" + ex.Message);
                        tilemap.use_custom_tileset = false;
                        tileset = Map.TILESETS[map.tilemap.tileset];
                    }
                }
                else
                {
                    tileset = Map.TILESETS[map.tilemap.tileset];
                }
                pictureBox9.Image.Dispose();
                tilesetbuffer.Dispose();
                tilesetbuffer = new Bitmap(tileset.bmp);
                pictureBox9.Image = tilesetbuffer;
                redrawTileSelector();
                redrawSelector();
                redrawMaps();
            }
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            brush_size = 1;
            redrawSelector();
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            brush_size = 3;
            redrawSelector();
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            brush_size = 5;
            redrawSelector();
        }

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

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

                deleteWPBoxes();
                createWPBoxes();
                refreshAll();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (map.num_paths < Map.MAX_PATHS)
            {
                map.paths.Add(new List<Waypoint>());
                map.num_paths++;
                numericUpDown1.Value = map.num_paths;
                refresh = false;
                listBox1.SelectedIndex = -1;
                refresh = true;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (map.num_paths > 1)
            {
                map.paths.RemoveAt(map.num_paths - 2);
                map.num_paths--;
                numericUpDown1.Value = map.num_paths;
                refresh = false;
                listBox1.SelectedIndex = -1;
                refresh = true;
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }



       
    }
}