/**
*
* Copyright (c) 2009-2016 Freedomotic team http://freedomotic.com
*
* This file is part of Freedomotic
*
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2, or (at your option) any later version.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* Freedomotic; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
package com.freedomotic.jfrontend;
import com.freedomotic.api.EventTemplate;
import com.freedomotic.api.Protocol;
import com.freedomotic.app.Freedomotic;
import com.freedomotic.environment.EnvironmentLogic;
import com.freedomotic.events.MessageEvent;
import com.freedomotic.events.ObjectHasChangedBehavior;
import com.freedomotic.events.ZoneHasChanged;
import com.freedomotic.exceptions.UnableToExecuteException;
import com.freedomotic.jfrontend.extras.GraphPanel;
import com.freedomotic.jfrontend.utils.SplashLogin;
import com.freedomotic.things.EnvObjectLogic;
import com.freedomotic.reactions.Command;
import java.awt.Color;
import java.awt.EventQueue;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JOptionPane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Enrico Nicoletti
*/
public class JavaDesktopFrontend extends Protocol {
private static final Logger LOG = LoggerFactory.getLogger(JavaDesktopFrontend.class.getName());
private MainWindow window;
private Drawer drawer;
private final Map<String, GraphPanel> graphs = new HashMap<>();
private SplashLogin sl;
private boolean init = false;
/**
*
*/
public JavaDesktopFrontend() {
super("Desktop Frontend", "/frontend-java/desktop-frontend.xml");
setPollingWait(-1); //disable threaded execution of onRun()
}
/**
*
*/
@Override
public void onStop() {
if (window != null) {
window.setVisible(false);
window.dispose();
window = null;
drawer = null;
for (GraphPanel pg : graphs.values()) {
pg.dispose();
}
graphs.clear();
sl = null;
}
}
/**
*
*/
@Override
public void onStart() {
try {
//onEvent stuff
addEventListener("app.event.sensor.object.behavior.change");
addEventListener("app.event.sensor.environment.zone.change");
addEventListener("app.event.sensor.plugin.change");
addEventListener("app.event.sensor.messages.callout");
if (getApi().getAuth().isInited()) {
sl = new SplashLogin(this);
if (!init) {
sl.trySSO();
}
} else {
createMainWindow();
}
init = true;
} catch (Exception e) {
LOG.error(Freedomotic.getStackTraceInfo(e));
}
}
/**
*
*/
public void createMainWindow() {
if (window == null) {
window = new MainWindow(this);
}
window.setVisible(true);
if (sl != null) {
sl.setVisible(false);
sl.dispose();
sl = null;
}
LOG.info("JFrontend running as user: \"{}\"", getApi().getAuth().getPrincipal());
}
/**
*
* @return
*/
public MainWindow getMainWindow() {
return window;
}
/**
*
* @param env
* @return
*/
protected Drawer createRenderer(EnvironmentLogic env) {
try {
if ("photo".equalsIgnoreCase(env.getPojo().getRenderer())) {
drawer = new PhotoDrawer(this);
drawer.setCurrEnv(env);
} else if ("image".equalsIgnoreCase(env.getPojo().getRenderer())) {
drawer = new ImageDrawer(this);
drawer.setCurrEnv(env);
} else if ("plain".equalsIgnoreCase(env.getPojo().getRenderer())) {
drawer = new PlainDrawer(this);
drawer.setCurrEnv(env);
} else {
drawer = new ListDrawer(this);
drawer.setCurrEnv(env);
}
} catch (Exception e) {
LOG.error("Error while initializing a drawer in desktop frontend ", Freedomotic.getStackTraceInfo(e));
}
if (drawer instanceof Renderer) {
Renderer renderer = (Renderer) drawer;
renderer.calloutsUpdater = new CalloutsUpdater(renderer, 1000);
}
return drawer;
}
@Override
protected void onCommand(final Command c)
throws IOException, UnableToExecuteException {
String callout = c.getProperty("callout.message");
if (callout != null) {
Callout callout1 = new Callout(this.getClass().getCanonicalName(), "info", callout, 0, 0, 0, 0);
drawer.createCallout(callout1);
} else if (c.getProperty("command") != null && "GRAPH-DATA".equalsIgnoreCase(c.getProperty("command"))) { // show GUI
// get related object from address
EnvObjectLogic obj = getApi().things().findByAddress("harvester", c.getProperty("event.object.address"));
// open GraphWindow related to the object
if (obj != null && obj.getBehavior("data") != null) { // has a 'data' behavior
if (!obj.getBehavior("data").getValueAsString().isEmpty()) {
GraphPanel gw = graphs.get(obj.getPojo().getUUID());
if (gw != null) {
gw.reDraw();
} else {
gw = new GraphPanel(this, obj);
graphs.put(obj.getPojo().getUUID(), gw);
}
}
}
} else {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
//Custom button text
if (c.getProperty("options") != null) {
Object[] options = c.getProperty("options").split(";");
int n = JOptionPane.showOptionDialog(window,
c.getProperty("question"),
"Please reply within "
+ (c.getReplyTimeout() / 1000)
+ " seconds",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[2]);
c.setProperty("result", options[n].toString());
}
reply(c);
}
}).start();
}
});
}
}
@Override
protected void onEvent(EventTemplate event) {
if (drawer == null) {
LOG.warn("Skipping this frontend refresh, the plugin is not yet fully loaded");
return;
}
if (event instanceof ObjectHasChangedBehavior) {
drawer.setNeedRepaint(true);
for (GraphPanel gp : graphs.values()) {
gp.reDraw();
}
if (drawer != null) {
drawer.setNeedRepaint(true);
}
} else if (event instanceof ZoneHasChanged) {
//writing the string on the screen
String zoneDesc = event.getProperty("zone.description");
Callout callout = new Callout(zoneDesc, -1, Color.blue);
drawer.createCallout(callout);
drawer.setNeedRepaint(true);
} else if (event instanceof MessageEvent) {
printCallout(event.getProperty("message.text"));
} else if (null != window) {
final PluginJList pluginJList = window.getPluginJList();
if (null != pluginJList) {
pluginJList.update();
}
}
}
// //annotation doesn't work because annotation parsing is enabled only in Protocol subclasses
// @ListenEventsOn(channel = "app.event.sensor.messages.callout")
/**
*
* @param message
*/
public void printCallout(String message) {
Callout callout = new Callout(
message,
3400,
Color.blue);
drawer.createCallout(callout);
drawer.setNeedRepaint(true);
}
@Override
protected boolean canExecute(Command c) {
//do nothing
return true;
}
@Override
protected void onRun() {
//do nothing
}
}