package taberion;

import javax.swing.table.*;
import java.math.*;
import java.awt.Point;


    /**
     *  This TableModel holds the Data for a TTable in form of an String[][].
     */
public class TTableModel extends AbstractTableModel implements TableModel{
    /**
     *  Contains every data you can see in TTable.
     */
private String[][] myContent;
private String[] myColumnNames;

    /**
     *  Number of Rows for this ContentHolder.
     */
private int rowCount;

    /**
     *  Number of Columns for this ContentHolder.
     */
private int columnCount;

    /**
     *  Contructs an empty TableModel
     */

private String myMinValue, myMaxValue;
private Point _MinValPos, _MaxValPos;


    public TTableModel()
    {
        myContent = new String[0][0];
        myColumnNames = new String[0];
        rowCount = 0;
        columnCount = 0;
    }

    /**
     *  Contructs an TableModel with the Dimensions
     *  columns and rows. The new String[][] is empty.
     *
     *@param columns Number of Columns used for the TableModel
     *@param rows Number of Rows used for the TableModel
     */
    public TTableModel(int rows, int columns)
    {
        myContent = new String[columns][rows];
        rowCount = rows;
        columnCount = columns;

        calcMinAndMax();

        myColumnNames = new String[columnCount];
        for(int i=(0); i < (columnCount); i++)
        {
            myColumnNames[i]=Integer.toString(i+TConsts.TABLESTARTNUM);
        }

        for(int i=0; i<this.getColumnCount(); i++){
            for (int j=0; j<getRowCount(); j++){
                this.myContent[i][j]="0";
            }
        }
    }

    /**
     *  Contructs an TableModel with the Dimensions
     *  columns and rows. The new String[][] is empty.
     *
     *@param columns Number of Columns used for the TableModel
     *@param rows Number of Rows used for the TableModel
     */
    public TTableModel(String[][] content)
    {
        this.setContent(content);
    }

    /**
     *  Returns the Object in Column col and Row row.
     *
     */
    public Object getValueAt(int row, int col)
    {
        return myContent[col][row];
    }

    /**
     *  Returns the Number of Columns in this TableModel.
     */
    public int getColumnCount()
    {
        return this.columnCount;
    }

    /**
     *  Returns the Number of Rows in this TableModel.
     */
    public int getRowCount()
    {
        return this.rowCount;
    }

    private void setColumnCount(int col)
    {
        this.columnCount = col;
    }

    private void setRowCount(int row)
    {
        this.rowCount = row;
    }
    /**
     *  Returns true and makes sure that every cell is editable.
     */
    public boolean isCellEditable(int row, int col)
    {
        return true;
    }

    /**
     *  Sets the Object value into Row row and Column col. Because of
     *  the Content Array being a String[][], it is parsed to String by toString().
     *
     *@param value The Object which should be inserted into the TableModel.
     *@param row The Row in which the Object should be inserted.
     *@param column The Column in which the Object should be inserted.
     */
    public void setValueAt(Object value, int row, int col) {
        myContent[col][row] = value.toString();
        try
        {
            BigDecimal tmpDec = new BigDecimal(value.toString());
            BigDecimal maxDec = new BigDecimal(getMaxValue());
            BigDecimal minDec = new BigDecimal(getMinValue());

            if (tmpDec.compareTo(new BigDecimal(getMaxValue()))==1)
            {
                //System.out.println("Set new Max");
                this.setMaxValue(value.toString(), new Point(col, row));
            }
            else if (tmpDec.compareTo(new BigDecimal(getMinValue()))==-1)
            {
                //System.out.println("Set new Min");
                this.setMinValue(value.toString(), new Point(col, row));
            }
            else if(tmpDec.compareTo(maxDec)==-1 && tmpDec.compareTo(minDec)==1)
            {
                //System.out.println("Set no new");
            }

            if(getMaxPos().equals(new Point(col, row))||getMinPos().equals(new Point(col, row)))
            {
                //System.out.println("equals one value...");
                this.calcMinAndMax();
            }

        }catch(Exception e)
        {
            //System.out.println(e);
        }

        fireTableCellUpdated(row, col);
    }

    public void changeSize(int nRowCnt, int nColCnt){
         int rowmax, colmax;
         String[][] oldContent = myContent;
         myContent = new String[nColCnt][nRowCnt];


         if (nRowCnt<getRowCount())
         {
            rowmax=nRowCnt;
         }else
         {
            rowmax=getRowCount();
         }

         if (nColCnt<getColumnCount())
         {
            colmax=nColCnt;
         }
         else {
            colmax=getColumnCount();
         }

         //System.out.println("MaxCol: "+colmax+" ; MaxRow: "+rowmax+" ; nRowCnt: "+nRowCnt+" ; nColCnt: "+nColCnt);

         for(int i=0; i<colmax; i++){
            for (int j=0; j<rowmax; j++){
                myContent[j][i]=oldContent[j][i];
            }
        }
        setColumnCount(nColCnt);
        setRowCount(nRowCnt);
    }

    public void insertTableModel(TTableModel ins)
    {
         int rowmax, colmax;
         String[][] oldContent = ins.getContent();

         if (ins.getRowCount()<getRowCount())
         {
            rowmax=ins.getRowCount();
         }else
         {
            rowmax=getRowCount();
         }

         if (ins.getColumnCount()<getColumnCount())
         {
            colmax=ins.getColumnCount();
         }
         else {
            colmax=getColumnCount();
         }

         //System.out.println("MaxCol: " + colmax + " MaxRow: " + rowmax);

         for(int i=0; i<colmax; i++){
            for (int j=0; j<rowmax; j++){
                this.myContent[i][j]=oldContent[i][j];
            }
        }
        //this.printlnContent();
    }

    public void printlnContent()
    {
        for(int i=0; i<getColumnCount(); i++){
            for (int j=0; j<getRowCount(); j++){
                System.out.print(" "+getContent()[i][j]+" ");
            }
            System.out.println();
        }
    }

    public String[][] getContent()
    {
        return this.myContent;
    }

    public void setContent(String[][] str){
        myContent=str;
        this.setRowCount(str[0].length);
        this.setColumnCount(str.length);

        this.calcMinAndMax();

         //System.out.println("In setContent");

//        tableModel.setMinAndMaxValue(minVal.toString(), maxVal.toString(), minPos, maxPos);

        myColumnNames = new String[columnCount];
        for(int i=TConsts.TABLESTARTNUM; i<(columnCount+TConsts.TABLESTARTNUM); i++)
        {
            myColumnNames[(i-TConsts.TABLESTARTNUM)]=Integer.toString(i);
        }
    }

    public void setMinAndMaxValue(String min, String max, Point minPos, Point maxPos){
        setMinValue(min, minPos);
        setMaxValue(max, maxPos);
    }

    public void setMinValue(String min, Point pos){
        myMinValue = min;
        _MinValPos = pos;
    }

    public void setMaxValue(String max, Point pos){
        myMaxValue = max;
        _MaxValPos = pos;
    }

    public String getMinValue(){
        return myMinValue;
    }

    public Point getMaxPos(){
        return _MaxValPos;
    }

    public Point getMinPos(){
        return _MinValPos;
    }

    public String getMaxValue(){
        return myMaxValue;
    }

    public String getColumnName(int col)
    {

        return myColumnNames[col];
    }

    public Class getColumnClass(int c)
    {
        return getValueAt(0, c).getClass();
    }

    public void calcMinAndMax(){
        try{
            BigDecimal minVal = new BigDecimal(getContent()[0][0]);
            BigDecimal maxVal = new BigDecimal(getContent()[0][0]);
            Point minPos = new Point(0,0);
            Point maxPos = new Point(0,0);

            for(int i=0; i<getColumnCount(); i++){
                for(int j=0; j<getRowCount(); j++){
                    BigDecimal content = new BigDecimal(getContent()[i][j]);
                    if(minVal.compareTo(content)==1)
                    {
                        minVal = content;
                        minPos = new Point(i, j);
                    }
                    if(maxVal.compareTo(content)==-1)
                    {
                        maxVal = content;
                        maxPos = new Point(i, j);
                    }
                }
            }
            this.setMaxValue(maxVal.toString(), maxPos);
            this.setMinValue(minVal.toString(), minPos);
            //System.out.println("MaxPos: "+this.getMaxPos()+" "+maxVal);

            //System.out.println("MinVal: "+this.getMinPos()+" "+ minVal);
        }catch(Exception e)
        {
            //System.out.println(e);
        }
    }
}