package taberion;

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


    /** Typical JTable which only overwrites a few methods
     *  to be able to react on user's input
     */
public class TTable extends JTable{

    /** The current type in which user's input is parsed.
     */
private int myParseState;

    /** The parser which is used to clean the input String from all
     *  non-type-conform characters.
     */
private TParser myNumParser;


    public TTable(int columns, int rows, int parseState)
    {
        super(columns, rows);
        this.setParseState(parseState);
        myNumParser = new TParser();
    }

    public TTable(TTableModel tableModel, int parseState)
    {
        super(tableModel.getColumnCount(), tableModel.getRowCount());
        this.setColumnSelectionAllowed(false);
        this.setModel(tableModel);
        this.setParseState(parseState);
        myNumParser = new TParser();
    }

    /** Parses the user's input of a cell into the type parseState after he has finished editing.
     *  It should parse the input not only into the types String, BigInt and BigDec, but also
     *  in smaller types like Byte or Float. Because of this, you'd never have content
     *  in your table which does not fit to the selected type.
     *  (Except from the time while editing a cell)
     */
    public void editingStopped(ChangeEvent e)
    {

        int edRow=this.getSelectedRow();
        int edCol = this.getSelectedColumn();

        super.editingStopped(e);

        String paul = (String)(this.getValueAt(edRow, edCol));
        int pS=getParseState();
        if (pS==TConsts.PARSE_BIGINT){
            this.setValueAt(myNumParser.clean2Int(paul), edRow, edCol);
        }else if (pS==TConsts.PARSE_BIGDEC){
            this.setValueAt(myNumParser.clean2Dec(paul), edRow, edCol);
        }
        updateCell(edCol, edRow);
    }

   // is called when SWITCHING the TYPE SWITCH BOX.
   // UPDATES the Table COMPLETELY
   /**
    * converts the contents of every cell in table to the type type
    *
    * @param table the table which contains all used data
    * @param type  describes the type of the conversion (i.e. BigInteger, String)
    */
    public void updateContent(int contentType, int roundState)
    {
        this.setParseState(contentType);
        myNumParser.setRoundState(roundState);
        //System.out.println("In updateContent");

        for(int m = 0; m<this.getRowCount(); m++)
        {
            for(int n = 0; n<this.getColumnCount(); n++)
            {
                this.updateCell(n, m);
            }
        }
    }

    public void updateCell(int col, int row){

        int contenttype = this.getParseState();

        //switched to BIGINTEGER
        if (contenttype==TConsts.PARSE_BIGINT)
        {
            String parseString = new String(myNumParser.clean2Int(this.getValueAt(row, col)));
            BigInteger myBigInt = new BigInteger(parseString);
            this.setValueAt(myBigInt.toString(), row, col);
        }
        else if (contenttype==TConsts.PARSE_BIGDEC)
        {
            String parseString = new String(myNumParser.clean2Dec(this.getValueAt(row, col)));
            BigDecimal myBigDec = new BigDecimal(parseString);
            this.setValueAt(myBigDec.toString(), row, col);
        }
    }


    /** Changes the type, in which the user's input should be parsed after having edited a cell
     */
    public void setParseState(int pS)
    {
        this.myParseState=pS;
    }

    /** Returns the type, in which the user's input is parsed after having edited a cell
     */
    public int getParseState()
    {
        return myParseState;
    }

    public Point getMiddleViewCell()
    {
        Rectangle tmpRect = this.getVisibleRect();

        Point middlePos = new Point((int)(tmpRect.getX()+tmpRect.getWidth()/2), (int)(tmpRect.getY()+tmpRect.getHeight()/2));
 //System.out.println("Table: Middle Pos x/y ["+ middlePos.getX() + "|" + middlePos.getY() + "]" );

        int xCellPos, yCellPos;

        xCellPos = (int)(middlePos.getX()/this.getColumn(Integer.toString(TConsts.TABLESTARTNUM)).getWidth());
 //System.out.println("Table: xCellPos ["+ xCellPos +"]");
        yCellPos = (int)(middlePos.getY()/this.getRowHeight());
  //System.out.println("Table: xCellPos ["+ yCellPos +"]");

/**///        //System.out.println("Table: CurrPos " + new Point (xCellPos, yCellPos));

        return new Point(xCellPos, yCellPos);
    }

    public Point getCellPos(Point cellPos)
    {
        Point tmpPoint = new Point((int)(this.getColumn(Integer.toString(TConsts.TABLESTARTNUM)).getWidth()*cellPos.getX()),
                                   (int)(this.getRowHeight()*cellPos.getY()));
/**///        //System.out.println("Table: CellPos " + tmpPoint);
        return tmpPoint;
    }

    public JList constRowHeader()
    {
        DefaultListModel list = new DefaultListModel();

        //System.out.println("In constRowHeader");
        for (int i = TConsts.TABLESTARTNUM; i < (getModel().getRowCount()+TConsts.TABLESTARTNUM); i++)
        {
            list.addElement(Integer.toString(i));
        }
        JList header = new JList(list);
 //       header.setSelectionMode(JList.
        return header;
    }
}