package kakuro.gui.editor;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.WindowConstants;
import kakuro.gui.Gui;
import kakuro.gui.GuiAction;
import kakuro.gui.GuiAncestor;
import kakuro.gui.ImageFactory;
import kakuro.gui.SquareLayoutManager;
import kakuro.server.ISkeletonTable;
import kakuro.server.tablefactory.SimpleSkeletonTable;
import kakuro.table.ITable;
import kakuro.table.TableException;
/**
* Skeleton szerkesztő ablak.
*/
public class SkeletonEditor extends GuiAncestor {
/** Referencia a főablakra */
private Gui _gui = null;
/** háttérkép */
private Image _back = ImageFactory.getInstance().getImage(
"kakuro/stone.jpg");
/** Toolbar és menü action-ök */
private GuiAction saveAction, exitAction, testAction, listAction, newAction, loadAction, createAction, refreshAction;
/** Skeleton panel */
private SkeletonPanel _panel = null;
/** négyzet-panel, ez kényszeríti négyzet alakúvá a skeleton panelt */
private JPanel squarePanel = null;
/** frame leghátső panelje, ez adja a kép-hátteret */
private JPanel backgroundPanel = null;
/** Vanilla konstruktor */
public SkeletonEditor(Gui gui) {
super();
_gui = gui;
}
/** Frame összerakás és konfig */
public void init() {
_frame = new JFrame("Skeleton Editor");
_frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
_frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
_frame.setVisible(false);
_frame.dispose();
}
});
populate();
_frame.pack();
_frame.setExtendedState(Frame.MAXIMIZED_BOTH|_frame.getExtendedState());
_frame.setVisible(true);
}
/** Swing komponensek felépítése, menü, toolbar, négyzetes layout a szerkesztőnek, háttér */
private void populate() {
backgroundPanel = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawTile(g, this, _back);
}
};
squarePanel = new JPanel();
squarePanel.setLayout(new SquareLayoutManager());
squarePanel.setOpaque(false);
backgroundPanel.add(squarePanel, BorderLayout.CENTER);
_frame.getContentPane().add(backgroundPanel);
backgroundPanel.setBackground(new Color(100, 100, 100));
backgroundPanel.setLayout(new BorderLayout(20, 20));
createActions();
createToolbar();
createMenus();
backgroundPanel.add(_toolbar, BorderLayout.PAGE_START);
}
/** Toolbar és menü action-öket itt hozzuk létre */
private void createActions() {
saveAction = new GuiAction("Save", "save", "Save new skeleton action",
new Integer(KeyEvent.VK_S), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
saveNewAction();
}
};
exitAction = new GuiAction("Exit", "close", "Exit action", new Integer(
KeyEvent.VK_Q), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
exitAction();
}
};
testAction = new GuiAction("Test", "fill", "Test table action", new Integer(
KeyEvent.VK_T), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
testAction();
}
};
listAction = new GuiAction("Open", "open", "List skeleton action", new Integer(
KeyEvent.VK_O), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
listAction();
}
};
newAction = new GuiAction("New", "newfile", "New skeleton action", new Integer(
KeyEvent.VK_N), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
newAction();
}
};
loadAction = new GuiAction("Load", "open", "Load skeleton action", new Integer(
KeyEvent.VK_L), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
loadAction();
}
};
createAction = new GuiAction("Create", "wizard", "Create skeleton action", new Integer(
KeyEvent.VK_W), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
createAction();
}
};
refreshAction = new GuiAction("Refresh", "refresh", "Refresh skeleton action", new Integer(
KeyEvent.VK_R), GuiAction.CTRL) {
public void actionPerformed(ActionEvent e) {
refreshAction();
}
};
}
/** Toolbar létrehozás */
private void createToolbar() {
_toolbar = new JToolBar() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//drawTile(g, this, _back);
}
};
_toolbar.setOpaque(false);
_toolbar.setFloatable(false);
loadIntoToolbar(new GuiAction[] { createAction, refreshAction, newAction, listAction, saveAction, testAction, exitAction });
}
/** Menü létrehozás */
private void createMenus() {
_menubar = new JMenuBar() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawTile(g, this, _back);
}
};
JMenu fileMenu = new JMenu("File");
loadIntoMenu(new Action[] { exitAction }, fileMenu);
fileMenu.setMnemonic(KeyEvent.VK_F);
_menubar.add(fileMenu);
//mégse kell menü, csak a helyet foglalja
//_frame.setJMenuBar(_menubar);
}
/** Kilépés a programból, az SQL shutdown hook-ok természetesen lefutnak előtte */
protected void exitAction() {
System.exit(0);
}
/** Új skeleton mentése */
protected void saveNewAction() {
_gui.getServer().saveSkeleton(_panel.getSkeleton());
}
/** Új skeleton létrehozása, ez a függvény összesen egyszer fut le, az ablak első feltöltésekor */
public void newSkeleton() {
if (_panel!=null) {
squarePanel.remove(_panel);
backgroundPanel.remove(squarePanel);
}
_panel = new SkeletonPanel(this, false);
_panel.load(new SimpleSkeletonTable());
squarePanel = new JPanel();
squarePanel.setLayout(new SquareLayoutManager());
squarePanel.setOpaque(false);
backgroundPanel.add(squarePanel, BorderLayout.CENTER);
squarePanel.add(_panel);
}
/** Új random skeletont generál, a létező skeleton nehézségi szintjével. */
protected void refreshAction() {
int level = _panel.getSkeleton().getDifficulty();
load(level);
}
/** Új random skeletont generál, a nehézségi szintet bekéri a felhasználótól. */
protected void createAction() {
int level = getDifficultyLevel();
load(level);
}
/** Új random skeletont generál, a nehézségi szintet paraméterként kapja.
*
* @param level nehézségi szint, értékei: {@link ITable#DIFFICULTY_EASY}, {@link ITable#DIFFICULTY_MEDIUM}, {@link ITable#DIFFICULTY_HARD}
* */
protected void load(int level) {
if (level>=0) {
switch (level) {
case 1: _panel.load(_gui.getServer().generateSkeleton(level));
break;
case 2: _panel.load(_gui.getServer().generateSkeleton(level));
break;
default: _panel.load(_gui.getServer().generateSkeleton(level));
break;
}
}
}
/** A szerkesztőben lévő skeletonhoz kitöltést generál. Ha a skeleton formailag nem jó(vannak benne túl hosszú
* szavak), akkor hibát dob, és nem csinál semmit. */
protected void testAction() {
if (!_panel.isCorrect()) {
JOptionPane.showMessageDialog(_frame, "<html>Nem jó a tábla.<br>Javítsd ki a sárga sorokat!</html>", "Hiba", JOptionPane.ERROR_MESSAGE);
return;
}
try {
_panel.showValues(_gui.getServer().populateSkeleton(_panel.getSkeleton()));
} catch (TableException te) {
_gui.debug(te.getLocalizedMessage());
}
}
/** Lekéri a szervertől a mentett skeleton pályák listáját, és kirakja egy dialógus ablakba, ahonnan
* a felhasználó meg tud nyitni egyet. */
protected void listAction() {
List<ISkeletonTable> list = _gui.getServer().listSkeletonTables(true);
ListSkeletonDialog dialog = new ListSkeletonDialog(_frame, "Skeleton list", list);
dialog.setLocationRelativeTo(_frame);
dialog.setVisible(true);
if (dialog.isValid()) {
_panel.load(list.get(dialog.getSelection()));
}
}
/** Kizárólag tesztelésre szolgált, a szerkesztőben lévő kitöltött táblát lehet átküldeni a fő játék ablakba. */
protected void loadAction() {
_gui.load(_panel.getLastTable());
}
/** Nehézségi szint választó dialógust dob fel.
*
* @return szint, -1 ha nem választott a felhasználó, amúgy pedig {@link ITable#DIFFICULTY_EASY},
* {@link ITable#DIFFICULTY_MEDIUM},
* {@link ITable#DIFFICULTY_HARD}
* */
protected int getDifficultyLevel() {
//Object[] possibilities = {"<html>Könnyű 5x5</html>", "<html>Közepes 8x10</html>", "<html>Nehéz 14x16</html>", "<html>Emberfeletti 42x33</html>"};
Object[] possibilities = {"<html>Könnyű 5x5</html>", "<html>Közepes 8x10</html>", "<html>Nehéz 14x16</html>"};
String s = (String)JOptionPane.showInputDialog(_frame, "<html>Nehézségi szint:<br>", "Tabla letrehozasa", JOptionPane.PLAIN_MESSAGE, null, possibilities, possibilities[0]);
if (s==null) return -1;
int level = -1;
for (int i=0; i<possibilities.length; i++) {
if (possibilities[i].equals(s)) level = i;
}
return level;
}
/** Új üres skeleton létrehozása, a nehézségi szintet bekéri a felhasználótól. */
protected void newAction() {
int level = getDifficultyLevel();
if (level>=0) {
switch (level) {
case 1: _panel.load(getNewSkeleton(8, 10, level));
break;
case 2: _panel.load(getNewSkeleton(14, 16, level));
break;
default: _panel.load(getNewSkeleton(5, 5, level));
break;
}
}
}
/** Üres Skeletont visszaadó függvény, a bal és a felső sor fekete, a maradék fehér.
*
* @param i oszlopok száma
* @param j sorok száma
* @param diff nehézségi szint, értékei: {@link ITable#DIFFICULTY_EASY},{@link ITable#DIFFICULTY_MEDIUM},
* {@link ITable#DIFFICULTY_HARD}
* @return Üres skeleton, bal és felső sor fekete
* */
protected ISkeletonTable getNewSkeleton(final int i, final int j, final int diff) {
return new ISkeletonTable() {
public int getColumnCount() { return i; }
public int getRowCount() { return j; }
public int getDifficulty() { return diff; }
public int getType(kakuro.table.Position p) {
return ((p.x==0 || p.y==0)?ISkeletonTable.CELL_BLACK:ISkeletonTable.CELL_WHITE);
}
public int getId() { return -1; }
};
}
}