/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

package installer;

/*
 * Welcome.java
 *
 * Created on 04 July 2002, 15:43
 */

/**
 *
 * @author  mike
 */

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.SwingUtilities.*;

public class IdeVersion extends javax.swing.JPanel implements ActionListener, TableModelListener {

    /** Creates new form Welcome */
    public IdeVersion(InstallWizard wizard) {
        this.wizard=wizard;
	setBackground(Color.white);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        Properties props = null;
        JPanel versionPanel = new JPanel();
        setLayout(new BorderLayout());


	try {
        	//props = InstUtil.getNetbeansLocation();

		Properties netbeansProps = InstUtil.getNetbeansLocation();
		//Properties jeditProps = InstUtil.getJeditLocation();
		Properties ideProps = new Properties();
		if(netbeansProps!=null )
		{
                System.out.println("**** Found netbeans install");
		for( int n = 0; n < netbeansProps.size(); n++ ) {
			for( int v = 0; v < InstUtil.versions.length; v++ ) {
				System.out.println("n: " +n+" v: " +v);
				String key = InstUtil.versions[v];
				System.out.println("It got here1");
				String path = null;
				if ( (path = netbeansProps.getProperty(key) ) != null ) {
					//System.out.println( "n="+n+" v="+v + " Netbeans " + " key=" + key + " path=" + path );
					ideProps.put(key, path);
				}
			}
		}
		}
                //System.out.println("*** About to look for jedit install");
		/*
		if(jeditProps!=null)
		{
			for( int j = 0; j < jeditProps.size(); j++ ) {
				for( int v = 0; v < InstUtil.versions.length; v++ ) {
				System.out.println("j: " +j+" v: " +v);
					String key = InstUtil.versions[v];
					String path = null;
					if ((path = jeditProps.getProperty(key)) != null) {
						//System.out.println( "j="+j+" v="+v + " jEdit " + " key=" + key + " path=" + path );
						ideProps.put(key, path);
					}
				}
			}
		}
		*/
		props = ideProps;
	}
        catch (IOException eIO) {
            System.err.println("Failed to parse .netbeans/ide.log");
	    //JOptionPane.showMessageDialog(this, "There was a problem reading from the NetBeans ide.log file.", "Parse Error", JOptionPane.ERROR_MESSAGE);
        }
        catch (Exception e) {
            System.err.println("Exception thrown in initComponents");
        }

	tableModel = new MyTableModelIDE (props, InstUtil.versions);

	if (tableModel.getRowCount() == 0)
	{
            JOptionPane.showMessageDialog(this, "No compatible IDEs were found.", "Invalid versions", JOptionPane.ERROR_MESSAGE);
            //wizard.exitForm(null);
	}

        tableModel.addTableModelListener(this);
        JTable tableVersions = new JTable(tableModel) {
            public String getToolTipText(MouseEvent event)
            {
                int col = columnAtPoint( event.getPoint() );
                if (col != 2)
                    return null;

                int row = rowAtPoint( event.getPoint() );
                Object o = getValueAt(row, col);

                if (o == null)
                    return null;

                if (o.toString().equals(""))
                    return null;

                return o.toString();
            }

            public Point getToolTipLocation(MouseEvent event)
            {
                int col = columnAtPoint( event.getPoint() );
                if (col != 2)
                    return null;

                int row = rowAtPoint( event.getPoint() );
                Object o = getValueAt(row,col);

                if (o == null)
                    return null;

                if (o.toString().equals(""))
                    return null;

                Point pt = getCellRect(row, col, true).getLocation();
                pt.translate(-1,-2);
                return pt;
            }
        };

        JScrollPane scroll = new JScrollPane(tableVersions);

        tableVersions.setPreferredSize(
            new Dimension(InstallWizard.DEFWIDTH,InstallWizard.DEFHEIGHT));

        tableVersions.setRowSelectionAllowed(false);
        tableVersions.setColumnSelectionAllowed(false);
        tableVersions.setCellSelectionEnabled(false);

        initColumnSizes(tableVersions, tableModel);
        versionPanel.add(scroll);

        JTextArea area = new JTextArea("Please select IDEs below that you wish to add Scripting support to");
        area.setLineWrap(true);
        area.setEditable(false);
        add(area, BorderLayout.NORTH);
        add(versionPanel, BorderLayout.CENTER);
        nav = new NavPanel(wizard, true, false, true, InstallWizard.IDEWELCOME, InstallWizard.IDEFINAL);
        nav.setNextListener(this);
        add(nav, BorderLayout.SOUTH);

    }// initComponents


    public java.awt.Dimension getPreferredSize() {
        return new java.awt.Dimension(320, 280);
    }


    public void actionPerformed(ActionEvent ev) {
        wizard.clearLocations();
        int len = tableModel.data.size();
        for (int i = 0; i < len; i++) {
            ArrayList list = (ArrayList)tableModel.data.get(i);
            if (((Boolean)list.get(0)).booleanValue() == true)
                wizard.storeLocation((String)list.get(2));
        }

        //System.out.println(wizard.getLocations());
    }


    public void tableChanged(TableModelEvent e) {
        if (tableModel.isAnySelected()) {
            nav.enableNext(true);
        }
        else {
            nav.enableNext(false);
        }
    }

    private void initColumnSizes(JTable table, MyTableModelIDE model) {
        TableColumn column = null;
        Component comp = null;
        int headerWidth = 0;
        int cellWidth = 0;
        int preferredWidth = 0;
        int totalWidth = 0;
        Object[] longValues = model.longValues;

        for (int i = 0; i < 3; i++) {
            column = table.getColumnModel().getColumn(i);

            try {
                comp = column.getHeaderRenderer().
                             getTableCellRendererComponent(
                                 null, column.getHeaderValue(),
                                 false, false, 0, 0);
                headerWidth = comp.getPreferredSize().width;
            } catch (NullPointerException e) {
                // System.err.println("Null pointer exception!");
                // System.err.println("  getHeaderRenderer returns null in 1.3.");
                // System.err.println("  The replacement is getDefaultRenderer.");
            }

            // need to replace spaces in String before getting preferred width
            if (longValues[i] instanceof String) {
                longValues[i] = ((String)longValues[i]).replace(' ', '_');
            }

            System.out.println("longValues: " + longValues[i]);
            comp = table.getDefaultRenderer(model.getColumnClass(i)).
                         getTableCellRendererComponent(
                             table, longValues[i],
                             false, false, 0, i);
            cellWidth = comp.getPreferredSize().width;

            preferredWidth = Math.max(headerWidth, cellWidth);

            if (false) {
                System.out.println("Initializing width of column "
                    + i + ". "
                    + "preferredWidth = " + preferredWidth
                    + "; totalWidth = " + totalWidth
                    + "; leftWidth = " + (InstallWizard.DEFWIDTH - totalWidth));
            }

            //XXX: Before Swing 1.1 Beta 2, use setMinWidth instead.
            if (i == 2) {
                if (preferredWidth > InstallWizard.DEFWIDTH - totalWidth)
                    column.setPreferredWidth(InstallWizard.DEFWIDTH - totalWidth);
                else
                    column.setPreferredWidth(preferredWidth);
            }
            else {
                column.setMinWidth(preferredWidth);
                totalWidth += preferredWidth;
            }
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField jTextField2;
	private InstallWizard wizard;
	private MyTableModelIDE  tableModel;
	private NavPanel nav;
    // End of variables declaration//GEN-END:variables

  }

class MyTableModelIDE extends AbstractTableModel {
    ArrayList data;
    String colNames[] = {"", "IDE Name", "IDE Location"};
    Object[] longValues = new Object[] {Boolean.TRUE, "Name", "Location"};

    MyTableModelIDE (Properties properties, String [] validVersions) {
        data = new ArrayList();
        //System.out.println(properties);

        int len = validVersions.length;
        for (int i = 0; i < len; i++) {
            String key = validVersions[i];
            String path = null;

            if ((path = properties.getProperty(key)) != null) {
                ArrayList row = new ArrayList();
                row.add(0, new Boolean(false));

                row.add(1, key);
                if (key.length() > ((String)longValues[1]).length()) {
                    longValues[1] = key;
                }

                row.add(2, path);
                if (path.length() > ((String)longValues[2]).length()) {
                    longValues[2] = path;
                }

                data.add(row);
            }
        }
    }// MyTableModel

    public int getColumnCount() {
        return 3;
    }

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

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

    public Object getValueAt(int row, int col) {
        if (row < 0 || row > getRowCount() ||
            col < 0 || col > getColumnCount())
            return null;

        ArrayList aRow = (ArrayList)data.get(row);
        return aRow.get(col);
    }

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

	    public boolean isCellEditable(int row, int col) {
		if (col == 0) {
		    return true;
		} else {
		    return false;
		}
	    }

	    public void setValueAt(Object value, int row, int col) {
		ArrayList aRow = (ArrayList)data.get(row);
		aRow.set(col, value);
		fireTableCellUpdated(row, col);
	    }

	    String [] getSelected() {
		return null;
	    }

	    public boolean isAnySelected() {
		Iterator iter = data.iterator();
		while (iter.hasNext()) {
		    ArrayList row = (ArrayList)iter.next();
		    if (((Boolean)row.get(0)).booleanValue() == true) {
			return true;
		    }
		}
		return false;
	    }

}
