/**************************************************************
 *
 * 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 Version extends javax.swing.JPanel implements ActionListener, TableModelListener {

    /** Creates new form Welcome */
    public Version(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());

        System.out.println("Initialising versions");

        File fileVersions = null;
	try
	{
            fileVersions = InstUtil.buildSversionLocation();
	}
	catch(IOException eFnF)
	{
            System.err.println("Cannot find sversion.ini/.sversionrc");
            JOptionPane.showMessageDialog(this, eFnF.getMessage(), "File not Found", JOptionPane.ERROR_MESSAGE);
            wizard.exitForm(null);
	}

        try {
            props = InstUtil.getOfficeVersions(fileVersions);
        }
        catch (IOException eIO) {
            //Message about no installed versions found
            System.err.println("Failed to parse SVERSION");
			JOptionPane.showMessageDialog(this, "There was a problem reading from the Office settings file.", "Parse Error", JOptionPane.ERROR_MESSAGE);
			wizard.exitForm(null);
        }

        tableModel = new MyTableModel(props, versions);
	if (tableModel.getRowCount() == 0)
	{
            JOptionPane.showMessageDialog(this, "No compatible versions of Office 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 the Office version you wish to Update");
        area.setLineWrap(true);
        area.setEditable(false);
        add(area, BorderLayout.NORTH);
        add(versionPanel, BorderLayout.CENTER);
        //nav = new NavPanel(wizard, true, false, true, InstallWizard.WELCOME, InstallWizard.FINAL);
	nav = new NavPanel(wizard, true, false, true, InstallWizard.WELCOME, InstallWizard.FINAL);
        nav.setNextListener(this);
        add(nav, BorderLayout.SOUTH);

    }// initComponents

    private void initColumnSizes(JTable table, MyTableModel 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;
            }
        }
    }

    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);
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField jTextField2;
	private InstallWizard wizard;
	private MyTableModel tableModel;
	private NavPanel nav;
	//private static final String [] versions = {"StarOffice 6.0", "OpenOffice.org 1.0","OpenOffice.org 1.0.1","OpenOffice.org 642","OpenOffice.org 643","StarOffice 6.1"};
	//private static final String [] versions = {"OpenOffice.org 643"};
	//private static final String [] versions = {"OpenOffice.org 643", "StarOffice 6.1"};
	private static final String [] versions = {"StarOffice 6.1", "OpenOffice.org 1.1Beta", "OpenOffice.org 644", "OpenOffice.org 1.1"};
    // End of variables declaration//GEN-END:variables

}

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

    MyTableModel (Properties properties, String [] validVersions) {
        data = new ArrayList();
        boolean isWindows =
            (System.getProperty("os.name").indexOf("Windows") != -1);
        int len = validVersions.length;
        for (Enumeration e = properties.propertyNames(); e.hasMoreElements() ;) {
            String key = (String)e.nextElement();
            String path = null;

            if ( !( key.startsWith("#") ) &&
                  ( path = properties.getProperty(key)) != null) {
                String pkgChkPath = path + File.separator + "program" + File.separator;
                if ( isWindows )
                {
                    pkgChkPath += "pkgchk.exe";
                }
                else
                {
                    pkgChkPath += "pkgchk";
                }
                File pkgChk = new File( pkgChkPath );
                if ( pkgChk.exists() )
                {
                    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;
    }

}
