package View;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import javax.swing.*;
import javax.swing.border.Border;

import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
import Model.LayeredGraphNode;

/**
 * A drawable representation of a node.
 * @author kolja
 *
 */
public class NodeView extends JPanel {
	private static final long serialVersionUID = 1L;
	private LayeredGraphNode model;
	private LayoutType layout;
	
	public NodeView( LayeredGraphNode model, LayoutType lt ) {
		this.model = model;
		layout = lt;
		setSize( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
	}
	
	@Override
	public Point getLocation()
	{
	    return new Point( (int)model.getX( layout ), (int)model.getY( layout ) );
	}
    
    @Override
    public Dimension getPreferredSize()
    {
    	return new Dimension( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
    }
    
    @Override
    public void paint( Graphics g )
    {
    	if( layout == LayoutType.COMBINED && model.getColor( layout ) == null )
    		return;
        double scale = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
        ((Graphics2D)g).scale( scale, scale );
        paintComponent( g );
        double minX = Double.POSITIVE_INFINITY;
        for( Component c : getComponents() )
        {
            minX = Math.min( c.getLocation().x, minX);
        }
        for( Component c : getComponents() )
        {
            if( c.getLocation().x < 0 )
                System.out.println( "x: " + c.getLocation().x + " y: " + c.getLocation().y );
            c.paint( g.create( 
                    c.getLocation().x + 25 - (int)minX, 
                    c.getLocation().y + 25, 
                    Math.min( (int)model.getWidth( layout ) - 25, c.getPreferredSize().width + Math.abs(c.getLocation().x) + 25 ), 
                    Math.min( (int)model.getHeight( layout ) - 25, c.getPreferredSize().height + Math.abs(c.getLocation().y) + 25 ) ) );
        }
    }

	@Override
	public void paintComponent( Graphics g )
	{
		Graphics2D g2 = (Graphics2D)g;
		g2.setColor( model.getColor( layout ) );
		g2.setStroke(new BasicStroke(5));
		if( model.getContainedNodes().size() == 0 )
		{
			if( model.getRoot( layout ) == model )
				g2.fillOval( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
			else
				g2.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
		}
		if( model.isSelected( layout ) )
		{
			g.setColor( Color.GRAY );
			g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
		}
		Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
		if( model.getRoot( layout ) != model || model.getContainedNodes().size() != 0  )
			linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
		if( layout != LayoutType.COMBINED && model.getRoot( layout ).getSink( layout ).getColor( layout ) != model.getColor( layout ))
		{
    		g.setColor( model.getRoot( layout ).getSink( layout ).getColor( layout ) );
    		if( model.getContainedNodes().size() == 0 )
    		    g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 3, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 3, (int)model.getWidth( layout ) / 3 * 2, (int)model.getHeight( layout ) / 3 * 2 );
		}
	}
}
