package de.kopis.jusenet;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Properties;
import javax.swing.AbstractAction;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import de.kopis.jusenet.nntp.NNTPUtils;
import de.kopis.jusenet.nntp.exceptions.NntpNotConnectedException;
import de.kopis.jusenet.ui.ComposeMessageWindow;
import de.kopis.jusenet.ui.MainFrame;
import de.kopis.jusenet.ui.actions.AboutAction;
import de.kopis.jusenet.ui.actions.ConnectAction;
import de.kopis.jusenet.ui.actions.CopyAction;
import de.kopis.jusenet.ui.actions.CreateNewArticleAction;
import de.kopis.jusenet.ui.actions.CutAction;
import de.kopis.jusenet.ui.actions.DisconnectAction;
import de.kopis.jusenet.ui.actions.EditServerAction;
import de.kopis.jusenet.ui.actions.ExitAction;
import de.kopis.jusenet.ui.actions.GetMessageIdAction;
import de.kopis.jusenet.ui.actions.LoadGroupsAction;
import de.kopis.jusenet.ui.actions.LockAction;
import de.kopis.jusenet.ui.actions.MarkArticleReadAction;
import de.kopis.jusenet.ui.actions.MarkArticleUnreadAction;
import de.kopis.jusenet.ui.actions.PasteAction;
import de.kopis.jusenet.ui.actions.RemoveArticleActio;
import de.kopis.jusenet.ui.actions.SubscribeAction;
import de.kopis.jusenet.ui.actions.UnsubscribeAction;
import de.kopis.jusenet.ui.actions.UpdateGroupAction;
import de.kopis.jusenet.utils.GuiUtils;
public class Application {
private static final String APP_CONFIG_FILE = "jusenet.ini";
protected static final int SAVE_PROPERTIES_INTERVAL = 60*5*1000;
public static final int ERROR_CONNECTION_NOT_READY = -1;
private static Application instance;
private static Properties _properties;
private static HashMap<String, AbstractAction> _actions;
private MainFrame _mainframe;
static {
_properties = new Properties();
try {
_properties.load(new FileInputStream(APP_CONFIG_FILE));
} catch (FileNotFoundException e) {
// e.printStackTrace();
System.err.println("No configuration file " + APP_CONFIG_FILE + " found. Creating a new one on exit.");
} catch (IOException e) {
e.printStackTrace();
}
_actions = new HashMap<String, AbstractAction>();
_actions.put("exit", new ExitAction());
_actions.put("loadgroups", new LoadGroupsAction());
_actions.put("updategroup", new UpdateGroupAction());
_actions.put("connect", new ConnectAction());
_actions.put("disconnect", new DisconnectAction());
_actions.put("removefromdb", new RemoveArticleActio());
_actions.put("markread", new MarkArticleReadAction());
_actions.put("markunread", new MarkArticleUnreadAction());
_actions.put("lock", new LockAction());
_actions.put("about", new AboutAction());
_actions.put("editserver", new EditServerAction());
_actions.put("cut", new CutAction());
_actions.put("copy", new CopyAction());
_actions.put("paste", new PasteAction());
_actions.put("subscribe", new SubscribeAction());
_actions.put("unsubscribe", new UnsubscribeAction());
_actions.put("getmessageid", new GetMessageIdAction());
_actions.put("newarticle", new CreateNewArticleAction());
// disable some actions that aren't available at program start
//TODO disable more actions at startup? re-enable them when connected?
_actions.get("connect").setEnabled(true);
_actions.get("disconnect").setEnabled(false);
}
private Application() {
// setup Timer to save properties
Timer timer = new Timer(Integer.parseInt(getProperty("saveinterval", "" + SAVE_PROPERTIES_INTERVAL)),
new ActionListener() {
public void actionPerformed(ActionEvent e) {
//TODO use Logger to log this messages
System.out.println(new Date() + ": Saving properties.");
saveProperties();
}});
timer.start();
}
public static Application getInstance() {
if(instance == null) instance = new Application();
return instance;
}
public AbstractAction getAction(String action) {
return _actions.get(action);
}
public void sendArticle(String content) {
try {
NNTPUtils.getInstance().send(content);
} catch (NntpNotConnectedException e) {
GuiUtils.showError(e);
}
}
/**
* Disconnects all opened connections from server.
*
* @throws IOException
*/
public void disconnect() {
try {
NNTPUtils.getInstance().disconnect();
getAction("connect").setEnabled(true);
getAction("disconnect").setEnabled(false);
} catch (IOException e) {
GuiUtils.showError(e);
}
}
/**
* Open 1 connection to server.
*
*/
public void connect() {
try {
NNTPUtils.getInstance().connect();
getAction("connect").setEnabled(false);
getAction("disconnect").setEnabled(true);
} catch (NntpNotConnectedException e) {
GuiUtils.showError(e);
}
}
public void quit(int exitcode) {
saveProperties();
// _mainframe.serializeLists();
System.exit(exitcode);
}
public String getProperty(String prop, String defValue) {
return _properties.getProperty(prop, defValue);
}
public String getProperty(String prop) {
return _properties.getProperty(prop);
}
public void setMainframe(MainFrame frame) {
_mainframe = frame;
}
public String getTitle() {
return BuildVersion.getTitle();
}
public void getGroups() {
try {
NNTPUtils.getInstance().getGroups();
} catch (NntpNotConnectedException e) {
GuiUtils.showError(e);
}
}
public void setProperty(String key, String value) {
_properties.setProperty(key, value);
}
/**
* Gets new articles for currently selected group.
*
*/
public void getNewArticles() {
_mainframe.getNewArticles();
}
/**
* Removes an Article from the database.
*
*/
public void removeArticleFromDatabase() {
_mainframe.removeArticle();
}
/**
* Marks an Article as read/unread.
*
* @param read
*/
public void markread(boolean read) {
_mainframe.markread(read);
}
public void lock() {
_mainframe.lock();
}
public void about() {
JOptionPane.showMessageDialog(_mainframe, "Created by\n" +
"Carsten Ringe\n" +
"schwarzer_peter@users.sourceforge.net\n" +
"http://jusenet.sourceforge.net/",
"About " + BuildVersion.getTitle() + " " + BuildVersion.getVersion(),
JOptionPane.INFORMATION_MESSAGE);
}
/**
* Displays a dialog to edit current settings of NNTP server.
*
*/
public void editServer() {
_mainframe.editServer();
}
/**
* Subscribed to a group.
*
*/
public void subscribe() {
_mainframe.subscribe();
}
public void unsubscribe() {
_mainframe.unsubscribe();
}
public void getArticleByMessageId() {
String msgid = JOptionPane.showInputDialog(_mainframe, "Enter Message ID:");
if(msgid != null) {
try {
NNTPUtils.getInstance().getArticle(msgid);
} catch (NntpNotConnectedException e) {
GuiUtils.showError(e);
}
}
}
/**
* Creates a window to write an article.
*
* Allows the user to enter all kind of data, like Group, Subject and stuff.
*/
public void composeArticle() {
ComposeMessageWindow window = new ComposeMessageWindow(_mainframe);
window.setVisible(true);
}
/**
* Saves the properties to file. This method should be called
* regularly to make sure the properties are saved even when
* the program crashes.
*
*/
private void saveProperties() {
// set configuration
String tmp = "" + _mainframe.getX();
_properties.setProperty("window.x", tmp);
tmp = "" + _mainframe.getY();
_properties.setProperty("window.y", tmp);
tmp = "" + _mainframe.getWidth();
_properties.setProperty("window.width", tmp);
tmp = "" + _mainframe.getHeight();
_properties.setProperty("window.height", tmp);
tmp = "" + _mainframe.getGroupDividerLocation();
_properties.setProperty("window.groupsplit", tmp);
tmp = "" + _mainframe.getArticleDividerLocation();
_properties.setProperty("window.articlesplit", tmp);
//save settings
try {
_properties.store(new FileOutputStream(APP_CONFIG_FILE),
"THIS IS THE CONFIGURATION FILE FOR JUSENET." +
"KEEP OUT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!");
} catch (FileNotFoundException e) {
GuiUtils.showError(e);
} catch (IOException e) {
GuiUtils.showError(e);
}
}
}