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

/*
 * InstallWizard.java
 *
 * Created on 04 July 2002, 15:09
 */

/**
 *
 * @author  mike
 */

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;

public class InstallWizard extends javax.swing.JFrame implements ActionListener {
/*
    private static class ShutdownHook extends Thread {
        public void run()
	{
            if (InstallWizard.isInstallStarted())
            {
                // Check for and backup any config.xml files
                // Check for and backup any StarBasic macro files
                // Check for and backup ProtocolHandler

                if (!InstallWizard.isPatchedTypes())
		{
                    File backup = new File(InstUtil.getTmpDir(), "TypeDetection.xml");
                    File destination = new File(InstallWizard.getTypesPath());
                    InstUtil.copy(backup, destination); //Restore typedetection.xml
		}
		if (!InstallWizard.isPatchedJava())
		{
                    File backup = new File(InstUtil.getTmpDir(), "Java.xml");
                    File destination = new File(InstallWizard.getJavaPath());
                    InstUtil.copy(backup, destination); //Restore typedetection.xml
		}
		if (!InstallWizard.isPatchedRDB())
		{
                    File backup = new File(InstUtil.getTmpDir(), "applicat.rdb");
                    File destination = new File(InstallWizard.getJavaPath());
                    //InstUtil.copy(backup, destination); //Restore typedetection.xml
		}

                System.out.println( "ShutdownHook" );
            }

            InstUtil.removeTmpDir();
	}
    }// class ShutdownHook

    static {
    	Runtime rt=Runtime.getRuntime();
    	rt.addShutdownHook(new ShutdownHook());
    }
*/
    /** Creates new form InstallWizard */
    public InstallWizard() {
        super("Office Scripting Framework Installer - Early Developer Release");

 	try {
 		System.out.print("All diagnostic output is being redirected to SFrameworkInstall.log\n");
 		System.out.print("Location: "+  System.getProperty( "user.dir" ) +
 			File.separator + "SFrameworkInstall.log\n");

 		LogStream log = new LogStream( "SFrameworkInstall.log" );
                 System.setErr(log);

                 System.setOut(log);
 	}
 	catch( FileNotFoundException fnfe ) {
 		System.err.println("Office Scripting Framework Installer - Error: ");
 		System.err.println("Unable to create log file for installation.");
 		exitForm(null);
 	}

	//setBackground(Color.WHITE);
	setBackground(new Color(0,0,0));
	locations = new ArrayList();
	//Point center = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
	Point center = new Point( 400, 400 );
	int windowWidth=200;
	int windowHeight=300;
	setSize(windowWidth,windowHeight);
	setBounds((center.x-windowWidth/2)-115,(center.y-windowWidth/2)-100, windowWidth,windowHeight);
	initComponents();
	setResizable(false);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     */
    private void initComponents() {
        navigation = new javax.swing.JPanel();
        navBack = new javax.swing.JButton();
        navNext = new javax.swing.JButton();
        navCancel = new javax.swing.JButton();
        screens = new javax.swing.JPanel();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        navigation.setLayout(new java.awt.GridBagLayout());
        java.awt.GridBagConstraints gridBagConstraints1;

        navBack.setText("<< Back");
        gridBagConstraints1 = new java.awt.GridBagConstraints();
        gridBagConstraints1.insets = new java.awt.Insets(1, 1, 1, 1);

        navNext.setText("Next >>");
        gridBagConstraints1 = new java.awt.GridBagConstraints();
        gridBagConstraints1.gridx = 2;
        gridBagConstraints1.gridy = 0;

        navCancel.setText("Cancel");
        gridBagConstraints1 = new java.awt.GridBagConstraints();
        gridBagConstraints1.gridx = 6;
        gridBagConstraints1.gridy = 0;
        //navigation.add(navNext, gridBagConstraints1);
        //navigation.add(navBack, gridBagConstraints1);
        //navigation.add(navCancel, gridBagConstraints1);

        getContentPane().add(navigation, java.awt.BorderLayout.SOUTH);
        screens.setLayout(new java.awt.CardLayout());
        screens.add(WELCOME, new Welcome(this));
        version = new Version(this);
        screens.add(VERSIONS, version);
	_final = new Final(this);
        screens.add(FINAL, _final);

	//boolean hasIDEInstallation = (InstUtil.hasNetbeansInstallation() || InstUtil.hasJeditInstallation()) ;
	boolean hasIDEInstallation = ( InstUtil.hasNetbeansInstallation() ) ;

	if( hasIDEInstallation )
	{
		idewelcome = new IdeWelcome(this);
		screens.add(IDEWELCOME, idewelcome);
		ideversion = new IdeVersion(this);
		screens.add(IDEVERSIONS, ideversion);
		idefinal = new IdeFinal(this);
		screens.add(IDEFINAL, idefinal);
	}
        getContentPane().add(screens, java.awt.BorderLayout.CENTER);

	navNext.addActionListener(this);
	navNext.addActionListener(version);
	navNext.addActionListener(_final);

	if( hasIDEInstallation )
	{
		navNext.addActionListener(ideversion);
		navNext.addActionListener(idefinal);
	}

	navCancel.addActionListener(this);
	navBack.addActionListener(this);


	URL url = this.getClass().getResource("sidebar.jpg");
	JLabel sideBar = new JLabel();
	sideBar.setIcon(new ImageIcon(url));
	getContentPane().add (sideBar, java.awt.BorderLayout.WEST);
        pack();
    }// initComponents

    /** Exit the Application */
    public void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }


    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == navNext)
	{
            ((CardLayout)screens.getLayout()).next(screens);
	}

	if (e.getSource() == navCancel)
	{
            exitForm(null);
	}

	if (e.getSource() == navBack)
	{
            ((CardLayout)screens.getLayout()).previous(screens);
	}
    }// actionPerformed

	public static void storeLocation(String path)
	{
		locations.add(path);
	}

	public static ArrayList getLocations()
	{
		return locations;
	}

	public static void clearLocations()
	{
		locations.clear();
	}

	public void show(String cardName)
	{
		((CardLayout)screens.getLayout()).show(screens, cardName);
	}

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        String officePath = null;
        String netbeansPath = null;
        //String jeditPath = null;
        int i = 0;

        while (i < args.length) {
            if (args[i].equals("-help")) {
                printUsage();
                System.exit(0);
            }
            if (args[i].equals("-office"))
                officePath = args[++i];
            if (args[i].equals("-netbeans"))
                netbeansPath = args[++i];
            if (args[i].equals("-net"))
                bNetworkInstall = true;
            if (args[i].equals("-bindings"))
                bBindingsInstall = true;
            //if (args[i].equals("-jedit"))
            //    jeditPath = args[++i];
            i++;
        }

        //if (officePath == null && netbeansPath == null && jeditPath == null)
        if (officePath == null && netbeansPath == null)
            new InstallWizard().show();

        JLabel label = new JLabel();
        JProgressBar progressbar = new JProgressBar();

        try {
            System.out.println("Log file is: " +
                System.getProperty("user.dir") +
                File.separator + "SFrameworkInstall.log");

            LogStream log = new LogStream( "SFrameworkInstall.log" );
            System.setErr(log);
            System.setOut(log);
        }
        catch( FileNotFoundException fnfe ) {
            System.err.println("Error: Unable to create log file: "
                + fnfe.getMessage());
            System.exit(-1);
        }

        if (officePath != null) {
            XmlUpdater xud = new XmlUpdater(officePath, label, progressbar, bNetworkInstall, bBindingsInstall );
            xud.run();
        }

        if (netbeansPath != null) {
            IdeUpdater ideup = new IdeUpdater(netbeansPath, label, progressbar);
            ideup.run();
        }

        //if (jeditPath != null) {
        //    IdeUpdater ideup = new IdeUpdater(jeditPath, label, progressbar);
        //    ideup.run();
        //}
    }

    private static void printUsage() {
        System.err.println("java -jar SFrameworkInstall.jar");
        System.err.println("\t[-office <path_to_office_installation]");
        System.err.println("\t[-netbeans <path_to_netbeans_installation]");
        System.err.println("\t[-net]");
        System.err.println("\t[-bindings]");
        System.err.println("\n\n-net indicates that this is the network part of a network install.");
        System.err.println("-bindings will only install the menu & key bindings in user/config/soffice.cfg.");
        //System.err.println("\t[-jedit <path_to_jedit_installation]");
    }

	public static synchronized boolean isPatchedTypes()
	{
		return bPatchedTypes;
	}

	public static synchronized boolean isPatchedJava()
	{
		return bPatchedJava;
	}

	public static synchronized boolean isPatchedRDB()
	{
		return bPatchedRDB;
	}

	public static synchronized boolean isInstallStarted()
	{
		return bInstallStarted;
	}

	public static synchronized void setPatchedTypes(boolean value)
	{
		bPatchedTypes = value;
	}

	public static synchronized void setPatchedJava(boolean value)
	{
		bPatchedJava = value;
	}

	public static synchronized void setPatchedRDB(boolean value)
	{
		bPatchedRDB = value;
	}

	public static synchronized void setInstallStarted(boolean value)
	{
		bInstallStarted = value;
	}

	public static synchronized void setTypesPath(String path)
	{
		typesPath = path;
	}

	public static synchronized void setJavaPath(String path)
	{
		javaPath = path;
	}

	public static synchronized String getTypesPath()
	{
		return typesPath;
	}

	public static synchronized String getJavaPath()
	{
		return javaPath;
	}

    private javax.swing.JPanel  navigation;
    private javax.swing.JButton navBack;
    private javax.swing.JButton navNext;
    private javax.swing.JButton navCancel;
    private javax.swing.JPanel  screens;

    private Version version = null;
    private Final _final  = null;
    private IdeVersion ideversion = null;
    private IdeFinal idefinal = null;
    private IdeWelcome idewelcome = null;
    private static ArrayList locations = null;

    public static String VERSIONS = "VERSIONS";
    public static String WELCOME  = "WELCOME";
    public static String FINAL    = "FINAL";
    public static String IDEVERSIONS = "IDEVERSIONS";
    public static String IDEWELCOME  = "IDEWELCOME";
    public static String IDEFINAL    = "IDEFINAL";

    public static int DEFWIDTH     = 480;
    public static int DEFHEIGHT    = 240;

    private static String typesPath = null;
    private static String javaPath  = null;

    public static boolean bNetworkInstall   = false;
    public static boolean bBindingsInstall   = false;

    private static boolean bPatchedTypes     = false;
    private static boolean bPatchedJava      = false;
    private static boolean bPatchedRDB       = false;
    private static boolean bInstallStarted   = false;

}// InstallWizard
