/*
 * Copyright (C) 2013 Yoshinori Hayakawa <hayakawa@cite.tohoku.ac.jp>
 *
 * 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 3 of the License, 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package turtlemessenger;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import static java.lang.Thread.sleep;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

/**
 *
 * @author Yoshinori Hayakawa <hayakawa@cite.tohoku.ac.jp>
 */
public class TMMessages extends javax.swing.JDialog {

    TMController controller ;
    private UpdateThread thread ;
    /**
     * Creates new form TMMessages
     */
    public TMMessages(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        controller = (TMController) parent ;
        setLocationRelativeTo(parent) ;
        // messageTextPane.setFont(new Font(Font.SANS_SERIF,Font.PLAIN, 14)) ;   
        thread = null ;
        

        JTableHeader tabHeader = messageTable.getTableHeader();
        tabHeader.setFont( new Font(Font.SANS_SERIF, Font.PLAIN, 14 ) );
        
        TableColumnModel tcm = messageTable.getColumnModel();
        MultiLineTableCellRenderer cellRenderer = new MultiLineTableCellRenderer() ;
        tcm.getColumn(0).setCellRenderer(cellRenderer);
        tcm.getColumn(1).setCellRenderer(cellRenderer);
        tcm.getColumn(2).setCellRenderer(cellRenderer);
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        doneButton = new javax.swing.JButton();
        updateButton = new javax.swing.JButton();
        largeFontCheckBox = new javax.swing.JCheckBox();
        autoUpdateCheckBox = new javax.swing.JCheckBox();
        enlargeButton = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        messageTable = new javax.swing.JTable();

        setTitle("List of received messages");
        setMinimumSize(new java.awt.Dimension(550, 200));

        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("turtlemessenger/TMBundle"); // NOI18N
        doneButton.setText(bundle.getString("DONE")); // NOI18N
        doneButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                doneButtonActionPerformed(evt);
            }
        });

        updateButton.setText(bundle.getString("UPDATE")); // NOI18N
        updateButton.setToolTipText("最新の投稿内容に更新します");
        updateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateButtonActionPerformed(evt);
            }
        });

        largeFontCheckBox.setText(bundle.getString("LARGE FONT")); // NOI18N
        largeFontCheckBox.setToolTipText("チェックを入れると、大きめのフォントで表示します");
        largeFontCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                largeFontCheckBoxActionPerformed(evt);
            }
        });

        autoUpdateCheckBox.setText(bundle.getString("AUTO UPDATE")); // NOI18N
        autoUpdateCheckBox.setToolTipText("チェックを入れると、投稿内容が10秒おきに更新されます");
        autoUpdateCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                autoUpdateCheckBoxActionPerformed(evt);
            }
        });

        enlargeButton.setText(bundle.getString("ENLARGE")); // NOI18N
        enlargeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                enlargeButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(28, Short.MAX_VALUE)
                .add(autoUpdateCheckBox)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(largeFontCheckBox)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(enlargeButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 123, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(updateButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(doneButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 87, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(20, 20, 20))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(18, Short.MAX_VALUE)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(doneButton)
                    .add(updateButton)
                    .add(largeFontCheckBox)
                    .add(autoUpdateCheckBox)
                    .add(enlargeButton))
                .addContainerGap())
        );

        messageTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Time", "Nickname", "Message"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        messageTable.setAutoCreateRowSorter(true);
        messageTable.setRowHeight(32);
        messageTable.setShowHorizontalLines(false);
        messageTable.setShowVerticalLines(false);
        messageTable.getTableHeader().setReorderingAllowed(false);
        jScrollPane2.setViewportView(messageTable);
        messageTable.getColumnModel().getColumn(0).setPreferredWidth(80);
        messageTable.getColumnModel().getColumn(1).setPreferredWidth(100);
        messageTable.getColumnModel().getColumn(2).setPreferredWidth(400);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(jScrollPane2)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void doneButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_doneButtonActionPerformed
        // dispose() ;
        setVisible(false) ;
    }//GEN-LAST:event_doneButtonActionPerformed

    private void updateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateButtonActionPerformed

        updateTable() ;
    }//GEN-LAST:event_updateButtonActionPerformed

    private void largeFontCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_largeFontCheckBoxActionPerformed
        TableColumnModel tcm = messageTable.getColumnModel();
        if (largeFontCheckBox.isSelected()) {
            ((MultiLineTableCellRenderer) tcm.getColumn(0).getCellRenderer()).enlargeFont(true);
            ((MultiLineTableCellRenderer) tcm.getColumn(1).getCellRenderer()).enlargeFont(true);
            ((MultiLineTableCellRenderer) tcm.getColumn(2).getCellRenderer()).enlargeFont(true);
        } else {
            ((MultiLineTableCellRenderer) tcm.getColumn(0).getCellRenderer()).enlargeFont(false);
            ((MultiLineTableCellRenderer) tcm.getColumn(1).getCellRenderer()).enlargeFont(false);
            ((MultiLineTableCellRenderer) tcm.getColumn(2).getCellRenderer()).enlargeFont(false);
        }
        messageTable.repaint();
    }//GEN-LAST:event_largeFontCheckBoxActionPerformed

    private void autoUpdateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoUpdateCheckBoxActionPerformed
        if (autoUpdateCheckBox.isSelected()) {
            if (thread == null) {
                thread = new UpdateThread();
                thread.start();;
            }
        } else {
            try {
                if (thread != null && thread.isAlive()) {
                    thread.interrupt();
                }
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                ;
            }
            thread = null;
        }
    }//GEN-LAST:event_autoUpdateCheckBoxActionPerformed

    private void enlargeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enlargeButtonActionPerformed
        Rectangle bounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();  
        this.setBounds(bounds);  
    }//GEN-LAST:event_enlargeButtonActionPerformed
         
    public synchronized void updateTable() {
        List<List<String>> msgList= controller.getNewMessages() ;
        for (int i=0 ; i<msgList.size() ; i++) {
            List<String> row = msgList.get(i) ;
            ((DefaultTableModel) messageTable.getModel()).insertRow(0,new Object[]{row.get(0),row.get(1),row.get(2)} );

        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox autoUpdateCheckBox;
    private javax.swing.JButton doneButton;
    private javax.swing.JButton enlargeButton;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JCheckBox largeFontCheckBox;
    private javax.swing.JTable messageTable;
    private javax.swing.JButton updateButton;
    // End of variables declaration//GEN-END:variables


// taken from http://blog.botunge.dk/post/2009/10/09/JTable-multiline-cell-renderer.aspx
public class MultiLineTableCellRenderer extends JTextArea implements TableCellRenderer {
    private List<List<Integer>> rowColHeight = new ArrayList<List<Integer>>();
    private Font font,largeFont,smallFont ;
   
    public MultiLineTableCellRenderer() {
      setLineWrap(true);
      setWrapStyleWord(true);
      setOpaque(true);
      
      largeFont = new Font(Font.SANS_SERIF,Font.PLAIN,36) ;
      smallFont = new Font(Font.SANS_SERIF,Font.PLAIN,14) ;
      font=smallFont ;
    }
   
    public void enlargeFont(boolean yn) {
       if (yn) font = largeFont ;
       else font = smallFont ;
    }
    
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
      if (isSelected) {
        setForeground(table.getSelectionForeground());
        setBackground(table.getSelectionBackground());
      } else {
        setForeground(table.getForeground());
        setBackground(table.getBackground());
      }
      setFont(font) ;
      // setFont(table.getFont());
      if (hasFocus) {
        setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
        if (table.isCellEditable(row, column)) {
          setForeground(UIManager.getColor("Table.focusCellForeground"));
          setBackground(UIManager.getColor("Table.focusCellBackground"));
        }
      } else {
        setBorder(new EmptyBorder(1, 2, 1, 2));
      }
      if (value != null) {
        setText(value.toString());
      } else {
        setText("");
      }
      adjustRowHeight(table, row, column);
      return this;
    }
   
    /**
     * Calculate the new preferred height for a given row, and sets the height on the table.
     */
    private void adjustRowHeight(JTable table, int row, int column) {
      //The trick to get this to work properly is to set the width of the column to the
      //textarea. The reason for this is that getPreferredSize(), without a width tries
      //to place all the text in one line. By setting the size with the with of the column,
      //getPreferredSize() returnes the proper height which the row should have in
      //order to make room for the text.
      int cWidth = table.getTableHeader().getColumnModel().getColumn(column).getWidth();
      setSize(new Dimension(cWidth, 1000));
      int prefH = getPreferredSize().height;
      while (rowColHeight.size() <= row) {
        rowColHeight.add(new ArrayList<Integer>(column));
      }
      List<Integer> colHeights = rowColHeight.get(row);
      while (colHeights.size() <= column) {
        colHeights.add(0);
      }
      colHeights.set(column, prefH);
      int maxH = prefH;
      for (Integer colHeight : colHeights) {
        if (colHeight > maxH) {
          maxH = colHeight;
        }
      }
      if (table.getRowHeight(row) != maxH) {
        table.setRowHeight(row, maxH);
      }
    }
  }



class UpdateThread extends Thread {

        public UpdateThread() {
        }

        @Override
        public void run() {
            try {
                for (;;) {
                    updateTable() ;
                    sleep(10000); // 10 sec
                }
            } catch (InterruptedException ex) {
                return ;
            }
        }
    }

}
