/**
 * 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.progress.ui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import org.netbeans.modules.progress.spi.InternalHandle;
import org.netbeans.modules.progress.spi.ProgressEvent;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;

/**
 *
 * @author mkleint
 */
public class ListComponent extends JPanel {
    private NbProgressBar bar;
    private JLabel mainLabel;
    private JLabel dynaLabel;
    private JButton closeButton;
    private InternalHandle handle;
    private boolean watched;
    private Action cancelAction;
    private Color selectBgColor;
    private Color selectFgColor;
    private Color bgColor;
    private Color fgColor;
//    private Color dynaFgColor;
    private int mainHeight;
    private int dynaHeight;
    
    /** Creates a new instance of ListComponent */
    public ListComponent(InternalHandle hndl) {
        setFocusable(true);
        setRequestFocusEnabled(true);
//        setVerifyInputWhenFocusTarget(false);
        mainLabel = new JLabel();
        dynaLabel = new JLabel();
        // in gtk, the panel is non-opague, meaning we cannot color background
        // #59419
        setOpaque(true);
        dynaLabel.setFont(dynaLabel.getFont().deriveFont((float) (dynaLabel.getFont().getSize() - 2)));
        bar = new NbProgressBar();        
        handle = hndl;
        Color bg = UIManager.getColor("nbProgressBar.popupText.background");
        if (bg != null) {
            setBackground(bg);
            mainLabel.setBackground(bg);
            dynaLabel.setBackground(bg);
        }
        bgColor = getBackground();
        Color dynaFg = UIManager.getColor("nbProgressBar.popupDynaText.foreground");
        if (dynaFg != null) {
            dynaLabel.setForeground(dynaFg);
        }
//        dynaFgColor = dynaLabel.getForeground();
        fgColor = UIManager.getColor("nbProgressBar.popupText.foreground");
        if (fgColor != null) {
            mainLabel.setForeground(fgColor);
        }
        fgColor = mainLabel.getForeground();
        selectBgColor = UIManager.getColor("nbProgressBar.popupText.selectBackground");
        if (selectBgColor == null) {
            selectBgColor = UIManager.getColor("List.selectionBackground");
        }
        selectFgColor = UIManager.getColor("nbProgressBar.popupText.selectForeground");
        if (selectFgColor == null) {
            selectFgColor = UIManager.getColor("List.selectionForeground");
        }
        bar.setToolTipText(NbBundle.getMessage(ListComponent.class, "ListComponent.bar.tooltip"));
        bar.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        //start figure out height
        mainLabel.setText("XYZ");
        dynaLabel.setText("XYZ");
        mainHeight = mainLabel.getPreferredSize().height;
        dynaHeight = dynaLabel.getPreferredSize().height;
        mainLabel.setText(null);
        dynaLabel.setText(null);
        //end figure out height
        
        setLayout(new CustomLayout());
        add(mainLabel);
        add(bar);
        MListener list = new MListener();
        if (handle.isAllowCancel()) {
            cancelAction = new CancelAction(false);
            closeButton = new JButton(cancelAction);
            closeButton.setBorderPainted(false);
            closeButton.setBorder(BorderFactory.createEmptyBorder());
            closeButton.setOpaque(false);
            closeButton.setContentAreaFilled(false);
            closeButton.setFocusable(false);
            
            Image img = (Image)UIManager.get("nb.progress.cancel.icon");
            if( null != img ) {
                closeButton.setIcon( new ImageIcon( img ) );
            }
            img = (Image)UIManager.get("nb.progress.cancel.icon.mouseover");
            if( null != img ) {
                closeButton.setRolloverEnabled(true);
                closeButton.setRolloverIcon( new ImageIcon( img ) );
            }
            img = (Image)UIManager.get("nb.progress.cancel.icon.pressed");
            if( null != img ) {
                closeButton.setPressedIcon( new ImageIcon( img ) );
            }
            
            closeButton.setToolTipText(NbBundle.getMessage(ListComponent.class, "ListComponent.btnClose.tooltip"));
            add(closeButton);
            if (handle.getState() != InternalHandle.STATE_RUNNING) {
                closeButton.setEnabled(false);
            }
        }
        add(dynaLabel);
        setBorder(BorderFactory.createEmptyBorder());
        addMouseListener(list);
        bar.addMouseListener(list);
        mainLabel.addMouseListener(list);
        dynaLabel.addMouseListener(list);
        if (handle.isAllowCancel()) {
            closeButton.addMouseListener(list);
        }
        
        mainLabel.setText(handle.getDisplayName());
        mainLabel.setToolTipText(mainLabel.getText());
        NbProgressBar.setupBar(handle, bar);
        addFocusListener(new FocusListener() {
            public void focusGained(java.awt.event.FocusEvent e) {
                if (!e.isTemporary()) {
                    setBackground(selectBgColor);
                    mainLabel.setBackground(selectBgColor);
                    dynaLabel.setBackground(selectBgColor);
                    mainLabel.setForeground(selectFgColor);
                    // TODO assuming now that dynalabel has always the same foreground color
                    // seems to be the case according to the spec
                    scrollRectToVisible(getBounds());
                }
            }

            public void focusLost(java.awt.event.FocusEvent e) {
                if (!e.isTemporary()) {
                    setBackground(bgColor);
                    mainLabel.setBackground(bgColor);
                    dynaLabel.setBackground(bgColor);
                    mainLabel.setForeground(fgColor);
                    // TODO assuming now that dynalabel has always the same foreground color
                    // seems to be the case according to the spec
                    
                }
            }
            
        });
        
    }
    
    
    Action getCancelAction() {
        return cancelAction;
    }
    
    InternalHandle getHandle() {
        return handle;
    }
    
    void processProgressEvent(ProgressEvent event) {
        if (event.getType() == ProgressEvent.TYPE_PROGRESS || 
                event.getType() == ProgressEvent.TYPE_SWITCH || 
                event.getType() == ProgressEvent.TYPE_SILENT) {
            if (event.getSource() != handle) {
                throw new IllegalStateException();
            }
            if (event.isSwitched()) {
                NbProgressBar.setupBar(event.getSource(), bar);
            }
            if (event.getWorkunitsDone() > 0) {
                bar.setValue(event.getWorkunitsDone());
            }
            bar.setString(StatusLineComponent.getBarString(event.getPercentageDone(), event.getEstimatedCompletion()));
            if (event.getMessage() != null) {
                dynaLabel.setText(event.getMessage());
            }
            if (event.getSource().getState() == InternalHandle.STATE_REQUEST_STOP) {
                closeButton.setEnabled(false);
            }
            if (event.getDisplayName() != null) {
                mainLabel.setText(event.getDisplayName());
            }
        } else {
            throw new IllegalStateException();
        }
    }

    void markAsActive(boolean sel) {
        if (sel == watched) {
            return;
        }
        watched = sel;
        if (sel) {
            mainLabel.setFont(mainLabel.getFont().deriveFont(Font.BOLD));
        } else {
            mainLabel.setFont(mainLabel.getFont().deriveFont(Font.PLAIN));
        }
        if (mainLabel.isVisible()) {
            mainLabel.repaint();
        }
    }

    //Called to clear the progressbar
    void clearProgressBarOSX() {
        //EMI: On OSX, an animation thread is started when the progressbar is created, even if not displayed (or added to a container).
        // The following line is needed to kill the animation thread otherwise this tends to be alive for the rest of the JVM execution
        // pumping a lot of repaing events in the event queue (in my tests, about 50% of the CPU while idle).
        // The culprit apple.laf.CUIAquaProgressBar$Animator was discovered with the normal Profiler, while Tim Boudreau told me about a similar
        // problem with OSX and the pulsating button (that also has a thread for that animation).
        // Finally, btrace and this IDEA bug report (http://www.jetbrains.net/jira/browse/IDEADEV-25376) connected the dots.
        if (bar != null) {
            bar.getUI().uninstallUI(bar);
        }
    }
    
    private class MListener extends MouseAdapter {
        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getSource() == bar) {
                handle.requestExplicitSelection();
//                markAsSelected(true);
            }
            if (e.getClickCount() > 1 && (e.getSource() == mainLabel || e.getSource() == dynaLabel)) {
                handle.requestView();
            }
            if (e.getButton() != MouseEvent.BUTTON1) {
                showMenu(e);
            } else {
                ListComponent.this.requestFocus();
            }
            
//            System.out.println("list component requesting focus..");
        }
    }
    
    private void showMenu(MouseEvent e) {
        if (!isShowing()) {
            return;
        }
        JPopupMenu popup = new JPopupMenu();
        //mark teh popup for the status line awt listener
        popup.setName("progresspopup");
        popup.add(new ViewAction());
        popup.add(new WatchAction());
        popup.add(new CancelAction(true));
        popup.show((Component)e.getSource(), e.getX(), e.getY());
    }    
    
   private class CancelAction extends AbstractAction {
       CancelAction(boolean text) {
           if (text) {
               putValue(Action.NAME, NbBundle.getMessage(ListComponent.class, "StatusLineComponent.Cancel"));
               putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
           } else {
               Image icon = (Image)UIManager.get("nb.progress.cancel.icon");
               if (icon == null) {
                   // for custom L&F?
                   icon = ImageUtilities.loadImage("org/netbeans/progress/module/resources/buton.png");
               }
               putValue(Action.SMALL_ICON, new ImageIcon(icon));
           }
            setEnabled(handle == null ? false : handle.isAllowCancel());
       }

        public void actionPerformed(ActionEvent actionEvent) {
            if (handle.getState() == InternalHandle.STATE_RUNNING) {
                String message = NbBundle.getMessage(ListComponent.class, "Cancel_Question", handle.getDisplayName());
                String title = NbBundle.getMessage(ListComponent.class, "Cancel_Question_Title");
                NotifyDescriptor dd = new NotifyDescriptor(message, title, 
                                           NotifyDescriptor.YES_NO_OPTION,
                                           NotifyDescriptor.QUESTION_MESSAGE, null, null);
                Object retType = DialogDisplayer.getDefault().notify(dd);
                if (retType == NotifyDescriptor.YES_OPTION) {
                    handle.requestCancel();
                }
            }
        }
    }

    private class ViewAction extends AbstractAction {
        public ViewAction() {
            putValue(Action.NAME, NbBundle.getMessage(ListComponent.class, "StatusLineComponent.View"));
            setEnabled(handle == null ? false : handle.isAllowView());
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
        }
        public void actionPerformed(ActionEvent actionEvent) {
            if (handle != null) {
                handle.requestView();
            }
        }
    }    

    private class WatchAction extends AbstractAction {
        public WatchAction() {
            putValue(Action.NAME, NbBundle.getMessage(ListComponent.class, "ListComponent.Watch"));
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0));
            setEnabled(true);
        }
        public void actionPerformed(ActionEvent actionEvent) {
            if (handle != null) {
                handle.requestExplicitSelection();
            }
        }
    }    
    
    
    private static final int UPPERMARGIN = 3;
    private static final int LEFTMARGIN = 2;
    private static final int BOTTOMMARGIN = 2;
    private static final int BETWEENTEXTMARGIN = 3;
    
    static final int ITEM_WIDTH = 600;
    
    private class CustomLayout implements LayoutManager {
        
        /**
         * If the layout manager uses a per-component string,
         * adds the component <code>comp</code> to the layout,
         * associating it 
         * with the string specified by <code>name</code>.
         * 
         * @param name the string to be associated with the component
         * @param comp the component to be added
         */
        public void addLayoutComponent(String name, java.awt.Component comp) {
        }

        /**
         * Calculates the preferred size dimensions for the specified 
         * container, given the components it contains.
         * @param parent the container to be laid out
         *  
         * @see #minimumLayoutSize
         */
        public Dimension preferredLayoutSize(java.awt.Container parent) {
            int height = UPPERMARGIN + mainHeight + BETWEENTEXTMARGIN + dynaHeight + BOTTOMMARGIN;
            return new Dimension(ITEM_WIDTH, height);
        }

        /**
         * 
         * Lays out the specified container.
         * @param parent the container to be laid out 
         */
        public void layoutContainer(java.awt.Container parent) {
            int parentWidth = parent.getWidth();
            int parentHeight = parent.getHeight();
            int offset = parentWidth - 18;
            if (closeButton != null) {
                closeButton.setBounds(offset, UPPERMARGIN, 18, mainHeight);            
            }
            // have the bar approx 30 percent of the width
            int barOffset = offset - (ITEM_WIDTH / 3);
            bar.setBounds(barOffset, UPPERMARGIN, offset - barOffset, mainHeight);
            mainLabel.setBounds(LEFTMARGIN, UPPERMARGIN, barOffset - LEFTMARGIN, mainHeight);
            dynaLabel.setBounds(LEFTMARGIN, mainHeight + UPPERMARGIN + BETWEENTEXTMARGIN, 
                                parentWidth - LEFTMARGIN, dynaHeight);
        }

        /**
         * 
         * Calculates the minimum size dimensions for the specified 
         * container, given the components it contains.
         * @param parent the component to be laid out
         * @see #preferredLayoutSize
         */
        public Dimension minimumLayoutSize(java.awt.Container parent) {
            return preferredLayoutSize(parent);
        }

        /**
         * Removes the specified component from the layout.
         * @param comp the component to be removed
         */
        public void removeLayoutComponent(java.awt.Component comp) {
        }

        
    }
}
