import com.denova.runtime.Exec;
import com.denova.runtime.WindowsConstants;
import com.denova.runtime.WindowsDirs;
import com.denova.runtime.WindowsServices;
import com.denova.runtime.WindowsUtils;
import com.denova.ui.Fonts;
import com.denova.ui.Swinger;
import com.denova.util.PropertyList;
import com.denova.JExpress.Installer.CustomInstaller;
import com.denova.JExpress.Installer.CustomUninstaller;
import com.denova.JExpress.Installer.InstallPropertyNames;
import com.denova.JExpress.Installer.StatusPanel;
import java.io.File;
import java.util.Iterator;


/**
    Configure all menus flagged as "auto startup" to install as a service.

    Note: 
     1. This class is no longer needed as you can simply use the Advanced interface
        for JExpress and check which launchers that you want installed as a service.
     2. You should include this class "After uninstaller created" on the Custom panel.
     3. You're welcome to adapt this class to use with a JExpress Installer or Updater.
     
    Copyright (C) 1998-2012 DeNova
    Last modified: 2012-06-15
*/
public class WinInstallService
    extends StatusPanel
    implements InstallPropertyNames
{
    private String progressLabel = CustomInstaller.getLocalizedString("Configuring") + " services";

    private class ServiceSwinger extends Swinger
    {
        public void swingBefore()
        {
            updateProgressBarLabel(progressLabel);
        }
        
        public void workInBackground()
        {
            // clear any errors
            WindowsUtils. clearError ();
    
            String installDir = getPropertyList().getProperty(ApplicationDirectory, "");
            PropertyList menus = getPropertyList().getPropertyListProperty(
                MenusAttributeName);
            Iterator menusEnum = menus.propertyNamesList().iterator();
            while (menusEnum.hasNext())
            {
                String menuName = (String)menusEnum.next();
                String propsString = menus.getProperty(menuName);
    
                if (propsString != null)
                {
                    PropertyList props = new PropertyList();
                    props.fromString(propsString);
    
                    String longName = props.getProperty(MenuLongName, "").trim();
                    boolean addStartupMenu = props.getBooleanProperty(MenuAutoStartup, false);
                    if (longName.length() > 0 && addStartupMenu)
                    {
                        CustomInstaller.logToInstaller("adding service for " + longName);
                        String executable = getExecutable(longName, props, installDir);
                        
                        if (addService(longName, executable, installDir))
                        {
                            removeAutoStartup(longName, props);
                        }
                    }
                }
            }
        }
        
        public void swingAfter()
        {
            // since there's no user interaction, simply move to the next panel
            showNextPanel();
        }
        
        private String getExecutable(String longName,
                                     PropertyList props,
                                     String installDir)
        {
            File executable;
            String exec = props.getProperty(MenuExecutableFile);
            boolean javaCommand = props.getBooleanProperty(MenuUseJavaCommandPrefix);
            
            if (javaCommand)
            {
                 executable = new File(installDir, longName + ".exe");
            }
            
            else
            {
                 executable = new File(installDir, exec);                
            }
            
            return executable.getPath();
        }
        
        
        private boolean addService(String serviceName, 
                                   String executable,
                                   String installDir)
        {
            boolean automatic = true;
            WindowsServices services = new WindowsServices();
            boolean ok = services.installService(serviceName, serviceName, 
              executable, automatic);
            
            CustomInstaller.logToInstaller("successful: " + ok);
            
            if (ok)
            {
                CustomUninstaller customUninstaller = new CustomUninstaller();
                customUninstaller.removeWindowsService(serviceName, executable);
                customUninstaller.append(installDir);
            }
            
            return ok;
        }
        
        
        private void removeAutoStartup(String longName, 
                                       PropertyList menuProperties)
        {
            boolean allUsers = menuProperties.getBooleanProperty(MenuAllUsers);
            String user = WindowsConstants.CurrentUser;
            if (allUsers)
            {
                user = WindowsConstants.AllUsers;
            }
            
            String startupDir = WindowsDirs.getStartupMenuDir(user);
            File f = new File(startupDir, "Autostart " + longName + ".lnk");
            f.delete();
        }
    }
    
    
    /**
     * Creates a new WinInstallService object.
     * 
     * @param properties installer's properties
     */
    public WinInstallService (PropertyList properties)
    {
        super (properties);
        
        updateProgressBarLabel(progressLabel);
    }

    /** 
     * Enter the panel. Method where the work for the class is done.
     *
     * Do not call this method; only the wizard should call it.
     */
    public synchronized void enter()
    {
        if (isWindows())
        {
            ServiceSwinger swinger = new ServiceSwinger();
            swinger.execute();
        }
        
        else
        {
            showNextPanel();
        }
    }

}