package com.apldbio.sds.platform.sae.audit.ui.view;



import com.jidesoft.dialog.ButtonPanel;
import com.jidesoft.dialog.StandardDialog;
import com.jidesoft.document.DocumentComponent;
import com.jidesoft.document.DocumentPane;
import com.jidesoft.icons.JideIconsFactory;
import com.jidesoft.pane.CollapsiblePane;
import com.jidesoft.pane.CollapsiblePanes;
import com.jidesoft.swing.*;
import com.jidesoft.utils.ProductNames;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * A template to create additional demo module.
 */
abstract public class AbstractDemo implements Demo, ProductNames {
    public AbstractDemo() {
    }

    public String getDescription() {
        return null;
    }

    public int hashCode() {
        return getName().hashCode();
    }

    public String toString() {
        return getName();
    }

    public Component getOptionsPanel() {
        return null;
    }

    protected static void showAsFrame(final AbstractDemo demo) {
        Component demoPanel = demo.getDemoPanel();
        Component optionsPanel = demo.getOptionsPanel();

        final JFrame frame = new JFrame(demo.getName());
        frame.setIconImage(JideIconsFactory.getImageIcon(JideIconsFactory.JIDE32).getImage());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();
        frame.setContentPane(contentPane);
        frame.getContentPane().setLayout(new BorderLayout());
        CollapsiblePanes panes = new CollapsiblePanes();

        if (optionsPanel != null) {
            CollapsiblePane pane = createCollapsiblePane("Options");
            pane.setEmphasized(true);
            if (optionsPanel instanceof JComponent) {
                JComponent optionPanel = (JComponent) optionsPanel;
                optionPanel.setBorder(BorderFactory.createEmptyBorder(8, 10, 8, 10));
                JideSwingUtilities.setOpaqueRecursively(optionPanel, false);
                pane.setContentPane(optionPanel);
            }
            panes.add(pane);
        }

        String description = demo.getDescription();
        if (description != null && description.trim().length() > 0) {
            CollapsiblePane pane = createCollapsiblePane("Description");
            MultilineLabel label = new MultilineLabel(description);
            label.setColumns(30);
            label.setBorder(BorderFactory.createEmptyBorder(8, 10, 8, 10));
            pane.setContentPane(label);
            panes.add(pane);
        }

        String[] source = demo.getDemoSource();
        if (source != null && source.length > 0) {
            CollapsiblePane pane = createCollapsiblePane("Source Code");
            JPanel panel = new JPanel(new BorderLayout(4, 4));
            StringBuffer sourceFiles = new StringBuffer();
            sourceFiles.append("Under examples/" + demo.getDemoFolder());
            for (int i = 0; i < source.length; i++) {
                String s = source[i];
                sourceFiles.append("\n  - ");
                sourceFiles.append(s);
            }
            MultilineLabel label = new MultilineLabel(sourceFiles.toString());
            label.setColumns(30);
            panel.add(label);
            panel.add(JideSwingUtilities.createLeftPanel(AbstractDemo.createBrowseSourceCodeButton(frame, demo)), BorderLayout.AFTER_LAST_LINE);
            pane.setContentPane(panel);
            panel.setBorder(BorderFactory.createEmptyBorder(8, 10, 8, 10));
            JideSwingUtilities.setOpaqueRecursively(panel, false);
            panes.add(pane);
        }

        if (demoPanel != null) {
            JPanel panel = new JPanel(new BorderLayout());
            panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            panel.add(demoPanel, BorderLayout.CENTER);
            frame.getContentPane().add(panel, BorderLayout.CENTER);
        }

        if (panes.getComponentCount() >= 1) {
            panes.addExpansion();
            frame.getContentPane().add(new JScrollPane(panes), BorderLayout.BEFORE_LINE_BEGINS);
        }

        frame.pack();
        JideSwingUtilities.globalCenterWindow(frame);
        frame.setVisible(true);
    }

    private static CollapsiblePane createCollapsiblePane(String title) {
        CollapsiblePane pane = new CollapsiblePane(title);
        return pane;
    }

    public String[] getDemoSource() {
        return new String[]{getClass().getName() + ".java"};
    }

    public String getDemoFolder() {
        return "";
    }

    public int getAttributes() {
        return ATTRIBUTE_NONE;
    }

    public static JButton createBrowseSourceCodeButton(final JFrame frame, final Demo demo) {
        JButton button = new JButton(new AbstractAction("Browse Source Code") {
            public void actionPerformed(ActionEvent e) {
                StandardDialog dialog = new StandardDialog(frame, "Browse Source Code", false) {
                    public JComponent createBannerPanel() {
                        return null;
                    }

                    public JComponent createContentPanel() {
                        JPanel panel = new JPanel(new BorderLayout());
                        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
                        panel.add(createSourceCodePanel(demo.getDemoSource()));
                        panel.setPreferredSize(new Dimension(600, 500));
                        return panel;
                    }

                    public ButtonPanel createButtonPanel() {
                        JButton closeButton = new JButton();
                        closeButton.setName(CLOSE);
                        closeButton.setAction(new AbstractAction(UIManager.getString("OptionPane.okButtonText")) {
                            public void actionPerformed(ActionEvent e) {
                                setDialogResult(RESULT_AFFIRMED);
                                setVisible(false);
                                dispose();
                            }
                        });

                        setDefaultCancelAction(closeButton.getAction());
                        return null;
                    }
                };
                dialog.pack();
                dialog.setLocationRelativeTo(frame);
                dialog.setVisible(true);
            }
        });
        return button;
    }

    public static JComponent createSourceCodePanel(String[] sourceCode) {
        DocumentPane pane = new DocumentPane();
        for (int i = 0; i < sourceCode.length; i++) {
            String s = sourceCode[i];
            pane.openDocument(new DocumentComponent(createSearchableTextArea(createTextComponent(s)), s));
        }
        pane.setTabbedPaneCustomizer(new DocumentPane.TabbedPaneCustomizer() {
            public void customize(JideTabbedPane tabbedPane) {
                tabbedPane.setTabPlacement(JideTabbedPane.BOTTOM);
            }
        });
        return pane;
    }

    private static JPanel createSearchableTextArea(final JTextComponent textComponent) {
        final JPanel panel = new JPanel(new BorderLayout());
        panel.add(new JScrollPane(textComponent), BorderLayout.CENTER);
        Searchable searchable = SearchableUtils.installSearchable(textComponent);
        searchable.setRepeats(true);
        SearchableBar searchableBar = SearchableBar.install(searchable, KeyStroke.getKeyStroke(KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK), new SearchableBar.Installer() {
            public void openSearchBar(SearchableBar searchableBar) {
                panel.add(searchableBar, BorderLayout.AFTER_LAST_LINE);
                panel.invalidate();
                panel.revalidate();
            }

            public void closeSearchBar(SearchableBar searchableBar) {
                panel.remove(searchableBar);
                panel.invalidate();
                panel.revalidate();
            }
        });
        return panel;
    }

    public static JTextComponent createTextComponent(String fileName) {
        JTextArea area = new JTextArea();
        area.setFont(new Font("Monospaced", Font.PLAIN, 12));
        Document doc = new PlainDocument();
        try {
            // try to start reading
            InputStream in = AbstractDemo.class.getResourceAsStream(fileName);
            if (in != null) {
                byte[] buff = new byte[4096];
                int nch;
                while ((nch = in.read(buff, 0, buff.length)) != -1) {
                    doc.insertString(doc.getLength(), new String(buff, 0, nch), null);
                }
                area.setDocument(doc);
            }
            else {
                area.setText("Please make sure the source code files are in the same location as classes.");
            }
        }
        catch (FileNotFoundException e) {
        }
        catch (IOException e) {
        }
        catch (BadLocationException e) {
        }
        return area;
    }
}


