
import com.sun.glf.demos.*;

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.font.*;
import java.awt.color.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;

import com.sun.glf.*;
import com.sun.glf.util.*;
import com.sun.glf.goodies.*;


public class BacklitGlowMenuComposition {
  String menuLabels = "Scienza \n    dei \n Media";

  File imageFile = new File("type01fl.jpg");

  File imageMaskFile = new File("type01fl_mask.jpg");

  File backgroundImageFile = new File("syberia30.jpg");

  Color backlitColor = Color.orange;

  Dimension margins = new Dimension(30,30);

  int menuImageGap = 30;

  Font menuLabelsFont = new Font("Impact MT", Font.PLAIN, 80);

  TextAlignment menuLabelsAlignment = TextAlignment.LEFT;

  int backlitRadius = 20;

  float menuLabelsScale = 1.1f;

  float glowScale = 6.0f;

  Color textureMaskColor = Color.black;




  public Composition build(){
    //
    // First, load images
    //
    BufferedImage backgroundImage = Toolbox.loadImage(backgroundImageFile, BufferedImage.TYPE_INT_ARGB_PRE);
    if(backgroundImage==null)
      throw new Error("Could not load : " + backgroundImageFile);

    BufferedImage image = Toolbox.loadImage(imageFile, BufferedImage.TYPE_INT_ARGB_PRE);
    if(image==null)
      throw new Error("Could not load : " + imageFile);

    BufferedImage imageMask = Toolbox.loadImage(imageMaskFile, BufferedImage.TYPE_INT_ARGB_PRE);
    if(imageMask==null)
      throw new Error("Could not load : " + imageMaskFile);

    //
    // Build a text block with all the menu items
    //
    int doNotWrap = -1;
    Shape textBlock = TextLayer.makeTextBlock(menuLabels, menuLabelsFont, doNotWrap, menuLabelsAlignment);

    //
    // Compute Composition size based on the base elements
    //
    Rectangle textBlockBounds = textBlock.getBounds();
    Dimension size = new Dimension();
    size.width = (int)Math.max(textBlockBounds.width, image.getWidth()) + 2*margins.width;
    size.height = textBlockBounds.height + menuImageGap + image.getHeight() + 2*margins.height;
    LayerComposition cmp = new LayerComposition(size);

    //
    // Fit background image to composition size
    //
    if(backgroundImage.getWidth()>size.width)
      backgroundImage = backgroundImage.getSubimage(0, 0, size.width, backgroundImage.getHeight());
    if(backgroundImage.getHeight()>size.height)
      backgroundImage = backgroundImage.getSubimage(0, 0, backgroundImage.getWidth(), size.height);

    AffineTransform backgroundScale = AffineTransform.getScaleInstance(size.width/(float)backgroundImage.getWidth(),
								       size.height/(float)backgroundImage.getHeight());
    AffineTransformOp backgroundScaler = new AffineTransformOp(backgroundScale, AffineTransformOp.TYPE_BILINEAR);
    backgroundImage = backgroundScaler.filter(backgroundImage, null);

    // Create texture paint with background image
    TexturePaint texturePaint = new TexturePaint(backgroundImage,
						 cmp.getBounds());

    //
    // Position text in composition
    //
    Position menuPosition = new Position(Anchor.TOP, 0, margins.height);
    textBlock = menuPosition.createTransformedShape(textBlock, cmp.getBounds());

    //
    // Create background layer
    //
    // ImageLayer backgroundLayer = new ImageLayer(cmp, backgroundImage);
    cmp.setBackgroundPaint(texturePaint);

    //
    // Create text backlit glow
    //
    FillRenderer glowRenderer = new FillRenderer(backlitColor);
    ShapeLayer backlitTextLayer = new ShapeLayer(cmp, textBlock, glowRenderer);

    // Create blur
    boolean useScaleTxf = (backlitRadius>12);
    float blurScale = 12f/backlitRadius;

    Dimension blurMargins = new Dimension(backlitRadius*2,
					  backlitRadius*2);

    if(useScaleTxf)
      backlitRadius = 12;

    GaussianKernel blurKernel = new GaussianKernel(backlitRadius);
    ConvolveOp blur = new ConvolveOp(blurKernel);

    RescaleOp alphaScale
      = new RescaleOp(
		      new float[]{glowScale, glowScale, glowScale, glowScale},
		      new float[]{0, 0, 0, 0},
		      null
		      );

    CompositeOp glowFilter = null;

    if(useScaleTxf){
      AffineTransform shrinkGlowTxf
	= AffineTransform.getScaleInstance(blurScale,
					   blurScale);
      AffineTransform blowUpGlowTxf
	= AffineTransform.getScaleInstance(1/blurScale,
					   1/blurScale);

      AffineTransformOp shrinkGlow
	= new AffineTransformOp(shrinkGlowTxf, null);
      AffineTransformOp blowUpGlow
	= new AffineTransformOp(blowUpGlowTxf, AffineTransformOp.TYPE_BILINEAR);

      glowFilter = new CompositeOp(new BufferedImageOp[]{shrinkGlow, blur, blowUpGlow, alphaScale});
    }
    else{
      glowFilter = new CompositeOp(blur, alphaScale);
    }

    backlitTextLayer.setImageFilter(glowFilter, blurMargins);

    //
    // Create adjusted text menu labels
    //
    ShapeLayer menuLabelsLayer = new ShapeLayer(cmp, textBlock, new FillRenderer(texturePaint));
    RescaleOp brightener
      = new RescaleOp(
		      new float[]{menuLabelsScale, menuLabelsScale, menuLabelsScale, 1},
		      new float[]{0, 0, 0, 0}, null);

    menuLabelsLayer.setImageFilter(brightener);

    //
    // Create image layer
    //
    Position imagePosition = new Position(Anchor.BOTTOM, 0, margins.height);
    ImageLayer imageLayer = new ImageLayer(cmp, image, imagePosition);

    // Set mask
    Point imageLeftCorner = new Point(0, 0);
    imageLayer.getTransform().transform(imageLeftCorner, imageLeftCorner);
    Rectangle imageRect = new Rectangle(imageLeftCorner.x, imageLeftCorner.y,
					imageMask.getWidth(), imageMask.getHeight());
    imageLayer.setLayerMask(imageMask, imageRect);

    //
    // Create image glow
    //
    BufferedImage imageGlow = new BufferedImage(imageMask.getWidth(), imageMask.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
    Graphics2D g = imageGlow.createGraphics();
    g.drawImage(imageLayer.getLayerMask(), 0, 0, null);
    g.setComposite(AlphaComposite.SrcIn);
    g.setPaint(backlitColor);
    g.fillRect(0, 0, imageMask.getWidth(), imageMask.getHeight());

    ImageLayer backlitImageLayer = new ImageLayer(cmp, imageGlow, imagePosition);
    backlitImageLayer.setImageFilter(glowFilter, blurMargins);

    //
    // Stack up layers



    cmp.setLayers(new Layer[]{ backlitTextLayer,
				 menuLabelsLayer,
				 backlitImageLayer,
				 imageLayer });
    cmp.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			 RenderingHints.VALUE_ANTIALIAS_ON);
    return cmp;
  }
  public static void main(String args[]){
  	BacklitGlowMenuComposition lpc = new BacklitGlowMenuComposition();
  	CompositionFrame cf = new CompositionFrame("Scolpire con la luce");
  	cf.setComposition(lpc.build());
  	cf.setVisible(true);
       }
 }

