Package editor

Source Code of editor.Editor

package editor;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import view.BoardPainter;
import view.BoardView;
import view.BoardViewListener;
import view.SchemeSetView;
import engine.Board;
import engine.Scheme;
import engine.SchemeSet;
import game.Synesthesia;
import generator.BoardManager;
import generator.MixGenerator;

/**
* The main editor class. Contains editor window with interface.
* It has main method so it is runnable.
*/
public class Editor extends JFrame implements
    ActionListener, MouseListener,
    AdjustmentListener, ListSelectionListener,
    BoardViewListener, WindowListener,
    SchemeDialogListener, SchemeSetDialogListener {
  private static final long serialVersionUID = 1L;

  public static void main(String[] args) {
    Editor mainFrame = new Editor();
    mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    mainFrame.setVisible(true);
  }
 
  // *****************************************************************
  // Interface content
 
  private static final int DEFAULT_FRAME_WIDTH = 850;
  private static final int DEFAULT_FRAME_HEIGHT = 650;
 
  private static final int SCHEME_ICON_SIZE = 80;
  private static final int SCHEME_FULL_ICON_SIZE = 192;
 
  // Menu interface
  private JMenuBar mbMainMenuBar;
  private JMenu mnSet;
  private JMenuItem miSetNew;
  private JMenuItem miSetOpen;
  private JMenuItem miSetReload;
  private JMenuItem miSetSave;
  private JMenuItem miSetSaveAs;
  private JMenuItem miExit;
  private JMenu mnEdit;
  private JMenuItem miEditUndo;
  private JMenuItem miEditRedo;
  private JMenuItem miEditNewScheme;
  private JMenuItem miEditDuplicateScheme;
  private JMenuItem miEditRemoveScheme;
  private JMenuItem miEditMoveSchemeForward;
  private JMenuItem miEditMoveSchemeBackward;
  private JMenuItem miEditAppendSet;
  private JMenuItem miEditRemoveAllSchemesMoves;
  private JMenuItem miEditSchemeSetProperties;
  private JMenu mnScheme;
  private JMenuItem miSchemeProperties;
  private JMenuItem miSchemeOptimizeMoves;
  private JMenuItem miSchemeAppendMoves;
  private JMenuItem miSchemeRemoveBeginMoves;
  private JMenuItem miSchemeRemoveEndMoves;
  private JMenuItem miSchemeRemoveAllMoves;
  private JMenu mnBoard;
  private JMenuItem miBoardRemoveElements;
  private JMenuItem miBoardRemoveBlocks;
  private JMenuItem miBoardConvertConcrete;
  private JMenuItem miBoardResize;
  private JMenuItem miBoardMakeConnected;
  private JMenuItem miBoardRemoveSurroundedSolids;
  private JMenu mnGenerator;
  private JMenuItem miGeneratorOutline;
  private JMenuItem miGeneratorEquivalent;
  private JMenuItem miGeneratorPrevious;
  private JMenuItem miGeneratorBlocks;
 
  // Main area interface
  private SchemeSetView viewFullSchemeSet;
  private JList lsFullSchemeSet;
  private JScrollPane spFullSchemeSet;
  private BoardView viewBoard;
 
  // Bar interface
  private JPanel plBar;
 
  private JToggleButton btSchemeList;
  private SchemeSetView viewSchemeSet;
  private JList lsSchemeSet;
  private JScrollPane spSchemeSet;
  private JButton btPrevScheme;
  private JButton btNextScheme;
 
  private JLabel lbMove;
  private JScrollBar sbMoves;

  private JLabel lbBoardMode;
  private DefaultListModel lmBoardSetType;
  private JList lsBoardSetType;
  private DefaultListModel lmBoardSetColor;
  private JList lsBoardSetColor;

  private JToggleButton btStats;
  private JToggleButton btPause;
 
  // Dialogs interface
  private JFileChooser dialogFileChooser;
  private SchemeSetDialog dialogSchemeSetProperties;
  private JDialog currentDialog;
  private SchemeDialog dialogSchemeProperties;
  private SchemeDialog dialogSchemeResize;
  private SchemeDialog dialogSchemeGenerateOutline;
  private SchemeDialog dialogSchemeGenerateBlocks;
 
  // *****************************************************************
 
  public Editor() {
    super();
    MediaTracker tracker = new MediaTracker(this);
    BoardPainter.initializeResources(tracker);
    BufferedImage imgArrow = BoardPainter.loadImage("arrow",tracker);
    try {tracker.waitForAll();} catch (InterruptedException e) {return;}
   
    // Setup interface
    this.addWindowListener(this);
    this.getContentPane().setLayout(new BorderLayout());
    this.getContentPane().setBackground(Color.BLACK);
    ArrayList<Object> gradients = new ArrayList<Object>(5);
    gradients.add(0.33f);
    gradients.add(0.00f);
    gradients.add(new Color(128,192,255));
    gradients.add(new Color(224,224,255));
    gradients.add(new Color(128,128,255));
    UIManager.put("Button.gradient",gradients);
    UIManager.put("ToggleButton.gradient",gradients);
    // Create menu interface
    mbMainMenuBar = new JMenuBar();
    this.setJMenuBar(mbMainMenuBar);

    mnSet = new JMenu("Plik");mbMainMenuBar.add(mnSet);
    miSetNew = new JMenuItem("Nowy");miSetNew.addActionListener(this);mnSet.add(miSetNew);
    mnSet.addSeparator();
    miSetOpen = new JMenuItem("Otwórz...");miSetOpen.addActionListener(this);mnSet.add(miSetOpen);
    miSetReload = new JMenuItem("Wczytaj ponownie");miSetReload.addActionListener(this);mnSet.add(miSetReload);
    mnSet.addSeparator();
    miSetSave = new JMenuItem("Zapisz");miSetSave.addActionListener(this);mnSet.add(miSetSave);
    miSetSaveAs = new JMenuItem("Zapisz jako...");miSetSaveAs.addActionListener(this);mnSet.add(miSetSaveAs);
    mnSet.addSeparator();
    miExit = new JMenuItem("Zamknij");miExit.addActionListener(this);mnSet.add(miExit);
   
    mnEdit = new JMenu("Edycja");mbMainMenuBar.add(mnEdit);
    miEditUndo = new JMenuItem("Cofnij");miEditUndo.addActionListener(this);mnEdit.add(miEditUndo);
    miEditUndo.setAccelerator(KeyStroke.getKeyStroke('Z',InputEvent.CTRL_DOWN_MASK));
    miEditRedo = new JMenuItem("Powtórz");miEditRedo.addActionListener(this);mnEdit.add(miEditRedo);
    miEditRedo.setAccelerator(KeyStroke.getKeyStroke('Y',InputEvent.CTRL_DOWN_MASK));
    mnEdit.addSeparator();
    miEditNewScheme = new JMenuItem("Nowy układ");miEditNewScheme.addActionListener(this);mnEdit.add(miEditNewScheme);
    miEditDuplicateScheme = new JMenuItem("Duplikuj układ");miEditDuplicateScheme.addActionListener(this);mnEdit.add(miEditDuplicateScheme);
    miEditRemoveScheme = new JMenuItem("Usuń układ");miEditRemoveScheme.addActionListener(this);mnEdit.add(miEditRemoveScheme);
    miEditMoveSchemeForward = new JMenuItem("Zamień z następnym układem");miEditMoveSchemeForward.addActionListener(this);mnEdit.add(miEditMoveSchemeForward);
    miEditMoveSchemeBackward = new JMenuItem("Zamień z poprzednim układem");miEditMoveSchemeBackward.addActionListener(this);mnEdit.add(miEditMoveSchemeBackward);
    mnEdit.addSeparator();
    miEditAppendSet = new JMenuItem("Dołącz układy...");miEditAppendSet.addActionListener(this);mnEdit.add(miEditAppendSet);
    mnEdit.addSeparator();
    miEditRemoveAllSchemesMoves = new JMenuItem("Usuń ruchy we wszystkich układach");miEditRemoveAllSchemesMoves.addActionListener(this);mnEdit.add(miEditRemoveAllSchemesMoves);
    mnEdit.addSeparator();
    miEditSchemeSetProperties = new JMenuItem("Schemeset properties...");miEditSchemeSetProperties.addActionListener(this);mnEdit.add(miEditSchemeSetProperties);
   
    mnScheme = new JMenu("Układ");mbMainMenuBar.add(mnScheme);
    miSchemeOptimizeMoves = new JMenuItem("Optymalizuj ruchy");miSchemeOptimizeMoves.addActionListener(this);mnScheme.add(miSchemeOptimizeMoves);
    mnScheme.addSeparator();
    miSchemeAppendMoves = new JMenuItem("Dołącz ruchy z następnego układu");miSchemeAppendMoves.addActionListener(this);mnScheme.add(miSchemeAppendMoves);
    mnScheme.addSeparator();
    miSchemeRemoveBeginMoves = new JMenuItem("Usuń wcześniejsze ruchy");miSchemeRemoveBeginMoves.addActionListener(this);mnScheme.add(miSchemeRemoveBeginMoves);
    miSchemeRemoveEndMoves = new JMenuItem("Usuń późniejsze ruchy");miSchemeRemoveEndMoves.addActionListener(this);mnScheme.add(miSchemeRemoveEndMoves);
    miSchemeRemoveAllMoves = new JMenuItem("Usuń wszystkie ruchy");miSchemeRemoveAllMoves.addActionListener(this);mnScheme.add(miSchemeRemoveAllMoves);
    mnScheme.addSeparator();
    miSchemeProperties = new JMenuItem("Scheme properties...");miSchemeProperties.addActionListener(this);mnScheme.add(miSchemeProperties);
   
    mnBoard = new JMenu("Plansza");mbMainMenuBar.add(mnBoard);
    miBoardResize = new JMenuItem("Zmień rozmiar...");miBoardResize.addActionListener(this);mnBoard.add(miBoardResize);
    mnBoard.addSeparator();
    miBoardMakeConnected = new JMenuItem("Uspójnij");miBoardMakeConnected.addActionListener(this);mnBoard.add(miBoardMakeConnected);
    mnBoard.addSeparator();
    miBoardRemoveElements = new JMenuItem("Usuń wszystko");miBoardRemoveElements.addActionListener(this);mnBoard.add(miBoardRemoveElements);
    miBoardRemoveBlocks = new JMenuItem("Usuń wszystkie bloki");miBoardRemoveBlocks.addActionListener(this);mnBoard.add(miBoardRemoveBlocks);
    miBoardRemoveSurroundedSolids = new JMenuItem("Usuń otoczone kamienie");miBoardRemoveSurroundedSolids.addActionListener(this);mnBoard.add(miBoardRemoveSurroundedSolids);
    miBoardConvertConcrete = new JMenuItem("Zamień obszary cementowe");miBoardConvertConcrete.addActionListener(this);mnBoard.add(miBoardConvertConcrete);

    mnGenerator = new JMenu("Generator");mbMainMenuBar.add(mnGenerator);
    miGeneratorOutline = new JMenuItem("Generuj szkic...");miGeneratorOutline.addActionListener(this);mnGenerator.add(miGeneratorOutline);
    mnGenerator.addSeparator();
    miGeneratorEquivalent = new JMenuItem("Mieszaj równoważnie");miGeneratorEquivalent.addActionListener(this);mnGenerator.add(miGeneratorEquivalent);
    miGeneratorPrevious = new JMenuItem("Mieszaj ze skokami");miGeneratorPrevious.addActionListener(this);mnGenerator.add(miGeneratorPrevious);
    mnGenerator.addSeparator();
    miGeneratorBlocks = new JMenuItem("Generuj bloki...");miGeneratorBlocks.addActionListener(this);mnGenerator.add(miGeneratorBlocks);

    // Create main area
    viewBoard = new BoardView();
    viewBoard.addBoardViewListener(this);
    viewBoard.setMode(BoardView.MODE_MOVING,0,0);
    this.getContentPane().add(viewBoard,BorderLayout.CENTER);
    viewFullSchemeSet = new SchemeSetView(SCHEME_FULL_ICON_SIZE,true,true);
    lsFullSchemeSet = new JList(viewFullSchemeSet);
    lsFullSchemeSet.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    lsFullSchemeSet.setLayoutOrientation(JList.HORIZONTAL_WRAP);
    lsFullSchemeSet.setFixedCellHeight(SCHEME_FULL_ICON_SIZE+2);
    lsFullSchemeSet.setFixedCellWidth(SCHEME_FULL_ICON_SIZE+2);
    lsFullSchemeSet.setVisibleRowCount(-1);
    lsFullSchemeSet.setBackground(Color.BLACK);
    lsFullSchemeSet.setSelectionBackground(Color.WHITE);
    lsFullSchemeSet.setSelectionForeground(Color.WHITE);
    lsFullSchemeSet.addListSelectionListener(this);
    lsFullSchemeSet.addMouseListener(this);
    spFullSchemeSet = new JScrollPane(lsFullSchemeSet);
    spFullSchemeSet.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    spFullSchemeSet.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

    // Create bar interface
    plBar = new JPanel();
    plBar.setLayout(new GridBagLayout());
    plBar.setPreferredSize(new Dimension(220,0));
    plBar.setBackground(Color.BLACK);
    plBar.setBorder(BorderFactory.createLoweredBevelBorder());
    this.getContentPane().add(plBar,BorderLayout.EAST);
    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 1;
    c.weighty = 0;
    c.gridx = 0;
    c.anchor = GridBagConstraints.NORTH;
    c.gridwidth = 2;

    btSchemeList = new JToggleButton();
    btSchemeList.addActionListener(this);
    plBar.add(btSchemeList,c);
   
    viewSchemeSet = new SchemeSetView(SCHEME_ICON_SIZE,false,false);
    lsSchemeSet = new JList(viewSchemeSet);
    lsSchemeSet.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    lsSchemeSet.setLayoutOrientation(JList.HORIZONTAL_WRAP);
    lsSchemeSet.setFixedCellHeight(SCHEME_ICON_SIZE+2);
    lsSchemeSet.setFixedCellWidth(SCHEME_ICON_SIZE+2);
    lsSchemeSet.setBackground(Color.BLACK);
    lsSchemeSet.setSelectionBackground(Color.DARK_GRAY);
    lsSchemeSet.setSelectionForeground(Color.WHITE);
    lsSchemeSet.setVisibleRowCount(1);
    lsSchemeSet.addListSelectionListener(this);
    lsSchemeSet.addMouseListener(this);
    spSchemeSet = new JScrollPane(lsSchemeSet);
    spSchemeSet.setBackground(Color.BLACK);
    spSchemeSet.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    spSchemeSet.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    spSchemeSet.setMinimumSize(new Dimension(2*SCHEME_ICON_SIZE,
        SCHEME_ICON_SIZE+2+spSchemeSet.getHorizontalScrollBar().getPreferredSize().height+
        spSchemeSet.getInsets().top+spSchemeSet.getInsets().bottom));
    plBar.add(spSchemeSet,c);
   
    btPrevScheme = new JButton("Poprzedni");
    btPrevScheme.addActionListener(this);
    c.gridwidth = 1;
    plBar.add(btPrevScheme,c);
    btNextScheme = new JButton("Następny");
    btNextScheme.addActionListener(this);
    c.gridx = 1;
    plBar.add(btNextScheme,c);
   
    lbMove = new JLabel();
    lbMove.setForeground(Color.WHITE);
    lbMove.setHorizontalAlignment(SwingConstants.CENTER);
    c.gridx = 0;
    c.gridwidth = 2;
    c.anchor = GridBagConstraints.SOUTH;
    c.weighty = 1;
    plBar.add(lbMove,c);
    sbMoves = new JScrollBar(JScrollBar.HORIZONTAL,0,0,0,1);
    sbMoves.addAdjustmentListener(this);
    c.weighty = 0;
    plBar.add(sbMoves,c);
   
    c.weighty = 0.2;
    lbBoardMode = new JLabel();
    lbBoardMode.setForeground(Color.WHITE);
    lbBoardMode.setHorizontalAlignment(SwingConstants.CENTER);
    plBar.add(lbBoardMode,c);
    lmBoardSetType = new DefaultListModel();
    lsBoardSetType = new JList(lmBoardSetType);
    lsBoardSetType.setBorder(BorderFactory.createEtchedBorder(Color.GRAY,Color.DARK_GRAY));
    lsBoardSetType.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    lsBoardSetType.setLayoutOrientation(JList.HORIZONTAL_WRAP);
    lsBoardSetType.setBackground(Color.BLACK);
    lsBoardSetType.setSelectionBackground(Color.GRAY);
    lsBoardSetType.setSelectionForeground(Color.WHITE);
    lsBoardSetType.setFixedCellWidth(BoardPainter.FIELD_SIZE+2);
    lsBoardSetType.setFixedCellHeight(BoardPainter.FIELD_SIZE+2);
    lsBoardSetType.setVisibleRowCount(-1);
    c.weighty = 0;
    plBar.add(lsBoardSetType,c);
    lmBoardSetColor = new DefaultListModel();
    lsBoardSetColor = new JList(lmBoardSetColor);
    lsBoardSetColor.setBorder(BorderFactory.createEtchedBorder(Color.GRAY,Color.DARK_GRAY));
    lsBoardSetColor.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    lsBoardSetColor.setLayoutOrientation(JList.HORIZONTAL_WRAP);
    lsBoardSetColor.setBackground(Color.BLACK);
    lsBoardSetColor.setSelectionBackground(Color.DARK_GRAY);
    lsBoardSetColor.setSelectionForeground(Color.WHITE);
    lsBoardSetColor.setFixedCellWidth(BoardPainter.FIELD_SIZE+2);
    lsBoardSetColor.setFixedCellHeight(BoardPainter.FIELD_SIZE+2);
    lsBoardSetColor.setVisibleRowCount(-1);
    plBar.add(lsBoardSetColor,c);
   
    btStats = new JToggleButton("Statistics");
    btStats.addActionListener(this);
    plBar.add(btStats,c);
   
    btPause = new JToggleButton("Pause");
    btPause.addActionListener(this);
    plBar.add(btPause,c);
   
    // Create dialogs
    dialogFileChooser = new JFileChooser();
    dialogSchemeSetProperties = new SchemeSetPropertiesDialog(this,this);
    dialogSchemeResize = new SchemeResizeDialog(this,this);
    dialogSchemeGenerateOutline = new SchemeGenerateOutlineDialog(this,this);   
    dialogSchemeGenerateBlocks = new SchemeGenerateBlocksDialog(this,this);
    dialogSchemeProperties = new SchemePropertiesDialog(this,this);
   
    // Create list board mode elements
    lmBoardSetType.addElement(new ImageIcon(imgArrow));// Moving
    lmBoardSetType.addElement(null);// EMPTY
    lmBoardSetType.addElement(new ImageIcon(BoardPainter.imgSolid));// SOLID
    lmBoardSetType.addElement(null);// CONCRETE
    lmBoardSetType.addElement(new ImageIcon(BoardPainter.imgIce[0]));// ICE
    lmBoardSetType.addElement(new ImageIcon(BoardPainter.imgElevator));// ELEVATOR
    lmBoardSetType.addElement(new ImageIcon(BoardPainter.imgElevatorRoot));// ELEVATOR_ROOT
    lmBoardSetType.addElement(new ImageIcon(BoardPainter.imgLava[0]));// LAVA
    lmBoardSetType.addElement(null);// CHROMATIC_PAINTER
    lmBoardSetType.addElement(null);// BLOCK_SPHERE
    lmBoardSetType.addElement(null);// BLOCK_CONCRETE
    lmBoardSetType.addElement(null);// BLOCK_BALLOON
    lmBoardSetType.addElement(null);// BLOCK_GLASS
    for (int i=0;i<Board.NUM_COLORS;i++)
      lmBoardSetColor.addElement(null);
   
    lsBoardSetType.addListSelectionListener(this);
    lsBoardSetColor.addListSelectionListener(this);
    lsBoardSetType.setSelectedIndex(0);
    lsBoardSetColor.setSelectedIndex(0);
   
    File defaultSet = new File("schemes/default.syn");
    if (!defaultSet.exists()) defaultSet = null;
    openSet(defaultSet);
   
    this.setSize(DEFAULT_FRAME_WIDTH,DEFAULT_FRAME_HEIGHT);
    viewBoard.setActive(true);
  }
 
  @Override
  public void windowClosing(WindowEvent ev) {
    actionPerformed(new ActionEvent(miExit,0,""));
  }
 
  // *****************************************************************
  // SchemeSet methods
 
  private File currentSetFile;
  private boolean currentModified;
  private int currentModifiedUndo;

  private static final int DEFAULT_BOARD_WIDTH = 0;
  private static final int DEFAULT_BOARD_HEIGHT = 0;
 
  private void openSet(File setFile) {
    currentSetFile = setFile;
    currentSchemeSet = new SchemeSet();
    boolean loaded = false;
    if (setFile != null)
      try {
        // Open and load set from given file
        currentSchemeSet.load(new FileInputStream(currentSetFile));
        loaded = true;
      } catch (IOException e) {
        JOptionPane.showMessageDialog(this,e.toString(),"Otwieranie",JOptionPane.ERROR_MESSAGE);
      }
    if (!loaded) {
      // Create new scheme in empty set
      currentSchemeSet.add(new Scheme(new Board(DEFAULT_BOARD_WIDTH,DEFAULT_BOARD_HEIGHT)));
    }
    initInterface();
    setSchemeSet(currentSchemeSet,null);
  }
 
  private void saveSet(boolean saveMoves) {
    try {
      currentSchemeSet.save(new FileOutputStream(currentSetFile));
      currentModifiedUndo = undoActions.size();
      currentModified = false;
      updateTitle();
    } catch (IOException e) {
      JOptionPane.showMessageDialog(this,e.toString(),"Zapis",JOptionPane.ERROR_MESSAGE);
    }
  }
 
  private void swapSchemes(int index1,int index2) {
    Scheme scheme = currentSchemeSet.get(index1);
    currentSchemeSet.set(index1,currentSchemeSet.get(index2));
    currentSchemeSet.set(index2,scheme);
    int moveIndex = currentMoveIndexes.get(index1);
    currentMoveIndexes.set(index1,currentMoveIndexes.get(index2));
    currentMoveIndexes.set(index2,moveIndex);
    viewSchemeSet.updateCache(index1);
    viewSchemeSet.updateCache(index2);
    viewFullSchemeSet.updateCache(index1);
    viewFullSchemeSet.updateCache(index2);
  }
 
  private void addScheme(int schemeIndex,Scheme scheme,int moveIndex) {
    currentSchemeSet.add(schemeIndex,scheme);
    currentMoveIndexes.add(schemeIndex,moveIndex);
    viewSchemeSet.updateCache();
    viewFullSchemeSet.updateCache();
  }

  private void removeScheme(int index) {
    currentSchemeSet.remove(index);
    currentMoveIndexes.remove(index);
    viewSchemeSet.updateCache();
    viewFullSchemeSet.updateCache();
  }
 
  private void replaceScheme(int index,Scheme scheme) {
    currentSchemeSet.set(index,scheme);
    viewSchemeSet.updateCache(index);
    viewFullSchemeSet.updateCache(index);
  }
 
  // *****************************************************************
  // Interface updates
 
  private void updateTitle() {
    String title;
    if (currentModified) title = "*"; else title = "";
    if (currentSetFile == null)
      title += "nowy"; else
      title += currentSetFile.getAbsolutePath();
    title += " - Synesthesia "+Synesthesia.VERSION;
    this.setTitle(title);
  }

  // The current state elements.
  public SchemeSet currentSchemeSet;
  public int currentSchemeIndex;
  public Scheme currentScheme;
  public ArrayList<Integer> currentMoveIndexes;
  public int currentMoveIndex;
 
  // Update = performs controls update connected with a state element
  // Set = sets new state and all bottom state elements

  private void initInterface() {
    currentModified = false;
    currentModifiedUndo = 0;
    updateTitle();
    undoActions = new LinkedList<UndoAction>();
    redoActions = new LinkedList<UndoAction>();
  }
 
  // SchemeSet set update
  private void setSchemeSet(SchemeSet schemeSet,ArrayList<Integer> moveIndexes) {
    setSchemeSet(schemeSet,moveIndexes,0);
  }
 
  private void setSchemeSet(SchemeSet schemeSet,ArrayList<Integer> moveIndexes,int currentSchemeIndex) {
    currentSchemeSet = schemeSet;
    if (moveIndexes == null) {
      moveIndexes = new ArrayList<Integer>(schemeSet.size());
      for (int i=0;i<schemeSet.size();i++)
        moveIndexes.add(0);
    }
    currentMoveIndexes = moveIndexes;
    viewSchemeSet.setSchemeSet(currentSchemeSet);
    viewFullSchemeSet.setSchemeSet(currentSchemeSet);
    updateUndo();
    updateSchemeSet();
    setSchemeIndex(currentSchemeIndex,true);
  }

  private void updateSchemeSet() {
    viewSchemeSet.updateCache();
    viewFullSchemeSet.updateCache();
  }
 
  // SchemeIndex
  private void setSchemeIndex(int schemeIndex,boolean fog) {
    if (schemeIndex < 0) schemeIndex = 0; else
    if (schemeIndex >= currentSchemeSet.size()) schemeIndex = currentSchemeSet.size()-1;
    currentSchemeIndex = schemeIndex;
    updateSchemeIndex();
    setScheme(currentSchemeSet.get(currentSchemeIndex),fog);
  }
 
  private void updateSchemeIndex() {
    lsSchemeSet.removeListSelectionListener(this);
    lsSchemeSet.setSelectedIndex(currentSchemeIndex);
    lsSchemeSet.ensureIndexIsVisible(currentSchemeIndex);
    lsSchemeSet.addListSelectionListener(this);
    lsFullSchemeSet.removeListSelectionListener(this);
    lsFullSchemeSet.setSelectedIndex(currentSchemeIndex);
    lsFullSchemeSet.ensureIndexIsVisible(currentSchemeIndex);
    lsFullSchemeSet.addListSelectionListener(this);
    btPrevScheme.setEnabled(currentDialog == null && currentSchemeIndex > 0);
    btNextScheme.setEnabled(currentDialog == null && currentSchemeIndex < currentSchemeSet.size()-1);
    btSchemeList.setText("Układ "+Integer.toString(currentSchemeIndex+1)+" / "+currentSchemeSet.size());
    miEditMoveSchemeBackward.setEnabled(currentSchemeIndex > 0);
    miEditMoveSchemeForward.setEnabled(currentSchemeIndex < currentSchemeSet.size()-1);
    miEditRemoveScheme.setEnabled(currentSchemeSet.size() > 1);
    miSchemeAppendMoves.setEnabled(currentSchemeIndex < currentSchemeSet.size()-1);
    updateUndo();
  }
 
  // Scheme
  private void setScheme(Scheme scheme,boolean fog) {
    currentScheme = scheme;
    updateScheme();
    if (currentMoveIndexes.get(currentSchemeIndex) > scheme.moves.size())
      setMoveIndex(scheme.moves.size(),fog); else
      setMoveIndex(currentMoveIndexes.get(currentSchemeIndex),fog);
  }
 
  private void updateScheme() {
    ;
  }

  // MoveIndex
  private void setMoveIndex(int moveIndex,boolean fog) {
    currentMoveIndex = moveIndex;
    updateMoveIndex();
    setBoard(currentScheme.getBoard(moveIndex),fog);
  }
 
  private void updateMoveIndex() {
    int moveCount = currentScheme.moves.size();
    lbMove.setText("Ruch "+Integer.toString(currentMoveIndex)+" / "+Integer.toString(moveCount));
    sbMoves.removeAdjustmentListener(this);
    sbMoves.setMaximum(moveCount);
    sbMoves.setValue(currentMoveIndex);
    sbMoves.addAdjustmentListener(this);
    miSchemeRemoveBeginMoves.setEnabled(currentMoveIndex > 0);
    miSchemeRemoveEndMoves.setEnabled(currentMoveIndex < moveCount);
    miSchemeRemoveAllMoves.setEnabled(moveCount > 0);
    currentMoveIndexes.set(currentSchemeIndex,currentMoveIndex);
    viewFullSchemeSet.updateCache(currentSchemeIndex);
  }
 
  // Board
  private void setBoard(Board board,boolean fog) {
    viewBoard.setBoard(board,currentSchemeIndex,fog);
  }
 
  // *****************************************************************
  // Undo interface
 
  private static final int MAX_UNDO = 16;
 
  private class UndoAction {
    public static final int EDIT_APPEND_SET = -8;
    public static final int EDIT_REMOVE_ALL_SCHEMES_MOVES = -7;
    public static final int EDIT_MOVE_SCHEME_BACKWARD = -6;
    public static final int EDIT_MOVE_SCHEME_FORWARD = -5;
    public static final int EDIT_REMOVE_SCHEME = -4;
    public static final int EDIT_DUPLICATE_SCHEME = -3;
    public static final int EDIT_NEW_SCHEME = -2;
    public static final int EDIT_SCHEMESET_PROPERTIES = -1;
   
    public static final int VIEW_ELEMENTS_SET = 0;
    public static final int VIEW_BLOCK_MOVED = 1;

    public static final int SCHEME_PROPERTIES = 2;
    public static final int SCHEME_OPTIMIZE_MOVES = 3;
    public static final int SCHEME_APPEND_MOVES = 4;
    public static final int SCHEME_REMOVE_BEGIN_MOVES = 5;
    public static final int SCHEME_REMOVE_END_MOVES = 6;
    public static final int SCHEME_REMOVE_ALL_MOVES = 7;

    public static final int BOARD_RESIZE = 8;
    public static final int BOARD_MAKE_CONNECTED = 9;
    public static final int BOARD_REMOVE_ELEMENTS = 10;
    public static final int BOARD_REMOVE_BLOCKS = 11;
    public static final int BOARD_CONVERT_CONCRETE = 12;
    public static final int BOARD_REMOVE_SURROUNDED_SOLIDS = 13;

    public static final int GENERATE_OUTLINE = 14;
    public static final int GENERATE_EQUIVALENT = 15;
    public static final int GENERATE_PREVIOUS = 16;
    public static final int GENERATE_BLOCKS = 17;
   
    public int type;
    // Backup data
    public SchemeSet schemeSet;
    public ArrayList<Integer> movesIndexes;
    public Scheme scheme;
    public int schemeIndex;
    public int prevMoveIndex,nextMoveIndex;
    public UndoAction(int type,SchemeSet schemeSet,ArrayList<Integer> movesIndexes,Scheme scheme,int schemeIndex,int prevMoveIndex,int nextMoveIndex) {
      this.type=type;this.schemeSet=schemeSet;this.movesIndexes=movesIndexes;this.scheme=scheme;this.schemeIndex=schemeIndex;this.prevMoveIndex=prevMoveIndex;this.nextMoveIndex=nextMoveIndex;}
    public String getName() {
      switch (type) {
      case EDIT_APPEND_SET: return miEditAppendSet.getText();
      case EDIT_REMOVE_ALL_SCHEMES_MOVES: return miEditRemoveAllSchemesMoves.getText();
      case EDIT_MOVE_SCHEME_BACKWARD: return miEditMoveSchemeBackward.getText();
      case EDIT_MOVE_SCHEME_FORWARD: return miEditMoveSchemeForward.getText();
      case EDIT_REMOVE_SCHEME: return miEditRemoveScheme.getText();
      case EDIT_DUPLICATE_SCHEME: return miEditDuplicateScheme.getText();
      case EDIT_NEW_SCHEME: return miEditNewScheme.getText();
      case EDIT_SCHEMESET_PROPERTIES: return miEditSchemeSetProperties.getText();
      case VIEW_ELEMENTS_SET: return "Ustaw elementy";
      case VIEW_BLOCK_MOVED: return "Dodaj ruch";
      case SCHEME_PROPERTIES: return miSchemeProperties.getText();
      case SCHEME_OPTIMIZE_MOVES: return miSchemeOptimizeMoves.getText();
      case SCHEME_REMOVE_BEGIN_MOVES: return miSchemeRemoveBeginMoves.getText();
      case SCHEME_REMOVE_END_MOVES: return miSchemeRemoveEndMoves.getText();
      case SCHEME_REMOVE_ALL_MOVES: return miSchemeRemoveAllMoves.getText();
      case SCHEME_APPEND_MOVES: return miSchemeAppendMoves.getText();
      case BOARD_RESIZE: return miBoardResize.getText();
      case BOARD_MAKE_CONNECTED: return miBoardMakeConnected.getText();
      case BOARD_REMOVE_ELEMENTS: return miBoardRemoveElements.getText();
      case BOARD_REMOVE_BLOCKS: return miBoardRemoveBlocks.getText();
      case BOARD_CONVERT_CONCRETE: return miBoardConvertConcrete.getText();
      case BOARD_REMOVE_SURROUNDED_SOLIDS: return miBoardRemoveSurroundedSolids.getText();
      case GENERATE_OUTLINE: return miGeneratorOutline.getText();
      case GENERATE_EQUIVALENT: return miGeneratorEquivalent.getText();
      case GENERATE_PREVIOUS: return miGeneratorPrevious.getText();
      case GENERATE_BLOCKS: return miGeneratorBlocks.getText();
      default: return "?";
      }
    }
  }
 
  private LinkedList<UndoAction> undoActions,redoActions;
 
  private void beginUndoAction(int type) {
    UndoAction action;
    // Construct undo action
    switch (type) {
    case UndoAction.EDIT_APPEND_SET: {
      action = new UndoAction(type,null,null,null,currentSchemeIndex,currentSchemeIndex,currentSchemeSet.size());
      break;
    }
    case UndoAction.EDIT_SCHEMESET_PROPERTIES:
    case UndoAction.EDIT_REMOVE_ALL_SCHEMES_MOVES: {
      action = new UndoAction(type,new SchemeSet(currentSchemeSet),new ArrayList<Integer>(currentMoveIndexes),null,0,0,0);
      break;
    }
    case UndoAction.EDIT_MOVE_SCHEME_FORWARD:
    case UndoAction.EDIT_MOVE_SCHEME_BACKWARD:
    case UndoAction.EDIT_DUPLICATE_SCHEME:
    case UndoAction.EDIT_NEW_SCHEME: {
      action = new UndoAction(type,null,null,null,currentSchemeIndex,currentMoveIndex,currentMoveIndex);
      break;
    }
    default: {
      action = new UndoAction(type,null,null,new Scheme(currentScheme),currentSchemeIndex,currentMoveIndex,currentMoveIndex);
      break;
    }
    }
    undoActions.addLast(action);
    redoActions.clear();
    while (undoActions.size() > MAX_UNDO) undoActions.removeFirst();
    updateUndo();
  }
 
  private void endUndoAction() {
    UndoAction action = undoActions.getLast();
    if (action.type == UndoAction.EDIT_APPEND_SET)
      action.nextMoveIndex = action.prevMoveIndex+currentSchemeSet.size()-action.nextMoveIndex; else
      action.nextMoveIndex = currentMoveIndex;
  }
 
  private void performUndoAction() {
    if (undoActions.size() == 0) return;
    UndoAction action = undoActions.removeLast();
    // Construct redo action
    switch (action.type) {
    case UndoAction.EDIT_APPEND_SET: {
      redoActions.addLast(new UndoAction(action.type,new SchemeSet(currentSchemeSet),new ArrayList<Integer>(currentMoveIndexes),null,action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    case UndoAction.EDIT_SCHEMESET_PROPERTIES:
    case UndoAction.EDIT_REMOVE_ALL_SCHEMES_MOVES: {
      redoActions.addLast(new UndoAction(action.type,new SchemeSet(currentSchemeSet),new ArrayList<Integer>(currentMoveIndexes),null,action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    case UndoAction.EDIT_REMOVE_SCHEME: {
      redoActions.addLast(new UndoAction(action.type,null,null,null,action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    default: {
      redoActions.addLast(new UndoAction(action.type,null,null,new Scheme(currentSchemeSet.get(action.schemeIndex)),action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    }
    updateUndo();
    // Perform undo action
    switch (action.type) {
    case UndoAction.EDIT_APPEND_SET: {
      for (int i=action.prevMoveIndex;i<action.nextMoveIndex;i++) {
        currentSchemeSet.remove(action.prevMoveIndex);
        currentMoveIndexes.remove(action.prevMoveIndex);
      }
      setSchemeSet(currentSchemeSet,currentMoveIndexes,action.schemeIndex-1);
      return;
    }
    case UndoAction.EDIT_SCHEMESET_PROPERTIES:
    case UndoAction.EDIT_REMOVE_ALL_SCHEMES_MOVES: {
      setSchemeSet(action.schemeSet,action.movesIndexes,currentSchemeIndex);
      return;
    }
    case UndoAction.EDIT_MOVE_SCHEME_BACKWARD: {
      swapSchemes(action.schemeIndex,action.schemeIndex-1);
      currentSchemeIndex = action.schemeIndex;
      break;
    }
    case UndoAction.EDIT_MOVE_SCHEME_FORWARD: {
      swapSchemes(action.schemeIndex,action.schemeIndex+1);
      currentSchemeIndex = action.schemeIndex;
      break;
    }
    case UndoAction.EDIT_REMOVE_SCHEME: {
      addScheme(action.schemeIndex,action.scheme,action.prevMoveIndex);
      currentSchemeIndex = action.schemeIndex;
      break;
    }
    case UndoAction.EDIT_DUPLICATE_SCHEME:
    case UndoAction.EDIT_NEW_SCHEME: {
      removeScheme(action.schemeIndex);
      currentSchemeIndex = action.schemeIndex-1;
      break;
    }
    default: {
      replaceScheme(action.schemeIndex,action.scheme);
      currentSchemeIndex = action.schemeIndex;
      break;
    }
    }
    currentMoveIndexes.set(currentSchemeIndex,action.prevMoveIndex);
    setSchemeIndex(currentSchemeIndex,false);
  }
 
  private void performRedoAction() {
    if (redoActions.size() == 0) return;
    UndoAction action = redoActions.removeLast();
    // Construct undo action
    switch (action.type) {
    case UndoAction.EDIT_APPEND_SET: {
      undoActions.addLast(new UndoAction(action.type,new SchemeSet(currentSchemeSet),new ArrayList<Integer>(currentMoveIndexes),null,action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    case UndoAction.EDIT_SCHEMESET_PROPERTIES:
    case UndoAction.EDIT_REMOVE_ALL_SCHEMES_MOVES: {
      undoActions.addLast(new UndoAction(action.type,new SchemeSet(currentSchemeSet),new ArrayList<Integer>(currentMoveIndexes),null,action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    case UndoAction.EDIT_REMOVE_SCHEME: {
      undoActions.addLast(new UndoAction(action.type,null,null,null,action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    case UndoAction.EDIT_NEW_SCHEME: {
      undoActions.addLast(new UndoAction(action.type,null,null,new Scheme(currentSchemeSet.get(action.schemeIndex-1)),action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    default: {
      undoActions.addLast(new UndoAction(action.type,null,null,new Scheme(currentSchemeSet.get(action.schemeIndex)),action.schemeIndex,action.prevMoveIndex,action.nextMoveIndex));
      break;
    }
    }
    updateUndo();
    // Perform redo action
    switch (action.type) {
    case UndoAction.EDIT_APPEND_SET: {
      for (int i=0;i<action.prevMoveIndex;i++)
        action.movesIndexes.set(i,currentMoveIndexes.get(i));
      for (int i=action.nextMoveIndex;i<action.movesIndexes.size();i++)
        action.movesIndexes.set(i,currentMoveIndexes.get(i-(action.nextMoveIndex-action.prevMoveIndex)));
      setSchemeSet(action.schemeSet,action.movesIndexes,action.schemeIndex);
      return;
    }
    case UndoAction.EDIT_SCHEMESET_PROPERTIES:
    case UndoAction.EDIT_REMOVE_ALL_SCHEMES_MOVES: {
      setSchemeSet(action.schemeSet,action.movesIndexes,currentSchemeIndex);
      return;
    }
    case UndoAction.EDIT_MOVE_SCHEME_BACKWARD: {
      action.schemeIndex--;
      swapSchemes(action.schemeIndex,action.schemeIndex+1);
      break;
    }
    case UndoAction.EDIT_MOVE_SCHEME_FORWARD: {
      action.schemeIndex++;
      swapSchemes(action.schemeIndex,action.schemeIndex-1);
      break;
    }
    case UndoAction.EDIT_REMOVE_SCHEME: {
      removeScheme(action.schemeIndex);
      break;
    }
    case UndoAction.EDIT_DUPLICATE_SCHEME:
    case UndoAction.EDIT_NEW_SCHEME: {
      addScheme(action.schemeIndex,action.scheme,action.nextMoveIndex);
      break;
    }
    default: {
      replaceScheme(action.schemeIndex,action.scheme);
      break;
    }
    }
    currentSchemeIndex = action.schemeIndex;
    if (currentSchemeIndex >= currentSchemeSet.size())
      currentSchemeIndex = currentSchemeSet.size()-1;
    currentMoveIndexes.set(currentSchemeIndex,action.nextMoveIndex);
    setSchemeIndex(currentSchemeIndex,false);
  }
 
  private void updateUndo() {
    if (undoActions.size() > 0) {
      miEditUndo.setEnabled(true);
      miEditUndo.setText("Cofnij: "+undoActions.getLast().getName());
    } else {
      miEditUndo.setEnabled(false);
      miEditUndo.setText("Cofnij");
    }
    if (currentModifiedUndo != undoActions.size()) {
      if (!currentModified) {
        currentModified = true;
        updateTitle();
      }
    } else {
      if (currentModified) {
        currentModified = false;
        updateTitle();
      }
    }
    if (redoActions.size() > 0) {
      miEditRedo.setEnabled(true);
      miEditRedo.setText("Powtórz: "+redoActions.getLast().getName());
    } else {
      miEditRedo.setEnabled(false);
      miEditRedo.setText("Powtórz");
    }
  }
 
  private void setDialog(JDialog dialog) {
    boolean enabled = (dialog == null);
    currentDialog = dialog;
    if (dialog != null) {
      if (dialog instanceof SchemeDialog) {
        setScheme(new Scheme(currentSchemeSet.get(currentSchemeIndex)),false);
        ((SchemeDialog)dialog).setScheme(currentSchemeSet.get(currentSchemeIndex));
      } else {
        setSchemeSet(new SchemeSet(currentSchemeSet),currentMoveIndexes);
        ((SchemeSetDialog)dialog).setSchemeSet(currentSchemeSet);
      }
      dialog.setVisible(true);
    }
    mnSet.setEnabled(enabled);
    mnEdit.setEnabled(enabled);
    mnScheme.setEnabled(enabled);
    mnBoard.setEnabled(enabled);
    mnGenerator.setEnabled(enabled);
    lsFullSchemeSet.setEnabled(enabled);
    lsSchemeSet.setEnabled(enabled);
    btPrevScheme.setEnabled(enabled);
    btNextScheme.setEnabled(enabled);
  }
 
  // *****************************************************************
  // Interface actions
 
  @Override
  public void blockMoved(boolean direction,int x,int y) {
    if (currentDialog == null) beginUndoAction(UndoAction.VIEW_BLOCK_MOVED);
    currentScheme.movesTrimEnd(currentScheme.moves.size() - currentMoveIndex);
    currentScheme.moves.add(new Scheme.Move(direction,x,y));
    currentMoveIndex++;
    updateMoveIndex();
    if (currentDialog == null) endUndoAction();
  }

  @Override
  public void elementsSet() {
    if (currentDialog == null) beginUndoAction(UndoAction.VIEW_ELEMENTS_SET);   
    currentScheme.movesTrimStart(currentMoveIndex);
    currentMoveIndex = 0;
    currentScheme.setStart(new Board(viewBoard.getBoard()));
    viewSchemeSet.updateCache(currentSchemeIndex);
    viewFullSchemeSet.updateCache(currentSchemeIndex);
    updateMoveIndex();
    if (currentDialog == null) endUndoAction();
  }

  @Override
  public void fieldSelected(int x, int y) {
    /*Board board = viewBoard.getBoard();
    if (board.isBlock(x,y)) {
      viewBoard.pause();
      currentScheme.movesTrimStart(currentMoveIndex);
      replaceScheme(currentSchemeIndex,currentScheme);
      setMoveIndex(0,false);
    }*/
  }
 
  @Override
  public void schemeDialogCanceled(SchemeDialog dialog) {
    setSchemeIndex(currentSchemeIndex,false);
    setDialog(null);
  }

  @Override
  public void schemeDialogDone(SchemeDialog dialog) {
    setDialog(null);
    if (dialog == dialogSchemeResize)
      beginUndoAction(UndoAction.BOARD_RESIZE); else   
    if (dialog == dialogSchemeGenerateOutline)
      beginUndoAction(UndoAction.GENERATE_OUTLINE); else
    //if (dialog == dialogSchemeGenerateBlocks)
      beginUndoAction(UndoAction.GENERATE_BLOCKS);
    replaceScheme(currentSchemeIndex,currentScheme);
    setSchemeIndex(currentSchemeIndex,false);
    endUndoAction();
  }

  @Override
  public void schemeDialogResult(SchemeDialog dialog,Scheme result) {
    setScheme(result,false);
  }

  @Override
  public void schemesetDialogDone(SchemeSetDialog dialog) {
    setDialog(null);
    SchemeSet newSchemeSet = currentSchemeSet;
    setSchemeSet(dialog.originalSchemeSet,currentMoveIndexes);
    beginUndoAction(UndoAction.EDIT_SCHEMESET_PROPERTIES);
    setSchemeSet(newSchemeSet,currentMoveIndexes,currentSchemeIndex);
    endUndoAction();
  }

  @Override
  public void schemesetDialogCanceled(SchemeSetDialog dialog) {
    setSchemeSet(dialog.originalSchemeSet,currentMoveIndexes);
    setDialog(null);
  }
 
  @Override
  public void schemesetDialogResult(SchemeSetDialog dialog,SchemeSet result) {
    setSchemeSet(result,currentMoveIndexes,currentSchemeIndex);
  }

  @Override
  public void adjustmentValueChanged(AdjustmentEvent ev) {
    if (ev.getSource() == sbMoves) {
      viewBoard.pause();
      setMoveIndex(sbMoves.getValue(),false);
    }
  }

  @Override
  public void valueChanged(ListSelectionEvent ev) {
    if (ev.getSource() == lsFullSchemeSet) {
      viewBoard.pause();
      setSchemeIndex(lsFullSchemeSet.getSelectedIndex(),true);
    } else
   
    if (ev.getSource() == lsSchemeSet) {
      viewBoard.pause();
      setSchemeIndex(lsSchemeSet.getSelectedIndex(),true);
    } else

    if (ev.getSource() == lsBoardSetType ||
        ev.getSource() == lsBoardSetColor) {
      int t = lsBoardSetType.getSelectedIndex()-1;
      int c = lsBoardSetColor.getSelectedIndex();
      lsBoardSetColor.setEnabled(true);
      if (ev.getSource() == lsBoardSetType) {
        switch (t) {
        case Board.CONCRETE: for (int i=0;i<Board.NUM_COLORS;i++) lmBoardSetColor.set(i,new ImageIcon(BoardPainter.imgConcrete[i]));break;
        case Board.PAINTER: for (int i=0;i<Board.NUM_COLORS;i++) lmBoardSetColor.set(i,new ImageIcon(BoardPainter.imgPainter[i]));break;
        case Board.BLOCK_SPHERE: for (int i=0;i<Board.NUM_COLORS;i++) lmBoardSetColor.set(i,new ImageIcon(BoardPainter.imgBlocks[0][i][0]));break;
        case Board.BLOCK_CONCRETE: for (int i=0;i<Board.NUM_COLORS;i++) lmBoardSetColor.set(i,new ImageIcon(BoardPainter.imgBlocks[1][i][0]));break;
        case Board.BLOCK_BALLOON: for (int i=0;i<Board.NUM_COLORS;i++) lmBoardSetColor.set(i,new ImageIcon(BoardPainter.imgBlocks[2][i][0]));break;
        case Board.BLOCK_GLASS: for (int i=0;i<Board.NUM_COLORS;i++) lmBoardSetColor.set(i,new ImageIcon(BoardPainter.imgBlocks[3][i][0]));break;
        default:lsBoardSetColor.setEnabled(false);for (int i=0;i<Board.NUM_COLORS;i++) lmBoardSetColor.set(i,null);break;
        }
      } else
      if (ev.getSource() == lsBoardSetColor) {
        lmBoardSetType.set(Board.CONCRETE+1,new ImageIcon(BoardPainter.imgConcrete[c]));
        lmBoardSetType.set(Board.PAINTER+1,new ImageIcon(BoardPainter.imgPainter[c]));
        lmBoardSetType.set(Board.BLOCK_SPHERE+1,new ImageIcon(BoardPainter.imgBlocks[0][c][0]));
        lmBoardSetType.set(Board.BLOCK_CONCRETE+1,new ImageIcon(BoardPainter.imgBlocks[1][c][0]));
        lmBoardSetType.set(Board.BLOCK_BALLOON+1,new ImageIcon(BoardPainter.imgBlocks[2][c][0]));
        lmBoardSetType.set(Board.BLOCK_GLASS+1,new ImageIcon(BoardPainter.imgBlocks[3][c][0]));
      }
      switch (t) {
      case -1: lbBoardMode.setText("Przesuwanie");break;
      case Board.EMPTY: lbBoardMode.setText("Obszar pusty");break;
      case Board.SOLID: lbBoardMode.setText("Obszar kamień");break;
      case Board.CONCRETE: lbBoardMode.setText("Obszar cement, kolor "+Integer.toString(c));break;
      case Board.ICE: lbBoardMode.setText("Obszar lód");break;
      case Board.ELEVATOR: lbBoardMode.setText("Winda");break;
      case Board.ELEVATOR_ROOT: lbBoardMode.setText("Kolumna windy");break;
      case Board.LAVA: lbBoardMode.setText("Lawa");break;
      case Board.PAINTER: lbBoardMode.setText("Malarz, kolor "+Integer.toString(c));break;
      case Board.BLOCK_SPHERE: lbBoardMode.setText("Blok sfera, kolor "+Integer.toString(c));break;
      case Board.BLOCK_CONCRETE: lbBoardMode.setText("Blok cement, kolor "+Integer.toString(c));break;
      case Board.BLOCK_BALLOON: lbBoardMode.setText("Blok balonik, kolor "+Integer.toString(c));break;
      case Board.BLOCK_GLASS: lbBoardMode.setText("Blok szkło, kolor "+Integer.toString(c));break;
      }
      switch (t) {
      case -1: viewBoard.setMode(BoardView.MODE_MOVING,0,0);break;
      default: viewBoard.setMode(BoardView.MODE_SETTING,t,c);break;
      }
    }
  }

  @Override
  public void mouseClicked(MouseEvent ev) {
    if (ev.getSource() == lsFullSchemeSet || ev.getSource() == lsSchemeSet) {
      if (ev.getClickCount() > 1) {
        btSchemeList.doClick();
      }
    }
  }

  @Override
  public void mouseEntered(MouseEvent ev) {}
  @Override
  public void mouseExited(MouseEvent ev) {}
  @Override
  public void mousePressed(MouseEvent ev) {}
  @Override
  public void mouseReleased(MouseEvent ev) {}

  public void actionPerformed(ActionEvent ev) {
    // ***************************************************************
    // Set menu
   
    if (ev.getSource() == miSetNew) {
      viewBoard.pause();
      openSet(null);
      viewBoard.resume();
    } else
     
    if (ev.getSource() == miSetOpen) {
      viewBoard.pause();
      if (dialogFileChooser.showDialog(this,"Otwórz...") == JFileChooser.APPROVE_OPTION) {
        openSet(dialogFileChooser.getSelectedFile());
      }
      viewBoard.resume();
    } else
     
    if (ev.getSource() == miSetReload) {
      viewBoard.pause();
      int oldCurrentSchemeIndex = currentSchemeIndex;
      openSet(currentSetFile);
      if (oldCurrentSchemeIndex < currentSchemeSet.size())
        setSchemeIndex(oldCurrentSchemeIndex,true);
      viewBoard.resume();
    } else
       
    if (ev.getSource() == miSetSave && currentSetFile != null) {
      viewBoard.pause();
      saveSet(true);
      viewBoard.resume();
    } else
       
    if (ev.getSource() == miSetSaveAs || (ev.getSource() == miSetSave && currentSetFile == null)) {
      viewBoard.pause();
      if (dialogFileChooser.showDialog(this,"Zapisz zestaw...") == JFileChooser.APPROVE_OPTION) {
        currentSetFile = dialogFileChooser.getSelectedFile();
        saveSet(true);
      }
      viewBoard.resume();
    } else

    if (ev.getSource() == miExit) {
      viewBoard.pause();
      if (currentModified) {
        int result = JOptionPane.showConfirmDialog(this,"Do you want to save the current schemeset?");
        if (result == JOptionPane.CANCEL_OPTION) return;
        if (result == JOptionPane.YES_OPTION) {
          actionPerformed(new ActionEvent(miSetSave,0,""));
          if (currentModified) return;
        }
      }
      this.setVisible(false);
      this.dispose();
      return;
    } else

    // ***************************************************************
    // Edit menu
   
    if (ev.getSource() == miEditUndo) {
      viewBoard.pause();
      performUndoAction();
      viewBoard.resume();
    } else

    if (ev.getSource() == miEditRedo) {
      viewBoard.pause();
      performRedoAction();
      viewBoard.resume();
    } else
       
    if (ev.getSource() == miEditNewScheme) {
      viewBoard.pause();
      currentSchemeIndex++;
      beginUndoAction(UndoAction.EDIT_NEW_SCHEME);
      addScheme(currentSchemeIndex,new Scheme(new Board(DEFAULT_BOARD_WIDTH,DEFAULT_BOARD_HEIGHT)),currentMoveIndex);
      setSchemeIndex(currentSchemeIndex,true);
      endUndoAction();
    } else

    if (ev.getSource() == miEditDuplicateScheme) {
      viewBoard.pause();
      currentSchemeIndex++;
      beginUndoAction(UndoAction.EDIT_DUPLICATE_SCHEME);   
      addScheme(currentSchemeIndex,new Scheme(currentSchemeSet.get(currentSchemeIndex-1)),currentMoveIndex);
      setSchemeIndex(currentSchemeIndex,true);
      endUndoAction();
    } else

    if (ev.getSource() == miEditRemoveScheme) {
      if (currentSchemeSet.size() > 1) {
        viewBoard.pause();
        beginUndoAction(UndoAction.EDIT_REMOVE_SCHEME);   
        removeScheme(currentSchemeIndex);
        if (currentSchemeIndex >= currentSchemeSet.size())
          currentSchemeIndex = currentSchemeSet.size()-1;
        setSchemeIndex(currentSchemeIndex,true);
        endUndoAction();
      }
    } else
     
    if (ev.getSource() == miEditMoveSchemeForward) {
      if (currentSchemeIndex < currentSchemeSet.size()-1) {
        viewBoard.pause();
        beginUndoAction(UndoAction.EDIT_MOVE_SCHEME_FORWARD);   
        swapSchemes(currentSchemeIndex,currentSchemeIndex+1);
        currentSchemeIndex++;
        updateSchemeIndex();
        endUndoAction();
        viewBoard.resume();
      }
    } else

    if (ev.getSource() == miEditMoveSchemeBackward) {
      if (currentSchemeIndex > 0) {
        viewBoard.pause();
        beginUndoAction(UndoAction.EDIT_MOVE_SCHEME_BACKWARD);   
        swapSchemes(currentSchemeIndex,currentSchemeIndex-1);
        currentSchemeIndex--;
        updateSchemeIndex();
        endUndoAction();
        viewBoard.resume();
      }
    } else

    if (ev.getSource() == miEditRemoveAllSchemesMoves) {
      viewBoard.pause();
      beginUndoAction(UndoAction.EDIT_REMOVE_ALL_SCHEMES_MOVES);
      for (int i=0;i<currentSchemeSet.size();i++) {
        currentSchemeSet.get(i).moves.clear();
        currentMoveIndexes.set(i,0);       
      }
      endUndoAction();
      updateSchemeSet();
      setMoveIndex(0,false);
      viewBoard.resume();
    } else
       
    if (ev.getSource() == miEditAppendSet) {
      viewBoard.pause();
      if (dialogFileChooser.showDialog(this,"Dołącz układy...") == JFileChooser.APPROVE_OPTION) {
        try {
        SchemeSet appendingSet = new SchemeSet(new FileInputStream(dialogFileChooser.getSelectedFile()));
        currentSchemeIndex++;
        beginUndoAction(UndoAction.EDIT_APPEND_SET);
        currentSchemeSet.addAll(currentSchemeIndex,appendingSet);
        for (int i=0;i<appendingSet.size();i++)
          currentMoveIndexes.add(currentSchemeIndex+i,0);
        setSchemeSet(currentSchemeSet,currentMoveIndexes,currentSchemeIndex);
        endUndoAction();
        } catch (IOException e) {}
      }
      viewBoard.resume();
    } else
   
    if (ev.getSource() == miEditSchemeSetProperties) {
      setDialog(dialogSchemeSetProperties);
    } else
   
    // ***************************************************************
    // Scheme menu
   
    if (ev.getSource() == miSchemeProperties) {
      setDialog(dialogSchemeProperties);
    } else
     
    if (ev.getSource() == miSchemeOptimizeMoves) {
      viewBoard.pause();
      beginUndoAction(UndoAction.SCHEME_OPTIMIZE_MOVES);
      currentScheme.optimizeMoves();
      setMoveIndex(0,false);
      endUndoAction();
    } else
     
    if (ev.getSource() == miSchemeRemoveBeginMoves) {
      viewBoard.pause();
      beginUndoAction(UndoAction.SCHEME_REMOVE_BEGIN_MOVES);
      currentScheme.movesTrimStart(currentMoveIndex);
      replaceScheme(currentSchemeIndex,currentScheme);
      setMoveIndex(0,false);
      endUndoAction();
    } else
   
    if (ev.getSource() == miSchemeRemoveEndMoves) {
      beginUndoAction(UndoAction.SCHEME_REMOVE_END_MOVES);
      currentScheme.movesTrimEnd(currentScheme.moves.size() - currentMoveIndex);
      updateMoveIndex();
      endUndoAction();
    } else
     
    if (ev.getSource() == miSchemeRemoveAllMoves) {
      beginUndoAction(UndoAction.SCHEME_REMOVE_ALL_MOVES);
      currentScheme.movesTrimStart(currentMoveIndex);
      currentScheme.movesTrimEnd(currentScheme.moves.size());
      replaceScheme(currentSchemeIndex,currentScheme);
      setMoveIndex(0,false);
      endUndoAction();
    } else
     
    if (ev.getSource() == miSchemeAppendMoves) {
      if (currentSchemeIndex < currentSchemeSet.size()-1) {
        viewBoard.pause();
        beginUndoAction(UndoAction.SCHEME_APPEND_MOVES);
        currentSchemeSet.get(currentSchemeIndex).appendMoves(currentSchemeSet.get(currentSchemeIndex+1));
        updateMoveIndex();
        endUndoAction();
        viewBoard.resume();
      }
    } else

    // ***************************************************************
    // Board menu
   
    if (ev.getSource() == miBoardResize) {
      setDialog(dialogSchemeResize);
    } else
              
    if (ev.getSource() == miBoardMakeConnected) {
      viewBoard.pause();
      beginUndoAction(UndoAction.BOARD_MAKE_CONNECTED);
      BoardManager.makeConnected(currentScheme.start);
      currentScheme.start.doFramesToStability();
      currentScheme.removeIncorrectMoves();
      replaceScheme(currentSchemeIndex,currentScheme);
      currentMoveIndexes.set(currentSchemeIndex,0);
      setSchemeIndex(currentSchemeIndex,false);
      endUndoAction();
    } else
   
    if (ev.getSource() == miBoardRemoveElements) {
      beginUndoAction(UndoAction.BOARD_REMOVE_ELEMENTS);
      BoardManager.removeElements(currentScheme.start);
      currentScheme.moves.clear();
      setSchemeIndex(currentSchemeIndex,false);
      endUndoAction();
    } else
         
    if (ev.getSource() == miBoardConvertConcrete) {
      beginUndoAction(UndoAction.BOARD_CONVERT_CONCRETE);
      BoardManager.convertConcrete(currentScheme.start);
      setSchemeIndex(currentSchemeIndex,false);
      endUndoAction();
    } else
           
    if (ev.getSource() == miBoardRemoveBlocks) {
      beginUndoAction(UndoAction.BOARD_REMOVE_BLOCKS);
      BoardManager.removeBlocks(currentScheme.start);
      currentScheme.moves.clear();
      setSchemeIndex(currentSchemeIndex,false);
      endUndoAction();
    } else
          
    if (ev.getSource() == miBoardRemoveSurroundedSolids) {
      viewBoard.pause();
      beginUndoAction(UndoAction.BOARD_REMOVE_SURROUNDED_SOLIDS);
      BoardManager.removeSurroundedSolids(currentScheme.start);
      replaceScheme(currentSchemeIndex,currentScheme);
      setSchemeIndex(currentSchemeIndex,false);
      endUndoAction();
    } else
     
    // ***************************************************************
    // Generator menu
   
    if (ev.getSource() == miGeneratorOutline) {
      setDialog(dialogSchemeGenerateOutline);
    } else
   
    if (ev.getSource() == miGeneratorEquivalent) {
      viewBoard.pause();
      beginUndoAction(UndoAction.GENERATE_EQUIVALENT);
      Scheme mixedScheme = MixGenerator.generateEquivalent(1.0d,currentScheme);
      mixedScheme.appendMoves(currentScheme);
      replaceScheme(currentSchemeIndex,mixedScheme);
      currentMoveIndexes.set(currentSchemeIndex,0);
      setSchemeIndex(currentSchemeIndex,false);
      endUndoAction();
    } else
    
    if (ev.getSource() == miGeneratorPrevious) {
      viewBoard.pause();
      beginUndoAction(UndoAction.GENERATE_PREVIOUS);
      Scheme mixedScheme = MixGenerator.generatePrevious(1.0d,currentScheme);
      mixedScheme.appendMoves(currentScheme);
      replaceScheme(currentSchemeIndex,mixedScheme);
      currentMoveIndexes.set(currentSchemeIndex,0);
      setSchemeIndex(currentSchemeIndex,false);
      endUndoAction();
    } else
     
    if (ev.getSource() == miGeneratorBlocks) {
      setDialog(dialogSchemeGenerateBlocks);
    } else
   
    // ***************************************************************
    // Bar menu
   
    if (ev.getSource() == btSchemeList) {
      if (btSchemeList.isSelected()) {
        this.getContentPane().remove(viewBoard);
        this.getContentPane().add(spFullSchemeSet,BorderLayout.CENTER);
      } else {
        this.getContentPane().remove(spFullSchemeSet);
        this.getContentPane().add(viewBoard,BorderLayout.CENTER);
      }
      this.validate();
      repaint();
    } else

    if (ev.getSource() == btPrevScheme) {
      if (currentSchemeIndex > 0) {
        setSchemeIndex(currentSchemeIndex-1,true);
      }
    } else
   
    if (ev.getSource() == btNextScheme) {
      if (currentSchemeIndex < currentSchemeSet.size()-1) {
        setSchemeIndex(currentSchemeIndex+1,true);
      }
    } else
   
    if (ev.getSource() == btStats) {
      viewBoard.setStatisticsVisible(btStats.isSelected());
    } else
   
    if (ev.getSource() == btPause) {
      viewBoard.setActive(!btPause.isSelected());
    }
  }

  @Override
  public void windowOpened(WindowEvent ev) {}
  @Override
  public void windowClosed(WindowEvent ev) {}
  @Override
  public void windowIconified(WindowEvent ev) {}
  @Override
  public void windowDeiconified(WindowEvent ev) {}
  @Override
  public void windowActivated(WindowEvent e) {}
  @Override
  public void windowDeactivated(WindowEvent e) {}

  // *****************************************************************
TOP

Related Classes of editor.Editor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.