
/*
 * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
 * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
 * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that Software is not designed,licensed or intended
 * for use in the design, construction, operation or maintenance of
 * any nuclear facility.
 */

// adapted from Text2D in package com.sun.j3d.utils.geometry;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.awt.image.DataBufferInt;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.util.Hashtable;

import javax.media.j3d.*;
import javax.vecmath.*;


/**
 * This class creates a Raster that displays the
 * text string sent in by the user, given the appearance parameters
 * also supplied by the user.  
 */
public class Label3D extends Shape3D {

    // This table caches FontMetrics objects to avoid the huge cost
    // of re-retrieving metrics for a font we've already seen.
    private static Hashtable metricsTable = new Hashtable(); 

    Color3f   color = new Color3f();
    String    fontName;
    int       fontSize, fontStyle;
    Point3f   textPt = new Point3f(); 
    BufferedImage bImage; 	   // the image for the text
    int	      imgWidth, imgHeight; // size of the text image
    int	      imgAscent, imgDescent;// offset above and below height
    int	      texWidth, texHeight; // size of texture holding image

    String text;


    /**
     * Creates a Shape3D object which holds a Raster that has an image that has
     * the specified text written with the specified font parameters.
     *
     * @param text The string to be written into the texture map.
     * @param color The color of the text string.
     * @param fontName The name of the Java font to be used for
     *  the text string.
     * @param fontSize The size of the Java font to be used.
     * @param fontStyle The style of the Java font to be used.
     */
    public Label3D(String text, Point3f textPt, 
		Color3f color, String fontName, int fontSize, int fontStyle) {

	this.textPt.set(textPt);
	this.text = text;
        this.color.set(color);
        this.fontName = fontName;
        this.fontSize = fontSize;
        this.fontStyle = fontStyle;

        updateLabel3D();
    }

    /*
     * Changes text of this Label3D to 'text'. All other
     * parameters (color, fontName, fontSize, fontStyle
     * remain the same.
     * @param text The string to be set.
     */
    public void setString(String text){
	this.text = text;
        updateLabel3D();
    }

    private void updateLabel3D() {

        setupImage(text, color, fontName, fontSize, fontStyle);

	ImageComponent2D imageComponent =
	    new ImageComponent2D(ImageComponent.FORMAT_RGBA, 
				 bImage);

        Raster raster = new Raster(textPt, Raster.RASTER_COLOR, 0, 0, 
		imgWidth, imgHeight, imageComponent,  null);

        Appearance appearance = setupAppearance();

        setGeometry(raster);
        setAppearance(appearance);
    }



    /**
     * Creates a bImage, a BufferedImage of the correct dimensions for the
     * given font attributes.  Draw the given text into the image in
     * the given color.  The background of the image is transparent
     * (alpha = 0). Initializes imgWidth, imgHeight, 
     * the image size for the image.
     */
    private void setupImage(String text, Color3f color,
				     String fontName,
				     int fontSize, int fontStyle) {
	Toolkit toolkit = Toolkit.getDefaultToolkit();
	Font font = new java.awt.Font(fontName, fontStyle, fontSize);

	FontMetrics metrics;
	if ((metrics = (FontMetrics)metricsTable.get(font)) == null) {
	    metrics = toolkit.getFontMetrics(font);
	    metricsTable.put(font, metrics);
	}
	imgDescent = metrics.getMaxDescent();
	imgAscent = metrics.getMaxAscent();

	imgWidth = metrics.stringWidth(text);
	imgHeight = imgDescent + imgAscent;

	// For now, jdk 1.2 only handles ARGB format, not the RGBA we want
	bImage = new BufferedImage(imgWidth, imgHeight,
						 BufferedImage.TYPE_INT_ARGB);
	Graphics offscreenGraphics = bImage.createGraphics();

	// First, erase the background to the text panel - set alpha to 0
	Color myFill = new Color(0f, 0f, 0f, 0f);
	offscreenGraphics.setColor(myFill);
	offscreenGraphics.fillRect(0, 0, imgWidth, imgHeight);

	// Next, set desired text properties (font, color) and draw String
	offscreenGraphics.setFont(font);
	Color myTextColor = new Color(color.x, color.y, color.z, 1f);
	offscreenGraphics.setColor(myTextColor);
	offscreenGraphics.drawString(text, 0, imgHeight - imgDescent);
    }

    /**
     * Creates Appearance for this Shape3D.  
     */
    private Appearance setupAppearance() {
	TransparencyAttributes transp = new TransparencyAttributes();
	transp.setTransparencyMode(TransparencyAttributes.BLENDED);
	transp.setTransparency(0f);
	Appearance appearance = new Appearance();
	appearance.setTransparencyAttributes(transp);

	Material m = new Material();
	m.setLightingEnable(false);
	appearance.setMaterial(m);
	
	return appearance;
    }

    /**
     * Returns the text string
     *
     * @since Java 3D 1.2.1
     */
    public String getString() {
	return text;
    }

    /**
     * Returns the color of the text
     *
     * @since Java 3D 1.2.1
     */
    public Color3f getColor() {
	return color;
    }

    /**
     * Returns the font
     *
     * @since Java 3D 1.2.1
     */
    public String getFontName() {
	return fontName;
    }

    /**
     * Returns the font size
     *
     * @since Java 3D 1.2.1
     */
    public int getFontSize() {
	return fontSize;
    }
    
    /**
     * Returns the font style
     *
     * @since Java 3D 1.2.1
     */
    public int getFontStyle() {
	return fontStyle;
    }
    
}





