/**
 * @(#)Taberion.java 1.0 03/07/09
 *
 * written by Patrick Thomas and Jörn Maas in 2003, Paderborn
 */

package taberion;

import java.math.*;
import java.lang.Float;

import java.awt.*;

import javax.swing.*;
import javax.swing.table.*;

import java.awt.event.*;

import java.util.*;
import java.text.SimpleDateFormat;

import javax.swing.event.TableModelListener;
import javax.swing.event.TableModelEvent;

import javax.swing.border.Border;

public class Taberion extends JFrame implements ActionListener, MouseListener, MouseMotionListener , KeyListener /*, FocusListener*/{

protected static ResourceBundle _LangBundle = null;

private Container _MainContainer;

private TMenuBar _MenuBar;
private JComboBox _TypeList, _FocusBox;

private JPanel _BoardPanel, _ButtonPanel, _MenuPanel;
private JTextField _RowField, _ColumnField;
private TMatrixStorage _MatrixStorage;

private boolean _TableActive;

private TPanel _DataPane;
private TTable _MatrixTable;
private TTableCellRenderer _TableRenderer;

private boolean _ChangeColMax;
private JButton _MaxButton, _MinButton, _SwitchTableBtn, _exitButton, _abortButton;

private GradientPanel _ColorPane;
private JTextField _StatusBar;
private JScrollPane _ScrollPane;
private Color _MinColor=TConsts.startMinCol, _MaxColor=TConsts.startMaxCol;

private int _LastSelectedIndex;
final JColorChooser _ColorChooser = new JColorChooser();
private JDialog _ColorDialog;

//------- Additions from Maas --------

private THandleCSV handleCSV;

// As default the user is asked if a conversion takes place.
private boolean askConversion = true;
private static boolean doWaitForMutex = false;
private static Object waitMutex = new Object();
// Usually the two buttons return result and abort edit do not have to be shown.
private boolean inMuPAD = false;
// If abort was pressed then return null instead of the matrix
private static boolean returnNull = false;

  /**
   * To define if the user is to be asked for a conversion or not.
   */
  public void changeAskConversion(boolean state) {
    this.askConversion = state;
  }

  public void setMuPADState(boolean state) {
    this.inMuPAD = state;
  }

  /**
   * will cause a waiting routine similar to a modal state.
   */
  public static void setDoWait(boolean state) {
    synchronized(waitMutex) {
      //System.out.println("Change state to " + state);
      doWaitForMutex = state;
      waitMutex.notify();
    }
  }

  private static void waitForTermination()
  {
    while (doWaitForMutex) {
      synchronized (waitMutex) {
        try {
          waitMutex.wait();
        } catch (InterruptedException e) {
            System.out.println("Some serious errors occured in Matrix Editor (waitForTermination):");
            e.printStackTrace();
          }
      }
    }
  }

  /*
   * matrixEditor :
   * 1) In MuPAD first matrixEditor is invoked and a Taberion object is returned
   * 2) The object is used to ask for the type of the matrix
   * 3) The object is set to changeAskConversion(false)
   * 4) The matrix is retrieved via getMatrix()
   */

  /**
   * starts a new Matrix Editor (for example from MuPAD)
   * @param content the squared matrix with predefined values
   * @return What type the stored matrix is.
   */
  public static Taberion matrixEditor(BigInteger[][] content) { // BigInteger[][]
    //System.out.println("matrixEditor with Integer");
    returnNull = false;
    Taberion tab = new Taberion(content, true);
    //tab.changeAskConversion(false);
    doWaitForMutex = true;
    waitForTermination();
    if (returnNull) {
      // System.out.println("Going to return null");
      returnNull = false; // so it will definitely be reseted when calling the same object again!
      return null;
    }
    else {
      return tab;
      // System.out.println("Going to return matrix (Size=" + tab.getSize() + ")");
      //return tab.getIntegerMatrix();
    }
  }

  /**
   * starts a new Matrix Editor (for example from MuPAD)
   * @param content the squared matrix with predefined values
   * @return The changed or unchanged new matrix.
   */
  public static Taberion matrixEditor(BigDecimal[][] content) { // BigDecimal[][]
    //System.out.println("matrixEditor with BigDecimal");
    Taberion tab = new Taberion(content, true);
    returnNull = false;
    //tab.changeAskConversion(false);
    doWaitForMutex = true;
    waitForTermination();
    if (returnNull) {
      // System.out.println("Going to return null");
      returnNull = false; // so it will definitely be reseted when calling the same object again!
      return null;
    }
    else {
      return tab;
      // System.out.println("Going to return matrix (Size=" + tab.getSize() + ")");
      //return tab.getFloatingPointMatrix();
    }
  }


  /**
   * to be able to start a waiting from outside.
   */
  public void waitForReturn() {
    doWaitForMutex = true;
    waitForTermination();
    changeAskConversion(false);
  }

  /**
   * starts a new Matrix Editor (for example from MuPAD)
   * @param content the squared matrix with predefined values
   * @return The changed or unchanged new matrix.
   */
  public static Taberion matrixEditor(String[][] content) { // String[][]
    //System.out.println("matrixEditor with String");
    Taberion tab = new Taberion(content, true);
    returnNull = false;
    //tab.changeAskConversion(false);
    doWaitForMutex = true;
    waitForTermination();
    if (returnNull) {
      // System.out.println("Going to return null");
      returnNull = false; // so it will definitely be reseted when calling the same object again!
      return null;
    }
    else {
      return tab;
      // System.out.println("Going to return matrix (Size=" + tab.getSize() + ")");
      //return tab.getStringMatrix();
    }
  }

  public void setVisible(boolean b) {
    super.setVisible(b);
    if (b)
      this.toFront();
  }

  public void centerScreen() {
   Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
   Dimension frameSize = this.getSize();
   if (frameSize.height > screenSize.height)
   {
     frameSize.height = screenSize.height;
   }
   if (frameSize.width > screenSize.width)
   {
     frameSize.width = screenSize.width;
   }
   this.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);

  }


//------- Generates a new Taberion Frame --------

  /**
   * creates an instance of Taberion, the main application
   */

    public static void main(String args[])
    {

        int width = 10;
        int height = 20;

        BigDecimal[][] tempNum = new BigDecimal[width][height];

        //Random newRand = new Random();
        for(int i=0; i<width; i++){
            for(int j=0; j<height; j++){
                tempNum[i][j] = new BigDecimal((0));
                //tempNum[i][j] = new BigDecimal(tempStr[j][i]);
            }
        }


        //System.out.println("Starting Taberion...");

        Taberion mainFrame = new Taberion(tempNum, false);

    }

//-----------------------------------------------

    /** initalizes the Object Taberion
     *The complete GUI is constructed
     *and all global variables become initialised
     */

    public Taberion()
    {
        String[][] tableCont = new String[1][1];
        tableCont[0][0]="0";
        TTableModel tableModel = new TTableModel(tableCont);
        buildFrame(tableModel, TConsts.PARSE_STRING);
    }

    public Taberion(String[][] content, boolean inMuPAD)
    {
        content = this.transposeMatrix(content);
        TTableModel tableModel = new TTableModel(content);
        this.setMuPADState(inMuPAD);
        buildFrame(tableModel, TConsts.PARSE_STRING);
    }


    public Taberion(BigInteger[][] content, boolean inMuPAD)
    {
        int col = content.length;
      	int row = content[0].length;
        String[][] tableCont = new String[col][row];

        for(int i=0; i<col; i++){
            for(int j=0; j<row; j++){
                tableCont[i][j] = content[i][j].toString();
            }
        }

        tableCont = this.transposeMatrix(tableCont);
        TTableModel tableModel = new TTableModel(tableCont);
        this.setMuPADState(inMuPAD);
        buildFrame(tableModel, TConsts.PARSE_BIGINT);
    }

    public Taberion(BigDecimal[][] content, boolean inMuPAD)
    {
        int col = content.length;
        int row = content[0].length;
        String[][] tableCont = new String[col][row];

        for(int i=0; i<col; i++){
            for(int j=0; j<row; j++){
                tableCont[i][j] = content[i][j].toString();
            }
        }

        tableCont = this.transposeMatrix(tableCont);
        TTableModel tableModel = new TTableModel(tableCont);
        this.setMuPADState(inMuPAD);
        buildFrame(tableModel, TConsts.PARSE_BIGDEC);
    }

    public void buildFrame(TTableModel tableModel, int contenttype){


        setResourceBundle();

        try{
            UIManager.setLookAndFeel(new com.incors.plaf.kunststoff.KunststoffLookAndFeel());
        } catch(Exception e)
        {
            JFrame.setDefaultLookAndFeelDecorated(true);
        }


        _ColorDialog = JColorChooser.createDialog(this, _LangBundle.getString("PickColor"),
                                        true, _ColorChooser,
                                        this, null);

        _ChangeColMax = false;

        // If set to true, the table is shown, if set to false, the graphic.
        _TableActive = true;


        _MatrixStorage= new TMatrixStorage();

        _LastSelectedIndex = 0;

        addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                //System.out.println("Taberion: Quitting...");
                setVisible(false);
                if (inMuPAD) {
                  returnNull = true;
                  setDoWait(false);
                }
                //dispose();
            }
        });

        _MainContainer = new Container();
        BorderLayout _MainLayout = new BorderLayout();
        _MainContainer.setLayout(_MainLayout);

        //System.out.println("Taberion: Constructing NorthBar");

        GridLayout controlLayout = new GridLayout(2, 1, 0, 0);
        Container controlCntnr = new Container();
        controlCntnr.setLayout(controlLayout);

        GridLayout menuLayout = new GridLayout(1, 2, 0, 0);
        Container menuCntnr = new Container();
        menuCntnr.setLayout(menuLayout);

        _MenuBar= new TMenuBar(this, _LangBundle);
        menuCntnr.add(_MenuBar);

        BorderLayout switchLayout = new BorderLayout();
        switchLayout.setHgap(0);
        switchLayout.setVgap(0);
        Container switchCntnr = new Container();
        switchCntnr.setLayout(switchLayout);

        _SwitchTableBtn = new JButton("T");
        //switchButton.setPreferredSize(new Dimension(30, 30));
        _SwitchTableBtn.addActionListener(this);
        switchCntnr.add(_SwitchTableBtn, BorderLayout.WEST);

        String[] focusStrings = {_LangBundle.getString("OnePoint"),
                                 _LangBundle.getString("FitToWindow")};

        _FocusBox = new JComboBox(focusStrings);
        _FocusBox.setSelectedIndex(0);
        _FocusBox.addActionListener(this);
        switchCntnr.add(_FocusBox);

        menuCntnr.add(switchCntnr, BorderLayout.CENTER);

        controlCntnr.add(menuCntnr);

        GridLayout buttonLayout = new GridLayout(1, 3, 0, 0);
        Container buttonCntnr = new JPanel(buttonLayout);

        FlowLayout columnLayout = new FlowLayout();
        Container columnCntnr = new Container();
        columnCntnr.setLayout(columnLayout);

        JLabel columnLabel = new JLabel(_LangBundle.getString("Columns"));
        columnCntnr.add(columnLabel);

        _ColumnField = new JTextField(Integer.toString(tableModel.getColumnCount()), 5);
        _ColumnField.setColumns(5);
        _ColumnField.addKeyListener(this);

        columnCntnr.add(_ColumnField);

        FlowLayout rowLayout = new FlowLayout();
        Container rowCntnr = new Container();
        rowCntnr.setLayout(rowLayout);

        JLabel rowLabel = new JLabel(_LangBundle.getString("Rows"));
        rowCntnr.add(rowLabel);

        _RowField = new JTextField(Integer.toString(tableModel.getRowCount()), 5);
        _RowField.addKeyListener(this);

        rowCntnr.add(_RowField);

        buttonCntnr.add(rowCntnr);
        buttonCntnr.add(columnCntnr);

        String[] typeStrings = {_LangBundle.getString("String"),
                                _LangBundle.getString("Integer"),
                                _LangBundle.getString("FloatingPoint")};

        _TypeList = new JComboBox(typeStrings);
        _TypeList.setSelectedIndex(contenttype);
        _TypeList.addActionListener(this);

        buttonCntnr.add(_TypeList);

        controlCntnr.add(buttonCntnr);

        _MainContainer.add(controlCntnr, BorderLayout.NORTH);

        GridLayout statusLayout;

        if (inMuPAD) {
          statusLayout = new GridLayout(3, 1, 0, 0);
        } else {
          statusLayout = new GridLayout(2, 1, 0, 0);
        }
        Container statusContainer = new Container();
        statusContainer.setLayout(statusLayout);

        _StatusBar = new JTextField();
        _StatusBar.setEditable(false);
        statusContainer.add(_StatusBar);

        BorderLayout colorLayout = new BorderLayout();

        Container colorCntnr = new Container();
        colorCntnr.setLayout(colorLayout);

        _MinButton = new JButton(_LangBundle.getString("Min"));
        _MinButton.setBackground(_MinColor);
        _MinButton.addActionListener(this);
        colorCntnr.add(_MinButton, BorderLayout.WEST);


        _ColorPane = new GradientPanel();
        _ColorPane.setColorGradient(_MaxColor, _MinColor);

        colorCntnr.add(_ColorPane, BorderLayout.CENTER);

        _MaxButton = new JButton(_LangBundle.getString("Max"));
        _MaxButton.addActionListener(this);
        _MaxButton.setBackground(_MaxColor);
        colorCntnr.add(_MaxButton, BorderLayout.EAST);

        statusContainer.add(colorCntnr);

        if (inMuPAD) {
          Container _buttonContainer = new Container();
          _buttonContainer.setLayout(menuLayout);

          _exitButton = new JButton(_LangBundle.getString("ReturnMatrix"));
          _exitButton.addActionListener(this);
          //statusContainer.add(_exitButton);

          _abortButton = new JButton(_LangBundle.getString("AbortEdit"));
          _abortButton.addActionListener(this);
          //statusContainer.add(_abortButton);

          _buttonContainer.add(_exitButton);
          _buttonContainer.add(_abortButton);
          statusContainer.add(_buttonContainer);

        }

        _MainContainer.add(statusContainer, BorderLayout.SOUTH);
        _MainContainer.addComponentListener(new ComponentAdapter() {
              public void componentResized(ComponentEvent event) {

                   //layoutComponents(getWidth(),getHeight());
                   validate();
                   repaint();
              }
         });


        this.setDataPane(new TPanel(tableModel));
        getDataPane().setBackground(Color.white);


        //TAbstractTableModel tabHead = new TAbstractTableModel(width);

        this.setTable(new TTable(tableModel, contenttype));

        //Table Row Header




        //getTable().setTableHeader(
        getTable().addMouseListener(this);
        getTable().setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        getTable().setIntercellSpacing(new Dimension(0, 0));

/*        int vColIndex = table.getColumnCount();
            for(int i = 0; i < vColIndex; i++){
            TableColumn col = getTable().getColumnModel().getColumn(i);
            int width = 1;
            col.setMinWidth(1);
            col.setPreferredWidth(width);
        }*/

        getTable().setRowHeight(18);


        //Set up renderer and editor for the Favorite Color column.
        _TableRenderer = new TTableCellRenderer(tableModel);


        setUpEditor(getTable(), contenttype);
        getTable().setDefaultRenderer(Object.class, _TableRenderer);


        _ScrollPane = new JScrollPane(getTable());


        setViewPane(_TableActive);

        _ScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        _ScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        getTable().setAutoResizeMode(JTable.AUTO_RESIZE_OFF);


        this.setContentPane(_MainContainer);

        this.pack();
        this.setSize(TConsts.startWidth, TConsts.startHeight);

        this.setTitle(_LangBundle.getString("WindowTitle"));
        //System.out.println("Taberion: Up and Running");
        getDataPane().calculateNewCellSize();
        this.centerScreen();
        this.toFront();
        this.setVisible(true);
    }

    class GradientPanel extends JPanel
    {
    private Color _MinColor=TConsts.startMinCol, _MaxColor=TConsts.startMaxCol;

         public void paint(Graphics g)
        {
            Graphics2D g2d = (Graphics2D)g;
            g2d.setPaint(new GradientPaint(0, this.getHeight()/2, _MinColor, this.getWidth(), this.getHeight()/2, _MaxColor));
            g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
        }

        public void setColorGradient(Color max, Color min)
        {
            _MaxColor = max;
            _MinColor = min;
            repaint();
        }
    }

//-----------------------------------------------

//  SETs the LANGUAGE BUNDLE
    /**
     * Internationalisation:
     * descides, which ResourceBundle has to be used on the current maschine
     */

    protected void setResourceBundle()
    {
        try
        {
            //System.out.println("Lade RB");
            _LangBundle = ResourceBundle.getBundle("taberion.TBundle", Locale.getDefault());
        } catch ( Exception e )
        {
            //System.out.println("setResourceBundle: Failed due to Exception!");
        }
    }

//-----------------------------------------------

    /**
     *Only listens to changes in the Type-Combo-Box
     *and initiates the update of the table.
     *Doesn't do so, if any cell is edited while changing the type.
     */
    public void actionPerformed(ActionEvent actEvt)
    {
        String commAnd = actEvt.getActionCommand();
        //System.out.println("ActionCommand:" + commAnd);
        if (commAnd==_LangBundle.getString("Exit"))
        {
            this.setVisible(false);
            if (inMuPAD) {
              returnNull = true;
              setDoWait(false);
            }
            //this.dispose();
        }
        else if (commAnd==_LangBundle.getString("ReturnMatrix"))
        {
            this.setVisible(false);
            setDoWait(false);
            //this.dispose();
        }
        else if (commAnd==_LangBundle.getString("NewMatrix"))
        {
            String[][] content = {{""}};
            TTableModel newtabmod = new TTableModel(content);
            this.setModel(newtabmod);
        }
        else if (commAnd==_LangBundle.getString("AbortEdit"))
        {
            this.setVisible(false);
            returnNull = true;
            setDoWait(false);
            //this.dispose();
        }
        else if (commAnd==_LangBundle.getString("About"))
        {
          JOptionPane.showMessageDialog(this, "MatrixEditor V1.0\nCreated by Patrick Thomas\nModified for MuPAD by Jörn Maas\n","MatrixEditor-About", JOptionPane.INFORMATION_MESSAGE);
        }
        else if (commAnd==_LangBundle.getString("Introduction"))
        {
          JOptionPane.showMessageDialog(this, "Yet to come...\n","MatrixEditor-Introduction", JOptionPane.INFORMATION_MESSAGE);
        }
        else if (commAnd==_LangBundle.getString("Max"))
        {
            _ChangeColMax = true;
            _ColorDialog.show();
        }
        else if (commAnd.equals(_LangBundle.getString("TransposeMatrix")))
        {
            String[][] content = this.transposeMatrix(((TTableModel)(this.getTable().getModel())).getContent());
            TTableModel newtabmod = new TTableModel(content);
            //buildFrame(newtabmod, TConsts.PARSE_STRING);
            this.setModel(newtabmod);

        }
        else if (commAnd==_LangBundle.getString("Min"))
        {
            _ChangeColMax = false;
            _ColorDialog.show();

        }
        else if (commAnd.equals/*_LangBundle.getString*/("OK"))
        {
            //System.out.println(_ColorChooser.getColor());
            if (_ChangeColMax)
            {
                setMaxColor(_ColorChooser.getColor());
            }else
            {
                setMinColor(_ColorChooser.getColor());
            }
        }
        else if (commAnd==_LangBundle.getString("LoadMatrix")) {
          handleCSV = new THandleCSV(this);
          String[][] content = handleCSV.getMatrix();
          if (content != null) {
            content = this.transposeMatrix(content);
            if (content != null) {
              TTableModel tableModel = new TTableModel(content);
              buildFrame(tableModel, TConsts.PARSE_STRING);
            }
          }
        }
        else if (commAnd==_LangBundle.getString("SaveMatrix")) {
          handleCSV = new THandleCSV(this, getStringMatrix());
          //System.out.println("Back in Taberion");
          handleCSV.getMatrix(); // just to stop the gui.
        }
        else if (commAnd==_LangBundle.getString("StoreMatrix"))
        {
            SimpleDateFormat formatter;  // Formats the date displayed
            Date currentDate;            // Used to get date to display
            currentDate = new Date();

            formatter = new SimpleDateFormat ("hh:mm:ss",
                                          Locale.getDefault());
            String today = formatter.format(currentDate);
            today = today +" "+ _TypeList.getSelectedItem().toString() +" "+ getTable().getColumnCount() + "x" +getTable().getRowCount();

            String s = (String)JOptionPane.showInputDialog(
                                        this,
                                        _LangBundle.getString("NameTheMatrix"),
                                        _LangBundle.getString("StoreTheMatrix"),
                                        JOptionPane.PLAIN_MESSAGE,
                                        null,
                                        null,
                                        today);
            if (s != null)
            {
                 _MatrixStorage.storeMatrix(cloneArray(((TTableModel)getTable().getModel()).getContent()), _TypeList.getSelectedIndex(), _MenuBar.addStoredMatrix(s));
                _MenuBar.revalidate();
            }
        }
        else if (Character.isDigit(commAnd.toCharArray()[0]))
        {
            int contentIndex = Integer.parseInt(commAnd.substring(0, 1));
            String[][] restoredContent = _MatrixStorage.restoreMatrix(contentIndex);

            int usersChoice = JOptionPane.YES_OPTION;
            if (restoredContent.length!=getTable().getColumnCount()||restoredContent[0].length!=getTable().getRowCount())
            {
                usersChoice = JOptionPane.showConfirmDialog(
                            this, _LangBundle.getString("DiffDimension"),
                            _LangBundle.getString("DiffDimTitle"),
                            JOptionPane.YES_NO_OPTION);
            }

            if (usersChoice == JOptionPane.YES_OPTION) {

                TTableModel newtabmod = new TTableModel(restoredContent[0].length, restoredContent.length);
                newtabmod.setContent(restoredContent);
                newtabmod.calcMinAndMax();
                _TableRenderer.setModel(newtabmod);
                getDataPane().setModel(newtabmod);
                getTable().setModel(newtabmod);
                _TypeList.setSelectedIndex(_MatrixStorage.restoreContentType(contentIndex));

                _RowField.setText(Integer.toString(restoredContent[0].length));
                _ColumnField.setText(Integer.toString(restoredContent.length));
            }

         //System.out.println("The new content with different Dimensions is set." + contentIndex);
        }
        else if(actEvt.getSource()==_SwitchTableBtn){
            // This is were the different views are chosen (Table->Image and Image->Table)
            _TableActive = !_TableActive;
            setViewPane(_TableActive);
            if (!_TableActive  && getTable().getColumnCount() <= 50) {
              _FocusBox.setSelectedIndex(1);
            } else if (!_TableActive  && getTable().getColumnCount() > 50) {
              _FocusBox.setSelectedIndex(0);
            }

        }
        else if(actEvt.getSource()==_TypeList)
        {
            //Content type can only be change if no cell is edited in this moment
            if (getTable().getEditingColumn()==-1)
            {
                int usersChoice;
                if (this.askConversion) {
                  usersChoice = JOptionPane.showConfirmDialog(
                          this, _LangBundle.getString("Proceed?"),
                          _LangBundle.getString("LossOfPrecTitle"),
                          JOptionPane.YES_NO_OPTION);
                } else {
                  usersChoice = JOptionPane.YES_OPTION;
                }

                if (usersChoice == JOptionPane.YES_OPTION)
                {
                    _LastSelectedIndex = _TypeList.getSelectedIndex();
                    setUpEditor(getTable(), _TypeList.getSelectedIndex());
                    getTable().updateContent(_TypeList.getSelectedIndex(), _MenuBar.getRoundState());

                    if(_TypeList.getSelectedIndex()==TConsts.PARSE_STRING)
                    {
                        _SwitchTableBtn.setEnabled(false);
                    }else
                    {
                        _SwitchTableBtn.setEnabled(true);
                    }
                }
                else
                {
                    _TypeList.setSelectedIndex(_LastSelectedIndex);
                }
            }
            else
            {
                _TypeList.setSelectedIndex(_LastSelectedIndex);
            }
        }
        else if(actEvt.getSource()==_FocusBox)
        {
            // Here is where the display of the graphics is determined.
            if(_FocusBox.getSelectedIndex()==0){
                getDataPane().setCellSize(new TCellSize(1.0d, 1.0d));
                getDataPane().repaint();
            }else{
                getDataPane().calculateNewCellSize();
                getDataPane().repaint();
            }

        }
    }

//-----------------------------------------------

    /*sets a new Editor for each cell in table table. The Editor gets the new
     *type contenttype to scan the cell content and to decide whether the user input
     *has the correct type or not.
     *
     *@param table The table which cells should get a new Editor
     *@param type The type which is allowed by the Editor
     */

    private void setUpEditor(JTable table, int contenttype) {

        final TVerificationField stringField = new TVerificationField(contenttype, 10);

        stringField.setHorizontalAlignment(TVerificationField.LEFT);

        DefaultCellEditor stringEditor =
            new DefaultCellEditor(stringField) {

                public Object getCellEditorValue() {
                    return new String(stringField.getText());
                }

            };
        for(int i=0; i<table.getColumnCount(); i++){
            table.setDefaultEditor(table.getColumnClass(i), stringEditor);
        }
    }

//-----------------------------------------------

//  MOUSELISTENER

    public void mouseReleased(MouseEvent mouEvt)
    {
    }

    /** shows the cell content in the cellEditField (in South of
     * the frame), when choosen it via mouse-pressed
     */
    public void mousePressed(MouseEvent mouseEvt)
    {
      _StatusBar.setText((String)(getTable().getValueAt(getTable().getSelectedRow(), getTable().getSelectedColumn())));
    }

    public void mouseExited(MouseEvent mouEvt)
    {
      //if (((String)(getTable().getValueAt(getTable().getSelectedRow(), getTable().getSelectedColumn()))).equals(""))
      //  getTable().setValueAt("0",getTable().getSelectedRow(), getTable().getSelectedColumn());
    }

    public void mouseEntered(MouseEvent mouEvt)
    {
      //if (Integer.parseInt((String)(getTable().getValueAt(getTable().getSelectedRow(), getTable().getSelectedColumn()))) == 0)
      //  getTable().setValueAt("",getTable().getSelectedRow(), getTable().getSelectedColumn());
    }

    public void mouseClicked(MouseEvent mouEvt) {
    }


//-----------------------------------------------
//    MOUSEMOTIONLISTENER

    public void mouseMoved(MouseEvent mouEvt)
    {
        String tmpStr = new String("width:"+(int)(mouEvt.getX()/_DataPane.getCellSize().getWidth()) +
        " y:"+(int)(mouEvt.getY()/_DataPane.getCellSize().getHeight()));
        if (tmpStr!=_StatusBar.getText())
            _StatusBar.setText(tmpStr);
    }

    public void mouseDragged(MouseEvent mouEvt){}

//-----------------------------------------------

    public void keyTyped(KeyEvent k){}

    public void keyReleased(KeyEvent k)
    {
        if (k.getKeyCode()==k.VK_ENTER)
        {
            //System.out.println("Table should reload now...");
            int colVaL, rowVaL;

            try{
                colVaL = Integer.parseInt(_ColumnField.getText());
                //System.out.println("colVal1 : " + colVaL);
                rowVaL = Integer.parseInt(_RowField.getText());
                //System.out.println("rowVal1 : " + rowVaL);
                rowVaL = (rowVaL<0) ? (rowVaL*-1) : rowVaL;
                //System.out.println("rowVal2 : " + rowVaL);
                colVaL = (colVaL<0) ? (colVaL*-1) : colVaL;
                //System.out.println("colVal2 : " + colVaL);
            }catch(NumberFormatException nFE){
                //System.out.println("Sorry, no correct number inserted");
                rowVaL = getTable().getRowCount();
                colVaL = getTable().getColumnCount();
            }
            if (rowVaL == 0 || colVaL ==0)
            {
                rowVaL = getTable().getRowCount();
                colVaL = getTable().getColumnCount();
            }
            else if(rowVaL!=getTable().getRowCount()||colVaL != getTable().getColumnCount()){
                TTableModel newtabmod = new TTableModel(rowVaL, colVaL);
                //System.out.println("Test..." + rowVaL+" "+colVaL);

                this.setModel(newtabmod);
                //System.out.println(getTable().getModel().getColumnCount());
            }
            _RowField.setText(Integer.toString(rowVaL));
            _ColumnField.setText(Integer.toString(colVaL));
            getDataPane().calculateNewCellSize();
        }
    }

    public void keyPressed(KeyEvent k)
    {
      //System.out.println("This seems to be a tab: "+k.getKeyChar());
    }

//-----------------------------------------------
    /** getter method for the private global variable matrixTable
     *  which represents the main table in this application
     */
    private TTable getTable()
    {
        return _MatrixTable;
    }

    private void setTable(TTable tab)
    {
        this.validate();
        this.repaint();

        _MatrixTable = tab;

        _MatrixTable.addMouseListener(this);
    }

    private TPanel getDataPane()
    {
        return _DataPane;
    }

    private void setDataPane(TPanel pane)
    {
        this.validate();
        this.repaint();

        _DataPane = pane;

        _DataPane.addMouseMotionListener(this);
    }

    private String[][] cloneArray(String[][] s)
    {
        String[][] tempNum = new String[s.length][s[0].length];

        for(int i=0; i<s.length; i++){
            for(int j=0; j<s[0].length; j++){
                tempNum[i][j]=s[i][j].toString();
            }
        }
        return tempNum;
    }

    public String[][] getStringMatrix(){
        changeAskConversion(false);
        return transposeMatrix(((TTableModel)getTable().getModel()).getContent());
    }

    public BigInteger[][] getIntegerMatrix(){
        changeAskConversion(false);
        _TypeList.setSelectedIndex(TConsts.PARSE_BIGINT);
        TTableModel tabMod = (TTableModel)getTable().getModel();

        BigInteger[][] bigIntArr = new BigInteger[tabMod.getRowCount()][tabMod.getColumnCount()];

        for(int i=0; i<tabMod.getRowCount(); i++){
            for(int j=0; j<tabMod.getColumnCount(); j++){
                bigIntArr[i][j]=new BigInteger(tabMod.getValueAt(i, j).toString());
            }
        }
/*
        BigInteger[][] bigIntArr = new BigInteger[tabMod.getColumnCount()][tabMod.getRowCount()];

        for(int i=0; i<tabMod.getColumnCount(); i++){
            for(int j=0; j<tabMod.getRowCount(); j++){
                bigIntArr[i][j]=new BigInteger(tabMod.getValueAt(j, i).toString());
            }
        }
*/
        return bigIntArr;
    }

    public BigDecimal[][] getFloatingPointMatrix(){
        changeAskConversion(false);
        _TypeList.setSelectedIndex(TConsts.PARSE_BIGDEC);
        TTableModel tabMod = (TTableModel)getTable().getModel();

        BigDecimal[][] bigDecArr = new BigDecimal[tabMod.getRowCount()][tabMod.getColumnCount()];

        for(int i=0; i<tabMod.getRowCount(); i++){
            for(int j=0; j<tabMod.getColumnCount(); j++){
              String testme = tabMod.getValueAt(i, j).toString();
              if (testme.indexOf(".") < 0)
              {
                testme += ".0";
              }
              bigDecArr[i][j]=new BigDecimal(testme);
            }
        }

        return bigDecArr;
    }

    /**
     * -1 = Cancel was pressed
     * 0 = PARSE_STRING
     * 1 = PARSE_BIGINT
     * 2 = PARSE_BIGDEC
     */
    public int getDataType(){
      if (returnNull) {
        returnNull = false; // so it will definitely be reseted when calling the same object again!
        return -1;
      }
      else
        return _TypeList.getSelectedIndex();
    }

    public void setMaxColor(Color max)
    {
        this._MaxColor=max;
        _ColorPane.setColorGradient(_MaxColor, _MinColor);
        _MaxButton.setBackground(_MaxColor);
        _DataPane.setColorRange(_MaxColor, _MinColor);
        _TableRenderer.setColorRange(_MaxColor, _MinColor);
        _ScrollPane.repaint();
    }

    public void setMinColor(Color min)
    {
        this._MinColor=min;

        _MinButton.setBackground(_MinColor);

        _ColorPane.setColorGradient(_MaxColor, _MinColor);
        _DataPane.setColorRange(_MaxColor, _MinColor);
        _TableRenderer.setColorRange(_MaxColor, _MinColor);
        _ScrollPane.repaint();
    }

    public void setViewPane(boolean tableActive)
    {
        _MainContainer.remove(_ScrollPane);

        Point middleCell;
        Point cellPos;

        if (tableActive==true)
        {
            // Show the matrix with the values
            middleCell = getDataPane().getMiddleViewCell();
            cellPos = getTable().getCellPos(middleCell);

            _ScrollPane = new JScrollPane(getTable());

            _ScrollPane.revalidate();

            _ScrollPane.setRowHeaderView(getTable().constRowHeader());

            _TypeList.setEnabled(true);
            _RowField.setEnabled(true);
            _ColumnField.setEnabled(true);
            _SwitchTableBtn.setText(_LangBundle.getString("TableToImage"));
            _FocusBox.setEnabled(false);
        }
        else
        {
            // Show the matrix as a graphic representation
            middleCell = getTable().getMiddleViewCell();
            cellPos = getDataPane().getCellPos(middleCell);

            _ScrollPane = new JScrollPane(getDataPane());

            _ScrollPane.revalidate();

            _TypeList.setEnabled(false);
            _RowField.setEnabled(false);
            _ColumnField.setEnabled(false);
            _SwitchTableBtn.setText(_LangBundle.getString("ImageToTable"));
            _FocusBox.setEnabled(true);
        }

        _MainContainer.add(_ScrollPane, BorderLayout.CENTER);

        //System.out.println("Middle Position " + cellPos);

        _MainContainer.validate();

        //System.out.println("ScrollPaneSize: "+_ScrollPane.getWidth());

        int scrollPosX, scrollPosY;
        scrollPosX = (int)(cellPos.getX()-(_ScrollPane.getWidth()/2));
        scrollPosY = (int)(cellPos.getY()-(_ScrollPane.getHeight()/2));

        if (scrollPosX<0) {
            scrollPosX = 0;
        }
        if (scrollPosY<0) {
            scrollPosY = 0;
        }

        //System.out.println("Pane should scroll to: " + scrollPosX + ", "+scrollPosY);

        //System.out.println("New calc Dim:"+getDataPane().calculateNewCellSize());

        _ScrollPane.getViewport().setViewPosition(new Point(scrollPosX, scrollPosY));

        _ScrollPane.validate();

        //System.out.println("ScrollPaneSize: "+_ScrollPane.getSize());
    }


    public String[][] transposeMatrix(String[][] content)
    {
        String[][] transposedMat = new String[content[0].length][content.length];
        for(int x = 0; x < content[0].length; x++)
        {
            for(int y=0; y < content.length; y++)
            {
                transposedMat[x][y] = content[y][x];
            }
        }
        return transposedMat;
    }

    public void setModel(TTableModel newtabmod)
    {
        _RowField.setText(Integer.toString(newtabmod.getRowCount()));
        _ColumnField.setText(Integer.toString(newtabmod.getColumnCount()));
        newtabmod.insertTableModel(((TTableModel)getTable().getModel()));
        newtabmod.calcMinAndMax();
        _TableRenderer.setModel(newtabmod);
        getTable().setModel(newtabmod);
        _ScrollPane.setRowHeaderView(getTable().constRowHeader());
        getDataPane().setModel(newtabmod);
    }
}