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

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.TableHeaderUI;
import javax.swing.plaf.TableUI;
import javax.swing.plaf.UIResource;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import org.netbeans.modules.tasklist.impl.OpenTaskAction;
import org.netbeans.spi.tasklist.Task;
import org.netbeans.modules.tasklist.trampoline.TaskGroup;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;

/**
 *
 * @author S. Aubrecht
 */
class TaskListTable extends JTable {
    
    private TableCellRenderer foldingGroupRenderer;
    private TableCellRenderer groupRenderer;
    
    private Action defaultAction = new DefaultAction();
    
    private Action nextTaskAction = new TaskNavigationAction( true );
    private Action prevTaskAction = new TaskNavigationAction( false );
    
    /** Creates a new instance of TaskListTable */
    public TaskListTable() {
        this.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
        addMouseListener( new MouseAdapter() {
            @Override
            public void mousePressed( MouseEvent e ) {
                maybePopup( e );
            }
            
            @Override
            public void mouseReleased( MouseEvent e ) {
                maybePopup( e );
            }
            
            @Override
            public void mouseClicked(MouseEvent e) {
                int row = rowAtPoint( e.getPoint() );
                if( isFoldingModel() ) {
                    FoldingTaskListModel foldingModel = getFoldingModel();
                    if( e.getClickCount() == 2 ) {
                        //handle group collapse/expand
                        if( foldingModel.isGroupRow( row ) ) {
                            foldingModel.toggleGroupExpanded( row );
                            return;
                        }
                    } else if( e.getClickCount() == 1 ) {
                        if( foldingModel.isGroupRow( row ) ) {
                            maybeExpandGroup( e.getPoint() );
                            return;
                        }
                    }
                }
                if( e.getClickCount() == 2 ) {
                    defaultAction.actionPerformed( null );
                }
            }
        });
        
        addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                repaintSelectedRow();
            }

            public void focusLost(FocusEvent e) {
                repaintSelectedRow();
            }
        });
        setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
        setBorder( BorderFactory.createEmptyBorder() );
        
        setAutoCreateColumnsFromModel( false );
        
        int requiredRowHeight = 16+2+2*getIntercellSpacing().height;
        setRowHeight( Math.max( getRowHeight(), requiredRowHeight ) );
        
        InputMap inputMap = getInputMap( JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
        Object right = inputMap.get( KeyStroke.getKeyStroke( KeyEvent.VK_RIGHT, 0 ) );
        Object left = inputMap.get( KeyStroke.getKeyStroke( KeyEvent.VK_LEFT, 0 ) );
        inputMap.put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), "defaultAction" ); // NOI18N
        
        getInputMap( JTable.WHEN_FOCUSED ).put( KeyStroke.getKeyStroke( KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK ), "org.openide.actions.PopupAction" ); //NOI18N
        getActionMap().put( "org.openide.actions.PopupAction", new PopupAction() ); //NOI18N
        
        ActionMap actionMap = getActionMap();
        Action actionLeft = actionMap.get( left );
        Action actionRight = actionMap.get( right );
        
        actionMap.put( left, new ToggleGroupAction( false, actionLeft ) );
        actionMap.put( right, new ToggleGroupAction( true, actionRight ) );
        actionMap.put( "defaultAction", defaultAction ); // NOI18N
        
        actionMap.put( "jumpPrev", prevTaskAction ); // NOI18N
        actionMap.put( "jumpNext", nextTaskAction ); // NOI18N
//        actionMap.put (FindAction.class.getName (), this.findAction);
//        actionMap.put (javax.swing.text.DefaultEditorKit.copyAction, this.copyAction);
    }
    
    @Override
    public void createDefaultColumnsFromModel() {
        TableModel m = getModel();
        if( m != null ) {
            // Remove any current columns
            TableColumnModel cm = getColumnModel();
            while( cm.getColumnCount() > 0 ) {
                cm.removeColumn( cm.getColumn(0) );
	    }

            // Create new columns from the data model info
            for( int i=0; i<m.getColumnCount(); i++ ) {
                TableColumn newColumn = new MyTableColumn(i);
                if( i == TaskListModel.COL_LOCATION )
                    newColumn.setCellRenderer( new LeftDotRenderer() );
                else if( i != TaskListModel.COL_GROUP )
                    newColumn.setCellRenderer( new TooltipRenderer() );
                addColumn(newColumn);
            }
        }
    }
    
    @Override
    public void removeNotify() {
        if( getModel() instanceof TaskListModel )
            storeColumnState();
        super.removeNotify();
    }
    
    @Override
    protected JTableHeader createDefaultTableHeader() {
        JTableHeader res = new MyTableHeader( columnModel );
        res.setTable(this);
        return res;
    }
    
    @Override
    public TableCellRenderer getCellRenderer( int row, int col ) {
        if( col == 0 ) {
            if( isFoldingModel() && getFoldingModel().isGroupRow( row ) )
                return getFoldingGroupRenderer();
            return getGroupRenderer();
        }
        return super.getCellRenderer( row, col );
    }
    
    private void maybePopup( MouseEvent e ) {
        if( e.isPopupTrigger() ) {
            e.consume();
            int row = rowAtPoint( e.getPoint() );
            if( row >= 0 )
                getSelectionModel().setSelectionInterval( row, row );
            JPopupMenu popup = Util.createPopup( this );
            popup.show( this, e.getX(), e.getY() );
        }
    }
    
    private TableCellRenderer getFoldingGroupRenderer() {
        if( null == foldingGroupRenderer )
            foldingGroupRenderer = new FoldingTaskGroupRenderer();
        return foldingGroupRenderer;
    }
    
    private TableCellRenderer getGroupRenderer() {
        if( null == groupRenderer )
            groupRenderer = new TaskGroupRenderer();
        return groupRenderer;
    }
    
    private void maybeExpandGroup( Point point ) {
        int row = rowAtPoint( point );
        int col = columnAtPoint( point );
        if( 0 != col )
            return;
        Rectangle rect = getCellRect( row, col, false );
        TableCellRenderer renderer = getCellRenderer(row, col);
        prepareRenderer(renderer, row, col);
        if( renderer instanceof FoldingTaskGroupRenderer ) {
            Icon icon = ((FoldingTaskGroupRenderer)renderer).getIcon();
            rect.grow( 0, -(rect.height-openedIcon.getIconHeight())/2 );
            rect.x = getColumnModel().getColumnMargin(); //rect.width - icon.getIconWidth();
            rect.width = openedIcon.getIconWidth();
            if( rect.contains( point ) ) {
                FoldingTaskListModel foldingModel = getFoldingModel();
                foldingModel.toggleGroupExpanded( row );
            }
        }
    }
    
    private void storeColumnState() {
        int count = getColumnModel().getColumnCount();
        for( int i=0; i<count; i++ ) {
            TableColumn tc = getColumnModel().getColumn( i );
            if( tc instanceof MyTableColumn ) {
                ((MyTableColumn)tc).storeState();
            }
        }
    }
    
    @Override
    public void setUI( TableUI ui ) {
        super.setUI( new TaskListTableUI() );
        setTableHeader( createDefaultTableHeader() );
    }
    
    @Override
    public void setModel( TableModel newModel ) {
        if( getModel() instanceof TaskListModel && newModel != getModel() ) {
            storeColumnState();
            ((TaskListModel)getModel()).detach();
        }
            
        if( newModel instanceof TaskListModel ) {
            ((TaskListModel)newModel).attach();
        }
        super.setModel( newModel );
        createDefaultColumnsFromModel();
    }

    private boolean isFoldingModel() {
        return getModel() instanceof FoldingTaskListModel;
    }
    
    private FoldingTaskListModel getFoldingModel() {
        return isFoldingModel() ? (FoldingTaskListModel)getModel() : null;
    }
    
    @Override
    public String getToolTipText( MouseEvent e ) {
        int hitRowIndex = rowAtPoint( e.getPoint() );
        if( isFoldingModel() && getFoldingModel().isGroupRow( hitRowIndex ) ) {
            return getFoldingModel().getGroupAtRow( hitRowIndex ).getGroup().getDescription();
        }
        return super.getToolTipText( e );
    }
    
    Task getSelectedTask() {
        int selRow = getSelectedRow();
        if( selRow < 0 )
            return null;
        return ((TaskListModel)getModel()).getTaskAtRow( selRow );
    }
    
    int getSortColumn() {
        return ((TaskListModel)getModel()).getSortingColumnn();
    }
    
    void setSortColumn( int col ) {
        ((TaskListModel)getModel()).toggleSort( col );
    }
    
    boolean isAscendingSort() {
        return ((TaskListModel)getModel()).isAscendingSort();
    }
    
    void setAscendingSort( boolean asc ) {
        ((TaskListModel)getModel()).setAscendingSort( asc );
    }
    
//    @Override
//    public Rectangle getCellRect( int row, int col, boolean includeSpacing ) {
//        Rectangle res = super.getCellRect( row, col, includeSpacing );
//        if( isFoldingModel() && getFoldingModel().isGroupRow(row) ) {
//            res.x = 0;
//            res.width = getWidth();
//            if( !includeSpacing )
//                res.width -= getColumnModel().getColumnMargin();
//        }
//        return res;
//    }
    
    
    
    private static final Icon openedIcon = (Icon)UIManager.get("Tree.expandedIcon"); // NOI18N
    private static final Icon closedIcon = (Icon)UIManager.get("Tree.collapsedIcon"); // NOI18N
    
    private static Map<Image, ImageIcon> iconCache = new HashMap<Image, ImageIcon>(10);
    
    private class TaskGroupRenderer extends DefaultTableCellRenderer {
        
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                              boolean isSelected, boolean hasFocus, int row, int column) {
            Component res = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            if( res instanceof JLabel ) {
                if( value instanceof TaskGroup ) {
                    TaskGroup tg = (TaskGroup)value;
                    JLabel renderer = (JLabel)res;
                    renderer.setText( null );
                    ImageIcon icon = iconCache.get( tg.getIcon() );
                    if( null == icon ) {
                        icon = new ImageIcon( tg.getIcon() );
                        iconCache.put( tg.getIcon(), icon );
                    }
                    renderer.setIcon( icon );
                    renderer.setToolTipText( tg.getDescription() );
                    renderer.setHorizontalAlignment( JLabel.RIGHT );
                }
            }
            return res;
        }
    }

    private class FoldingTaskGroupRenderer extends DefaultTableCellRenderer {
        
        private final Color GTK_BK_COLOR = new Color( 184,207,229 );
        private final Color AQUA_BK_COLOR = new Color(225, 235, 240);

        private final boolean isGTK = "GTK".equals( UIManager.getLookAndFeel().getID() ); // NOI18N
        private final boolean isAqua = "Aqua".equals( UIManager.getLookAndFeel().getID() ); // NOI18N
        
        public FoldingTaskGroupRenderer() {
            //force initialization of PropSheet look'n'feel values 
            UIManager.get( "nb.propertysheet" ); // NOI18N
            setOpaque( true );
        }
        
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                              boolean isSelected, boolean hasFocus, int row, int column) {
            
            if( getFoldingModel().isGroupRow( row ) ) {
//                hasFocus = table.isFocusOwner() && isSelected;
            }
            Component res = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            if( res instanceof JLabel ) {
                if( value instanceof FoldingTaskListModel.FoldingGroup ) {
                    FoldingTaskListModel.FoldingGroup fg = (FoldingTaskListModel.FoldingGroup)value;
                    JLabel renderer = (JLabel)res;
                    renderer.setText( fg.getGroup().getDisplayName() + " ("+fg.getTaskCount()+")" );
                    Icon treeIcon = fg.isExpanded() ? openedIcon : closedIcon;
                    renderer.setIcon( treeIcon );
                    renderer.setToolTipText( fg.getGroup().getDescription() );
                    renderer.setHorizontalAlignment( JLabel.LEFT );
                    if( !isSelected )
                        renderer.setBackground( getBackgroundColor() );
                }
            }
            return res;
        }
        
        public Color getBackgroundColor() {
            if( isGTK ) {
                return GTK_BK_COLOR;
            } else if( isAqua ) {
                return AQUA_BK_COLOR;
            } else {
                return UIManager.getColor( "PropSheet.setBackground" ); //NOI18N
            }
        }
    }
    
    
    
    private class ToggleGroupAction extends AbstractAction {
        private Action defaultAction;
        private boolean expand;
        public ToggleGroupAction( boolean expand, Action defaultAction ) {
            this.defaultAction = defaultAction;
            this.expand = expand;
        }
    
        public void actionPerformed( ActionEvent e ) {
            if( isFoldingModel() ) {
                FoldingTaskListModel foldingModel = getFoldingModel();
                int selRow = getSelectedRow();
                if( selRow >= 0 ) {
                    FoldingTaskListModel.FoldingGroup group = foldingModel.getGroupAtRow( selRow );
                    if( null != group && group.isExpanded() != expand ) {
                        group.setExpanded( expand );
                        return;
                    }
                }
            }
            defaultAction.actionPerformed( e );
        }
    }
    
    
    
    private class MyTableHeader extends JTableHeader {
        
        public MyTableHeader( TableColumnModel model ) {
            super( model );
            addMouseListener( new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if( e.getClickCount() != 1 )
                        return;
                    int column = columnAtPoint( e.getPoint() );
                    if( column > 0 && getModel() instanceof TaskListModel ) {
                        ((TaskListModel)getModel()).toggleSort( column );
                        repaint();
                    }
                }
            });
            this.setReorderingAllowed( false );
        }
        
        @Override
        public void setDraggedColumn( TableColumn aColumn ) {
            if( null != aColumn && aColumn.getModelIndex() == 0 )
                return; //don't allow the first column to be dragged
            super.setDraggedColumn( aColumn );
        }

        @Override
        public void setDefaultRenderer(TableCellRenderer defaultRenderer) {
            if( !(defaultRenderer instanceof SortingHeaderRenderer) && !isNimbus() )
                defaultRenderer = new SortingHeaderRenderer( defaultRenderer );
            super.setDefaultRenderer( defaultRenderer );
        }
        
        @Override
        public void setUI(TableHeaderUI ui) {
            super.setUI(ui);
        }
    
        @Override
        public void setResizingColumn( TableColumn col ) {
            if( null != getResizingColumn() && null == col ) {
                storeColumnState();
            }
            super.setResizingColumn( col );
        }

        @Override
        public JTable getTable() {
            return TaskListTable.this;
        }
    }
    
    
    private class DefaultAction extends AbstractAction {
        
        public void actionPerformed(ActionEvent arg0) {
            Task t = getSelectedTask();
            if( null != t ) {
                Action a = Util.getDefaultAction( t );
                if( a.isEnabled() ) {
                    a.actionPerformed( null );
                } else {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        }
    }
    
    
    private class TaskNavigationAction extends AbstractAction {
        private boolean navigateToNextTask;
        public TaskNavigationAction( boolean navigateToNextTask ) {
            super( navigateToNextTask ? NbBundle.getMessage( TaskListTable.class, "LBL_NextTask" )  //NOI18N
                    : NbBundle.getMessage( TaskListTable.class, "LBL_PrevTask" ) ); //NOI18N
            this.navigateToNextTask = navigateToNextTask;
        }
    
        public void actionPerformed( ActionEvent e ) {
            if( 0 == getModel().getRowCount() )
                return;
            
            int currentRow = getSelectedRow();
            if( currentRow < 0 ) {
                currentRow = 0;
            } else if( !(isFoldingModel() && getFoldingModel().isGroupRow(currentRow)) ) {
                currentRow += (navigateToNextTask ? 1 : -1);
            }
            
            TaskListModel tlm = (TaskListModel)getModel();
            while( true ) {
                if( currentRow < 0 )
                    currentRow = tlm.getRowCount()-1;
                else if( currentRow >= tlm.getRowCount() )
                    currentRow = 0;
                Task t = tlm.getTaskAtRow( currentRow );
                if( null != t ) {
                    getSelectionModel().setSelectionInterval( currentRow, currentRow );
                    scrollRectToVisible( getCellRect( currentRow, 0, true ) );
                    Action a = new OpenTaskAction( t );
                    if( a.isEnabled() ) {
                        a.actionPerformed( e );
                    } else {
                        TaskListTopComponent.findInstance().requestActive();
                    }
                    break;
                } else if( isFoldingModel() ) {
                    FoldingTaskListModel.FoldingGroup fg = getFoldingModel().getGroupAtRow( currentRow );
                    if( !fg.isExpanded() )
                        fg.setExpanded( true );
                }
                currentRow += (navigateToNextTask ? 1 : -1);
            }
        }
    }
    
    
    private class MyTableColumn extends TableColumn {
        private float ratio;
        
        public MyTableColumn( int index ) {
            super( index );
            if( index == TaskListModel.COL_GROUP ) {
                setWidth( isFoldingModel() ? 35 : 20 );
                setMinWidth( isFoldingModel() ? 35 : 20 );
                setMaxWidth( isFoldingModel() ? 35 : 20 );
                setResizable( false );
            } else {
                switch( modelIndex ) {
                case TaskListModel.COL_DESCRIPTION:
                    ratio = 0.65f;
                    break;
                case TaskListModel.COL_LOCATION:
                    ratio = 0.2f;
                    break;
                case TaskListModel.COL_FILE:
                    ratio = 0.1f;
                    break;
                }
                ratio = Settings.getDefault().getPreferredColumnWidth( index, isFoldingModel(), ratio );
            }
        }
        
        @Override
        public int getPreferredWidth() {
            int idx = this.getModelIndex();
            if( isFoldingModel() && idx == TaskListModel.COL_GROUP )
                return getWidth();
            
            int totalWidth = getParent().getWidth();
            return (int)(totalWidth*ratio);
        }
        
        public void storeState() {
            float totalWidth = TaskListTable.this.getWidth();
            if( totalWidth > 0 ) {
                ratio = this.getWidth() / totalWidth;
                Settings.getDefault().setPreferredColumnWidth( getModelIndex(), isFoldingModel(), ratio );
            }
        }

        @Override
        public Object getHeaderValue() {
            Object res = super.getHeaderValue();
            if( isNimbus() && getModel() instanceof TaskListModel && res instanceof String ) {
                TaskListModel tlm = (TaskListModel) getModel();
                if( getModelIndex() == tlm.getSortingColumnn() ) {
                    String name = res.toString();
                    if( tlm.isAscendingSort() ) {
                        name += "  ʌ";
                    } else {
                        name += "  v";
                    }
                    res = name;
                }
            }
            return res;
        }
    }

    private static class LeftDotRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
                
            super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );

            int availableWidth = table.getColumnModel().getColumn( column ).getWidth();
            availableWidth -= table.getIntercellSpacing().getWidth();
            Insets borderInsets = getBorder().getBorderInsets( (Component)this );
            availableWidth -= (borderInsets.left + borderInsets.right);
            String cellText = getText();
            FontMetrics fm = getFontMetrics( getFont() );

            if( fm.stringWidth(cellText) > availableWidth ) {
                setToolTipText( value.toString() );
                String dots = "..."; //NOI18N
                int textWidth = fm.stringWidth( dots );
                int nChars = cellText.length() - 1;
                for( ; nChars > 0; nChars-- ) {
                    textWidth += fm.charWidth( cellText.charAt( nChars ) );

                    if( textWidth > availableWidth ) {
                        break;
                    }
                }

                setText( dots + cellText.substring(nChars + 1) );
            } else {
                setToolTipText( null );
            }

            return this;
        }
    }
    

    private static class TooltipRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
                
            super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );

            int availableWidth = table.getColumnModel().getColumn( column ).getWidth();
            availableWidth -= table.getIntercellSpacing().getWidth();
            Insets borderInsets = getBorder().getBorderInsets( (Component)this );
            availableWidth -= (borderInsets.left + borderInsets.right);
            String cellText = getText();
            FontMetrics fm = getFontMetrics( getFont() );

            if( fm.stringWidth(cellText) > availableWidth ) {
                setToolTipText( cellText );

            } else {
                setToolTipText( null );
            }

            return this;
        }
    }

    private class SortingHeaderRenderer implements TableCellRenderer, UIResource {
        
        private TableCellRenderer origRenderer;
        
        private static final String SORT_ASC_ICON = "org/netbeans/modules/tasklist/ui/resources/columnsSortedAsc.gif"; // NOI18N
        private static final String SORT_DESC_ICON = "org/netbeans/modules/tasklist/ui/resources/columnsSortedDesc.gif"; // NOI18N

        private JLabel defaultRenderer;
        
        SortingHeaderRenderer( TableCellRenderer origRenderer ) {
            this.origRenderer = origRenderer;
            if( isGTK() ) {
                TableCellRenderer ren = new JTableHeader().getDefaultRenderer();
                if( ren instanceof JLabel )
                    defaultRenderer = (JLabel) ren;
            }
        }

        /** Overrides superclass method. */
        public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
            if( null == table ) {
                return new JLabel();
            }
            Component comp = origRenderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );

            if( comp instanceof JLabel ) {
                JLabel label = (JLabel)comp;
                TaskListModel tlm = (TaskListModel)getModel();
                if( column == tlm.getSortingColumnn() ) {
                    label.setIcon( getProperIcon( !tlm.isAscendingSort() ) );
                    label.setHorizontalTextPosition( SwingConstants.LEADING );
                } else {
                    label.setIcon( NO_ICON );
                }
                if( isGTK() && null != defaultRenderer ) {
                    defaultRenderer.setText(label.getText());
                    Dimension prefSize = defaultRenderer.getPreferredSize();
                    if( prefSize.width > 1 && prefSize.height > 1 )
                        label.setPreferredSize(prefSize);
                    label.setText(" " + label.getText());
                }
            }

            return comp;
        }

        private ImageIcon getProperIcon( boolean descending ) {
            if( descending ) {
                return ImageUtilities.loadImageIcon(SORT_DESC_ICON, false);
            } else {
                return ImageUtilities.loadImageIcon(SORT_ASC_ICON, false);
            }
        }
    }

    private static final Icon NO_ICON = new Icon() {

        public void paintIcon(Component c, Graphics g, int x, int y) {
        }

        public int getIconWidth() {
            return 1;
        }

        public int getIconHeight() {
            return 12;
        }
    };
    
    private class PopupAction extends AbstractAction {
        public PopupAction() {
            super( "Popup" ); //NOI18N
        }
    
        public void actionPerformed( ActionEvent e ) {
            Point p = getPositionForPopup();

            if (p == null) {
                //we're going to create a popup menu for the root node
                p = new Point(0, 0);
            }

            JPopupMenu popup = Util.createPopup( TaskListTable.this );
            popup.show( TaskListTable.this, p.x, p.y );
        }
        
        @Override
        public boolean isEnabled() {
            return TaskListTable.this.isFocusOwner();
        }
    }
    
    private Point getPositionForPopup() {
        int selRow = getSelectedRow();

        if( selRow < 0 ) {
            return null;
        }

        Rectangle rect = getCellRect( selRow, 0, true );

        if( rect == null ) {
            return null;
        }

        return new Point(0, rect.y + rect.height );
    }

    @Override
    public Color getSelectionBackground() {
        if( !hasFocus() && !isNimbus() && !isGTK() )
            return getUnfocusedSelectionBackground();
        return UIManager.getColor("Table.selectionBackground");//NOI18N
    }

    @Override
    public Color getSelectionForeground() {
        if( !hasFocus() && !isNimbus() && !isGTK() )
            return getUnfocusedSelectionForeground();
        return UIManager.getColor("Table.selectionForeground");//NOI18N
    }
    
    private void repaintSelectedRow() {
        int selRow = getSelectedRow();
        if( selRow < 0 )
            return;
        Rectangle rect = getCellRect(selRow, 0, true);
        Rectangle rect2 = getCellRect(selRow, getColumnCount()-1, true);
        rect.width = rect2.x + rect2.width;
        repaint(rect);
    }

    private static Color unfocusedSelBg = null;
    /** Get the system-wide unfocused selection background color */
    private static Color getUnfocusedSelectionBackground() {
        if (unfocusedSelBg == null) {
            //allow theme/ui custom definition
            unfocusedSelBg = UIManager.getColor("nb.explorer.unfocusedSelBg"); //NOI18N
            
            if (unfocusedSelBg == null) {
                //try to get standard shadow color
                unfocusedSelBg = UIManager.getColor("controlShadow"); //NOI18N
                
                if (unfocusedSelBg == null) {
                    //Okay, the look and feel doesn't suport it, punt
                    unfocusedSelBg = Color.lightGray;
                }

                //Lighten it a bit because disabled text will use controlShadow/
                //gray
                if (!Color.WHITE.equals(unfocusedSelBg.brighter())) {
                    unfocusedSelBg = unfocusedSelBg.brighter();
                }
            }
        }

        return unfocusedSelBg;
    }

    private static Color unfocusedSelFg = null;
    /** Get the system-wide unfocused selection foreground color */
    private static Color getUnfocusedSelectionForeground() {
        if (unfocusedSelFg == null) {
            //allow theme/ui custom definition
            unfocusedSelFg = UIManager.getColor("nb.explorer.unfocusedSelFg"); //NOI18N
            
            if (unfocusedSelFg == null) {
                //try to get standard shadow color
                unfocusedSelFg = UIManager.getColor("textText"); //NOI18N
                
                if (unfocusedSelFg == null) {
                    //Okay, the look and feel doesn't suport it, punt
                    unfocusedSelFg = Color.BLACK;
                }
            }
        }

        return unfocusedSelFg;
    }
    
    private static boolean isGTK () {
        return "GTK".equals(UIManager.getLookAndFeel().getID()); //NOI18N
    }
    
    private static boolean isNimbus () {
        return "Nimbus".equals(UIManager.getLookAndFeel().getID()); //NOI18N
    }
}

    
