/*
 * 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.samples.shell.components.HTMLText;
import com.jniwrapper.samples.shell.components.LazyPanel;
import com.jniwrapper.samples.shell.components.LineBevel;
import com.jniwrapper.win32.io.FileSystem;
import com.jniwrapper.win32.shell.ShellIcon;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.text.DecimalFormat;
import java.text.FieldPosition;

/**
 @author Vladimir Kondrashchenko
 */
public class FileSystemInfoSample extends LazyPanel
{
    private static final String HEADER[] new String[]{"""Type""Total Size""Free Space""Serial No."};

    private JLabel lblAdvisoryText;
    private JPanel _hardDrivesList;
    private JButton btnUpdate;

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

    public void initialize() throws Exception
    {
        lblAdvisoryText = new HTMLText("This page demonstrates FileSystem class features to retrieve file system information.");

        _hardDrivesList = new JPanel(new GridBagLayout());
        updateHardDrivesList();

        JLabel lblCaption = new JLabel("File System Information");

        JPanel bevel = new LineBevel();

        btnUpdate = new JButton(new AbstractAction("Update")
        {
            public void actionPerformed(ActionEvent e)
            {
                updateHardDrivesList();
            }
        });

        setLayout(new GridBagLayout());

        add(lblAdvisoryText, new GridBagConstraints(00210.00.0
                , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10101510)00));

        add(lblCaption, new GridBagConstraints(02110.00.0
                , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0101010)00));

        add(bevel, new GridBagConstraints(12111.00.0
                , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(051010)00));

        add(_hardDrivesList, new GridBagConstraints(03210.00.0
                , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0000)00));

        add(btnUpdate, new GridBagConstraints(04210.00.0
                , GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10000)00));

        add(new JPanel()new GridBagConstraints(05211.01.0
                , GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0000)00));

        super.initialize();
    }

    private void updateHardDrivesList()
    {
        _hardDrivesList.removeAll();

        File[] roots = File.listRoots();

        for (int i = 0; i < HEADER.length; i++)
        {
            _hardDrivesList.add(new JLabel("<html><b><nobr>" + HEADER[i"</nobr></b></html>"),
                    new GridBagConstraints(i, 0110.00.0
                    , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(010510)00));
        }

        for (int i = 0; i < roots.length; i++)
        {
            ShellIcon icon = new ShellIcon(roots[i]);
            String label = FileSystem.getVolumeLabel(roots[i]);
            String driveName = roots[i].getAbsolutePath();
            String volumeType = getVolumeType(FileSystem.getDriveType(roots[i]));
            String totalSpace = formatBytes(FileSystem.getDiskTotalSize(roots[i]));
            String freeSpace = formatBytes(FileSystem.getDiskFreeSpace(roots[i]));
            String serialNumber = Long.toString(FileSystem.getSerialNumber(roots[i]));

            JLabel lblDrive = new JLabel(label + " (" + driveName + ")"new ImageIcon(icon.toImage()), JLabel.LEFT);

            _hardDrivesList.add(lblDrive, new GridBagConstraints(0, i+1110.00.0
                    , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(010020)00));
            _hardDrivesList.add(new JLabel(volumeType)new GridBagConstraints(1, i+1110.00.0
                    , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(010010)00));
            _hardDrivesList.add(new JLabel(totalSpace)new GridBagConstraints(2, i+1110.00.0
                    , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(010010)00));
            _hardDrivesList.add(new JLabel(freeSpace)new GridBagConstraints(3, i+1110.00.0
                    , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(010010)00));
            _hardDrivesList.add(new JLabel(serialNumber)new GridBagConstraints(4, i+1110.00.0
                    , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(010010)00));
        }

        _hardDrivesList.revalidate();
    }

    private String getVolumeType(FileSystem.DriveType driveType)
    {
        if (driveType.equals(FileSystem.DriveType.CDROM))
        {
            return "CD-ROM";
        }
        else if (driveType.equals(FileSystem.DriveType.FIXED))
        {
            return "Local Disk";
        }
        else if (driveType.equals(FileSystem.DriveType.RAMDISK))
        {
            return "RAM Disk";
        }
        else if (driveType.equals(FileSystem.DriveType.REMOTE))
        {
            return "Remote Drive";
        }
        else if (driveType.equals(FileSystem.DriveType.REMOVABLE))
        {
            return "Removable Drive";
        }
        else
        {
            return "Unknown";
        }
    }

    private String formatBytes(long value)
    {
        double result;
        int i = 0;
        do
        {
            result = value / Math.pow(210 * i);
            if (result < 1000 || i == 3)
            {
                StringBuffer buffer = new StringBuffer();
                DecimalFormat decimalFormat = new DecimalFormat("0.#");
                buffer = decimalFormat.format(result, buffer, new FieldPosition(DecimalFormat.FRACTION_FIELD));

                switch (i)
                {
                    case 0:
                        buffer.append(" Bytes");
                        break;

                    case 1:
                        buffer.append(" KBytes");
                        break;

                    case 2:
                        buffer.append(" MBytes");
                        break;

                    default:
                        buffer.append(" GBytes");
                        break;
                }
                return buffer.toString();
            }
            i++;
        }
        while (true);
    }
}