package de.renew.splashscreen.impl;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.beans.PropertyChangeEvent;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


/**
 * This class creates an extended progress bar as singleton.<br>
 * It provides a textual overview of currently loaded plug-ins and a progress
 * bar to visualize the overall loading process.
 *
 * @author Eva Mueller
 * @date Nov 27, 2010
 */
public class ExtendedProgressBar extends JPanel {
    /**
     * The scroll pane that contains the text area for displaying loaded plug-in information.
     */
    private JScrollPane _scrollPane;
    private static ExtendedProgressBar _extendedProgressBar;
    private static final int PROGRESS_MAX_VALUE = 100;
    private static final int SPACE_BETWEEN_COMPONENTS = 5;
    private static final int TEXTAREA_ROWS = 10;
    private static final int TEXTAREA_COLUMNS = 30;
    private static final int FONT_SIZE = 14;

    private static final String LOADED_INFO_SCROLL_PANE = "loadedInfoScrollPane";
    private static final String LOADED_INFO_TEXT_AREA = "loadedInfoTextArea";
    /**
     * The progress bar used to visualize the current loading progress of plug-ins.
     */
    private JProgressBar _progressBar;
    /**
     * The text area displaying the names of plug-ins as they are being loaded.
     */
    private JTextArea _textArea;

    /**
     * Private constructor to create singleton instance of this class.<br>
     *
     * @author Eva Mueller
     * @date Nov 27, 2010
     */
    private ExtendedProgressBar() {
        if (_extendedProgressBar == null) {
            init();
        }
    }

    /**
     * Get (singleton) instance of this class.
     *
     * @return [{@link ExtendedProgressBar}]
     * @date Nov 27, 2010
     */
    public synchronized static ExtendedProgressBar getInstance() {
        if (_extendedProgressBar == null) {
            _extendedProgressBar = new ExtendedProgressBar();
        }
        return _extendedProgressBar;
    }

    /**
     * Create {@link JTextArea} nested within a {@link JScrollPane} for the<br>
     * textual representation of the loaded plug-ins.<br>
     * Additionally, a {@link JProgressBar} is created to visualize the overall<br>
     * plug-in loading process.
     */
    private void init() {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        _textArea = new JTextArea(TEXTAREA_ROWS, TEXTAREA_COLUMNS);
        _textArea.setName(LOADED_INFO_TEXT_AREA);
        _scrollPane = new JScrollPane(_textArea);
        _scrollPane.setName(LOADED_INFO_SCROLL_PANE);
        _scrollPane.setAutoscrolls(true);
        _textArea.setEditable(false);
        Font font = new Font("Arial", Font.BOLD, FONT_SIZE);
        _textArea.setFont(font);
        _textArea.setBorder(BorderFactory.createLineBorder(Color.WHITE));
        _scrollPane.setBorder(BorderFactory.createLineBorder(Color.WHITE));
        add(_scrollPane);

        _progressBar = new JProgressBar(0, PROGRESS_MAX_VALUE);
        _progressBar.setValue(0);
        _progressBar.setStringPainted(true);
        setOpaque(false);
        setBackground(Color.WHITE);
        _progressBar.setAlignmentY(Component.CENTER_ALIGNMENT);
        add(Box.createRigidArea(new Dimension(0, SPACE_BETWEEN_COMPONENTS)));
        add(_progressBar);
    }

    /**
     * Updates the Progressbar whenever a {@link PropertyChangeEvent} is triggered in
     * {@link de.renew.plugin.load.PluginLoaderComposition}
     * @param evt holds information about the loading status in {@link de.renew.plugin.load.PluginLoaderComposition}
     */
    protected void propertyChange(PropertyChangeEvent evt) {
        if ("progress".equals(evt.getPropertyName())) {
            int progress = (Integer) evt.getNewValue();

            if (progress > PROGRESS_MAX_VALUE) {
                progress = PROGRESS_MAX_VALUE;
            }
            _progressBar.setValue(progress);
            _progressBar.validate();
        }
        if ("pluginLoaded".equals(evt.getPropertyName())) {
            String tmp = "Loaded plugin : " + evt.getNewValue() + "\n";
            _textArea.append(tmp);
            _textArea.setCaretPosition(_textArea.getCaretPosition() + tmp.length());
        }
    }

    /**
     * Close the extended progress bar by removing all components.
     */
    void closeExtendedProgressBar() {
        remove(_progressBar);
        remove(_scrollPane);
        remove(_textArea);
        _progressBar = null;
        _scrollPane = null;
        _textArea = null;
        _extendedProgressBar = null;
        validate();
    }
}