/*
 *  Draco Econometrics
 *  Copyright (C) 2006-2008 Approximatrix, LLC
 *  http://www.approximatrix.com
 *  
 *  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 com.approximatrix.draco.general.ui;

import java.text.NumberFormat;

import javax.swing.SwingUtilities;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;

import com.approximatrix.draco.datamodel.StatTableModel;
import com.approximatrix.draco.datamodel.VariableModel;

/** An extended JTable class that allows the use of number formatting
 * when drawing the table.  This class is used exclusively for rendering
 * StatTableModels
 * 
 * @author jarmstrong
 */
public class StatTable extends JCSelectTable implements TableColumnModelListener {

	private StatTableModel stmodel = null;
	private volatile int pass_count = 0;
	
	public StatTable() {
		super();
	}

	@Override
	public void setModel(TableModel dataModel) {
		super.setModel(dataModel);

		if(dataModel instanceof StatTableModel) {
			this.stmodel = (StatTableModel)dataModel;
			for(int i=0;i<stmodel.getColumnCount();i++)
				this.getColumnModel().getColumn(i).setCellRenderer(new VariableCellRenderer(stmodel.getVariable(i)));
		}
		
	}
	
	/** Class for rendering variables using their internally stored
	 * decimal formats.
	 * 
	 * @author armstrong
	 */
	protected class VariableCellRenderer extends DefaultTableCellRenderer {
		
		private VariableModel column = null;
		
		public VariableCellRenderer(VariableModel column) {
			this.column = column;
		}
		
		@Override
		protected void setValue(Object value) {
			
			NumberFormat formatter = column.getDecimalFormatting();
			Object topass = value;
			
			if(formatter != null && topass != null && topass instanceof Number) {
				topass = formatter.format(value);
			}
				
			super.setValue(topass);
		}
		
	}


	@Override
	public void tableChanged(TableModelEvent e) {
		super.tableChanged(e);
		
		if(stmodel == null) return;
		doTableChangedWork();
	}
    
	/** Attempts to perform a tableChanged work over and over until successful. */
	private void doTableChangedWork() {
		if(pass_count > 20) {
			System.err.println("Exceeded attempts at tableChanged()...");
			return;
		}
		for(int i=0;i<stmodel.getColumnCount();i++){
			try {
				if(this.getColumnModel().getColumn(i).getCellRenderer() instanceof VariableCellRenderer)
					continue;
			
				this.getColumnModel().getColumn(i).setCellRenderer(new VariableCellRenderer(stmodel.getVariable(i)));
				this.pass_count = 0;
			} catch(ArrayIndexOutOfBoundsException aiobe) {
				pass_count++;
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						doTableChangedWork();
					}
				});
			}
		}
	}
	
	
}
