package com.ronald.gantengtimesheet.ui.timesheet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.Timer;
import org.jdesktop.swingx.JXButton;
import org.jdesktop.swingx.JXFrame;
import org.jdesktop.swingx.JXLabel;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.VerticalLayout;
import com.ronald.gantengtimesheet.config.Config;
import com.ronald.gantengtimesheet.db.RecordEntity;
import com.ronald.gantengtimesheet.ui.MainFrame;
import com.ronald.gantengtimesheet.ui.util.FixedLengthDocument;
import com.ronald.gantengtimesheet.ui.util.Util;
@SuppressWarnings("serial")
public class TimerDialog extends JDialog {
public TimerDialog() {
super();
setTitle("Timer");
setResizable(false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setSize(new Dimension(500,200));
addComponents();
addListeners();
setModal(true);
}
private int elapsed = 0;
private final Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
elapsed++;
updateLabel();
}
});
private final JXButton btnStart = new JXButton("Start");
{
btnStart.setMnemonic('S');
}
private final JXButton btnReset = new JXButton("Reset");
{
btnReset.setMnemonic('R');
}
private final JXButton btnMinimize = new JXButton("Minimize");
{
btnMinimize.setMnemonic('M');
}
private final JTextField txtDescription = new JTextField();
{
txtDescription.setDocument(new FixedLengthDocument(255));
}
private final JCheckBox chkUpdate = new JCheckBox("Add duration to last row");
private final JXLabel label = new JXLabel("00:00:00", JLabel.CENTER);
{
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.setFont(new Font("Dialog", Font.PLAIN, 80));
}
private void addComponents() {
setLayout(new BorderLayout());
Util.setFixedSize(btnStart, new Dimension(100,30));
Util.setFixedSize(btnReset, new Dimension(100,30));
Util.setFixedSize(btnMinimize, new Dimension(100,30));
getRootPane().setDefaultButton(btnStart);
final JXPanel top = new JXPanel();
top.setLayout(new VerticalLayout(5));
top.add(Util.createBoxLayoutPanel(BoxLayout.X_AXIS, btnStart, btnReset,
Box.createHorizontalGlue(), chkUpdate, Box.createHorizontalGlue(), btnMinimize));
top.add(Util.createBoxLayoutPanel(BoxLayout.X_AXIS, new JXLabel("Description: "),
txtDescription));
add(top, BorderLayout.NORTH);
add(label);
}
private void updateLabel() {
label.setText(formatDuration(elapsed));
}
private void addListeners() {
chkUpdate.addActionListener(new ActionListener() {
String previous;
@Override
public void actionPerformed(ActionEvent e) {
if (chkUpdate.isSelected()) {
previous = txtDescription.getText();
final RecordEntity recordEntity = TimesheetComponent.getInstance().getLastRowRecordEntity();
if (recordEntity != null) {
txtDescription.setText(recordEntity.getDescription());
}
} else {
txtDescription.setText(previous);
}
}
});
btnStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
timer.stop();
} else {
timer.start();
}
String title = "";
char mnemonic = ' ';
if (timer.isRunning()) {
title = "Pause";
mnemonic = 'P';
} else {
title = "Continue";
mnemonic = 'C';
}
btnStart.setText(title);
btnStart.setMnemonic(mnemonic);
}
});
btnReset.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.stop();
elapsed = 0;
updateLabel();
btnStart.setText("Start");
btnStart.setMnemonic('S');
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
// if elapsed time is 0, do not insert data into the table
if (elapsed == 0) return;
RecordEntity recordEntity;
double previousDuration = 0;
Double rate = null;
if (chkUpdate.isSelected()) {
// do an update
recordEntity = TimesheetComponent.getInstance().getLastRowRecordEntity();
if (recordEntity == null) {
// insert it instead
recordEntity = TimesheetComponent.getInstance().getNewRecordEntity();
} else {
previousDuration = recordEntity.getDuration();
rate = recordEntity.getRate();
}
} else {
// insert
recordEntity = TimesheetComponent.getInstance().getNewRecordEntity();
}
if (rate == null) {
rate = Config.getDefaultRate();
}
recordEntity.setDate(TimesheetComponent.getInstance().getSelectedDate());
recordEntity.setDuration(previousDuration + (elapsed / 3600.0));
recordEntity.setDescription(txtDescription.getText());
recordEntity.setRate(rate);
recordEntity.setUpdated(new Date());
recordEntity.save();
}
});
btnMinimize.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
MainFrame.getInstance().setState(JXFrame.ICONIFIED);
}
});
}
private String formatDuration(final long duration) {
final StringBuffer buf = new StringBuffer(8);
long hour = 0;
long min = 0;
long sec = 0;
sec = duration % 60;
min = (duration / 60) % 60;
hour = duration / 3600;
// check if need to add extra 0 in front of the number
if (hour / 10 == 0) {
buf.append('0');
}
buf.append(hour);
buf.append(':');
if (min / 10 == 0) {
buf.append('0');
}
buf.append(min);
buf.append(':');
if (sec / 10 == 0) {
buf.append('0');
}
buf.append(sec);
return buf.toString();
}
public int getElapsed() {
return elapsed;
}
public String getDescription() {
return txtDescription.getText().trim();
}
public boolean isUpdateLastRow() {
return chkUpdate.isSelected();
}
}