aboutsummaryrefslogtreecommitdiff
path: root/src/esieequest/ui/rich/app/AppInterface.java
blob: 79a51cfb9b27aadd5550d1f55c9836bf9c054eaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
package esieequest.ui.rich.app;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JTextPane;
import javax.swing.filechooser.FileNameExtensionFilter;

import lombok.Getter;

import com.wordpress.tipsforjava.swing.StretchIcon;

import esieequest.engine.audioplayer.SysAudioPlayer;
import esieequest.engine.commands.Command;
import esieequest.engine.datastore.DataStore;
import esieequest.engine.datastore.FileDataStore;
import esieequest.engine.scheduler.SysScheduler;
import esieequest.game.Text;
import esieequest.game.items.Inventory;
import esieequest.game.items.Item;
import esieequest.game.map.Direction;
import esieequest.game.map.Room;
import esieequest.game.map.Side;
import esieequest.game.states.Quest;
import esieequest.ui.rich.RichInterface;

/**
 * The Swing based graphical user interface.
 * 
 * @author Pacien TRAN-GIRARD
 * @author Benoît LUBRANO DI SBARAGLIONE
 */
abstract class AppInterface extends RichInterface implements ActionListener {

	private static final String ILLUSTRATION_DIR = "resources/images/";
	private static final String ILLUSTRATION_EXT = ".jpg";

	@Getter
	private final Layout layout;

	/**
	 * The default constructor.
	 */
	public AppInterface() {
		super(new FileDataStore(), new SysScheduler(), new SysAudioPlayer());

		this.layout = new Layout(this);

		this.setControlsState(false);
	}

	/**
	 * Clears the textual input field.
	 */
	private void clearInputField() {
		this.layout.getInputField().setText(null);
	}

	/**
	 * Sets the controls state.
	 * 
	 * @param state
	 *            the controls state
	 */
	private void setControlsState(final boolean state) {
		this.layout.getInputField().setEnabled(state);
		this.layout.getSaveButton().setEnabled(state);
		this.layout.getInventoryButton().setEnabled(state);
		this.layout.getLeftButton().setEnabled(state);
		this.layout.getRightButton().setEnabled(state);
		if (!state) {
			this.layout.getForwardButton().setEnabled(state);
			this.layout.getBackButton().setEnabled(state);
			this.layout.getActionButton().setEnabled(state);
		}
	}

	/**
	 * Placeholder image generation from
	 * http://stackoverflow.com/a/17802477/1348634
	 * 
	 * @param text
	 *            the image text
	 * @return the Image
	 */
	private Image generatePlaceholderImage(final String text) {
		final BufferedImage bufferedImage = new BufferedImage(240, 135,
				BufferedImage.TYPE_BYTE_BINARY);
		final Graphics graphics = bufferedImage.getGraphics();
		graphics.drawString(text, 5, 10 + 5);
		return bufferedImage;
	}

	/**
	 * Opens the inventory (switches to the inventory tab).
	 */
	private void openInventory() {
		this.layout.getConsolePanel().setVisible(false);
		this.layout.getInventoryPanel().setVisible(true);
	}

	/**
	 * Closes the inventory (switches to the console tab).
	 */
	private void closeInventory() {
		this.layout.getInventoryPanel().setVisible(false);
		this.layout.getConsolePanel().setVisible(true);
	}

	/**
	 * Toggles the inventory tab.
	 */
	private void toggleInventory() {
		if (this.layout.getInventoryPanel().isVisible()) {
			this.closeInventory();
		} else {
			this.openInventory();
		}
	}

	/**
	 * Translates the received ActionEvent into the corresponding game command
	 * and forwards it to the game engine.
	 */
	@Override
	public void actionPerformed(final ActionEvent actionEvent) {
		if (actionEvent.getActionCommand() == Command.INVENTORY.name()) {
			this.toggleInventory();
		} else if (actionEvent.getActionCommand() == Command.LOAD.name()) {
			final JFileChooser fileChooser = new JFileChooser();
			fileChooser.setFileFilter(new FileNameExtensionFilter(DataStore.SAVE_LABEL,
					DataStore.SAVE_EXT));
			final int option = fileChooser.showOpenDialog(this.layout.getMainPanel());
			if (option == JFileChooser.APPROVE_OPTION) {
				this.getGameEngine().interpret(
						actionEvent.getActionCommand() + Text.COMMAND_SEPARATOR
								+ fileChooser.getSelectedFile().getPath());
			}
		} else if (actionEvent.getActionCommand() == Command.SAVE.name()) {
			final JFileChooser fileChooser = new JFileChooser();
			fileChooser.setFileFilter(new FileNameExtensionFilter(DataStore.SAVE_LABEL,
					DataStore.SAVE_EXT));
			final int option = fileChooser.showSaveDialog(this.layout.getMainPanel());
			if (option == JFileChooser.APPROVE_OPTION) {
				final String path = fileChooser.getSelectedFile().getPath();
				final String filePath = path.endsWith(DataStore.SAVE_EXT) ? path : path + "."
						+ DataStore.SAVE_EXT;
				this.getGameEngine().interpret(
						actionEvent.getActionCommand() + Text.COMMAND_SEPARATOR + filePath);
			}
		} else {
			this.getGameEngine().interpret(actionEvent.getActionCommand());
			this.clearInputField();
		}
	}

	@Override
	public void setLabel(final String questTitle) {
		this.layout.getQuestTextPane().setText(questTitle);
	}

	@Override
	public void setFrame(final String imageName) {
		final URL imageURL = this.getClass().getClassLoader().getResource(
				AppInterface.ILLUSTRATION_DIR + imageName + AppInterface.ILLUSTRATION_EXT);
		final StretchIcon imageIcon;
		if (imageURL == null) {
			imageIcon = new StretchIcon(this.generatePlaceholderImage(imageName), true);
		} else {
			imageIcon = new StretchIcon(imageURL, true);
		}
		this.layout.getImageLabel().setIcon(imageIcon);
	}

	@Override
	public void enableInput() {
		this.setControlsState(true);
	}

	@Override
	public void disableInput() {
		this.setControlsState(false);
		this.setLabel(Text.DEFAULT_QUEST_TITLE.toString());
	}

	@Override
	public void echo(final String message) {
		this.closeInventory();
		this.layout.getInfoTextPane().setText(message);
	}

	@Override
	public void updateQuest(final Quest quest) {
		this.setLabel(quest.getTitle());
		this.getAudioPlayer().play(quest.name());
	}

	@Override
	public void updateLocation(final Room room, final Direction direction, final Side side,
			final boolean canGoBack) {
		String locationImageName = room.name() + Text.FILENAME_SEPARATOR.toString()
				+ direction.name();
		if (side.getInventory().getSize() > 0) {
			locationImageName += Text.FILENAME_SEPARATOR.toString()
					+ side.getInventory().getItem().name();
		}
		this.setFrame(locationImageName);
		this.layout.getBackButton().setEnabled(canGoBack);
		this.layout.getForwardButton().setEnabled(side.hasDoor());
		this.layout.getActionButton().setEnabled(
				side.hasCharacter() || (side.getInventory().getSize() > 0));

		this.echo(room.getInformations());
	}

	@Override
	public void updateInventory(final Inventory inventory) {
		this.layout.getInventoryPanel().removeAll();

		if (inventory.getSize() < 1) {
			final JTextPane emptyTextPane = new JTextPane();
			emptyTextPane.setText(Text.INVENTORY_EMPTY.toString());
			this.layout.getInventoryPanel().add(emptyTextPane);
			return;
		}

		for (final Item item : inventory.getItems().values()) {
			final JButton button = new JButton(item.getName());
			button.setActionCommand(Command.USE.name() + Text.COMMAND_SEPARATOR.toString()
					+ item.getName());
			button.addActionListener(this);
			this.layout.getInventoryPanel().add(button);
		}

		this.openInventory();
	}

}