/**
 * 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.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.border.Border;
import org.netbeans.modules.progress.spi.InternalHandle;
import org.netbeans.modules.progress.spi.UIInternalHandle;
import org.openide.util.Mutex;

/**
 * @author mkleint
 */
public class PopupPane extends JScrollPane {
    private JPanel view;
    private Set<ListComponent> listComponents;
    private ListComponent selected;
    
    public PopupPane() {
        listComponents = new HashSet<ListComponent>();
        view = new JPanel();
        GridLayout grid = new GridLayout(0, 1);
        grid.setHgap(0);
        grid.setVgap(0);
        view.setLayout(grid);
        view.setBorder(BorderFactory.createEmptyBorder());
        setName("progresspopup"); //NOI18N
        setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        setViewportView(view);
        setFocusable(true);
        setRequestFocusEnabled(true);

        Action down = new MoveDownAction();
        getActionMap().put("Move-Down", down);
        getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Move-Down");
        getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Move-Down");
        
        Action up = new MoveUpAction();
        getActionMap().put("Move-Up", up);
        getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Move-Up");
        getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Move-Up");
        Action cancel = new CancelAction();
        getActionMap().put("Cancel-Task", cancel);
        getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "Cancel-Task");
        getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "Cancel-Task");
        
        Action select = new SelectAction();
        getActionMap().put("select-task", select);
        getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "select-task");
        getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "select-task");
        
        
        setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    }
    
    public void addListComponent(final ListComponent lst) {
        Mutex.EVENT.readAccess(new Runnable() {            
            public @Override void run() {
                listComponents.add(lst);
                if (view.getComponentCount() > 0) {
                    JComponent previous = (JComponent)view.getComponent(view.getComponentCount() - 1);
                    previous.setBorder(new BottomLineBorder());
                }
                lst.setBorder(BorderFactory.createEmptyBorder());
                view.add(lst);
                if (listComponents.size() > 3) {
                    setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
                } else {
                    setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
                }
            }
        });
    }
    
    public void removeListComponent(final InternalHandle handle) {
        Mutex.EVENT.readAccess(new Runnable() {            
            public @Override void run() {
                Iterator<ListComponent> it = listComponents.iterator();
                while (it.hasNext()) {
                    ListComponent comp = it.next();
                    if (comp.getHandle() == handle) {
                        view.remove(comp);
                        it.remove();
                        break;
                    }
                }
                if (listComponents.size() > 3) {
                    setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
                } else {
                    setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
                }
            }
        });
    }

    public @Override Dimension getPreferredSize() {
        int count = view.getComponentCount();
        int height = count > 0 ? view.getComponent(0).getPreferredSize().height : 0;
        int offset = count > 3 ? height * 3 + 5 : (count * height) + 5;
        // 22 is the width of the additional scrollbar
        return new Dimension(count >3 ? ListComponent.ITEM_WIDTH + 22 
                                      : ListComponent.ITEM_WIDTH + 2, offset);
    }

    /**
     * bold font is now used not only for explicitly selected items, but for any 
     * change in currently selected task.
     */
    public void updateBoldFont(final InternalHandle handle) {
        Mutex.EVENT.readAccess(new Runnable() {            
            public @Override void run() {
                for (ListComponent comp : listComponents) {
                    comp.markAsActive(handle == comp.getHandle());
                }
            }
        });
    }
    
    
    
    private static class BottomLineBorder implements Border {
        private Insets ins = new Insets(0, 0, 1, 0);
        private Color col = new Color(221, 229, 248);
        
        public BottomLineBorder () {}
        
        public @Override Insets getBorderInsets(Component c) {
            return ins;
        }

        public @Override boolean isBorderOpaque() {
            return false;
        }

        public @Override void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
           Color old = g.getColor();
           g.setColor(col);
           g.drawRect(x, y + height - 2,  width, 1);
           g.setColor(old);
        }
    }
    
    private int findIndex(Component comp) {
        Component[] comps = view.getComponents();
        for (int i = 0; i < comps.length; i++) {
            if (comps[i] == comp) {
                return i;
            }
        }
        return -1;
    }

    public @Override void requestFocus() {
//#63666 - don't focus any of the tasks explicitly, wait for user action.
//        if (view.getComponentCount() > 1) {
//            if (selected == null || !selected.isDisplayable()) {
//                selected = (ListComponent)view.getComponent(0);
//            }
//            selected.requestFocus();
//        } else {
            super.requestFocus();
//        }
    }
    
    private class MoveDownAction extends AbstractAction {
        
        MoveDownAction() {
        }
         
        public @Override void actionPerformed(ActionEvent actionEvent) {
            int index = -1;
            if (selected != null) {
                index = findIndex(selected);
            }
            index = index + 1;
            if (index >= PopupPane.this.view.getComponentCount()) {
                index = 0;
            }
            selected = (ListComponent)PopupPane.this.view.getComponent(index);
            selected.requestFocus();
        }
        
    }
    
    private class MoveUpAction extends AbstractAction {
        
        MoveUpAction() {
        }
         
        public @Override void actionPerformed(ActionEvent actionEvent) {
            int index = PopupPane.this.view.getComponentCount();
            if (selected != null) {
                index = findIndex(selected);
//                selected.setBackground(new Color(249, 249, 249));
            }
            index = index - 1;
            if (index < 0) {
                index = PopupPane.this.view.getComponentCount() - 1;
            }
            selected = (ListComponent)PopupPane.this.view.getComponent(index);
            selected.requestFocus();
//            selected.setBackground(selectBgColor);
//            selected.scrollRectToVisible(selected.getBounds());
        }
    }
    
    private class CancelAction extends AbstractAction {
        public CancelAction () {}
        
        public @Override void actionPerformed(ActionEvent actionEvent) {
            if (selected != null) {
                Action act = selected.getCancelAction();
                if (act != null) {
                    act.actionPerformed(actionEvent);
                } else {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        }
    }

    private class SelectAction extends AbstractAction {
        public SelectAction () {}
        
        public @Override void actionPerformed(ActionEvent actionEvent) {
            if (selected != null) {
                selected.getHandle().requestExplicitSelection();
            }
        }
    }
    
}
