001package jmri.jmrit.consisttool;
002
003import java.awt.*;
004import java.awt.image.BufferedImage;
005
006import javax.swing.*;
007
008import jmri.*;
009import jmri.jmrit.roster.*;
010import jmri.util.gui.GuiLafPreferencesManager;
011
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015/**
016 * 
017 * A ListCellRenderer for the ConsistComboBox
018 *
019 * @author Lionel Jeanson Copyright (c) 2023
020 * 
021 */
022public class ConsistListCellRenderer extends JLabel implements ListCellRenderer<Object> {
023    private final static int IMAGE_HEIGHT = 19;
024    
025    @Override
026    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {        
027        if (value == null) {
028            return null;
029        }
030        
031        if (value instanceof String) {
032            setText((String) value);
033            setIcon(null);
034            return this;            
035        }
036        
037        if (value instanceof LocoAddress) {            
038            LocoAddress consistAddress = (LocoAddress) value;
039            setText(consistAddress.toString());
040            
041            BufferedImage bi = new BufferedImage( 1, IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);            
042            Consist consist =  InstanceManager.getDefault(jmri.ConsistManager.class).getConsist(consistAddress);
043            Font f = new Font("Monospaced", Font.PLAIN, InstanceManager.getDefault(GuiLafPreferencesManager.class).getFontSize());
044            
045            for (DccLocoAddress loco : consist.getConsistList()) {
046                log.debug("Loco : {} - Position : {}", loco, consist.getPosition(loco));
047                String reName = consist.getRosterId(loco);
048                String label = null;
049                if (reName != null) {
050                    ImageIcon icon;
051                    Boolean dir = consist.getLocoDirection(loco);
052                    if (dir) {
053                        icon = InstanceManager.getDefault(RosterIconFactory.class).getIcon(reName);
054                    } else {
055                        icon = InstanceManager.getDefault(RosterIconFactory.class).getReversedIcon(reName);
056                    }
057                    if ( (icon != null) && (bi.getWidth() + icon.getIconWidth() > 0) ) {                        
058                        BufferedImage ti = new BufferedImage(bi.getWidth() + icon.getIconWidth(), IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
059                        Graphics g = ti.createGraphics();
060                        g.drawImage(icon.getImage(), ti.getHeight()/2-icon.getIconHeight()/2, 0, null);
061                        g.drawImage(bi, icon.getIconWidth(), 0, null);           
062                        g.dispose(); 
063                        bi = ti;
064                    } else {
065                        label = "["+reName+"]";
066                    }
067                } else {
068                     label = "["+loco.toString()+"]";
069                }
070                if (label != null) {
071                    // write label for that locomotive in a buffered image                    
072                    BufferedImage li =  new BufferedImage( label.length()*f.getSize(),  IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
073                    Graphics gli = li.createGraphics();
074                    gli.setFont(f);
075                    gli.setColor(this.getForeground());
076                    gli.drawString(label, 0, IMAGE_HEIGHT/2 + gli.getFontMetrics().getMaxAscent()/2);                    
077                    // expand existing buffered image
078                    BufferedImage ti = new BufferedImage( gli.getFontMetrics().stringWidth(label) + bi.getWidth() +2, IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
079                    Graphics gti = ti.createGraphics(); 
080                    gti.drawImage(li, 0, 0, null);
081                    gti.drawImage(bi, gli.getFontMetrics().stringWidth(label)+2, 0, null);
082                    // update and free ressources
083                    bi = ti;
084                    gli.dispose();
085                    gti.dispose();                     
086                }
087            }
088            setIcon(new ImageIcon(bi));
089        }
090        return this;        
091    }    
092    
093    private static final Logger log = LoggerFactory.getLogger(ConsistListCellRenderer.class);
094}