package gui;
import api.API;
import api.Message;
import dropbox.Config;
import dropbox.Dropbox;
import error.ConfigFileNotFoundException;
import error.FileCorruptedException;
import error.NotLoggedInException;
import error.UserAlreadyExistsException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Timer;
import java.util.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class DBM extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
public static void main(String[] args) {
DBM frame = new DBM();
frame.setVisible(true);
}
private JTextArea editor;
private MessageTabs tabber;
private List<Message> control;
private API messenger;
private Timer updater;
private Config config;
public DBM() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 700, 500);
this.setTitle("DBM: kilépve");
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JSplitPane splitPane = new JSplitPane();
splitPane.setContinuousLayout(true);
splitPane.setResizeWeight(0.95);
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
splitPane.setDividerSize(4);
splitPane.setBorder(null);
contentPane.add(splitPane, BorderLayout.CENTER);
JPanel tabberPanel = new JPanel();
splitPane.setLeftComponent(tabberPanel);
tabberPanel.setLayout(new BorderLayout(0, 0));
tabber = new MessageTabs();
tabberPanel.add(tabber, BorderLayout.CENTER);
JPanel editorPanel = new JPanel();
splitPane.setRightComponent(editorPanel);
editorPanel.setLayout(new BorderLayout(0, 0));
editor = new JTextArea();
editor.setAutoscrolls(true);
editor.addKeyListener(new InputKeyListener());
editor.setBorder(new LineBorder(UIManager.getColor("CheckBox.focus")));
editor.setLineWrap(true);
JScrollPane scroll = new JScrollPane(editor);
editorPanel.add(scroll, BorderLayout.CENTER);
JButton editorButton = new JButton("Küld");
editorPanel.add(editorButton, BorderLayout.EAST);
editorButton.addActionListener(new SendButtonListener());
editorButton.setFont(new Font("Dialog", Font.PLAIN, 11));
editorButton.setContentAreaFilled(false);
control = new ArrayList<Message>();
try {
messenger = new Dropbox();
config = messenger.getConfig();
if (config.getMessagePath() == null || !config.getMessagePath().exists()) {
Object[] options = {"Kijelölés", "Kilépés"};
int n = JOptionPane.showOptionDialog(null, "Nincsen megadva üzenetkönyvtár.", "DBM indulás", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
if (n != 0 || !this.setMessagePath()) {
this.dispose();
}
}
control.add(new Message("Control", "Konfigurációs fájl sikeresen betöltve.", ""));
control.add(new Message("Control", "Üzenetkönyvtár: " + messenger.getPath(), ""));
if (config.getAutoLoginUsername().length() == 0) {
control.add(new Message("Control", "Írd be a felhasználóneved!", ""));
} else {
this.login(config.getAutoLoginUsername());
}
tabber.updateTab("Control", control);
} catch (IOException e) {
somethingGoneWrong("Fájl hozzáférés sikertelen.");
} catch (ConfigFileNotFoundException e) {
somethingGoneWrong("Hiányzó konfigurációs fájl.");
} catch (FileCorruptedException r) {
somethingGoneWrong("Hibás konfigurációs fájl.");
} finally {
this.dispose();
}
startUpdater();
}
private boolean setMessagePath() throws IOException {
File path;
final JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int fcValue = fc.showOpenDialog(null);
if (fcValue == JFileChooser.APPROVE_OPTION) {
path = fc.getSelectedFile();
config.setMessagePath(path);
return true;
} else {
return false;
}
}
private void startUpdater() {
if (config.getRefreshInterval() >= 1000) {
updater = new Timer();
updater.schedule(new Updater(), config.getRefreshInterval(), config.getRefreshInterval());
}
}
private class Updater extends TimerTask {
//private Map<String, Long> size = new HashMap<String, Long>();
private long sumSize;
public Updater() {
this.sumSize = 0;
}
@Override
public void run() {
try {
update();
} catch (IOException ex) {
somethingGoneWrong("Fájl hozzáférés sikertelen.");
} catch (FileCorruptedException ex) {
somethingGoneWrong("Hibás felhasználói fájl.");
} catch (NotLoggedInException ex) {
somethingGoneWrong("Nem vagy belépve.");
}
}
private void update() throws IOException, FileCorruptedException, NotLoggedInException {
System.out.println("check");
if (config.getRefreshInterval() >= 1000) {
long actSize = 0;
for (String n : messenger.getAllUsers()) {
actSize += messenger.getUserFileSize(n);
}
if (actSize != sumSize) {
sumSize = actSize;
synchronized (messenger) {
messenger.loadAllUserMessages();
}
tabber.updateAllTabs();
}
}
}
}
private void somethingGoneWrong(String error) {
JOptionPane.showMessageDialog(this, error, "DBM Hiba", JOptionPane.ERROR_MESSAGE);
control.add(new Message("Control", "Hiba: " + error, ""));
}
private class SendButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
submit();
}
}
private class InputKeyListener implements KeyListener {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
submit();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
private void login(String name) throws IOException, FileCorruptedException {
if (messenger.userExists(name)) {
messenger.login(name);
setTitle("DBM: " + name);
control.add(new Message("Control", "Üdv, <b>" + name + "</b>!", ""));
try {
tabber.updateAllTabs();
tabber.setSelectedIndex(0);
} catch (NotLoggedInException e) {
// login error
}
} else {
control.add(new Message("Control", ((messenger.isLoggedIn()) ? "Átjelentkezés" : "Bejelentkezés") + " sikertelen.", ""));
}
tabber.updateTab("Control", control);
}
private void submit() {
try {
String text = editor.getText().trim();
editor.setText("");
if (messenger.isLoggedIn()) {
if (!text.equals("")) {
if (text.startsWith("/")) {
if (text.equals("/help") || text.equals("/h") || text.equals("/?")) {
control.add(new Message(
"Control",
"<strong>Használható utasítások:</strong><br/><ul><li><strong>/h /help /?</strong><br/>Ennek a súgónak a megjelenítése.</li><li><strong>/t [téma] [üzenet]</strong><br/>Üzenet küldése megadott témába, ill. nem létező téma megadása esetén téma létrehozása. A témanév nem tartalmazhat szóközt.</li><li><strong>/f off|[int]</strong><br/>Automatikus frissítés kikapcsolása vagy a gyakoriság megadott értékre (>1000) való beállítása (mértékegység: millisec).</li><li><strong>/u [username]</strong><br/>Bejelentkezés másik, már létező felhasználóként.</li><li><strong>/m</strong><br/>Üzenetkönyvtár helyének módosítása.</li></ul>",
""));
tabber.updateTab("Control", control);
tabber.setSelectedIndex(0);
}
if (text.startsWith("/m")) {
setMessagePath();
tabber.removeAllTabs();
messenger.loadAllUserMessages();
tabber.updateAllTabs();
control.add(new Message("Control", "Új üzenetkönyvtár beállítva: " + config.getMessagePath(), ""));
tabber.updateTab("Control", control);
}
if (text.startsWith("/u ")) {
if (text.length() > 3) {
String name = text.substring(3);
control.add(new Message("Control", "Átjelentkezés: " + messenger.getUsername() + " -> " + name, ""));
login(name);
if (messenger.getUsername().equals(name)) {
tabber.removeAllTabs();
}
tabber.updateAllTabs();
tabber.setSelectedIndex(0);
}
}
if (text.startsWith("/t ")) {
if (text.contains(" ") && text.substring(text.indexOf(" ") + 1).contains(" ")) {
String topic = text.substring(3, text.indexOf(' ', 3));
String message = text.substring(text.indexOf(' ', 3));
messenger.newMessage(topic, message);
tabber.newTab(topic);
tabber.updateTab(topic, messenger.getMessages(topic));
}
}
if (text.startsWith("/f")) {
if (text.length() > 2 && text.contains(" ")) {
String option = text.substring(text.indexOf(' ') + 1);
if (option.equals("off")) {
config.setRefreshInterval(0);
updater.cancel();
control.add(new Message("Control", "Automatikus frissítés kikapcsolva.", ""));
tabber.updateTab("Control", control);
} else {
try {
if (Integer.parseInt(option) > 1000) {
config.setRefreshInterval(Integer.parseInt(option));
startUpdater();
control.add(new Message("Control", "Frissítési gyakoriság megváltozott, új érték: " + config.getRefreshInterval() + "ms", ""));
tabber.updateTab("Control", control);
}
} catch (NumberFormatException e) {
control.add(new Message("Control", "Frissítési időköz beállítása sikertelen: számot kell megadni.", ""));
tabber.updateTab("Control", control);
}
}
} else {
(new Updater()).run();
}
}
} else {
String topic = tabber.getSelectedTopic();
if (!topic.equals("Control")) {
messenger.newMessage(topic, text);
tabber.updateTab(topic, messenger.getMessages(topic));
}
}
} else {
// blank message
}
} else {
String name = text;
if (text.equals("")) {
somethingGoneWrong("A felhasználónévnek betűket kell tartalmaznia.");
} else {
if (name.contains(" ")) {
name = name.substring(0, name.indexOf(' '));
}
if (messenger.userExists(name)) {
this.login(name);
int answer = JOptionPane.showConfirmDialog(this, "Szeretnél mindig " + name + " néven belépni a program indításakor?", "Automatikus bejelentkezés", JOptionPane.YES_NO_OPTION);
if (answer == 0) {
config.setAutoLoginUsername(name);
control.add(new Message("Control", name + ": automatikus bejelentkezés beállítva.", ""));
tabber.updateTab("Control", control);
}
} else {
int answer = JOptionPane.showConfirmDialog(this, name + ": felhasználó nem létezik. Szeretnéd létrehozni?", "Bejelentkezés", JOptionPane.YES_NO_OPTION);
if (answer == 0) {
messenger.newUser(name);
control.add(new Message("Control", name + ": felhasználói fájl létrehozva.", ""));
this.login(name);
}
}
}
}
} catch (IOException e) {
somethingGoneWrong("Fájl hozzáférés sikertelen.");
} catch (FileCorruptedException e) {
somethingGoneWrong("Felhasználói fájl sérült.");
} catch (NotLoggedInException e) {
somethingGoneWrong("Nem vagy belépve.");
} catch (UserAlreadyExistsException e) {
somethingGoneWrong("A megadott felhasználónév már foglalt.");
}
}
private class MessageTabs extends JTabbedPane {
private static final long serialVersionUID = 1L;
private Map<String, Tab> tabs;
public MessageTabs() {
super(JTabbedPane.TOP);
this.setBorder(null);
this.tabs = new HashMap<String, Tab>();
this.newTab("Control");
}
public void removeTab(String topic) {
this.remove(this.tabs.remove(topic));
}
public void removeAllTabs() {
for (String tab : this.tabs.keySet().toArray(new String[0])) {
if (!tab.equals("Control")) {
this.removeTab(tab);
}
}
}
public String getSelectedTopic() {
return ((Tab) this.getSelectedComponent()).title;
}
public void updateAllTabs() throws NotLoggedInException {
for (String t : messenger.getTopics()) {
tabber.updateTab(t, messenger.getMessages(t));
}
}
public void updateTab(String title, List<Message> messages) {
if (!this.tabs.containsKey(title)) {
this.newTab(title);
}
JTextPane output = this.tabs.get(title).output;
String wall = "";
for (Message m : messages) {
wall += formatMessage(m);
}
output.setText(wall);
}
private void newTab(String title) {
if (!this.tabs.containsKey(title)) {
Tab tab = new Tab(title);
this.addTab(title, null, tab, null);
this.setEnabledAt(this.getTabCount() - 1, true);
this.setSelectedComponent(tab);
this.tabs.put(title, tab);
}
}
private class StyleColorScheme {
public final String color1;
public final String color2;
public StyleColorScheme(String c1, String c2) {
this.color1 = c1;
this.color2 = c2;
}
}
private String styleLastUsername;
private String styleLastTopic;
private int styleActiveColor;
private String formatMessage(Message message) {
Date date = new Date(message.getTimestamp());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy. MMM. dd k:mm");
StyleColorScheme color[] = new StyleColorScheme[4];
color[0] = new StyleColorScheme("#DBE9F3", "#9191b1"); // blue
color[1] = new StyleColorScheme("#D5EAD6", "#80a080"); // green
color[2] = new StyleColorScheme("#feeded", "#a08080"); // red
color[3] = new StyleColorScheme("#F9F9C9", "#bbbb7f"); // yellow
if (this.styleLastTopic == null) {
this.styleLastTopic = message.getTopic();
} else if (!message.getTopic().equals(this.styleLastTopic)) {
this.styleLastUsername = null;
this.styleLastTopic = message.getTopic();
this.styleActiveColor = 0;
}
if (this.styleLastUsername != null) {
if (!this.styleLastUsername.equals(message.getUsername())) {
this.styleActiveColor = (this.styleActiveColor == 0) ? 1 : 0;
}
} else {
this.styleActiveColor = 0;
}
if (message.getTopic().equals("Control")) {
this.styleActiveColor = 3;
}
this.styleLastUsername = message.getUsername();
return "<div style=\"margin:0;padding:0 0 1px 0;background-color:"
+ color[this.styleActiveColor].color2 + ";\"><div style=\"background:"
+ color[this.styleActiveColor].color1
+ ";margin:0;padding:3px;font-size:11;font-family:Arial;\">"
+ message.getText() + "\t <span style=\"text-align:right;font-size:10;color:"
+ color[this.styleActiveColor].color2 + ";\">-<b>" + message.getUsername()
+ "</b> " + sdf.format(date) + "</span></div></div>";
}
private class Tab extends JPanel {
private static final long serialVersionUID = 1L;
public final String title;
public final JTextPane output;
public Tab(String title) {
super();
this.title = title;
this.setLayout(new BorderLayout(0, 0));
output = new JTextPane();
JScrollPane slider = new JScrollPane(output);
slider.setSize(new Dimension(100, 100));
slider.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
output.setEditable(false);
output.setCaretPosition(output.getDocument().getLength());
output.setContentType("text/html");
this.add(slider);
}
}
}
}