/*
 *  Draco Econometrics
 *  Copyright (C) 2006-2007 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.datamodel;
import javax.swing.table.AbstractTableModel;

/*
 * Created on Mar 24, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author armstrongj
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class IndepDepTableModel extends AbstractTableModel {
	
	private static final int NAME_COLUMN = 0;
	private static final int INDEPENDENT_COLUMN = 1;
	private static final int DEPENDENT_COLUMN = 2;
	
	private Object[][] data;
	private String[] columnNames = {"Column","Independent","Dependent"};
	
	private boolean reverse = false;
	
	public IndepDepTableModel(String[] strings, boolean[] indep, boolean[] dep) {
		data = new Object[strings.length][3];
		for(int i=0;i<strings.length;i++) {
			data[i][NAME_COLUMN] = strings[i];
			data[i][INDEPENDENT_COLUMN] = new Boolean(indep[i]);
			data[i][DEPENDENT_COLUMN] = new Boolean(dep[i]);
		}			
	}
	
	public IndepDepTableModel(String[] strings) {
		data = new Object[strings.length][3];
		for(int i=0;i<strings.length;i++) {
			data[i][0] = strings[i];
			data[i][1] = new Boolean(false);
			data[i][DEPENDENT_COLUMN] = new Boolean(false);
		}			
	}
	
	public IndepDepTableModel(String[] strings, boolean only_one_indep) {
		data = new Object[strings.length][3];
		for(int i=0;i<strings.length;i++) {
			data[i][NAME_COLUMN] = strings[i];
			data[i][INDEPENDENT_COLUMN] = new Boolean(false);
			data[i][DEPENDENT_COLUMN] = new Boolean(false);
		}
		reverse = only_one_indep;
	}
	
	public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.length;
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        return data[row][col];
    }

    /*
     * JTable uses this method to determine the default renderer/
     * editor for each cell.  If we didn't implement this method,
     * then the last column would contain text ("true"/"false"),
     * rather than a check box.
     */
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    /*
     * Don't need to implement this method unless your table's
     * editable.
     */
    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if (col < 1) {
            return false;
        } else {
            return true;
        }
    }

    /*
     * Don't need to implement this method unless your table's
     * data can change.
     */
    public void setValueAt(Object value, int row, int col) {
    	// Can't change variable names
    	if(col == 0) return;
    	
    	boolean indep, dep;
    	
    	switch(col) {
    		case INDEPENDENT_COLUMN:
    			indep = ((Boolean)value).booleanValue();
    			if(indep) {
    				
    				if(reverse) {
    					for(int i=0;i<this.getRowCount();i++) {
        					if(i != row) {
        						data[i][INDEPENDENT_COLUMN] = new Boolean(false);
        					}
        				}
    				}
    				
    				data[row][DEPENDENT_COLUMN] = new Boolean(false);
    			}
    			break;
    		case DEPENDENT_COLUMN:
    			dep = ((Boolean)value).booleanValue();
    			if(dep) {
    				
    				if(!reverse) {
    					for(int i=0;i<this.getRowCount();i++) {
    						if(i != row) {
    							data[i][DEPENDENT_COLUMN] = new Boolean(false);
    						}
    					}
    				}
    				
    				data[row][INDEPENDENT_COLUMN] = new Boolean(false);
    			}
    			break;
    	}
    	
        data[row][col] = value;
        fireTableDataChanged(); 
        //fireTableStructureChanged();
    }

    /* For accessing lists of independent and dependent variables */
    public String getDependentVariable() {
    	return getFirstTrue(DEPENDENT_COLUMN);
    }
    public String getIndependentVariable() {
    	return getFirstTrue(INDEPENDENT_COLUMN);
    }
    
    public String[] getIndependentVariables() {
    	return getAllTrues(INDEPENDENT_COLUMN);
    }
    
    public String[] getDependentVariables() {
    	return getAllTrues(DEPENDENT_COLUMN);
    }
    
    private String[] getAllTrues(int col) {
    	String[] return_val = null;
    	
    	int count=0;
    	for(int i=0;i<this.getRowCount();i++) {
    		if(((Boolean)data[i][col]).booleanValue()) count++;
    	}
    	
    	if(count == 0) return null;
    	
    	return_val = new String[count];
    	count = 0;
    	for(int i=0;i<this.getRowCount() && count<return_val.length;i++) {
    		if(((Boolean)data[i][col]).booleanValue()) {
    			return_val[count] = (String)data[i][NAME_COLUMN];
    			count++;
    		}
    	}
    	
    	return return_val;
    }
    
    private String getFirstTrue(int col) {
    	String return_val = null;
    	
    	for(int i=0;i<this.getRowCount();i++) {
    		if(((Boolean)data[i][col]).booleanValue()) {
    			return_val = (String)data[i][NAME_COLUMN];
    		}
    	}
    	
    	return return_val;
    }
    
    private void setCheckState(String name, int column, boolean value) {
    	int i = this.getRowNumber(name);
    	if(i >= 0)
    		data[i][column] = new Boolean(value);
    }
    
    protected int getRowNumber(String name) {
    	for(int i=0;i<data.length;i++) {
    		if(((String)data[i][NAME_COLUMN]).compareTo(name) == 0) {
    			return i;
    		}
    	}
    	return -1;
    }
    
    public void setDepenedentChecked(String name) {
    	setCheckState(name,DEPENDENT_COLUMN,true);
    }
    
    public void setIndepenedentChecked(String name) {
    	setCheckState(name,INDEPENDENT_COLUMN,true);
    }
}
