package view;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeNode;

import animation.PseudoCodeNode;

/**
 * A tree-like display of pseudocode.
 * Extends {@link DefaultTreeCellRenderer}
 * @author kolja
 *
 */
public class PseudoCodeRenderer extends DefaultTreeCellRenderer {
	
    private static final long serialVersionUID = 1L;
    private static ImageIcon currentLine = new ImageIcon( PseudoCodeNode.class.getResource( "/img/current_line.png" ) );
    
    private Color specialColor = null;

    @Override
    public Color getBackgroundNonSelectionColor() {
        if(specialColor != null) {
            return specialColor;
        } else {
            return RenderHelper.BACKGROUND_COLOR;
        }
    }
    
    @Override
    public Color getForeground() {
        return new Color(0xa9b7c6);
    }
    
    private int countChildren( TreeNode treeNode )
    {
        if( treeNode.isLeaf() )
            return 0;
        else
        {
            int sum = 0;
            for( int i = 0; i < treeNode.getChildCount(); i++ )
            {
                sum += countChildren( treeNode.getChildAt( i ) ) + 1;
            }
            return sum;
        }
    }

    private int getLineNumber( TreeNode treeNode )
    {
        TreeNode parent = treeNode.getParent();
        if( parent == null )
            return 1;
        int sum = getLineNumber( parent ) + 1;
        for( int i = 0; i < parent.getChildCount(); i++ )
        {
            if( i == parent.getIndex( treeNode ) )
                return sum;
            sum += countChildren( parent.getChildAt( i ) ) + 1;
        }
        return 0;
    }
    
    @Override
    public Font getFont() {
        return new Font("Monospaced", Font.PLAIN, 12);
    }
    
    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean arg2, boolean arg3, boolean arg4, int arg5, boolean arg6) {

        PseudoCodeNode node = (PseudoCodeNode) value;
        int width = 10;
        if( !node.hasSelectedSubnode() && node.isSelected() )
            width += 25;
        if( node.hasBreakPoint() )
            width += 15;
        String line = "" + getLineNumber( (TreeNode) value );
        width += tree.getFontMetrics( this.getFont() ).stringWidth( line );
        this.setPreferredSize( new Dimension( width + tree.getFontMetrics( this.getFont() ).stringWidth( (String)node.getUserObject() ) + 5, 30 ) );
        this.setSize( new Dimension( width + tree.getFontMetrics( this.getFont() ).stringWidth( (String)node.getUserObject() ) + 5, 30 ) );
        this.doLayout();
        BufferedImage rowNumerImg = new BufferedImage( width, 30, BufferedImage.TYPE_INT_ARGB );
        Graphics2D g = (Graphics2D) rowNumerImg.getGraphics();
        int x = 5;
        if( !node.hasSelectedSubnode() && node.isSelected() )
        {
        	g.drawImage( currentLine.getImage(), x, 5, 20, 20, null );
        	x += 25;
        }
        g.setColor( RenderHelper.CURRENT_LINE_COLOR );
        g.drawString( line, x, 20 );
        x += g.getFontMetrics().stringWidth( line ) + 5;
        if( node.hasBreakPoint() )
        {
            g.setColor( new Color (0xe7887a) );
            g.fillOval(x, 10, 10, 10 );
        }
        g.dispose();
        this.setClosedIcon( new ImageIcon( rowNumerImg ) );
        this.setOpenIcon( new ImageIcon( rowNumerImg ) );
        this.setLeafIcon( new ImageIcon( rowNumerImg ) );
        super.getTreeCellRendererComponent(tree, value, arg2, arg3, arg4, arg5, arg6);
        specialColor = null;
        if(node.isSelected()) {
            specialColor = new Color(0x2d6099);
        } else if (node.hasBreakPoint()) {
            specialColor = RenderHelper.BREAKPOINT_COLOR;
        }
        setText((String)node.getUserObject());
        return this;
    }

}
