package gargoyle.util.applet;
import gargoyle.util.log.Log;
import gargoyle.util.res.Resources;
import java.applet.Applet;
import java.applet.AppletContext;
import java.applet.AppletStub;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
final class GFrame extends JFrame implements WindowListener, AppletStub, AppletContext {
private static final long serialVersionUID = 1L;
final G0Applet applet;
private final Map<String, String> parameters = new HashMap<String, String>();
private final JLabel status;
private final Map<String, InputStream> streams = new HashMap<String, InputStream>();
public GFrame(final G0Applet applet, final String[] args) {
this.applet = applet;
applet.application = this;
applet.setStub(this);
this.setArgs(args);
this.setTitle(applet.getTitle());
this.setLayout(new BorderLayout());
this.add(applet, BorderLayout.CENTER);
this.status = new JLabel("Ready");
this.status.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
this.add(this.status, BorderLayout.SOUTH);
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
this.addWindowListener(this);
final Dimension size = new Dimension(GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().getSize());
size.width >>= 1;
size.height >>= 1;
applet.setPreferredSize(size);
this.pack();
this.setLocationRelativeTo(null);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GFrame.this.setVisible(true);
applet.init();
}
});
}
@Override
public void appletResize(final int width, final int height) {
synchronized (this.getTreeLock()) {
final Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
final Rectangle size = new Rectangle(this.getLocation(), this.applet.getMinimumSize());
if (width > size.width) {
size.width = width;
}
if (height > size.height) {
size.height = height;
}
if (size.width > screen.width) {
size.width = screen.width;
}
if (size.height > screen.height) {
size.height = screen.height;
}
final int x = screen.x + screen.width - size.width;
if (size.x > x) {
size.x = x;
}
final int y = screen.y + screen.height - size.height;
if (size.y > y) {
size.y = y;
}
this.applet.setPreferredSize(size.getSize());
this.applet.setSize(size.getSize());
this.setLocation(size.getLocation());
this.pack();
}
}
void exit() {
this.applet.destroy();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GFrame.this.setVisible(false);
GFrame.this.dispose();
}
});
}
@Override
public Applet getApplet(final String name) {
return this.applet;
}
@Override
public AppletContext getAppletContext() {
return this;
}
@Override
public Enumeration<applet rel='nofollow' onclick='return false;'> getApplets() {
return Collections.enumeration(Arrays.asList(new Applet[] { this.applet }));
}
@Override
public AudioClip getAudioClip(final URL url) {
return Resources.createAudioClip(url);
}
@Override
public URL getCodeBase() {
try {
return new URL(this.applet.getClass().getResource('/' + this.applet.getClass().getCanonicalName().replace('.', '/') + ".class"), ".");
} catch (final MalformedURLException e) {
Log.error(e);
}
return null;
}
@Override
public URL getDocumentBase() {
try {
return new URL(new File(System.getProperty("user.dir", ".")).getCanonicalFile().toURI().toURL(), "");
} catch (final MalformedURLException e) {
Log.error(e);
} catch (final IOException e) {
Log.error(e);
}
return null;
}
@Override
public Image getImage(final URL url) {
return Resources.createImage(url);
}
@Override
public String getParameter(final String name) {
return this.parameters.get(name);
}
@Override
public InputStream getStream(final String key) {
return this.streams.get(key);
}
@Override
public Iterator<String> getStreamKeys() {
return this.streams.keySet().iterator();
}
private void setArgs(final String[] args) {
for (final String arg : args) {
final String[] split = arg.split("=", 2);
this.parameters.put(split[0], split[1]);
}
}
@Override
public void setStream(final String key, final InputStream stream) throws IOException {
this.streams.put(key, stream);
}
@Override
public void showDocument(final URL url) {
try {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(url.toURI());
}
} catch (final IOException e) {
Log.warn(e);
} catch (final URISyntaxException e) {
Log.warn(e);
}
}
@Override
public void showDocument(final URL url, final String target) {
try {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(url.toURI());
}
} catch (final IOException e) {
Log.warn(e);
} catch (final URISyntaxException e) {
Log.warn(e);
}
}
@Override
public void showStatus(final String status) {
if (this.isVisible()) {
this.status.setText(status);
}
}
@Override
public void windowActivated(final WindowEvent e) {
GFrame.this.applet.start();
}
@Override
public void windowClosed(final WindowEvent e) {
}
@Override
public void windowClosing(final WindowEvent e) {
try {
if (this.applet.canExit()) {
this.applet.exit();
} else {
if (!this.isVisible()) {
GFrame.this.setVisible(true);
}
}
} catch (final RuntimeException e1) {
this.applet.error(e1);
if (this.applet instanceof GApplet) {
((GApplet) this.applet).setRunning(false);
} else {
this.dispose();
}
}
}
@Override
public void windowDeactivated(final WindowEvent e) {
GFrame.this.applet.stop();
}
@Override
public void windowDeiconified(final WindowEvent e) {
}
@Override
public void windowIconified(final WindowEvent e) {
}
@Override
public void windowOpened(final WindowEvent e) {
}
}