package simulate;

import simulate.*;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTable;
import javax.swing.table.*;
import javax.swing.Box;
import javax.swing.JScrollPane;
import java.util.Observer;
import java.util.Observable;

public class DisplayTable extends simulate.Display
{
    public JTable table;
    MyTableData dataSource;
    Meter[] meter = new Meter[0];
    int nMeters = 0;
    private boolean showingPE = false;  //flag to indicate if PotentialEnergy meter should be displayed
    private boolean showingKE = false;  //same for KineticEnergy meter
    Box panel = Box.createVerticalBox();
    Button resetButton = new Button("Reset averages");
    /**
     * Shows only averages and error if true, shows only current values if false
     * Default is <code>true</code>
     */
    private boolean showAverages = true;
    
    public DisplayTable() {this(true);}
    public DisplayTable(boolean showAvgs) {
        super();
        showAverages = showAvgs;
        panel.setSize(100,150);
        dataSource = new MyTableData();   //inner class, defined below
        table = new JTable(dataSource);
        panel.add(new JScrollPane(table));
		if(showAverages) {
		    resetButton.addActionListener(new ActionListener() {
		    public void actionPerformed(java.awt.event.ActionEvent event) {DisplayTable.this.resetAverages();}
		});
//        setVisible(false);  //get out of way of painting of table
            panel.add(resetButton);
        }
        add(panel);
    }
    
    public void resetAverages() {
        for(int i=0; i<nMeters; i++) {meter[i].reset();}
    }
    public void setResetVisible(boolean b) {resetButton.setVisible(b);}
    public boolean getResetVisible() {return resetButton.isVisible();}
    public void setShowingKE(boolean b) {showingKE = b;}
    public boolean isShowingKE() {return showingKE;}
    public void setShowingPE(boolean b) {showingPE = b;}
    public boolean isShowingPE() {return showingPE;}
    
    public void addMeter(Meter m) {
        if(m instanceof MeterPotentialEnergy && !showingPE) {return;}
        if(m instanceof MeterKineticEnergy && !showingKE) {return;}
        nMeters++;
        Meter[] temp = new Meter[nMeters];
        for(int i=0; i<meter.length; i++) {temp[i] = meter[i];}
        temp[nMeters-1] = m;
        meter = temp;
    }
        
    public void setPhase(Phase p) {
        p.meterManager().addObserver(new Observer() {
            public void update(Observable mgr, Object obj) {
                if(obj instanceof Meter) DisplayTable.this.addMeter((Meter)obj);
            }
        });
    }

    public void doUpdate() {}
    public void repaint() {table.repaint();}
    
    class MyTableData extends AbstractTableModel {
        
//        String[] columnNames = new String[] {"Property", "Current", "Average"};
        String[] columnNames = new String[] {"Property", "Average", "Error"};
        Class[] columnClasses = {String.class, Double.class, Double.class};
        
        MyTableData() {
            if(showAverages) {
                columnNames = new String[] {"Property", "Average", "Error"};
                columnClasses = new Class[] {String.class, Double.class, Double.class};
            }
            else {
                columnNames = new String[] {"Property", "Current"};
                columnClasses = new Class[] {String.class, Double.class};
            }
        }
        
        public Object getValueAt(int row, int column) {
            Meter m = meter[row];
            switch(column) {
                case 0: return m.getLabel();
//                case 1: return new Double(m.currentValue());
//                case 2: return new Double(m.average());
                case 1: return new Double(showAverages ? m.average() : m.currentValue());
                case 2: return new Double(m.error());
                default: return null;
            }
        }
        
        public int getRowCount() {return meter.length;}
        public int getColumnCount() {return showAverages ? 3 : 2;}
                
        public String getColumnName(int column) {return columnNames[column];}
        public Class getColumnClass(int column) {return columnClasses[column];}
    }
    
}