/**
 * Copyright (c) Artenum SARL 2004-2005
 * @author Sebastien Jourdain
 *
 * All rights reserved. This software can
 * not be used or copy or diffused without
 * an explicit license of Artenum SARL, Paris-France
 */
package com.artenum.cassandra.pipeline.graph;

import com.artenum.cassandra.pipeline.CassandraObject;

import vtk.vtkLookupTable;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.geom.Rectangle2D;

import java.net.URL;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

/**
 * @author Sebastien Jourdain, Artenum SARL
 * @author Julien Forest, Artenum SARL
 */
public class VtkObjectUI2 extends JLabel implements VtkObjectUI {
    private CassandraObject object;
    /**
     * dimension of the cell in the pipeline manager.
     */
    protected final Dimension size = new Dimension(59, 66);
    /** Position of the Icon corresponding to the Cell. */
    protected Point position;
    protected String txt;
    protected ImageIcon glassIcon;
    protected ImageIcon glassIcon2;
    protected ImageIcon icon;
    protected int leftMarging = 0;
    protected Font iconTextFont;
    
    /**
     * padding in the graphical representation of the pipeline manager
     */
    private final int deltaX = 75;
	private final int deltaY = 60;
	
    /**
	 * @return deltaX, the horizontal cell padding.
	 */
	public int getDeltaX() {
		return deltaX;
	}

	/**
	 * @return deltaY, the vertical cell padding.
	 */
	public int getDeltaY() {
		return deltaY;
	}

	/**
	 * Build a cell rendering for the Cassandra object given in argument and set its
	 * automatically its default position for a later rendering. 
	 * <BR>
	 * By default, the cells are disposed in 7 columns, one for each type of cell 
	 * (i.e Actor, Mapper, DataSet, Filter, LookupTable, ScalarBar, TextActor). 
	 * By default the vertical position of the cell is defined column by column on the 
	 * basis of the LocalTypeId of the given Cassandra object multiplied by the
	 * vertical padding. 
	 * <BR>
	 * NB: For this reason, we recommend that each CassandraObject has a unique LocalTypeId
	 * in order to avoid to be positioned on the same place than another cell by default. 
	 * @param object
	 */
    public VtkObjectUI2(CassandraObject object) {
        this.object = object;
        position = new Point(10, 10);

        // font of the text below each icon and used to display the name
        iconTextFont = new java.awt.Font("Lucida Grande", 0, 10);
        
        // because if the cell size is too small the text cannot be print
        txt = object.getName();
        setToolTipText(txt);
        if (txt.length() > 8) {
            txt = txt.substring(0, 8);
            txt += "...";
        }

        //System.out.println("DEBUG - In VtkObjectUI2, object type: " + object.getType());
        //System.out.println("DEBUG - In VtkObjectUI2, object LocalTypeId().intValue(): " + object.getLocalTypeId().intValue() ) ;
        //System.out.println("DEBUG - Position before: " + position.x + ", " + position.y);
        
        switch (object.getType()) {
        case CassandraObject.ACTOR:
            icon = createImageIcon("icon/actor.png", "Actor");
            glassIcon = createImageIcon("icon/actorEye.png", "Visible");
            position.x = deltaX * (leftMarging+3);
            position.y += ((object.getLocalTypeId().intValue() - 1) * deltaY);
            break;
        case CassandraObject.MAPPER:
            icon = createImageIcon("icon/mapper.png", "Mapper");
            txt = "";
            position.x = deltaX * (leftMarging+2);
            position.y += ((object.getLocalTypeId().intValue() - 1) * deltaY);
            break;
        case CassandraObject.DATASET:
            icon = createImageIcon("icon/dataset.png", "DataSet");
            position.x = deltaX * (leftMarging+1);
            position.y += ((object.getLocalTypeId().intValue() - 1) * deltaY);
            break;
        case CassandraObject.FILTER:
            icon = createImageIcon("icon/filter.png", "Filter");
            position.x = deltaX * leftMarging;
            position.y += ((object.getLocalTypeId().intValue() - 1) * deltaY);
            break;
        case CassandraObject.LOOKUP_TABLE:
            icon = createImageIcon("icon/lookuptable.png", "Lookup Table");
            glassIcon = createImageIcon("icon/linearLT.png", "Lookup Table");
            glassIcon2 = createImageIcon("icon/logLT.png", "Lookup Table");
            position.x = deltaX * (leftMarging+4);
            position.y += ((object.getLocalTypeId().intValue() - 1) * deltaY);
            break;
        case CassandraObject.SCALAR_BAR:
            icon = createImageIcon("icon/scalarBar.png", "ScalarBar");
            glassIcon = createImageIcon("icon/actorEye.png", "Visible");
            position.x = deltaX * (leftMarging+5);
            position.y += ((object.getLocalTypeId().intValue() - 1) * deltaY);
            break;
        case CassandraObject.TXT_ACTOR:
            icon = createImageIcon("icon/txtActor.png", "Text actor");
            glassIcon = createImageIcon("icon/txtActorEye.png", "Visible");
            position.x = deltaX * (leftMarging+6);
            position.y += ((object.getLocalTypeId().intValue() - 1) * deltaY);
            break;
        }

        //System.out.println("DEBUG - Position after: " + position.x + ", " + position.y);
        setIcon(icon);
    }

    /**
     * Set the name (and displayed label) of the current cell. 
     */
    public void setName(String newName) {
        txt = newName;
        repaint();
    }

    protected static ImageIcon createImageIcon(String path, String description) {
        URL imgURL = VtkObjectCellAdapter.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + imgURL);
            return null;
        }
    }

    /**
     * save the position of the current cell. 
     */
    public void savePosition() {
        position = getLocation();
        if (position.x < 0) {
            position.x = 0;
        }

        if (position.y < 0) {
            position.y = 0;
        }

        setLocation(position);
    }

    public void setPosition(Point p) {
        position = p;
        if (position.x < 0) {
            position.x = 0;
        }

        if (position.y < 0) {
            position.y = 0;
        }

        setLocation(position);
    }

    public Point getPosition() {
        return position;
    }

    public Dimension getSize() {
        return size;
    }

    public void paint(Graphics g) {
        super.paint(g);
        //g.drawImage(icon.getImage(), 0, 0, icon.getImageObserver());
        if (((object.getType() == CassandraObject.ACTOR) || (object.getType() == CassandraObject.SCALAR_BAR) || (object.getType() == CassandraObject.TXT_ACTOR)) &&
                (object.getMetaData().get(CassandraObject.ACTOR_VISIBLE) != null)) {
            if (((String) object.getMetaData().get(CassandraObject.ACTOR_VISIBLE)).equals("true")) {
                g.drawImage(glassIcon.getImage(), 0, 0, glassIcon.getImageObserver());
            }
        } else if (object.getType() == CassandraObject.LOOKUP_TABLE) {
            if (((vtkLookupTable) object.getVtkObject()).GetScale() == 0) {
                g.drawImage(glassIcon.getImage(), 0, 0, glassIcon.getImageObserver());
            } else {
                g.drawImage(glassIcon2.getImage(), 0, 0, glassIcon2.getImageObserver());
            }
        }

        // write txt below the icon
        Rectangle2D txtR = g.getFontMetrics().getStringBounds(txt, g);
        
        //to see something when icons are small
        g.setFont(iconTextFont);
        
        // cell width * (icon size - 5)
        int dx = (int) (size.getWidth() - txtR.getWidth()) / 2;
        if (dx < 0){
        	dx = 0;
        }
        g.drawString(txt, dx, 50);
    }
}
