/**************************************************************
 * 
 * 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;
    }
    
}
