/*
 * GridView.java    1.0 97/08/28
 *
 * Copyright (c) 1997 Netscape Communications Corporation
 *
 * Netscape grants you a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Netscape.
 *
 * This software is provided "AS IS," without a warranty of any kind.
 * See the CDK License Agreement for additional terms and conditions.
 * created: 2/97 cls
 */


package netscape.peas;

import netscape.application.*;
import netscape.util.Vector;
import netscape.palomar.widget.layout.*;


/**
 * GridView implements a very basic IFC based table control.  A very limited set
 * of methods are provided for getting and column information, values and rows of values.
 */
public class GridView extends View { //

    /**
     * Construct a GridView which sends event notifications to the specified Target.
     */
    public GridView( Target oTarget ) {
        super();
        moTarget = oTarget;
        moLayout = new GridSpringLayout();
	    setLayoutManager(moLayout);
  	}


    public int getRowIndex( int iRow ) {
        return (1+iRow)*getNumColumns();
    }


    public void setCurrentRow( int iNewCurrentRow ) {

        if ( miCurrentRow != iNewCurrentRow ) {

            //System.out.println( "setCurrentRow " + iNewCurrentRow );
            int iNumColumns = getNumColumns();
            Vector vSubViews = subviews();

            // existing current row no longer current
            if ( miCurrentRow != -1 ) {
                int iIndex = getRowIndex( miCurrentRow );
                for ( int i = 0; i < iNumColumns; i++ ) {
                    TextField oTF = (TextField)vSubViews.elementAt(iIndex + i);
                    oTF.setBackgroundColor(Color.white);
                }
            }

            // new current row is current
            if ( iNewCurrentRow != -1 ) {

                int iIndex = getRowIndex( iNewCurrentRow );
                for ( int i = 0; i < iNumColumns; i++ ) {
                    TextField oTF = (TextField)vSubViews.elementAt(iIndex + i);
                    oTF.setBackgroundColor(Color.pink);
                }
            }
            miCurrentRow = iNewCurrentRow;
        }
    }


    /**
     * Ensure that GridView is of appropriate size.  Called whenever size is chagned.
     */
    public void sizeTo() {
		int w = 0;
	    for (int i=0; i < getNumColumns(); i++) {
			w += getWidth( i );
	    }

        sizeTo( w, miHeaderHeight + getNumRows() *  getHeight() );
    }


    /**
     * Return the index of the given element, adjusted so as to ignore the
     * fact that the column headers are elements.  To get the row/column
     * from this index:  row = iIndex / NumRows; col = iIndex % NumRows;
     */
    public int getIndex( Object oElement ) {
        Vector vSubViews = subviews();
        return vSubViews.indexOf( oElement ) - getNumColumns();
    }

    /**
     * Given an index for a field, return its text field.  Indexes are zero based
     * and are adjusted to ignore the fact that column headers are in same vector.
     */
    public TextField getField( int iIndex ) {
        Vector vSubViews = subviews();
        return (TextField)vSubViews.elementAt( iIndex + getNumColumns() );
    }

    /**
     * Remove a row from the layout and a row of viws from this view.
     */
    public void removeRowAt( int iRow ) {
        Spring oRow = moLayout.getRowAt( iRow );

        Vector vSubViews = subviews();
        int iNumColumns = getNumColumns();
        int iRemoveIndex = (1+iRow)*iNumColumns;

        // call removeSubview with first index numColumns times
        for ( int i = 0; i < iNumColumns; i++ ) {
            View oView = (View)vSubViews.elementAt(iRemoveIndex);
            removeSubview( oView );
        }
        moLayout.removeRowAt( iRow );
        setNumRows( getNumRows() - 1 );
    }

    /**
     * Remove everything: layout mgr. rows, and TextFields (subviews).
     */
    public void removeAll() {
        for ( int i = moLayout.columnCount()-1; i>=0; i--) {
            moLayout.removeColumnAt( i );
        }
        for ( int j = moLayout.rowCount()-1; j>=0; j-- ) {
            moLayout.removeRowAt( j );
        }
        Vector vSubViews = subviews();
        int iCount = vSubViews.size();
        for ( int k = 0; k < iCount; k++ ) {
            View oView = (View)vSubViews.elementAt( 0 );
            removeSubview( oView );
        }
    }


    /**
     * Add a row to the end of the table using the given values.
     */
    public void addRow( Object[] aValues ) {

        if ( aValues.length != getNumColumns() ) {
            return;
        }
        setNumRows( getNumRows() + 1 );

        // Add Row for each column in cursor
        Spring fixedRow = new Spring();
        //fixedRow.setSpringConstant(0.001);
        fixedRow.setPreferredSize( getHeight() );

        moLayout.addRow(fixedRow);

        for (int c=0; c < getNumColumns(); c++) {
            TextField tf = new GridTextField();

            tf.setStringValue( aValues[c].toString() );
            tf.setTransparent(false);
            tf.setEditable(true);
            //tf.setWrapsContents(true);  // if this is on, we can't edit!!

            tf.setBackgroundColor(Color.white);
            tf.setCommand( "change" );
            tf.setTarget( moTarget );
            addSubview(tf);
        }

    } // addRow


    /**
     *  Given column information, create a row for the column names
     */
    public void setColumnInfo( int iNumColumns, String[] aColumnNames, int[] aColumnWidths ) {

        setNumRows( 0 );

        setNumColumns( iNumColumns );

        // Add Row for each column in cursor
        Spring fixedRow = new Spring();
        //fixedRow.setSpringConstant(0.001);
        fixedRow.setPreferredSize( miHeaderHeight );
        moLayout.addRow(fixedRow);

	    for (int i=0; i < getNumColumns(); i++) {
			Spring fixedCol = new Spring();
			//fixedCol.setSpringConstant(0.001);
			if ( null != aColumnWidths &&  aColumnWidths[i] != -1 ) {
			    setWidth( i, aColumnWidths[i] );
			}

			fixedCol.setPreferredSize( getWidth( i ) );
	        moLayout.addColumn(fixedCol);
	    }

        // Display Column Names
	    for (int i=0; i < getNumColumns(); i++) {
 	        TextField tf = new TextField();
            tf.setStringValue(aColumnNames[i]);
            tf.setTransparent(false);
            tf.setEditable(false);
            tf.setWrapsContents(true);
            tf.setBackgroundColor(Color.yellow);
            addSubview(tf);
	    }
	}


    /**
     *  Set the number of rows.  This does not include column header row.
     */
    public void setNumRows( int iNewValue ) {
        miNumRows = iNewValue;
    }


    /**
     *  Return the number of rows. This does not include column header row.
     */
    public int getNumRows() {
        return miNumRows;
    }

    /**
     *  Set the number of columns.
     */
    public void setNumColumns( int iNewValue ) {
        miNumColumns = iNewValue;
		miColWidth = new int[miNumColumns];
		// Set default width
	    for (int i=0; i < getNumColumns(); i++) {
			setWidth( i, getWidth() );
		}
    }

    /**
     *  Return the number of columns
     */
    public int getNumColumns() {
        return miNumColumns;
    }

    /**
     *  Return the cell height
     */
    public int getHeight() {
        return miHeight;
    }

    /**
     *  Return the cell width
     */
    public int getWidth() {
        return miWidth;
    }

    public int getWidth( int i ) {
        return miColWidth[i];
    }

    /**
     *  Set the cell width
     */
     public void setWidth( int ind, int w ) {
		 miColWidth[ind] = w;
	 }

    //-------------------------------
    // instance variables

    private int miHeaderHeight = 30;
    private int miHeight = 20;

    private int miWidth = 100;
	private int[] miColWidth = new int[1];

    private int miNumRows = 0;
    private int miNumColumns = 0;
    private GridSpringLayout moLayout = null;
    private Target moTarget = null;

    private int miCurrentRow = -1;

 } //GridView
