package com.pointcliki.dizgruntled;
import java.awt.Desktop;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.zip.ZipInputStream;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.geom.Vector2f;
import com.pointcliki.core.Entity;
import com.pointcliki.core.Scene;
import com.pointcliki.core.Sprite;
import com.pointcliki.core.TextEntity;
import com.pointcliki.dizgruntled.rez.MonolithFile;
import com.pointcliki.event.Dispatcher;
import com.pointcliki.event.FrameEvent;
import com.pointcliki.event.Minion;
import com.pointcliki.input.MouseEvent;
import com.pointcliki.io.ResourceManager;
import com.pointcliki.text.HyperlinkText;
import com.pointcliki.ui.ProgressBar;
import com.pointcliki.utils.HoverSprite;
import com.pointcliki.utils.SyncObject;
import com.sun.org.apache.xerces.internal.impl.xs.identity.Selector.Matcher;
public class StartScene extends Scene {
/**
* Serial key
*/
private static final long serialVersionUID = 688862336870414195L;
private static final Color HOVER = new Color(249, 216, 31);
public static final String[] WORLD_NAMES = new String[]{"Home Baked", "Rocky Roadz", "Gruntziclez", "Trouble in the Tropicz", "High on Sweetz", "High Rollerz", "Honey, I Shrunk the Gruntz!", "The Miniature Masterz", "Gruntz in Space"};
public static final String[] LEVEL_NAMES = new String[]{"the giant rock", "holy shovelz!", "Gruntz, start your enginez", "I get by with a little help from my friendz", "spyz like us", "brick layerz have all the fun", "the Grunt that was left behind", "I want a rock right now!", "toobin it", "la la la la la bomba", "now who put that warpstone piece there?!", "Guardz! There's a thief on the premisez!", "just wing it", "candlez and cupcakez and bombz, oh my!", "you take the high road and I'll take the low", "the intersection", "swordz akimbo", "I've always wanted to be a welder", "back from the dead and into the pool", "keep your eye on the ball", "you should never play near electrical outletz!", "pay no attention to the grunt with the shield", "the big split up", "with four Gruntz, you can take on the world!", "come back with a friend", "save that squeak toy!", "golf anyone?", "where's my buddy?", "use those sponge gunz!", "would you like some holez to go with that?", "could someone get those purple switchez for me?", "the final battle"};
public static final String[] TUTORIAL_NAMES = new String[]{"Basic Controlz", "Toolz and Toyz", "Combat Exercisez", "Pyramidz, Bridgez, and Switchez"};
private UnicodeFont fFont;
private Sprite fFront;
private BackEntity fBack;
private HyperlinkText fDownYes;
private HyperlinkText fDownNo;
private Sprite fDownInfo;
private int fPage = 0;
private Minion<FrameEvent> fFinishedDownload;
private Sound fMenuMusic;
private HoverSprite fHoverPlay;
private HoverSprite fHoverEditor;
private HoverSprite fHoverLearn;
private HoverSprite fHoverWww;
private HyperlinkText fAudio;
private HyperlinkText fFullscreen;
private HyperlinkText fScreensize;
public StartScene(GruntzGame game) {
super(game);
registerUIMinion();
}
@Override
public void init() {
super.init();
fFront = new Sprite("alpha-2.6");
addChild(fFront);
fBack = new BackEntity();
fTimeManager.start();
try {
fFont = ResourceManager.createLocalFont("lib/whiz bang.ttf", 18);
} catch (SlickException e) {
e.printStackTrace();
}
try {
fMenuMusic = new Sound("lib/menu.ogg");
fMenuMusic.loop();
} catch (SlickException e) {
// TODO Log error
}
}
@Override
public void handleUIMouseEvent(String type, Vector2f local, MouseEvent event) {
super.handleUIMouseEvent(type, local, event);
if (type.equals("mouse.click")) {
if (fPage == 0) {
// Check for existence of REZ
if (!new File("lib/GRUNTZ.REZ").exists() || !new File("lib/GRUNTZ.VRZ").exists()) showDownloadPage();
else showMenuPage();
}
}
}
private void showDownloadPage() {
fPage = 1;
fBack.setTopHeight(334);
addChild(fBack);
fDownInfo = new Sprite("downinfo");
addChild(fDownInfo.position(new Vector2f(60, 115)));
final SyncObject<Integer> done = new SyncObject<Integer>(0);
fDownYes = new HyperlinkText("I have already installed Gruntz", TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = 3255208115397490201L;
@Override
public void click() {
// Locate Gruntz
JFileChooser loader = new JFileChooser();
loader.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
loader.setDialogTitle("Locate Gruntz game folder");
int r = loader.showOpenDialog(null);
if (r == JFileChooser.APPROVE_OPTION) {
File f = loader.getSelectedFile();
File rez = new File(f.getAbsolutePath() + "/GRUNTZ.REZ");
File vrz = new File(f.getAbsolutePath() + "/GRUNTZ.VRZ");
// TODO: use zzz file
//File zzz = new File(f.getAbsolutePath() + "/GRUNTZ.ZZZ");
boolean copy = false;
if (!rez.exists() || !vrz.exists()) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(frame, "Sorry, the folder selected doesn't appear to have the resources\nrequired to play Dizgruntled. Please try again or select the\noption to download the resources.", "Resources Not Found", 0);
frame.dispose();
}/* else if (!zzz.exists()) {
r = JOptionPane.showConfirmDialog(null, "Dizgruntled couldn't find the Gruntz 1.01 patch with your game. Please note that\nwhile you can play Dizgruntled without this patch, a few of the original levels\nare incorrect. Would you like to continue without the patch?", "Patch Not Found", JOptionPane.YES_NO_OPTION);
if (r == 0) copy = true;
} */else {
copy = true;
}
if (copy) {
try {
copyFile(rez, new File("lib/GRUNTZ.REZ"));
copyFile(vrz, new File("lib/GRUNTZ.VRZ"));
// Remove Hyperlinks
fDownYes.cleanup();
fDownYes = null;
fDownNo.cleanup();
fDownNo = null;
fDownInfo.cleanup();
fDownInfo = null;
// Continue
removeChild(fBack);
showMenuPage();
} catch (IOException e) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(frame, "Sorry, Dizgruntled couldn't copy over the required resource files GRUNTZ.REZ and GRUNTZ.VRZ. Please check they exist and are not in use.", "Copy Error", 0);
frame.dispose();
}
}
}
}
};
addChild(fDownYes.position(new Vector2f(65, 450)));
fDownNo = new HyperlinkText("I haven't previously installed Gruntz", TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = -4682660357282196588L;
@Override
public void click() {
// Remove Hyperlinks
fDownYes.cleanup();
fDownYes = null;
fDownNo.cleanup();
fDownNo = null;
fDownInfo.cleanup();
fDownInfo = null;
final ProgressBar downloadBar = new ProgressBar(new Vector2f(340, 32), new Color(20, 44, 48), HOVER);
StartScene.this.addChild(downloadBar.position(new Vector2f(60, 115)));
final TextEntity downloadText = new TextEntity("Please wait while Dizgruntled downloads\nrequired resources", TextEntity.ALIGN_LEFT, fFont);
StartScene.this.addChild(downloadText.position(new Vector2f(60, 200)));
// Download the resources
final Thread downloader = new Thread() {
private DownloadExtractor fVrzDown;
private DownloadExtractor fRezDown;
@Override
public void run() {
try {
URL url = new URL("http://pointcliki.com/gruntz/download.txt");
Scanner s = new Scanner(url.openStream());
final String rez = s.nextLine();
final String vrz = s.nextLine();
s.close();
// Download the VRZ
fVrzDown = new DownloadExtractor(new URL(vrz), new File("lib/vrz.zip"), new File("lib/GRUNTZ.VRZ")) {
@Override
public void onError(Exception e) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(frame, "Sorry, Dizgruntled can't download the files at this time. Please try again later", "Download Error", 0);
frame.dispose();
fVrzDown.cancel();
fRezDown.cancel();
// Clean up
removeChild(fBack);
downloadBar.cleanup();
downloadText.cleanup();
showDownloadPage();
}
@Override
public void onExtracting() {
downloadText.text("Extracting resources...");
}
@Override
public void onProgress(float f) {
downloadBar.percent(f / 2 + fRezDown.progress() / 2);
}
@Override
public void onDone() {
done.set(done.get() + 1);
}
};
// Download the REZ
fRezDown = new DownloadExtractor(new URL(rez), new File("lib/rez.zip"), new File("lib/GRUNTZ.REZ")) {
@Override
public void onError(Exception e) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(frame, "Sorry, Dizgruntled can't download the files at this time. Please try again later", "Download Error", 0);
frame.dispose();
fVrzDown.cancel();
fRezDown.cancel();
// Clean up
removeChild(fBack);
downloadBar.cleanup();
downloadText.cleanup();
showDownloadPage();
}
@Override
public void onExtracting() {
downloadText.text("Extracting resources...");
}
@Override
public void onProgress(float f) {
downloadBar.percent(f / 2 + fVrzDown.progress() / 2);
}
@Override
public void onDone() {
done.set(done.get() + 1);
}
};
final HyperlinkText cancelText = new HyperlinkText("Cancel Download", TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = 896122497881495986L;
@Override
public void click() {
fVrzDown.cancel();
fRezDown.cancel();
// Clean up
removeChild(fBack);
downloadBar.cleanup();
downloadText.cleanup();
showDownloadPage();
}
};
StartScene.this.addChild(cancelText.position(new Vector2f(60, 450)));
fVrzDown.start();
fRezDown.start();
} catch (Exception e) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(frame, "Sorry, Dizgruntled can't download the files at this time. Please try again later", "Download Error", 0);
frame.dispose();
// Clean up
removeChild(fBack);
downloadBar.cleanup();
downloadText.cleanup();
showDownloadPage();
}
fFinishedDownload = new Minion<FrameEvent>() {
@Override
public long run(Dispatcher<FrameEvent> dispatcher, String type, FrameEvent event) {
if (done.get() < 2) {
return Minion.CONTINUE;
} else {
// Clean up
removeChild(fBack);
downloadBar.cleanup();
downloadText.cleanup();
showMenuPage();
return Minion.FINISH;
}
}
};
StartScene.this.frameManager().queueNext(fFinishedDownload);
}
};
downloader.start();
}
};
addChild(fDownNo.position(new Vector2f(65, 485)));
}
private static class BackEntity extends Entity {
/**
* Serial key
*/
private static final long serialVersionUID = -166256346855270060L;
public static final Color TOP = new Color(35, 77, 72);
public static final Color BOTTOM = new Color(20, 44, 48);
private int fTopHeight = 334;
public void setTopHeight(int i) {
fTopHeight = i;
}
@Override
public void render(Graphics graphics, long currentTime) {
graphics.setColor(TOP);
graphics.fillRect(0, 74, 451, fTopHeight);
graphics.setColor(BOTTOM);
graphics.fillRect(0, 74 + fTopHeight, 451, 451 - fTopHeight);
}
}
private static void copyFile(File sourceFile, File destFile) throws IOException {
if(!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}
private abstract static class DownloadExtractor extends Thread {
private URL fDownload;
private File fDownloadTo;
private File fExtractTo;
private boolean fCancelled;
private float fProgress;
public DownloadExtractor(URL download, File downloadTo, File extractTo) {
fDownload = download;
fDownloadTo = downloadTo;
fExtractTo = extractTo;
}
@Override
public void run() {
try {
// Download the file
URLConnection con = fDownload.openConnection();
con.connect();
int size = con.getContentLength();
if (!fDownloadTo.exists()) fDownloadTo.createNewFile();
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fDownloadTo));
BufferedInputStream in = new BufferedInputStream(con.getInputStream());
byte[] buf = new byte[1024];
int count;
int written = 0;
while ((count = in.read(buf)) >= 0) {
if (fCancelled) {
break;
} else {
out.write(buf, 0, count);
written += count;
fProgress = (written + 0.0f) / size;
onProgress(fProgress);
}
}
out.flush();
in.close();
out.close();
if (fCancelled) {
fDownloadTo.delete();
} else {
onExtracting();
// Extract
ZipInputStream zis = new ZipInputStream(new FileInputStream(fDownloadTo.getAbsolutePath()));
zis.getNextEntry();
FileOutputStream fos = new FileOutputStream(fExtractTo);
byte[] buffer = new byte[1024];
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
zis.close();
fDownloadTo.delete();
onDone();
}
} catch (MalformedURLException e) {
e.printStackTrace();
onError(e);
} catch (IOException e) {
e.printStackTrace();
onError(e);
}
}
public synchronized void cancel() {
fCancelled = true;
}
public synchronized float progress() {
return fProgress;
}
public abstract void onError(Exception e);
public abstract void onExtracting();
public abstract void onProgress(float f);
public abstract void onDone();
}
private void showMenuPage() {
fPage = 2;
fBack.setTopHeight(290);
addChild(fBack);
fHoverPlay = new HoverSprite("ui/button_play", "ui/button_play_hover") {
/**
* Serial key
*/
private static final long serialVersionUID = -4972728615626326360L;
@Override
public void click() {
fHoverPlay.cleanup();
fHoverEditor.cleanup();
fHoverLearn.cleanup();
fHoverWww.cleanup();
fAudio.cleanup();
fFullscreen.cleanup();
fScreensize.cleanup();
removeChild(fBack);
showLevelPage(SET_PLAY);
}
};
fHoverEditor = new HoverSprite("ui/button_editor", "ui/button_editor_hover") {
/**
* Serial key
*/
private static final long serialVersionUID = -4972728615626326360L;
@Override
public void click() {
GruntzGame.instance().startEditor();
}
};
fHoverLearn = new HoverSprite("ui/button_learn", "ui/button_learn_hover") {
/**
* Serial key
*/
private static final long serialVersionUID = -4972728615626326360L;
@Override
public void click() {
fHoverPlay.cleanup();
fHoverEditor.cleanup();
fHoverLearn.cleanup();
fHoverWww.cleanup();
fAudio.cleanup();
fFullscreen.cleanup();
fScreensize.cleanup();
removeChild(fBack);
showLevelPage(SET_LEARN);
}
};
fHoverWww = new HoverSprite("ui/button_www", "ui/button_www_hover") {
/**
* Serial key
*/
private static final long serialVersionUID = -4972728615626326360L;
@Override
public void click() {
try {
Desktop.getDesktop().browse(new URI("http://pointcliki.com/gruntz"));
} catch (IOException e) {} catch (URISyntaxException e) {}
}
};
addChild(fHoverPlay.position(new Vector2f(60, 90)));
addChild(fHoverEditor.position(new Vector2f(270, 90)));
addChild(fHoverLearn.position(new Vector2f(60, 230)));
addChild(fHoverWww.position(new Vector2f(270, 230)));
fAudio = new HyperlinkText("Audio Yes", TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = -5199274170691192012L;
@Override
public void click() {
if (GruntzGame.instance().mute()) {
GruntzGame.instance().mute(false);
fAudio.text("Audio Yes");
} else {
GruntzGame.instance().mute(true);
fAudio.text("Audio No");
}
}
};
fFullscreen = new HyperlinkText("Fullscreen Yes", TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = 7826676731391952554L;
@Override
public void click() {
if (GruntzGame.instance().fullscreen()) {
GruntzGame.instance().fullscreen(false);
fFullscreen.text("Fullscreen No");
} else {
GruntzGame.instance().fullscreen(true);
fFullscreen.text("Fullscreen Yes");
}
}
};
fScreensize = new HyperlinkText("Screen Size 1024x768", TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = -6542663871541452203L;
@Override
public void click() {
//
if (GruntzGame.instance().screenSize().x == 1024) {
GruntzGame.instance().screenSize(new Vector2f(1280, 720));
fScreensize.text("Screen Size 1280x720");
} else if (GruntzGame.instance().screenSize().x == 1280) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
String result = JOptionPane.showInputDialog(frame, "Enter Custom Screen Size...");
frame.dispose();
try {
String[] s = result.split("[^0-9]+");
int x = Integer.parseInt(s[0]);
int y = Integer.parseInt(s[1]);
GruntzGame.instance().screenSize(new Vector2f(x, y));
fScreensize.text("Screen Size " + x + "x" + y);
} catch (Exception e) {
GruntzGame.instance().screenSize(new Vector2f(1024, 768));
fScreensize.text("Screen Size 1024x768");
}
} else {
GruntzGame.instance().screenSize(new Vector2f(1024, 768));
fScreensize.text("Screen Size 1024x768");
}
}
};
addChild(fAudio.position(new Vector2f(70, 400)));
addChild(fFullscreen.position(new Vector2f(70, 440)));
addChild(fScreensize.position(new Vector2f(70, 480)));
}
private static final int SET_PLAY = 0;
private static final int SET_LEARN = 1;
private static final int SET_WORLD_OFFSET = 2;
private void showLevelPage(final int quest) {
fPage = 3;
addChild(fBack);
fBack.setTopHeight(451);
final ArrayList<HyperlinkText> links = new ArrayList<HyperlinkText>();
String[] s;
if (quest == SET_PLAY) {
s = WORLD_NAMES;
} else if (quest == SET_LEARN) {
s = TUTORIAL_NAMES;
} else {
int i = (quest - SET_WORLD_OFFSET) * 4;
s = Arrays.copyOfRange(LEVEL_NAMES, i, i + 4);
}
int y = 150;
int i = 0;
for (String str: s) {
final int id = i;
i++;
HyperlinkText link = new HyperlinkText(str, TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = 1649654658328820595L;
@Override
public void click() {
if (quest == SET_PLAY) {
if (id == 0) {
JFileChooser loader = new JFileChooser();
loader.setAcceptAllFileFilterUsed(false);
loader.addChoosableFileFilter(new FileNameExtensionFilter("Dizgruntled Maps (*.map)", "map"));
loader.addChoosableFileFilter(new FileNameExtensionFilter("Wap World Maps (*.wwd)", "wwd"));
loader.addChoosableFileFilter(new FileNameExtensionFilter("All Maps", "wwd", "map"));
loader.setDialogTitle("Open Dizgruntled Map");
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
int r = loader.showOpenDialog(frame);
frame.dispose();
if (r == JFileChooser.APPROVE_OPTION) GruntzGame.instance().playLevel(loader.getSelectedFile());
} else {
for (HyperlinkText t: links) t.cleanup();
removeChild(fBack);
showLevelPage(id - 1 + SET_WORLD_OFFSET);
}
} else if (quest == SET_LEARN) {
String level = "AREA1/WORLDZ/TRAINING" + (id + 1);
MonolithFile wwd = GruntzGame.resourceManager().rez().file(level, "wwd");
GruntzGame.instance().playLevel(wwd);
} else {
String level = "AREA" + (quest - SET_WORLD_OFFSET + 1) + "/WORLDZ/LEVEL" + ((id + 1) + 4 * (quest - SET_WORLD_OFFSET));
MonolithFile wwd = GruntzGame.resourceManager().rez().file(level, "wwd");
GruntzGame.instance().playLevel(wwd);
}
}
};
links.add(link);
addChild(link.position(new Vector2f(70, y)));
y += 30;
}
HyperlinkText back = new HyperlinkText("Go Back", TextEntity.ALIGN_LEFT, fFont, Color.white, HOVER) {
/**
* Serial key
*/
private static final long serialVersionUID = 1649654658328820595L;
@Override
public void click() {
for (HyperlinkText t: links) t.cleanup();
removeChild(fBack);
if (quest < SET_WORLD_OFFSET) {
showMenuPage();
} else {
showLevelPage(SET_PLAY);
}
}
};
addChild(back.position(new Vector2f(70, 480)));
}
@Override
public void cleanup() {
super.cleanup();
fMenuMusic.stop();
}
}