package interesting;
import java.io.InputStream;
import java.lang.Exception;
import javafx.io.http.HttpRequest;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import interesting.model.Photo;
import interesting.parser.PhotoPullParser;
import interesting.view.FullImageView;
import interesting.view.ImageButton;
def apiKey = FX.getArgument("flickr_apikey");
var stageX = 280.0;
var stageY = 140.0;
def stageWidth = 240;
def stageHeight = 320;
var inBrowser = "true".equals(FX.getArgument("isApplet") as String);
var bgSuffix = "_x";
if(inBrowser) { bgSuffix = ""; }
var isMobile = (FX.getProperty("javafx.me.profiles") != null);
var imgSuffix = "t";
if(isMobile) { imgSuffix = "s"; }
var page:Integer = 0;
var photos: Photo[];
var bgImage = ImageView {
focusable: true
image: Image {
url: "{__DIR__}images/background{bgSuffix}.png"
}
onKeyPressed:function(e:KeyEvent) {
if(e.code == KeyCode.VK_LEFT) {
onBack();
} else if(e.code == KeyCode.VK_RIGHT) {
onNext();
}
}
}
bgImage.requestFocus();
var closeButton:ImageView = ImageButton {
x: stageWidth - 36
y: 8
normalImage: Image { url: "{__DIR__}images/close_n.png" }
selectImage: Image { url: "{__DIR__}images/close_h.png" }
visible: bind (not inBrowser)
onMouseClicked: function(e) {
javafx.lang.FX.exit();
}
}
var nextButton = ImageButton {
x: stageWidth - 42
y: stageHeight - 23
normalImage: Image { url: "{__DIR__}images/next_n.png" };
selectImage: Image { url: "{__DIR__}images/next_h.png" };
onMouseClicked: function(e) {
onNext();
}
}
function onNext() {
fullImageView.show = false;
page++;
if(page >= 10) page = 0;
updateImages();
}
var backButton = ImageButton {
x: stageWidth - 67
y: stageHeight - 23
normalImage: Image { url: "{__DIR__}images/back_n.png" };
selectImage: Image { url: "{__DIR__}images/back_h.png" };
onMouseClicked: function(e) {
onBack();
}
}
function onBack() {
fullImageView.show = false;
page--;
if(page < 0) page = 10;
updateImages();
}
var titleText: Text;
var title = "";
var statusText: Text;
var status = "Loading Photos...";
var thumbBaseX = 21;
var thumbBaseY = 75;
var thumbSize = 64;
var thumbSpace = 3;
class ThumbImageView extends ImageView {
override var fitWidth = thumbSize;
override var fitHeight = thumbSize;
var photo: Photo;
public override var onMouseClicked = function(e:MouseEvent) {
if(isMobile) {
fullImageView.image = image;
} else {
fullImageView.image = Image {
url: "http:
placeholder: image
backgroundLoading: true
};
}
fullImageView.show = true;
}
public override var onMouseMoved = function(e:MouseEvent) {
if(photo != null) {
if(photo.title.length() > 65) {
title = "{photo.title.substring(0, 60)}...";
} else {
title = photo.title;
}
} else {
title = "";
}
}
}
var thumbImageViews: ThumbImageView[];
for(col in [0..2]) {
for(row in [0..2]) {
def thumbImageView = ThumbImageView {
x: thumbBaseX + (col * (thumbSize + thumbSpace))
y: thumbBaseY + (row * (thumbSize + thumbSpace))
fitWidth: thumbSize
fitHeight: thumbSize
}
insert thumbImageView into thumbImageViews;
}
}
var thumbImageViewGroup = Group {
content: bind thumbImageViews
}
var fullImageView = FullImageView {
translateX: thumbBaseX
translateY: thumbBaseY
useEffects: not isMobile
visible: false
}
fullImageView.onVisibleChange = function() {
if(not fullImageView.visible) { title = ""; }
};
function loadImage(photo: Photo, thumbImageView: ThumbImageView): Void {
thumbImageView.image = Image {
url: "http:;
width: thumbSize
height: thumbSize
backgroundLoading: true
placeholder: thumbImageView.image
};
thumbImageView.photo = photo;
}
function updateImages() {
for(i in [0..8]) {
var photoIndex = (page*8) + i;
loadImage(photos[photoIndex], thumbImageViews[i]);
}
title = "";
status = "Page {page+1}";
}
var titleBar = Rectangle {
width: stageWidth
height: 25
fill: Color.TRANSPARENT
visible: bind (not inBrowser)
onMouseDragged: function(e) {
stageX += e.dragX;
stageY += e.dragY;
}
}
var stageContent: Node[];
if (apiKey == null) {
var invalidAPIKey = [
"This application", "requires an api key",
"from Flickr.", "", "Get yours from",
"http:
];
var errorText: Text[];
var lineIndex = 1;
var fontSize = 16;
var smooth = true;
for(text in invalidAPIKey) {
insert Text {
x: thumbBaseX + thumbSpace
y: thumbBaseY + (20 * lineIndex);
font: Font { name: "Bitstream Vera Sans" size: fontSize }
content: text
fill: Color.WHITE
smooth: smooth
} into errorText;
lineIndex++;
if(lineIndex == 6) {
fontSize = 11;
smooth = false;
}
};
stageContent = [
bgImage, titleBar, closeButton, errorText, statusText
];
} else {
titleText = Text {
x: thumbBaseX
y: 43
font: Font { name: "Bitstream Vera Sans" size: 11 }
wrappingWidth: stageWidth * 0.8
content: bind title
fill: Color.WHITE
smooth: true
clip: Rectangle {
x: thumbBaseX - 2
y: 30
width: stageWidth - 20
height: 30
}
}
statusText = Text {
x: thumbBaseX + thumbSpace
y: stageHeight - 12
font: Font { name: "Bitstream Vera Sans" size: 11 }
content: bind status
fill: Color.WHITE
smooth: true
clip: Rectangle {
x: thumbBaseX - 2
y: stageHeight - 40
width: stageWidth - 40
height: 50
}
}
stageContent = [
bgImage, titleBar, nextButton, backButton, closeButton,
titleText, statusText, thumbImageViewGroup, fullImageView
];
loadImageMetadata();
}
function loadImageMetadata() {
println("Loading image metadata...");
var httpRequestError: Boolean = false;
var request: HttpRequest = HttpRequest {
location: "http:
"flickr.interestingness.getList&api_key={apiKey}&per_page=92"
method: HttpRequest.GET
onException: function(exception: Exception) {
exception.printStackTrace();
alert("Error", "{exception}");
httpRequestError = true;
}
onResponseCode: function(responseCode:Integer) {
if (responseCode != 200) {
println("failed, response: {responseCode} {request.responseMessage}");
}
}
onInput: function(input: java.io.InputStream) {
try {
var parser = PhotoPullParser{};
photos = parser.parse(input);
if(parser.errorMessage.length() > 0) {
alert("Error", parser.errorMessage);
httpRequestError = true;
}
} finally {
input.close();
}
}
onDone: function() {
if(not httpRequestError) {
updateImages();
}
}
}
request.enqueue();
}
function alert(alertTitle:String, msg:String): Void {
println(msg);
status = alertTitle;
title = msg;
}
def stage = Stage {
title: "Interesting Photos"
resizable: false
x: bind stageX with inverse
y: bind stageY with inverse
width: stageWidth
height: stageHeight
visible: true
style: StageStyle.TRANSPARENT
scene: Scene {
content: Group {
content: bind stageContent
clip: Rectangle {
width: stageWidth
height: stageHeight
arcWidth: 20
arcHeight: 20
}
}
fill: Color.TRANSPARENT
}
}