/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.profiler.heapwalk.ui;

import java.awt.BorderLayout;
import java.net.URL;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Segment;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import org.netbeans.lib.profiler.heap.Instance;
import org.netbeans.lib.profiler.ui.UIConstants;
import org.netbeans.lib.profiler.ui.UIUtils;
import org.netbeans.lib.profiler.ui.components.HTMLTextArea;
import org.netbeans.lib.profiler.ui.components.JTitledPanel;
import org.netbeans.modules.profiler.api.icons.GeneralIcons;
import org.netbeans.modules.profiler.api.icons.Icons;
import org.netbeans.modules.profiler.heapwalk.OverviewController;
import org.netbeans.modules.profiler.heapwalk.model.BrowserUtils;
import org.openide.util.NbBundle;

/**
 *
 * @author Jiri Sedlacek
 * @author Tomas Hurka
 */
@NbBundle.Messages({
    "OverviewControllerUI_ViewTitle=Overview",
    "OverviewControllerUI_ViewDescr=Overview",
    "OverviewControllerUI_InProgressMsg=In progress..."
})
public class OverviewControllerUI extends JTitledPanel {
    
    //~ Static fields/initializers -----------------------------------------------------------------------------------------------
    
    private static Icon ICON_INFO = Icons.getIcon(GeneralIcons.INFO);
    
    //~ Instance fields ----------------------------------------------------------------------------------------------------------
    
    private AbstractButton presenter;
    private HTMLTextArea dataArea;
    
    // --- UI definition ---------------------------------------------------------
    private OverviewController overviewController;
    
    // --- Private implementation ------------------------------------------------
    private Instance instanceToSelect;
    private boolean showSysprops = false;
    private boolean showThreads = false;
    
    //~ Constructors -------------------------------------------------------------------------------------------------------------
    
    // --- Constructors ----------------------------------------------------------
    public OverviewControllerUI(OverviewController controller) {
        super(Bundle.OverviewControllerUI_ViewTitle(),ICON_INFO,true);
        overviewController = controller;
        initComponents();
        refreshSummary();
    }
    
    //~ Methods ------------------------------------------------------------------------------------------------------------------
    
    // --- Public interface ------------------------------------------------------

    public void showInThreads(Instance instance) {
        if (!showThreads) {
            showThreads = true;
            instanceToSelect = instance;
            refreshSummary();
            return;
        }
        String referenceId = String.valueOf(instance.getInstanceId());
        
        dataArea.scrollToReference(referenceId);
        Document d = dataArea.getDocument();
        HTMLDocument doc = (HTMLDocument) d;
        HTMLDocument.Iterator iter = doc.getIterator(HTML.Tag.A);
        for (; iter.isValid(); iter.next()) {
            AttributeSet a = iter.getAttributes();
            String nm = (String) a.getAttribute(HTML.Attribute.NAME);
            if ((nm != null) && nm.equals(referenceId)) {
                dataArea.select(iter.getStartOffset(),iter.getEndOffset());
                dataArea.requestFocusInWindow();
            }
        }
    }

    private void refreshSummary() {
        if (!showSysprops && !showThreads) {
            dataArea.setText(Bundle.OverviewControllerUI_InProgressMsg());
        }
        
        BrowserUtils.performTask(new Runnable() {
            public void run() {
                String summary = "<nobr>" + overviewController.computeSummary() + "</nobr>"; // NOI18N
                String environment = "<nobr>" + overviewController.computeEnvironment() + "</nobr>"; // NOI18N
                String properties = "<nobr>" + overviewController.computeSystemProperties(showSysprops) + "</nobr>"; // NOI18N
                String threads = "<nobr>" + overviewController.computeThreads(showThreads) + "</nobr>"; // NOI18N
                final String dataAreaText = summary + "<br><br>" // NOI18N
                        + environment + "<br><br>" // NOI18N
                        + properties + "<br><br>" // NOI18N
                        + threads;
                
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        dataArea.setText(dataAreaText);
                        if (instanceToSelect != null) {
                            showInThreads(instanceToSelect);
                            instanceToSelect = null;
                        } else {
                            dataArea.setCaretPosition(0);
                        }
                    }
                });
            }
        });
    }
        
    private void initComponents() {
        // dataArea
        dataArea = new HTMLTextArea() {
            protected void showURL(URL url) {
                if (url == null) return;
                String urls = url.toString();
                if (urls.equals(OverviewController.SHOW_SYSPROPS_URL)) {
                    showSysprops = true;
                    refreshSummary();
                } else if (urls.equals(OverviewController.SHOW_THREADS_URL)) {
                    showThreads = true;
                    refreshSummary();
                } else if (urls.equals(OverviewController.SHOW_NEXT_SEGMENT_URL)) {
                    overviewController.showNextSegment();
                } else {
                    overviewController.showURL(urls);
                }
            }
        };
        dataArea.setEditorKit(new CustomHtmlEditorKit());
        dataArea.setSelectionColor(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);
        JScrollPane dataAreaScrollPane = new JScrollPane(dataArea,
                                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        dataAreaScrollPane.setBorder(BorderFactory.createMatteBorder(5, 5, 5, 5,
                                        UIUtils.getProfilerResultsBackground()));
        dataAreaScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
        dataAreaScrollPane.getVerticalScrollBar().setUnitIncrement(10);
        dataAreaScrollPane.getHorizontalScrollBar().setUnitIncrement(10);

        JPanel contentsPanel = new JPanel();
        contentsPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, getTitleBorderColor()));
        contentsPanel.setLayout(new BorderLayout());
        contentsPanel.setOpaque(true);
        contentsPanel.setBackground(dataArea.getBackground());
        contentsPanel.add(dataAreaScrollPane, BorderLayout.CENTER);

        setLayout(new BorderLayout());
        add(contentsPanel, BorderLayout.CENTER);
        
        // UI tweaks
        setBackground(dataArea.getBackground());
    }

    private class CustomHtmlEditorKit extends HTMLEditorKit {

        @Override
        public Document createDefaultDocument() {
            StyleSheet styles = getStyleSheet();
            StyleSheet ss = new StyleSheet();

            ss.addStyleSheet(styles);

            HTMLDocument doc = new CustomHTMLDocument(ss);
            doc.setParser(getParser());
            doc.setAsynchronousLoadPriority(4);
            doc.setTokenThreshold(100);
            return doc;
        }
    }
    
    private class CustomHTMLDocument extends HTMLDocument {
        private static final int CACHE_BOUNDARY = 1000;
        private char[] segArray;
        private int segOffset;
        private int segCount;
        private boolean segPartialReturn;
        private int lastOffset;
        private int lastLength;
        
        private CustomHTMLDocument(StyleSheet ss) {
            super(ss);
            lastOffset = -1;
            lastLength = -1;
            putProperty("multiByte", Boolean.TRUE);      // NOI18N
        }

        @Override
        public void getText(int offset, int length, Segment txt) throws BadLocationException {
            if (lastOffset == offset && lastLength == length) {
                txt.array = segArray;
                txt.offset = segOffset;
                txt.count = segCount;
                txt.setPartialReturn(segPartialReturn);
                return;
            }
            super.getText(offset, length, txt);
            if (length > CACHE_BOUNDARY || lastLength <= CACHE_BOUNDARY) {
                segArray = txt.array;
                segOffset = txt.offset;
                segCount = txt.count;
                segPartialReturn = txt.isPartialReturn();
                lastOffset = offset;
                lastLength = length;
            }
        }
    }

}
