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

import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.net.URL;
import java.net.JarURLConnection;
import javax.swing.*;

/**
 *
 *
 *  @author  Aidan Butler
 */
public class XmlUpdater extends Thread {
    
    private String classesPath = null;
    private String jarfilename;
    private String installPath;
    private boolean netInstall;
    private boolean bindingsInstall;
    
    private JLabel statusLabel;
    	
    private Vector listeners;
    private Thread internalThread;
    private boolean threadSuspended;
    private JProgressBar progressBar;
    
    private final String[] bakFiles =
    {
        "writermenubar.xml",		
        "writerkeybinding.xml",
        "calcmenubar.xml",
        "calckeybinding.xml",
        "impressmenubar.xml",
        "impresskeybinding.xml",
        "drawmenubar.xml",
        "drawkeybinding.xml",
        "eventbindings.xml",
        "META-INF" + File.separator + "manifest.xml"
    };

    private final String[] dirs = 
    {
        "java" + File.separator + "Highlight",
        "java" + File.separator + "MemoryUsage",
        "java" + File.separator + "ScriptFrmwrkHelper",
        "java" + File.separator + "debugger",
        "java" + File.separator + "debugger" + File.separator + "rhino",
        "beanshell" + File.separator + "InteractiveBeanShell",
        "beanshell" + File.separator + "Highlight",
        "beanshell" + File.separator + "MemoryUsage",
        "javascript" + File.separator + "ExportSheetsToHTML"
    };

    private final String[] names = 
    {
        "java/Highlight/HighlightUtil.java",
        "java/Highlight/HighlightText.java",
        "java/Highlight/Highlight.jar",
        "java/Highlight/parcel-descriptor.xml",
        "java/MemoryUsage/MemoryUsage.java",
        "java/MemoryUsage/MemoryUsage.class",
        "java/MemoryUsage/parcel-descriptor.xml",
        "java/MemoryUsage/ExampleSpreadSheet.sxc",
        "java/ScriptFrmwrkHelper/parcel-descriptor.xml",
        "java/ScriptFrmwrkHelper/ScriptFrmwrkHelper.java",
        "java/ScriptFrmwrkHelper/ScriptFrmwrkHelper.class",
        "java/ScriptFrmwrkHelper/ScriptFrmwrkHelper.jar",
        "java/debugger/debugger.jar",
        "java/debugger/OOBeanShellDebugger.java",
        "java/debugger/OOScriptDebugger.java",
        "java/debugger/DebugRunner.java",
        "java/debugger/OORhinoDebugger.java",
        "java/debugger/parcel-descriptor.xml",
        "java/debugger/rhino/Main.java",
        "beanshell/InteractiveBeanShell/parcel-descriptor.xml",
        "beanshell/InteractiveBeanShell/interactive.bsh",
        "beanshell/Highlight/parcel-descriptor.xml",
        "beanshell/Highlight/highlighter.bsh",
        "beanshell/MemoryUsage/parcel-descriptor.xml",
        "beanshell/MemoryUsage/memusage.bsh",
        "javascript/ExportSheetsToHTML/parcel-descriptor.xml",
        "javascript/ExportSheetsToHTML/exportsheetstohtml.js"
    };

    
    public XmlUpdater(String installPath, JLabel statusLabel,JProgressBar pBar, boolean netInstall, boolean bindingsInstall) {
        this.installPath = installPath;
        this.statusLabel = statusLabel;
        this.netInstall = netInstall;
        this.bindingsInstall = bindingsInstall;
        listeners = new Vector();
        threadSuspended = false;
        progressBar=pBar;
        progressBar.setStringPainted(true);
    }// XmlUpdater


	public boolean checkStop()
	{
        if (internalThread == Thread.currentThread())
            return false;
        return true;
	}// checkStop


	public void checkSuspend()
	{
        if (threadSuspended) {
            synchronized(this) {
                while (threadSuspended) {
                    try	{
                        wait();
                    } catch (InterruptedException eInt) {
                        //...
                    }
                }
            }
        }
	}// checkSuspend
    

	public void setSuspend()
	{
        threadSuspended = true;
	}// setSuspend


	public void setResume()
	{
        threadSuspended = false;
        notify();
	}// setResume
	

	public void setStop()
	{
        internalThread = null;
	}// setStop
	

    public void run() {

        InputStream            istream;
        //InputSource            isource;
        //DocumentBuilderFactory builderFactory;
        //DocumentBuilder        builder = null;
        URL                    url;
        String                 fileName = null;

        internalThread = Thread.currentThread();
		
        //System.out.println("\n\n\n\nFileName: "+installPath);
        classesPath= installPath.concat(File.separator+"program"+File.separator+"classes"+File.separator);
        String opSys =System.getProperty("os.name");
        //System.out.println("\n System "+opSys);

        String progpath=installPath;
        progpath= progpath.concat(File.separator+"program"+File.separator);
        //System.out.println("Office progpath" + progpath );
        //System.out.println("\nModifying Installation "+installPath);	
        
        String starBasicPath=installPath;
        starBasicPath= starBasicPath.concat(File.separator+"share"+File.separator+"basic"+File.separator+"ScriptBindingLibrary"+File.separator);
        //System.out.println( "Office StarBasic path: " + starBasicPath );  
        
        String regSchemaOfficePath=installPath;
        regSchemaOfficePath= regSchemaOfficePath.concat(File.separator+"share"+File.separator+"registry"+File.separator+"schema"+File.separator+"org"+File.separator+"openoffice"+File.separator+"Office"+File.separator);
        //System.out.println( "Office schema path: " + regSchemaOfficePath );  

        // Get the NetBeans installation
        //String netbeansPath=
        
        progressBar.setString("Unzipping Required Files");
        ZipData zd = new ZipData("SFrameworkInstall.jar");
        
        
        if( (!netInstall) || bindingsInstall) {
            String configPath=installPath;
            configPath= configPath.concat(File.separator+"user"+File.separator+"config"+File.separator+"soffice.cfg"+File.separator);
            //System.out.println( "Office configuration path: " + configPath );
            String manifestPath=configPath + "META-INF" + File.separator;
            
            //Adding <Office>/user/config/soffice.cfg/
            File configDir = new File( configPath );
            if( !configDir.isDirectory() ) {
                if( !configDir.mkdir() ) {
                    System.out.println( "creating  " + configDir + "directory failed");
                }
                else {
                    System.out.println( configDir + "directory created");
                }
            } 
            else
                System.out.println( "soffice.cfg exists" );

            File manifestDir = new File( manifestPath );
            if( !manifestDir.isDirectory() ) {
                if( !manifestDir.mkdir() ) {
                    System.out.println( "creating " + manifestPath + "directory failed");
                }
                else {
                    System.out.println( manifestPath + " directory created");
                }
            } 
            else
                System.out.println( manifestPath + " exists" );

            // Backup the confguration files in 
            // <office>/user/config/soffice.cfg/
            // If they already exist.

            for( int i=0; i < bakFiles.length; i++ )
            {
                String pathNameBak = configPath + bakFiles[i];
                File origFile = new File( pathNameBak );
                if( origFile.exists() )
                {
                    System.out.println( "Attempting to backup " + pathNameBak + " to " + pathNameBak + ".bak" );
                    if(! origFile.renameTo( new File( pathNameBak + ".bak" ) ) )
                    {
                        System.out.println( "Failed to backup " + pathNameBak + " to " + pathNameBak + ".bak" );
                    }
                }
            }

            // Adding Office configuration files
            if (!zd.extractEntry("bindingdialog/writermenubar.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
            if (!zd.extractEntry("bindingdialog/writerkeybinding.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }    
            if (!zd.extractEntry("bindingdialog/calcmenubar.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }   
            if (!zd.extractEntry("bindingdialog/calckeybinding.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
            if (!zd.extractEntry("bindingdialog/impressmenubar.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }   
            if (!zd.extractEntry("bindingdialog/impresskeybinding.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
            if (!zd.extractEntry("bindingdialog/drawmenubar.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }   
            if (!zd.extractEntry("bindingdialog/drawkeybinding.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
            if (!zd.extractEntry("bindingdialog/eventbindings.xml",configPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
            if (!zd.extractEntry("bindingdialog/manifest.xml",manifestPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
        }

        if(!bindingsInstall) {
            // Adding new directories to Office
            // Adding <Office>/user/basic/ScriptBindingLibrary/
            File scriptBindingLib = new File( starBasicPath );
            if( !scriptBindingLib.isDirectory() ) {
                if( !scriptBindingLib.mkdir() ) {
                    System.out.println( "ScriptBindingLibrary failed");
                }
                else {
                    System.out.println( "ScriptBindingLibrary directory created");
                }
            }
            else
                System.out.println( "ScriptBindingLibrary exists" );

            // Adding Scripting Framework and tools
            if (!zd.extractEntry("sframework/ooscriptframe.zip",progpath, statusLabel))
            {
                onInstallComplete();
                return;
            }
        
            if (!zd.extractEntry("sframework/bshruntime.zip",progpath, statusLabel))
            {
                onInstallComplete();
                return;
            }
        
            if (!zd.extractEntry("sframework/jsruntime.zip",progpath, statusLabel))
            {
                onInstallComplete();
                return;
            }
        
            if (!zd.extractEntry("schema/Scripting.xcs",regSchemaOfficePath, statusLabel))
            {
                onInstallComplete();
                return;
            }
        
    //--------------------------------	

            progressBar.setString("Registering Scripting Framework");
            progressBar.setValue(3);
            if(!Register.register(installPath+File.separator, statusLabel) ) {
               onInstallComplete();
               return;
            }
            progressBar.setValue(5);
        
            String path = installPath + File.separator +
                "share" + File.separator + "Scripts" + File.separator;

            for (int i = 0; i < dirs.length; i++) {
                File dir = new File(path + dirs[i]);

                if (!dir.exists()) {
                    if (!dir.mkdirs()) {
                        System.err.println("Error making dir: " +
                            dir.getAbsolutePath());
                        onInstallComplete();
                        return;
                    }
                }
            }

            for (int i = 0; i < names.length; i++) {
                String source = "/examples/" + names[i];
                String dest = path + names[i].replace('/', File.separatorChar);

                if (!zd.extractEntry(source, dest, statusLabel)) {
                    onInstallComplete();
                    return;
                }
            }

        
            // Adding binding dialog
            if (!zd.extractEntry("bindingdialog/ScriptBinding.xba",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            }         
            if (!zd.extractEntry("bindingdialog/MenuBinding.xdl",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
            if (!zd.extractEntry("bindingdialog/KeyBinding.xdl",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            }        
            if (!zd.extractEntry("bindingdialog/EventsBinding.xdl",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            }        
            if (!zd.extractEntry("bindingdialog/HelpBinding.xdl",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            } 
            if (!zd.extractEntry("bindingdialog/EditDebug.xdl",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            } 
            if (!zd.extractEntry("bindingdialog/dialog.xlb",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            }
            if (!zd.extractEntry("bindingdialog/script.xlb",starBasicPath, statusLabel))
            {
                onInstallComplete();
                return;
            }   
        }	
	
	
        statusLabel.setText("Installation Complete");
        progressBar.setString("Installation Complete");
        progressBar.setValue(10);
        onInstallComplete();

    }// run
    

    public void addInstallListener(InstallListener listener)
    {
        listeners.addElement(listener);
    }// addInstallListener


    private void onInstallComplete()
    {
        Enumeration e = listeners.elements();
        while (e.hasMoreElements())
        {
            InstallListener listener = (InstallListener)e.nextElement();
            listener.installationComplete(null);
        }
    }// onInstallComplete
 
}// XmlUpdater class
