/*
 * Copyright (c) 2000-2009 TeamDev Ltd. All rights reserved.
 * TeamDev PROPRIETARY and CONFIDENTIAL.
 * Use is subject to license terms.
 */
package com.jniwrapper.win32.samples.demo;

import com.jniwrapper.win32.service.Service;
import com.jniwrapper.win32.service.ServiceManager;
import com.jniwrapper.win32.system.VersionInfo;
import com.jniwrapper.NoSuchFunctionException;
import com.jniwrapper.samples.shell.components.LazyPanel;
import com.jniwrapper.samples.shell.components.HTMLText;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableColumn;
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

public class ServicesSample extends LazyPanel
{
    private static final Vector COLUMN_NAMES = new Vector();

    static
    {
        COLUMN_NAMES.add("Name");
        COLUMN_NAMES.add("Description");
        COLUMN_NAMES.add("Status");
        COLUMN_NAMES.add("Startup Type");
        COLUMN_NAMES.add("");
//        COLUMN_NAMES.add("Log On As");
    }
    private static final String DOMAIN_SEPARATOR = "\\";

    private JLabel lblAdvisoryText;
    private Vector _servicesInfo = new Vector();
    private JTable _servicesTable;
    private boolean _isWinNT;
    private JLabel lblNotSupported;
    private JPanel servicesPanel;
    private JPanel updatePanel;

    public ServicesSample(Window parent)
    {
        super(parent);
    }

    public void initialize() throws Exception
    {
        VersionInfo versionInfo = new VersionInfo();
        _isWinNT = false;
        if (versionInfo.isNT())
        {
            _isWinNT = true;
        }

        DefaultTableModel tableModel = new DefaultTableModel(_servicesInfo, COLUMN_NAMES)
        {
            public boolean isCellEditable(int row, int column)
            {
                return false;
            }
        };

        servicesPanel = new JPanel();
        servicesPanel.setLayout(new BorderLayout());

        _servicesTable = new JTable(tableModel);
        _servicesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        _servicesTable.setRowSelectionAllowed(true);
        _servicesTable.setShowHorizontalLines(false);
        _servicesTable.setShowVerticalLines(false);

        final TableColumnModel columnModel = _servicesTable.getColumnModel();
        columnModel.getColumn(0).setPreferredWidth(70);
        columnModel.getColumn(1).setPreferredWidth(200);
        columnModel.getColumn(2).setPreferredWidth(30);
        columnModel.getColumn(3).setPreferredWidth(50);
        final TableColumn emptyColumn = columnModel.getColumn(4);
        emptyColumn.setPreferredWidth(4);
        emptyColumn.setMaxWidth(4);
        emptyColumn.setMinWidth(4);

        if (!_isWinNT)
        {
            lblNotSupported = new HTMLText("<b><FONT color = red>NOTE:</FONT> Service management functionality " +
                    "is not supported by current version of operation system.");
            lblNotSupported.setBorder(BorderFactory.createEmptyBorder(10101010));
        }
        else
        {
            lblNotSupported = new JLabel();
        }

        setLayout(new BorderLayout());

        servicesPanel.add(_servicesTable.getTableHeader(), BorderLayout.NORTH);
        servicesPanel.add(new JScrollPane(_servicesTable), BorderLayout.CENTER);

        lblAdvisoryText = new HTMLText("The page demonstrates the WinPack ability to manage NT Services, using the Services API.<br>Press the \"Update\" button to update the list.");

        lblAdvisoryText.setBorder(BorderFactory.createEmptyBorder(10101010));
        servicesPanel.setBorder(BorderFactory.createEmptyBorder(10101010));

        JButton updateButton = new JButton("Update");
        if (!_isWinNT)
        {
            updateButton.setEnabled(false);
        }
        updateButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                loadServicesInfo();
            }
        });

        updatePanel = new JPanel();
        updatePanel.add(updateButton);

        add(lblAdvisoryText, BorderLayout.NORTH);
        if (_isWinNT)
        {
            add(servicesPanel, BorderLayout.CENTER);
            add(updatePanel, BorderLayout.SOUTH);
        }
        else
        {
            add(lblNotSupported, BorderLayout.CENTER);
        }

        super.initialize();
    }

    public void activate() throws Exception
    {
        super.activate();

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                loadServicesInfo();
            }
        });
    }

    private void loadServicesInfo()
    {
        if (_isWinNT)
        {
            try
            {
                ServiceManager serviceManager = new ServiceManager();
                loadServicesInfo(serviceManager);
            }
            catch(Exception ex)
            {
                remove(servicesPanel);
                lblAdvisoryText.setText("The page demonstrates the WinPack ability to manage NT Services," +
                    " using the Services API.<br>Press the \"Update\" button to update the list." +
                    "<br><br>&nbsp;<b><FONT color = red>NOTE:</FONT> You should have " +
                    "Administrator rights to have the services displayed.</b>");
                repaint();
            }
        }
    }

    private void loadServicesInfo(ServiceManager serviceManager)
    {
        _servicesInfo.clear();

        Service[] services = serviceManager.getServices();

        for (int i = 0; i < services.length; i++)
        {
            final Service service = services[i];

            try
            {
                Vector row = new Vector(5);
                row.add(service.getDisplayName());

                try
                {
                    row.add(getDescription(service));
                    row.add(getStatus(service));
                    row.add(getStartupType(service));
                    row.add("");
//                    row.add(getLogin(service));
                }
                finally
                {
                    service.close();
                }

                _servicesInfo.add(row);
            }
            catch (Exception e)
            {
                System.out.println("failed for " + service.getName());
            }
        }

        ((AbstractTableModel)_servicesTable.getModel()).fireTableDataChanged();
    }

    private String getDescription(Service service)
    {
        String description = null;
        try
        {
            description = service.getDescription();
        }
        catch (NoSuchFunctionException e)
        {
            description = "";
        }
        return description;
    }

    private String getStatus(Service service)
    {
        return service.getCurrentState().toString();
    }

    private String getStartupType(Service service)
    {
        return service.getStartupType().toString();
    }
}