package view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;

import javax.swing.JPanel;

import bk.LayoutType;
import graph.LayeredGraphEdge;

/**
 * A drawable representation of an edge.
 * @author kolja
 *
 */
public class EdgeView extends JPanel implements AnnimatedView {
    private static final long serialVersionUID = 1L;

    private LayeredGraphEdge model;
    private LayoutType layout;
    
    public EdgeView( LayeredGraphEdge model, LayoutType lt ) {
        this.model = model;
        layout = lt;
    }
    
    @Override
    public void paint( Graphics g )
    {
        paintComponent( g );
    }
    
    private int getScaledX( int x )
    {
        double scale = Math.min( getWidth() / (double)getVirtualWidth(), getHeight() / (double)getVirtualHeight());
        x *= scale;
        return x;
    }
    
    private int getScaledY( int y )
    {
        double scale = Math.min( getWidth() / (double)getVirtualWidth(), getHeight() / (double)getVirtualHeight());
        y *= scale;
        return y;
    }

    @Override
    public void paintComponent( Graphics g )
    {
        ((Graphics2D)g).setStroke(new BasicStroke(1));
        g.setColor( Color.LIGHT_GRAY );
        if( model.isConflicted( layout ) )
            g.setColor( Color.RED );
        ArrayList<Point> bps = model.getLinePoints( layout );
        int x = getVirtualX();
        int y = getVirtualY();
        for( int i = 1; i < bps.size(); i++ )
        {
            g.drawLine( getScaledX((int)bps.get( i - 1 ).getX() - x), getScaledY((int)bps.get( i - 1 ).getY() - y), getScaledX((int)bps.get( i ).getX() - x), getScaledY((int)bps.get( i ).getY() - y ));
        }
        ((Graphics2D)g).fill( RenderHelper.createArrowShape( new Point( getScaledX( bps.get( 0 ).x - x ), getScaledY( bps.get( 0 ).y - y ) ), new Point( getScaledX( bps.get( bps.size() - 1 ).x - x ), getScaledY( bps.get( bps.size() - 1 ).y - y ) ) ) );
    }

    @Override
    public int getVirtualX() {
        int min = Integer.MAX_VALUE;
        ArrayList<Point> bps = model.getLinePoints( layout );
        for( Point p : bps )
            min = Math.min( min, (int)p.getX() - 5 );
        return min;
    }

    @Override
    public int getVirtualY() {
        int min = Integer.MAX_VALUE;
        ArrayList<Point> bps = model.getLinePoints( layout );
        for( Point p : bps )
            min = Math.min( min, (int)p.getY() - 5 );
        return min;
    }

    @Override
    public int getVirtualWidth() {
        int max = Integer.MIN_VALUE;
        ArrayList<Point> bps = model.getLinePoints( layout );
        for( Point p : bps )
            max = Math.max( max, (int)p.getX() + 5 );
        return max - getVirtualX();
    }

    @Override
    public int getVirtualHeight() {
        int max = Integer.MIN_VALUE;
        ArrayList<Point> bps = model.getLinePoints( layout );
        for( Point p : bps )
            max = Math.max( max, (int)p.getY() + 5 );
        return max - getVirtualY();
    }
}
