1 /*
2  *  CVS: $Id: MapEditorComposite.java,v 1.22 2004/07/25 21:40:56 marcus Exp $
3  * 
4  *  This file is part of zuul.
5  *
6  *  zuul is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10 *
11 *  zuul is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with zuul; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 * 
20 *  Copyrigth 2004 by marcus, leh
21 * 
22 */
23package org.jzuul.gdk.swt;
24
25import java.text.MessageFormat;
26import java.util.ArrayList;
27import java.util.Iterator;
28
29import org.eclipse.swt.SWT;
30import org.eclipse.swt.events.SelectionEvent;
31import org.eclipse.swt.events.SelectionListener;
32import org.eclipse.swt.layout.GridData;
33import org.eclipse.swt.layout.GridLayout;
34import org.eclipse.swt.widgets.Button;
35import org.eclipse.swt.widgets.Combo;
36import org.eclipse.swt.widgets.Composite;
37import org.eclipse.swt.widgets.Event;
38import org.eclipse.swt.widgets.Group;
39import org.eclipse.swt.widgets.Label;
40import org.eclipse.swt.widgets.List;
41import org.eclipse.swt.widgets.Menu;
42import org.eclipse.swt.widgets.MenuItem;
43import org.eclipse.swt.widgets.MessageBox;
44import org.eclipse.swt.widgets.Shell;
45import org.jdom.Element;
46import org.jzuul.engine.GameFileReader;
47import org.jzuul.engine.GameMap;
48import org.jzuul.engine.exceptions.ConnectAllRoomsFailed;
49import org.jzuul.engine.exceptions.NoSuchRoomException;
50
51/**
52 * 
53 * Created on Jul 14, 2004
54 * 
55 * 
56 * @version $Revision: 1.22 $
57 */
58public class MapEditorComposite extends Composite {
59
60    java.util.List maps;
61
62    Combo mapCombo;
63
64    private List roomList;
65
66    private RoomDetailsComposite roomDetailComp;
67
68    private Combo startRoom;
69
70    private Button verifyButton;
71
72    /**
73     * @param arg0
74     * @param arg1
75     */
76    public MapEditorComposite(Composite arg0, int arg1) {
77        super(arg0, arg1);
78        maps = new ArrayList();
79
80        this.setLayout(new GridLayout(5, true));
81        GridData mapEditorDat = new GridData(GridData.FILL_BOTH);
82        this.setLayoutData(mapEditorDat);
83
84        // first row: label, map combo, new button, delete button
85        Label mapLabel = new Label(this, SWT.NONE);
86        GridData labelDat = new GridData(GridData.HORIZONTAL_ALIGN_END);
87        mapLabel.setLayoutData(labelDat);
88        mapLabel.setText(Messages.getString("MAP_COLON")); //$NON-NLS-1$
89
90        mapCombo = new Combo(this, SWT.READ_ONLY);
91        GridData comboDat = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
92        mapCombo.setLayoutData(comboDat);
93        mapCombo.add("default"); //$NON-NLS-1$
94        mapCombo.addSelectionListener(new SelectionListener() {
95
96            public void widgetSelected(SelectionEvent arg0) {
97                String[] roomNames = getRoomNames(mapCombo.getText());
98                roomList.setItems(roomNames);
99                roomList.select(0);
00                roomList.notifyListeners(SWT.Selection, new Event());
01                startRoom.setItems(roomNames);
02                String startroom = getMap(mapCombo.getText()).getAttributeValue("startroom"); //$NON-NLS-1$
03                if (startroom != null) startRoom.select(startRoom.indexOf(startroom));
04
05            }
06
07            public void widgetDefaultSelected(SelectionEvent arg0) {
08            }
09        });
10
11        final int buttonWidthHint = 100;
12        Button newButton = new Button(this, SWT.PUSH);
13        GridData nbDat = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
14        nbDat.widthHint = buttonWidthHint;
15        newButton.setLayoutData(nbDat);
16        newButton.setText(Messages.getString("NEW_2")); //$NON-NLS-1$
17        newButton.addSelectionListener(new SelectionListener() {
18
19            public void widgetSelected(SelectionEvent arg0) {
20                InputDialog id = new InputDialog(new Shell(arg0.display), SWT.NONE);
21                id.setMessage(Messages.getString("MAP_NAME_ENTER")); //$NON-NLS-1$
22                String retval = id.openNoWhitespace();
23                if (retval != null) {
24                    if (mapCombo.indexOf(retval) > -1) {
25                        Object[] formatArgs = {retval};
26                        MessageBox mb = new MessageBox(new Shell(arg0.display), SWT.ICON_ERROR);
27                        mb.setMessage(MessageFormat.format(Messages.getString("MAP_SAME_NAME_MSG"),formatArgs)); //$NON-NLS-1$
28                        mb.open();
29                    } else {
30                        mapCombo.add(retval);
31                        maps.add(new Element("map").setAttribute("name", retval)); //$NON-NLS-1$ //$NON-NLS-2$
32                        mapCombo.select(mapCombo.indexOf(retval));
33                        mapCombo.notifyListeners(SWT.Selection, new Event());
34                    }
35                }
36
37            }
38
39            public void widgetDefaultSelected(SelectionEvent arg0) {
40            }
41        });
42
43        Button deleteButton = new Button(this, SWT.PUSH);
44        GridData dbDat = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
45        dbDat.widthHint = buttonWidthHint;
46        deleteButton.setLayoutData(dbDat);
47        deleteButton.setText(Messages.getString("DELETE")); //$NON-NLS-1$
48        deleteButton.addSelectionListener(new SelectionListener() {
49
50            public void widgetSelected(SelectionEvent arg0) {
51                //TODO add r u sure
52                try {
53                    String mapName = mapCombo.getText();
54                    if (mapName.equals("default")) { //$NON-NLS-1$
55                        MessageBox mb = new MessageBox(new Shell(arg0.display), SWT.ICON_ERROR);
56                        mb.setMessage(Messages.getString("DELETE_DEFAULT_ERROR")); //$NON-NLS-1$
57                        mb.open();
58                        return;
59                    }
60                    roomDetailComp.clear();
61                    roomList.removeAll();
62                    getMap(mapName).detach();
63                    mapCombo.setItems(getMapNames()); 
64                    if (mapCombo.getItemCount() > 0 ) {
65                        mapCombo.select(0);
66                        mapCombo.notifyListeners(SWT.Selection, new Event());
67                    }
68                } catch (Exception e) {
69                    System.err.println("Silent Catch: \nprevented nullpointer expection (renaming null-object)\n" //$NON-NLS-1$
70                            + e.getLocalizedMessage());
71                }
72            }
73
74            public void widgetDefaultSelected(SelectionEvent arg0) {
75            }
76        });
77
78        verifyButton = new Button(this, SWT.PUSH);
79        GridData vbDat = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
80        vbDat.widthHint = buttonWidthHint;
81        verifyButton.setLayoutData(vbDat);
82        verifyButton.setText(Messages.getString("VERIFY_MAP")); //$NON-NLS-1$
83        verifyButton.addSelectionListener(new SelectionListener() {
84
85            public void widgetSelected(SelectionEvent arg0) {
86                verifyMap(true);
87            }
88
89            public void widgetDefaultSelected(SelectionEvent arg0) {
90            }
91        });
92
93        Group leftGroup = new Group(this, SWT.NONE);
94        GridData leftGroupDat = new GridData(GridData.FILL_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL);
95        leftGroup.setLayoutData(leftGroupDat);
96        leftGroup.setLayout(new GridLayout(1, false));
97
98        roomList = new List(leftGroup, SWT.SINGLE | SWT.BORDER);
99        GridData listData = new GridData(GridData.FILL_BOTH);
00        roomList.setLayoutData(listData);
01
02        roomList.addSelectionListener(new SelectionListener() {
03
04            public void widgetSelected(SelectionEvent arg0) {
05                if (roomList.getItemCount() > 0) {
06                    Element room = getRoom(roomList.getItem(roomList.getSelectionIndex()));
07                    if (room != null) roomDetailComp.showRoomDetails(room, getCurrentMapName());
08                } else {
09                    roomDetailComp.clear();
10                }
11
12            }
13
14            public void widgetDefaultSelected(SelectionEvent arg0) {
15            }
16        });
17        roomList.setToolTipText(Messages.getString("ROOM_TOOLTIP")); //$NON-NLS-1$
18
19        Menu popupMenu = new Menu(roomList);
20        roomList.setMenu(popupMenu);
21
22        MenuItem add = new MenuItem(popupMenu, SWT.NONE);
23        add.setText(Messages.getString("ADD")); //$NON-NLS-1$
24        add.addSelectionListener(new SelectionListener() {
25
26            public void widgetSelected(SelectionEvent arg0) {
27                InputDialog id = new InputDialog(new Shell(arg0.display), SWT.NONE);
28                id.setMessage(Messages.getString("ROOM_NAME_ENTER")); //$NON-NLS-1$
29                String name = id.openNoWhitespace();
30                if (name != null) {
31                    if (roomList.indexOf(name) == -1) {
32                        startRoom.add(name);
33
34                        if (roomList.getItemCount() == 0) {
35                            startRoom.select(0);
36                            startRoom.notifyListeners(SWT.Selection, new Event());
37                        }
38                        getCurrentMap().addContent(
39                                new Element("room").setAttribute("name", name).setAttribute("class", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
40                                        "org.jzuul.engine.rooms.Room")); //$NON-NLS-1$
41                        roomList.setItems(getRoomNames(getCurrentMapName()));
42                        roomList.select(roomList.indexOf(name));
43                        roomList.notifyListeners(SWT.Selection, new Event());
44                    } else {
45                        Object[] formatArgs = {name};
46                        MessageBox mb = new MessageBox(new Shell(arg0.display), SWT.ICON_ERROR);
47                        mb.setMessage(MessageFormat.format(Messages.getString("ROOM_SAME_NAME_ERROR"),formatArgs) ); //$NON-NLS-1$
48                        mb.open();
49                    }
50                }
51            }
52
53            public void widgetDefaultSelected(SelectionEvent arg0) {
54            }
55        });
56
57        MenuItem rename = new MenuItem(popupMenu, SWT.NONE);
58        rename.setText(Messages.getString("RENAME")); //$NON-NLS-1$
59        rename.addSelectionListener(new SelectionListener() {
60
61            public void widgetSelected(SelectionEvent arg0) {
62                try {
63                    String oldName = roomList.getItem(roomList.getSelectionIndex());
64                    InputDialog id = new InputDialog(new Shell(arg0.display), SWT.NONE);
65                    id.setMessage(Messages.getString("ROOM_RENAME_ENTER") + oldName); //$NON-NLS-1$
66                    id.setDefaultValue(oldName);
67                    String newName = id.openNoWhitespace();
68                    if (newName != null) {
69                        getRoom(oldName).setAttribute("name", newName); //$NON-NLS-1$
70                        roomList.setItems(getRoomNames(getCurrentMapName()));
71                        startRoom.remove(oldName);
72                        startRoom.add(newName);
73                    }
74                } catch (Exception e) {
75                    System.err.println("Silent Catch: \nprevented nullpointer expection (renaming null-object)\n" //$NON-NLS-1$
76                            + e.getLocalizedMessage());
77                }
78
79            }
80
81            public void widgetDefaultSelected(SelectionEvent arg0) {
82            }
83        });
84
85        MenuItem delete = new MenuItem(popupMenu, SWT.NONE);
86        delete.setText(Messages.getString("DELETE")); //$NON-NLS-1$
87        delete.addSelectionListener(new SelectionListener() {
88
89            public void widgetSelected(SelectionEvent arg0) {
90                //TODO add r u sure
91                try {
92                    roomDetailComp.clear();
93                    getRoom(roomList.getItem(roomList.getSelectionIndex())).detach();
94                    roomList.setItems(getRoomNames(getCurrentMapName()));
95                    if (roomList.getItemCount() > 0) {
96                        roomList.select(0);
97                        roomList.notifyListeners(SWT.Selection, new Event());
98                    }
99                    startRoom.removeAll();
00                    startRoom.setItems(getRoomNames(getCurrentMapName()));
01                    if (startRoom.getItemCount() > 0) {
02                        startRoom.select(0);
03                        startRoom.notifyListeners(SWT.Selection, new Event());
04                    }
05                } catch (Exception e) {
06                    System.err.println("Silent Catch: \nprevented nullpointer expection (deleting null-object)\n" //$NON-NLS-1$
07                            + e.getLocalizedMessage());
08                }
09            }
10
11            public void widgetDefaultSelected(SelectionEvent arg0) {
12            }
13        });
14
15        Group startRoomGroup = new Group(leftGroup, SWT.NONE);
16        startRoomGroup.setLayout(new GridLayout(2, false));
17        startRoomGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
18
19        Label srLabel = new Label(startRoomGroup, SWT.NONE);
20        srLabel.setText(Messages.getString("STARTROOM")); //$NON-NLS-1$
21
22        startRoom = new Combo(startRoomGroup, SWT.READ_ONLY);
23        startRoom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
24        startRoom.addSelectionListener(new SelectionListener() {
25
26            public void widgetSelected(SelectionEvent arg0) {
27                getCurrentMap().setAttribute("startroom", startRoom.getText()); //$NON-NLS-1$
28
29            }
30
31            public void widgetDefaultSelected(SelectionEvent arg0) {
32            }
33        });
34
35        // the right side
36        roomDetailComp = new RoomDetailsComposite(this, SWT.NONE);
37
38    }
39
40    public void setMaps(java.util.List maps) {
41        System.err.println("setMaps called " + maps); //$NON-NLS-1$
42        this.maps = maps;
43        if (maps != null) {
44            System.err.println("Map names are " + getMapNames()); //$NON-NLS-1$
45            this.mapCombo.setItems(getMapNames());
46        }
47    }
48
49    public String[] getMapNames() {
50        java.util.List mapNames = new ArrayList();
51        for (Iterator mapIter = maps.iterator(); mapIter.hasNext();) {
52            Element map = (Element) mapIter.next();
53            mapNames.add(map.getAttributeValue("name")); //$NON-NLS-1$
54        }
55        String[] retval = new String[mapNames.size()];
56        mapNames.toArray(retval);
57        return retval;
58    }
59
60    public Element getMap(String name) {
61        for (Iterator mapIter = maps.iterator(); mapIter.hasNext();) {
62            Element map = (Element) mapIter.next();
63            if (map.getAttributeValue("name").equals(name)) return map; //$NON-NLS-1$
64        }
65        System.err.println("Creating new Element for map named " + name); //$NON-NLS-1$
66        Element newMap = new Element("map"); //$NON-NLS-1$
67        newMap.setAttribute("name", name); //$NON-NLS-1$
68        maps.add(newMap);
69        return newMap;
70    }
71
72    public String[] getRoomNames(String mapName) {
73        Element map = getMap(mapName);
74        java.util.List roomNames = new ArrayList();
75        for (Iterator roomIter = map.getChildren().iterator(); roomIter.hasNext();) {
76            Element mapChildEl = (Element) roomIter.next();
77            String tag = mapChildEl.getName();
78            if (tag.equals("room") || tag.equals("transitionroom")) { //$NON-NLS-1$ //$NON-NLS-2$
79                roomNames.add(mapChildEl.getAttributeValue("name")); //$NON-NLS-1$
80            }
81        }
82        String[] retval = new String[roomNames.size()];
83        roomNames.toArray(retval);
84        return retval;
85    }
86
87    public Element getRoom(String roomName) {
88        Element map = getMap(mapCombo.getText());
89        java.util.List children = map.getChildren();
90        for (Iterator childIter = children.iterator(); childIter.hasNext();) {
91            Element childElement = (Element) childIter.next();
92            String name = childElement.getAttributeValue("name"); //$NON-NLS-1$
93            if (name != null && name.equals(roomName)) return childElement;
94        }
95        // we don't know the tag yet
96        return null;
97
98    }
99
00    public void initalSelect() {
01        if (maps != null && maps.size() > 0) {
02            mapCombo.select(0);
03            mapCombo.notifyListeners(SWT.Selection, new Event());
04            roomList.select(roomList.getTopIndex());
05            roomList.notifyListeners(SWT.Selection, new Event());
06        } else {
07            clean();
08        }
09    }
10
11    public String getCurrentMapName() {
12        return this.mapCombo.getText();
13    }
14
15    public Element getCurrentMap() {
16        return getMap(getCurrentMapName());
17    }
18
19    public void updateData() {
20        mapCombo.notifyListeners(SWT.Selection, new Event());
21        roomList.notifyListeners(SWT.Selection, new Event());
22    }
23
24    public Element getCurrentRoom() {
25        return getRoom(roomList.getItem(roomList.getSelectionIndex()));
26    }
27
28    public boolean verifyMap(boolean showMsg) {
29        return verifyMap(showMsg, getCurrentMapName());
30    }
31
32    public boolean verifyMap(boolean showMsg, String mapName) {
33        boolean retval = true;
34        GameFileReader reader = new GameFileReader();
35        reader.parseTree(JdomHelpers.getRoot());
36        try {
37            GameMap foo = reader.getMap(mapName);
38            foo.verifyMap();
39            if (showMsg) {
40                MessageBox mb = new MessageBox(this.getShell(), SWT.ICON_INFORMATION);
41                mb.setMessage(Messages.getString("MAP_PERFECT")); //$NON-NLS-1$
42                mb.open();
43            }
44        } catch (ConnectAllRoomsFailed e) {
45            MessageBox mb = new MessageBox(this.getShell(), SWT.ICON_ERROR);
46            mb.setText(Messages.getString("ERROR_IN_MAP") + mapName); //$NON-NLS-1$
47            mb.setMessage(e.getMessage());
48            mb.open();
49            retval = false;
50        } catch (NoSuchRoomException e) {
51            MessageBox mb = new MessageBox(this.getShell(), SWT.ICON_ERROR);
52            mb.setText(Messages.getString("ERROR_IN_MAP") + mapName); //$NON-NLS-1$
53            mb.setMessage(e.getMessage());
54            mb.open();
55            retval = false;
56        } catch (NullPointerException e) {
57            MessageBox mb = new MessageBox(this.getShell(), SWT.ICON_ERROR);
58            mb.setText(Messages.getString("ERROR_IN_MAP") + mapName); //$NON-NLS-1$
59            mb.setMessage(Messages.getString("MAP_FATAL_ERROR")); //$NON-NLS-1$
60            mb.open();
61            retval = false;
62        }
63        return retval;
64    }
65
66    public boolean verifyAllMaps(boolean showMsg) {
67        boolean retval = true;
68        String[] map = getMapNames();
69        for (int i = 0; i < map.length; i++) {
70            retval &= verifyMap(showMsg, map[i]);
71        }
72        return retval;
73    }
74
75    public void clean() {
76        mapCombo.removeAll();
77        roomList.removeAll();
78        startRoom.removeAll();
79        roomDetailComp.clear();
80    }
81
82}