/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package d.d;

import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

/**
 *
 * @author pospis
 */
public class MapPanel extends JPanel {

    MainFrame frame;
    static final int Main = 1;
    static final int HeroesEditor = 2;
    static final int HeroesManagment = 3;
    static final int Battle = 4;
    static final int Creatures = 5;
    static final int Map = 6;

    static final int GRASS = 1;
    static final int WATER = 2;
    static final int ROCK = 3;
    static final int TREE = 4;
    static final int GROUND_STONE = 5;
    static final int WALL_STONE = 6;

    static final int FIRE = 7;
    static final int TABLE = 8;
    static final int CUPBOARD = 9;
    static final int CHEST = 10;
    static final int LTABLER = 11;
    static final int LTABLEL = 12;
    static final int CHAIR = 13;
    static final int BED = 14;
    static final int ARMORY = 15;

    static final int SELECTION = 200;
    static final int DELETE = 201;

    public static final int SquareSize = 25;
    int Selected = WALL_STONE;
    int width;
    int height;
    int MapWidth = 50;
    int MapHeight = 50;

    boolean pressedZ = false;
    int selectedItem = -1;

    Random rn;
    Square[][] squares;
    int XC = -5;
    int YC = -5;
    int cY = 0;
    int cX = 0;
    int seed;

    MapPanel MP = this;
    SelectionPanel SPanel;
    DrawPanel DPanel;
    JFrame cframe;
    JPanel opt;
    JFrame optFrame;
    Keyboard keyboard;
    ProcGen procgen;
    JTextField SeedField;
    JTextField countExactly;
    JComboBox cor;
    JComboBox pot;

    ArrayList<ChangesOfSquares> changeSquares;
    ArrayList<ChangesOpt> changeOpts = new ArrayList<ChangesOpt>();
    ArrayList<def> defOfRooms;

    boolean PG = false;
    boolean preSet = false;
    boolean loaded=false;


    public MapPanel(final MainFrame frame) throws IOException {
        this.frame = frame;
        OptPanel();
    }

    private void OptPanel() {
        optFrame = new JFrame();
        optFrame.setSize(frame.getWidth() / 2, frame.getHeight() / 3);
        optFrame.setVisible(true);
        optFrame.setLocation(frame.width / 2 - optFrame.getSize().width / 2, frame.height / 2 - optFrame.getSize().height / 2);
        opt = new JPanel();

        opt.setPreferredSize(new Dimension(frame.getWidth() / 3, frame.getHeight() / 8));
        add(opt);
        opt.setVisible(true);

        Box VBox = Box.createVerticalBox();
        Box b1 = Box.createHorizontalBox();

        opt.add(VBox);
        b1.add(new JLabel("Choose:"));
        b1.add(Box.createRigidArea(new Dimension(20, 10)));

        JButton nm = new JButton("Normal mode");
        nm.setPreferredSize(new Dimension(500, 200));
        JButton gen = new JButton("Generating");
        gen.setPreferredSize(new Dimension(500, 200));

        Box b3 = Box.createHorizontalBox();
        b3.add(nm);
        b3.add(Box.createRigidArea(new Dimension(20, 0)));
        b3.add(gen);

        VBox.add(b1);
        VBox.add(Box.createRigidArea(new Dimension(0, 20)));
        VBox.add(b3);

        optFrame.add(opt);
        optFrame.setAlwaysOnTop(true);

        gen.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                optFrame.dispose();
                PG = true;
                SizePanel();
            }
        });

        nm.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                optFrame.dispose();
                SizePanel();
            }
        });

    }

    private void SizePanel() {

        optFrame = new JFrame();
        optFrame.setSize(frame.getWidth() / 2, frame.getHeight() / 3);
        optFrame.setVisible(true);
        optFrame.setLocation(frame.width / 2 - optFrame.getSize().width / 2, frame.height / 2 - optFrame.getSize().height / 2);

        opt = new JPanel();

        opt.setPreferredSize(new Dimension(frame.getHeight() / 2, frame.getWidth() / 4));
        add(opt);
        opt.setVisible(true);

        Box VBox = Box.createVerticalBox();
        Box b1 = Box.createHorizontalBox();
        Box b2 = Box.createHorizontalBox();
        Box b3 = Box.createHorizontalBox();
        Box b4 = Box.createHorizontalBox();
        Box b5 = Box.createHorizontalBox();

        opt.add(VBox);
        b1.add(new JLabel("Write dimensions:"));
        b1.add(Box.createRigidArea(new Dimension(20, 10)));

        final JTextField f1 = new JTextField("50");
        final JTextField f2 = new JTextField("50");

        b2.add(f1);
        b2.add(f2);

        JButton ok = new JButton("ok");
        ok.setMaximumSize(new Dimension(100, 200));
        JButton storno = new JButton("storno");
        ok.setMaximumSize(new Dimension(100, 200));
        b3.add(ok);
        b3.add(Box.createRigidArea(new Dimension(20, 0)));
        b3.add(storno);

        b4.add(new JLabel("min: 40, max: 99"));
        b5.add(new JLabel("Maps not big enough may not fit in all the rooms"));
        VBox.add(b1);
        VBox.add(Box.createRigidArea(new Dimension(0, 20)));
        VBox.add(b2);
        VBox.add(Box.createRigidArea(new Dimension(0, 20)));
        VBox.add(b3);
        VBox.add(Box.createRigidArea(new Dimension(0, 20)));
        VBox.add(b4);
        VBox.add(b5);

        optFrame.add(opt);
        optFrame.setAlwaysOnTop(true);

        storno.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                frame.ChangePanel(Main);
                optFrame.dispose();
            }
        });

        ok.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (isInt(f1.getText()) && isInt(f2.getText())) {
                    int w = Integer.parseInt(f1.getText());
                    int h = Integer.parseInt(f1.getText());
                    if (w > 39 && w < 100 && h > 39 && h < 100) {
                        MapWidth = w;
                        MapHeight = h;
                        optFrame.dispose();
                        if (PG) {
                            ProcOptPanel();

                        } else {
                            SetMapPanel();
                        }
                    }
                }

            }
        });

    }

    private void ProcOptPanel() {
        
        int x=0;
        int y=0;
        optFrame = new JFrame();
        optFrame.setSize(frame.getWidth() / 2, frame.getHeight() / 3);
        optFrame.setVisible(true);
        optFrame.setLocation(frame.width / 2 - optFrame.getSize().width / 2, frame.height / 2 - optFrame.getSize().height / 2);
        opt = new JPanel();

        opt.setPreferredSize(new Dimension(frame.getHeight() / 3, frame.getWidth() / 8));
        add(opt);
        opt.setVisible(true);

        String[] countStrings = {"void", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"};
        final JComboBox c = new JComboBox(countStrings);
        String[] patStrings = {"void", "Labyrinth", "Trough", "Sun"};
        final JComboBox p = new JComboBox(patStrings);
        JButton man = new JButton("Rooms managment");

        c.setMaximumSize(new Dimension(200, 20));
        p.setMaximumSize(new Dimension(200, 20));
        man.setMaximumSize(new Dimension(200, 20));

        Box VBox = Box.createVerticalBox();
        Box b1 = Box.createHorizontalBox();
        Box b2 = Box.createHorizontalBox();
        Box b3 = Box.createHorizontalBox();
        Box b0 = Box.createHorizontalBox();

        b1.add(new JLabel("Count of rooms: "));
        b1.add(c);

        
        b2.add(new JLabel("Pattern: "));
        b2.add(p);

        
        
        b3.add(new JLabel("Rooms managment: "));
        b3.add(man);


        Box b = Box.createHorizontalBox();
        JButton yes = new JButton("yes");
        yes.setMaximumSize(new Dimension(100, 200));
        JButton no = new JButton("no");
        yes.setMaximumSize(new Dimension(100, 200));
        b.add(yes);
        b.add(Box.createRigidArea(new Dimension(20, 0)));
        b.add(no);
        
        b0.add(new JLabel("Do you have idea?"));
        VBox.add(b0);
        VBox.add(b1);
        VBox.add(b2);
        VBox.add(b3);
        VBox.add(b);

        opt.add(VBox);
        no.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                PG = true;
                try {
                    procgen = new ProcGen(MP);
                } catch (IOException ex) {
                    Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
                procgen.setSquares(squares);
                SetMapPanel();
            }
        });

        yes.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                preSet = true;

                PG = true;
                try {
                    procgen = new ProcGen(MP);
                } catch (IOException ex) {
                    Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
                procgen.setSquares(squares);
                SetMapPanel();
                if (c.getSelectedIndex() != 0) {
                    countExactly.setEnabled(true);
                    countExactly.setText(c.getSelectedIndex() + "");
                    cor.setSelectedIndex(4);
                }

                if (p.getSelectedIndex() != 0) {
                    pot.setSelectedIndex(p.getSelectedIndex() - 1);
                }
                generate();

            }

        });

        man.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                RoomManager m = new RoomManager(c.getSelectedIndex());
            }
        });

        optFrame.add(opt);

    }

    private void SetMapPanel() {

        optFrame.dispose();
        width = frame.getWidth();
        height = frame.getHeight();
        frame.repaint();
        keyboard = new Keyboard();
        frame.add(keyboard);
        keyboard.requestFocusInWindow();

        DPanel = new DrawPanel(MapWidth, MapHeight, null);
        SPanel = new SelectionPanel();

        this.setLayout(new FlowLayout());

        DPanel.setPreferredSize(new Dimension(2 * width / 3 - 40, height - 80));
        SPanel.setPreferredSize(new Dimension(width / 3 - 40, height - 80));

        add(DPanel);
        add(SPanel);

        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        JMenu file = new JMenu("File");
        menuBar.add(file);

        JMenuItem newF = new JMenuItem("New");
        JMenuItem open = new JMenuItem("Open");
        JMenuItem save = new JMenuItem("Save");
        JMenuItem savePG = new JMenuItem("PG Save");
        JMenuItem exit = new JMenuItem("Return to Menu");

        file.add(newF);
        file.add(open);
        file.add(save);
        file.add(savePG);
        file.addSeparator();
        file.add(exit);
        frame.setVisible(true);
        setVisible(true);
        
        exit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                frame.ChangePanel(Main);
            }
        });
        newF.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                frame.ChangePanel(Map);
            }
        });
        open.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (!PG) {
                    try {
                        Square[][] sq;
                        sq = open();
                        if (sq != null) {
                            DPanel.repaintMap(sq);
                            repaint();
                        }
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex) {
                        Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } else {
                    try {
                        open();
                    } catch (IOException ex) {
                        Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    if(loaded){
                        PG = false;
                        SPanel.changePanel();
                        XC = -5;
                        YC = -5;
                        cY = 0;
                        cX = 0;
                        keyboard.requestFocusInWindow();
                        loaded=false;
                    }
                }

            }
        });
        save.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                try {
                    save(squares);
                } catch (IOException ex) {
                    Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

        savePG.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                try {
                    savePG();
                } catch (IOException ex) {
                    Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    private Square[][] open() throws FileNotFoundException, IOException {
        JFrame open = new JFrame("OPEN");

        JPanel op = new JPanel();
        op.setLayout(new BorderLayout());
        JTextArea log = new JTextArea(5, 20);
        log.setMargin(new Insets(5, 5, 5, 5));
        log.setEditable(false);
        JScrollPane logScrollPane = new JScrollPane(log);
        JFileChooser fc = new JFileChooser();
        op.add(logScrollPane, BorderLayout.CENTER);
        if (PG) {
            JOptionPane.showMessageDialog(frame, "You can open procedural generated maps only");
        } else {
            JOptionPane.showMessageDialog(frame, "You can open drawn maps only");
        }

        int returnVal = fc.showOpenDialog(op);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            Square[][] sq = new Square[MapWidth][MapHeight];
            File file = fc.getSelectedFile();
            BufferedReader br = new BufferedReader(new FileReader(file.getPath()));
            String str;
            loaded=true;
            if (PG) {
                str = br.readLine();
                String[] options = str.split(" ");
                SeedField.setText(options[0]);
                int count = Integer.parseInt(options[1]);
                if (count < 0) {
                    cor.setSelectedIndex(4);
                    countExactly.setText(Math.abs(count) + "");
                } else {
                    cor.setSelectedIndex(count);
                }

                pot.setSelectedIndex(Integer.parseInt(options[2]));
                MapWidth = Integer.parseInt(options[3]);
                MapHeight = Integer.parseInt(options[4]);

                DPanel = new DrawPanel(MapWidth, MapHeight, null);
                procgen.setSize(MapWidth, MapHeight);
                procgen.setSquares(squares);
                generate();

                str = br.readLine();
                if (!"X".equals(str)) {
                    options = str.split(" ");
                    for (String option : options) {
                        str = option;
                        changeOpts.add(new ChangesOpt(str));
                    }
                }
                str = br.readLine();
                if (!"X".equals(str)) {
                    options = str.split(" ");
                    for (String option : options) {
                        str = option;
                        changeSquares.add(new ChangesOfSquares(str));
                    }
                }

            } else {

                for (int i = 0; i < MapHeight; i++) {
                    str = br.readLine();
                    String[] strs = str.split(" ");
                    for (int j = 0; j < MapWidth; j++) {
                        sq[i][j] = new Square(i, j, Integer.parseInt(strs[j]));
                    }
                }

            }
            return sq;
        }

        open.pack();
        open.setVisible(true);
        frame.repaint();
        open.dispose();
        return null;

    }

    private void savePG() throws IOException {
        JFrame save = new JFrame("SAVE");

        JPanel op = new JPanel();
        op.setLayout(new BorderLayout());
        JTextArea log = new JTextArea(5, 20);
        log.setMargin(new Insets(5, 5, 5, 5));
        log.setEditable(false);
        JScrollPane logScrollPane = new JScrollPane(log);
        JFileChooser fc = new JFileChooser();
        op.add(logScrollPane, BorderLayout.CENTER);

        int returnVal = fc.showSaveDialog(save);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File f = fc.getSelectedFile();

            String str;

            BufferedWriter output = new BufferedWriter(new FileWriter(f));
            if (cor.getSelectedIndex() < 4) {
                str = "" + seed + " " + cor.getSelectedIndex() + " " + pot.getSelectedIndex();
            } else {
                str = "" + seed + " " + ("-" + countExactly.getText()) + " " + pot.getSelectedIndex();
            }
            str += " " + MapWidth + " " + MapHeight;
            output.write(str);
            output.newLine();
            str = "";
            if (!changeOpts.isEmpty()) {
                for (ChangesOpt change : changeOpts) {
                    str += change.print() + " ";
                }
            } else {
                str += "X";
            }
            output.write(str);
            output.newLine();
            str = "";
            if (!changeSquares.isEmpty()) {

                for (ChangesOfSquares changeSquare : changeSquares) {
                    str += changeSquare.print() + " ";
                }
            } else {
                str += "X";
            }

            output.write(str);
            output.close();
        }

    }

    private void save(Square[][] sq) throws IOException {

        JFrame save = new JFrame("SAVE");

        JPanel op = new JPanel();
        op.setLayout(new BorderLayout());
        JTextArea log = new JTextArea(5, 20);
        log.setMargin(new Insets(5, 5, 5, 5));
        log.setEditable(false);
        JScrollPane logScrollPane = new JScrollPane(log);
        JFileChooser fc = new JFileChooser();
        op.add(logScrollPane, BorderLayout.CENTER);

        int returnVal = fc.showSaveDialog(save);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File f = fc.getSelectedFile();

            String str;

            BufferedWriter output = new BufferedWriter(new FileWriter(f));
            for (Square[] sq1 : sq) {
                str = "";
                for (Square sq11 : sq1) {
                    str += Integer.toString(sq11.data) + " ";
                }
                output.write(str);
                output.newLine();
            }
            output.close();

        }
    }

    public class Square {

        int x;
        int y;

        int Xposition;
        int Yposition;

        Square predecessor = null;
        boolean seen = false;

        int size = SquareSize;
        int data = WALL_STONE;

        public void setX(int x) {
            this.x = x;
        }

        public int getX() {
            return x;
        }

        public void setY(int y) {
            this.y = y;
        }

        public int getY() {
            return y;
        }

        public Square(int x, int y) {

            Xposition = x;
            Yposition = y;

            this.x = x * size;
            this.y = y * size;
        }

        public Square(int x, int y, int c) {

            Xposition = x;
            Yposition = y;

            this.x = x * size;
            this.y = y * size;
            this.data = c;
        }

        public void changeY() {
            y = y - YC * SquareSize;

        }

        public void changeX() {
            x = x - XC * SquareSize;
        }

        public void paintSquare(Graphics g) {

            if (x < 1 || y < 1) {
                return;
            }

            g.fillRect(x, y, size, size);
            g.drawRect(x, y, size, size);

            if (data == GROUND_STONE) {
                g.drawImage(new ImageIcon("resources/img/ground_stone.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == WALL_STONE) {
                g.drawImage(new ImageIcon("resources/img/wall_stone.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == FIRE) {
                g.drawImage(new ImageIcon("resources/img/fire.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == CUPBOARD) {
                g.drawImage(new ImageIcon("resources/img/cupboard.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == CHAIR) {
                g.drawImage(new ImageIcon("resources/img/chair.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == LTABLEL) {
                g.drawImage(new ImageIcon("resources/img/ltable.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == TABLE) {
                g.drawImage(new ImageIcon("resources/img/table.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == BED) {
                g.drawImage(new ImageIcon("resources/img/bed.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == CHEST) {
                g.drawImage(new ImageIcon("resources/img/chest.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }
            if (data == ARMORY) {
                g.drawImage(new ImageIcon("resources/img/armory.jpg").getImage(), x+1, y+1, SquareSize, SquareSize, null);
            }

        }

        public void ChangeGround() {
            if (Selected == SELECTION) {
                if (selectedItem != -1) {
                    makeChange(Xposition, Yposition, data, selectedItem);
                    data = selectedItem;
                    selectedItem = -1;
                } else {
                    if (data > 6 && selectedItem == -1) {
                        makeChange(Xposition, Yposition, data, GROUND_STONE);
                        selectedItem = data;
                        data = GROUND_STONE;
                    }
                }

            } else {
                if (Selected == DELETE) {
                    if (data > 6) {
                        makeChange(Xposition, Yposition, data, GROUND_STONE);
                        data = GROUND_STONE;
                    }
                } else {
                    makeChange(Xposition, Yposition, data, Selected);
                    data = Selected;
                }

            }
        }
    }

    public void makeChange(int x, int y, int prev, int act) {

        ChangesOfSquares tmp;
        for (ChangesOfSquares changeSquare : changeSquares) {
            tmp = changeSquare;
            if (tmp.x == x && tmp.y == y) {
                changeSquare.actual = act;
                return;
            }
        }
        changeSquares.add(new ChangesOfSquares(x, y, prev, act));
    }

    class DrawPanel extends JPanel {

        int x;
        int y;

        public void repaintMap(Square[][] sq) {
            for (int i = 0; i < squares.length; i++) {
                for (int j = 0; j < squares[i].length; j++) {
                    Selected = sq[i][j].data;
                    squares[i][j].ChangeGround();
                }
            }
            repaint();
        }

        public DrawPanel(int x, int y, Square[][] sq) {
            
            this.x = x;
            this.y = y;
            setSize(new Dimension(x * SquareSize, y * SquareSize));
            squares = new Square[x][y];
            setBorder(BorderFactory.createLineBorder(Color.black));

            for (int i = 0; i < x; i++) {
                for (int j = 0; j < y; j++) {
                    squares[i][j] = new Square(i, j);
                }
            }

            addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    findSquare(e.getX(), e.getY()).ChangeGround();
                    repaint();
                    keyboard.requestFocusInWindow();
                }

            });
            keyboard.requestFocusInWindow();
        }

        private Square findSquare(int x, int y) {
            return squares[(x + (cX * SquareSize)) / SquareSize][(y + (cY * SquareSize)) / SquareSize];
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(new ImageIcon("resources/map.jpg").getImage(), 0, 0, this.getWidth(), this.getHeight(), null);
            for (Square[] square : squares) {
                for (Square sq : square) {
                    sq.paintSquare(g);
                }
            }
            
        }
    }

    final class SelectionPanel extends JPanel {

        public SelectionPanel() {

            this.setBackground(Color.LIGHT_GRAY);
            setBorder(BorderFactory.createLineBorder(Color.black));
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            this.setVisible(true);
            changePanel();
        }

        public void changePanel() {

            removeAll();

            if (PG) {
                rn = new Random();
                if (changeSquares == null) {
                    changeSquares = new ArrayList<ChangesOfSquares>();
                }
                if (changeOpts == null) {
                    changeOpts = new ArrayList<ChangesOpt>();
                }
                if (defOfRooms == null) {
                    defOfRooms = new ArrayList<def>();
                }
                procgen.setSize(MapWidth, MapHeight);
                procgen.setSquares(squares);

                SeedField = new JTextField("");
                final JButton gen = new JButton("Generate");
                String[] countStrings = {"Few", "Some", "Many", "A lot of", "Exactly"};
                cor = new JComboBox(countStrings);
                String[] patStrings = {"Labyrinth", "Trough", "Sun"};
                pot = new JComboBox(patStrings);
                JButton ok = new JButton("OK");
                JButton man = new JButton("Rooms managment");
                JButton rand = new JButton("Random");
                JButton chs = new JButton("Change");
                countExactly = new JTextField("");

                cor.setSelectedIndex(0);

                cor.setMaximumSize(new Dimension(200, 20));
                SeedField.setMaximumSize(new Dimension(200, 20));
                gen.setMaximumSize(new Dimension(200, 20));
                ok.setMaximumSize(new Dimension(200, 20));
                rand.setMaximumSize(new Dimension(200, 20));
                man.setMaximumSize(new Dimension(200, 20));
                pot.setMaximumSize(new Dimension(200, 20));
                chs.setMaximumSize(new Dimension(100, 20));
                countExactly.setMaximumSize(new Dimension(200, 20));

                rand.setAlignmentX(CENTER_ALIGNMENT);
                cor.setAlignmentX(CENTER_ALIGNMENT);
                SeedField.setAlignmentX(CENTER_ALIGNMENT);
                gen.setAlignmentX(CENTER_ALIGNMENT);
                ok.setAlignmentX(CENTER_ALIGNMENT);
                man.setAlignmentX(CENTER_ALIGNMENT);
                pot.setAlignmentX(CENTER_ALIGNMENT);
                countExactly.setAlignmentX(CENTER_ALIGNMENT);

                Box b1 = Box.createHorizontalBox();
                b1.add(SeedField);
                b1.add(chs);

                add(b1);
                add(cor);
                add(countExactly);
                add(pot);
                add(rand);
                add(man);
                add(gen);
                add(ok);

                if (preSet) {

                } else {
                    makeRandomValues();
                    countExactly.setEnabled(false);
                }

                ok.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        PG = false;
                        changePanel();
                        keyboard.requestFocusInWindow();
                    }
                });

                gen.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        generate();
                    }

                });

                rand.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        makeRandomValues();
                        generate();
                    }
                });

                man.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        RoomManager m = new RoomManager();
                    }
                });
                chs.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SeedField.setText(Math.abs(rn.nextInt()) + "");
                        generate();
                    }
                });
                cor.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (cor.getSelectedIndex() == 4) {
                            countExactly.setEnabled(true);
                        } else {
                            countExactly.setText("");
                            countExactly.setEnabled(false);
                        }
                    }
                });

            } else {
                
                if (changeSquares == null) {
                    changeSquares = new ArrayList<ChangesOfSquares>();
                }

                JButton ground = new JButton("Ground");
                JButton water = new JButton("Water");
                JButton rock = new JButton("Rock");
                JButton tree = new JButton("Tree");
                JButton ground_stone = new JButton("Ground");
                JButton wall_stone = new JButton("Wall");
                JButton sel = new JButton("Select");
                JButton ite = new JButton("Item");
                JButton del = new JButton("DELETE");

                ground.setMaximumSize(new Dimension(100, 50));
                water.setMaximumSize(new Dimension(100, 50));
                rock.setMaximumSize(new Dimension(100, 50));
                tree.setMaximumSize(new Dimension(100, 50));
                ground_stone.setMaximumSize(new Dimension(100, 50));
                wall_stone.setMaximumSize(new Dimension(100, 50));
                sel.setMaximumSize(new Dimension(100, 50));
                ite.setMaximumSize(new Dimension(100, 50));
                del.setMaximumSize(new Dimension(100, 50));

                ground.setAlignmentX(CENTER_ALIGNMENT);
                water.setAlignmentX(CENTER_ALIGNMENT);
                rock.setAlignmentX(CENTER_ALIGNMENT);
                tree.setAlignmentX(CENTER_ALIGNMENT);
                ground_stone.setAlignmentX(CENTER_ALIGNMENT);
                wall_stone.setAlignmentX(CENTER_ALIGNMENT);
                sel.setAlignmentX(CENTER_ALIGNMENT);
                ite.setAlignmentX(CENTER_ALIGNMENT);
                del.setAlignmentX(CENTER_ALIGNMENT);

                add(Box.createRigidArea(new Dimension(0, 20)));
                add(ground_stone);
                add(Box.createRigidArea(new Dimension(0, 20)));
                add(wall_stone);
                add(Box.createRigidArea(new Dimension(0, 20)));
                add(sel);
                add(Box.createRigidArea(new Dimension(0, 20)));
                add(ite);
                add(Box.createRigidArea(new Dimension(0, 20)));
                add(del);

                ground.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = GRASS;
                        keyboard.requestFocusInWindow();
                    }
                });
                water.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = WATER;
                        keyboard.requestFocusInWindow();
                    }
                });
                rock.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = ROCK;
                        keyboard.requestFocusInWindow();
                    }
                });
                tree.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = TREE;
                        keyboard.requestFocusInWindow();
                    }
                });
                ground_stone.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = GROUND_STONE;
                        keyboard.requestFocusInWindow();
                    }
                });
                wall_stone.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = WALL_STONE;
                        keyboard.requestFocusInWindow();
                    }
                });
                sel.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = SELECTION;
                        keyboard.requestFocusInWindow();
                    }
                });
                ite.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        addItem();
                        keyboard.requestFocusInWindow();
                    }
                });
                del.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Selected = DELETE;
                        keyboard.requestFocusInWindow();
                    }
                });

            }
            revalidate();
            repaint();
            keyboard.requestFocusInWindow();

        }

        public void addItem() {
            final JFrame f = new JFrame();
            f.setSize(150, 300);
            JPanel p = new JPanel();
            f.add(p);
            String[] itemStrings = {"Fire", "Table", "Chair", "Armory", "Chest", "Bed", "Cupboard"};
            final JComboBox combo = new JComboBox(itemStrings);
            combo.setMaximumSize(new Dimension(400, 100));
            combo.setSelectedIndex(0);
            p.add(combo);
            f.setVisible(true);
            JButton ok = new JButton("ok");
            p.add(ok);

            ok.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    int choice = combo.getSelectedIndex();
                    switch (choice) {
                        case 0:
                            Selected = FIRE;
                            break;
                        case 1:
                            Selected = TABLE;
                            break;
                        case 2:
                            Selected = CHAIR;
                            break;
                        case 3:
                            Selected = ARMORY;
                            break;
                        case 4:
                            Selected = CHEST;
                            break;
                        case 5:
                            Selected = BED;
                            break;
                        case 6:
                            Selected = CUPBOARD;
                            break;
                    }
                    f.dispose();
                }
            });

        }

        private void makeRandomValues() {
            SeedField.setText(Math.abs(rn.nextInt()) + "");
            cor.setSelectedIndex(Math.abs(rn.nextInt(4)));
            pot.setSelectedIndex(Math.abs(rn.nextInt(3)));
        }
    }

    class RoomManager extends JFrame {

        public RoomManager() {

            JPanel p = new JPanel();
            add(p);
            final ArrayList<ProcGen.Room> rooms = procgen.rooms;
            setSize(300, rooms.size() * 50);
            final ArrayList<JComboBox> boxes = new ArrayList<JComboBox>();
            String[] roomsStrings = {"Kitchen", "Living Room", "Armory"};
            final ArrayList<JButton> buttons = new ArrayList<JButton>();
            Box vb = Box.createVerticalBox();
            
            for (int i = 0; i < rooms.size(); i++) {
                Box b = Box.createHorizontalBox();
                b.add(new JLabel("Room " + i + ":"));
                final JComboBox combo = new JComboBox(roomsStrings);
                boxes.add(combo);
                combo.setMaximumSize(new Dimension(400, 100));
                combo.setSelectedIndex(rooms.get(i).type.type);
                final JButton ch = new JButton("change");
                buttons.add(ch);
                ch.setMaximumSize(new Dimension(400, 100));
                b.add(combo);
                b.add(ch);
                vb.add(b);

                ch.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            procgen.changeType(buttons.indexOf(ch), boxes.get(buttons.indexOf(ch)).getSelectedIndex());
                            changeOpts.add(new ChangesOpt(buttons.indexOf(ch), boxes.get(buttons.indexOf(ch)).getSelectedIndex()));
                            repaint();
                            keyboard.requestFocusInWindow();
                        } catch (IOException ex) {
                            Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }

                });

            }
            setVisible(true);
            JButton ok = new JButton("ok");
            Box b1 = Box.createHorizontalBox();
            b1.add(ok);
            vb.add(b1);
            p.add(vb);
            
            ok.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    for (int i = 0; i < rooms.size(); i++) {
                        if (rooms.get(i).type.type != boxes.get(i).getSelectedIndex()) {
                            try {
                                for (int j = 0; j < defOfRooms.size(); j++) {
                                    if (defOfRooms.get(j).room == i) {
                                        defOfRooms.remove(j);
                                        //System.out.println("mazem miestnost "+j +"z pamate ");
                                    }
                                }
                                procgen.changeType(i, boxes.get(i).getSelectedIndex());
                                changeOpts.add(new ChangesOpt(i, boxes.get(i).getSelectedIndex()));
                                repaint();
                                keyboard.requestFocusInWindow();
                                dispose();

                            } catch (IOException ex) {
                                Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }
                    dispose();
                }
            });
        }

        public RoomManager(int x) {

            final int c = x;

            JPanel p = new JPanel();
            add(p);

            setSize(300, c * 50);
            final ArrayList<JComboBox> boxes = new ArrayList<JComboBox>();
            String[] roomsStrings = {"void", "Kitchen", "Living Room", "Armory"};
            setVisible(true);
            Box Vb = Box.createVerticalBox();
            
            for (int i = 0; i < c; i++) {
                Box b = Box.createHorizontalBox();
                b.add(new JLabel("Room " + i + ":"));
                final JComboBox combo = new JComboBox(roomsStrings);
                boxes.add(combo);
                combo.setMaximumSize(new Dimension(400, 100));
                b.add(combo);
                Vb.add(b);
            }
            Box b1 = Box.createHorizontalBox();
            
            JButton ok = new JButton("ok");
            b1.add(ok);
            Vb.add(b1);
            p.add(Vb);
            defOfRooms = new ArrayList<def>();
            ok.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    for (int i = 0; i < c; i++) {
                        if (boxes.get(i).getSelectedIndex() > 0) {
                            defOfRooms.add(new def(i, boxes.get(i).getSelectedIndex() - 1));
                            changeOpts.add(new ChangesOpt(i, boxes.get(i).getSelectedIndex() - 1));
                        }
                    }
                    dispose();
                }
            });
        }
    }

    class Keyboard extends JPanel {

        public Keyboard() {
            KeyListener listener = new KeyboarddListener();
            addKeyListener(listener);
            requestFocusInWindow();
            setFocusable(true);
        }
    }

    class KeyboarddListener implements KeyListener {

        @Override
        public void keyPressed(KeyEvent e) {

            if (e.getKeyChar() == 'w') {
                YC = -1;
                cY--;
                for (Square[] square : squares) {
                    for (Square square1 : square) {
                        square1.changeY();
                    }
                }
            }
            if (e.getKeyChar() == 's') {
                YC = 1;
                cY++;
                for (Square[] square : squares) {
                    for (Square square1 : square) {
                        square1.changeY();
                    }
                }
            }
            if (e.getKeyChar() == 'a') {
                XC = -1;
                cX--;
                for (Square[] square : squares) {
                    for (Square square1 : square) {
                        square1.changeX();
                    }
                }
            }
            if (e.getKeyChar() == 'd') {
                XC = 1;
                cX++;
                for (Square[] square : squares) {
                    for (Square square1 : square) {
                        square1.changeX();
                    }
                }
            }

            repaint();
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyReleased(KeyEvent e) {
        }

    }

    public Square[][] getSquares() {
        return squares;
    }

    public void repaintMap() {
        repaint();
    }

    public void readKeyboard() {
        keyboard.requestFocusInWindow();
    }

    public void generate() {
        String str = SeedField.getText();
        clearMap();
        if (!str.isEmpty()) {
            seed = Integer.parseInt(str);
        } else {
            seed = Math.abs(rn.nextInt());
        }
        SeedField.setText(seed + "");
        procgen.setSeed(seed);
        procgen.setPattern(pot.getSelectedIndex());
        if (cor.getSelectedIndex() < 4) {
            procgen.setCountOfRooms(cor.getSelectedIndex());
        } else {
            procgen.setCountOfRoomsExactly(Integer.parseInt(countExactly.getText()));
        }
        try {
            procgen.Generate();

            for (def defOfRoom : defOfRooms) {
                procgen.changeType(defOfRoom.room, defOfRoom.type);
            }
        } catch (IOException ex) {
            Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void clearMap() {
        for (int i = 0; i < MapWidth; i++) {
            for (int j = 0; j < MapHeight; j++) {
                squares[i][j].data = WALL_STONE;
            }
        }
    }

    final class ChangesOfSquares {

        int x;
        int y;
        int initial = -1;
        int actual;

        public ChangesOfSquares(int x, int y, int prev, int act) {
            this.x = x;
            this.y = y;
            actual = act;
            if (initial == -1) {
                initial = prev;
            }
        }

        public ChangesOfSquares(String str) {
            x = Integer.parseInt(str.substring(0, 2));
            y = Integer.parseInt(str.substring(2, 4));
            actual = Integer.parseInt(str.substring(4));
            changeSquare();
        }

        public String print() {
            String str;
            if (x < 10) {
                str = "0" + x;
            } else {
                str = x + "";
            }

            if (y < 10) {
                str += "0" + y;
            } else {
                str += y;
            }

            str += actual;
            return str;
        }

        public void changeSquare() {
            squares[x][y].data = actual;
        }

    }

    final class ChangesOpt {

        int room;
        int type;

        public ChangesOpt(int r, int t) {
            room = r;
            type = t;
        }

        public ChangesOpt(String str) throws IOException {
            if (str.length() > 2) {
                room = Integer.parseInt(str.substring(0, 2));
                type = Integer.parseInt(str.substring(2));
            } else {
                room = str.charAt(0);
                type = str.charAt(1);
            }
            changeOpt();
        }

        public void changeOpt() throws IOException {
            procgen.changeType(room, type);
        }

        public String print() {
            String str;
            if (room < 10) {
                str = "0" + room;
            } else {
                str = room + "";
            }
            str += type;
            return str;
        }
    }

    class def {

        int room;
        int type;

        public def(int r, int t) {
            room = r;
            type = t;
        }
    }

    public void abort() {
        JOptionPane.showMessageDialog(frame, "I can't generate map. Too small map?");
    }

    public static boolean isInt(String str) {
        try {
            int in = Integer.parseInt(str);
        } catch (NumberFormatException nfe) {
            return false;
        }
        return true;
    }

}
