/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package image.loader;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;

import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.DefaultImageContext;
import org.apache.xmlgraphics.image.loader.impl.DefaultImageSessionContext;
import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;

/**
 * Very simple image viewer application that demonstrates the use of the image loader framework.
 */
public class ImageViewer {

    private ImageManager imageManager;
    
    public ImageViewer() {
        //The ImageManager is set up for the whole application
        this.imageManager = new ImageManager(new DefaultImageContext());
    }
    
    public void display(File f) throws IOException {
        //The ImageSessionContext might for each processing run
        ImageSessionContext sessionContext = new DefaultImageSessionContext(
                this.imageManager.getImageContext(), null);
        
        //Construct URI from filename
        String uri = f.toURI().toASCIIString();
        
        ImageGraphics2D g2dImage = null;
        try {
            //Preload image
            ImageInfo info = this.imageManager.getImageInfo(uri, sessionContext);
            
            //Load image and request Graphics2D image
            g2dImage = (ImageGraphics2D)this.imageManager.getImage(
                    info, ImageFlavor.GRAPHICS2D, sessionContext);
            
        } catch (ImageException e) {
            e.printStackTrace();
            
            //Create "error image" if the image cannot be displayed
            g2dImage = createErrorImage();
        }
        
        //Display frame with image
        ViewerFrame frame = new ViewerFrame(g2dImage);
        frame.setVisible(true);
    }

    private ImageGraphics2D createErrorImage() {
        Graphics2DImagePainter painter = new Graphics2DImagePainter() {

            public Dimension getImageSize() {
                return new Dimension(10, 10);
            }

            public void paint(Graphics2D g2d, Rectangle2D area) {
                g2d.translate(area.getX(), area.getY());
                double w = area.getWidth();
                double h = area.getHeight();

                //Fit in paint area
                Dimension imageSize = getImageSize();
                double sx = w / imageSize.getWidth();
                double sy = h / imageSize.getHeight();
                if (sx != 1.0 || sy != 1.0) {
                    g2d.scale(sx, sy);
                }

                g2d.setColor(Color.RED);
                g2d.setStroke(new BasicStroke(0));
                g2d.drawRect(0, 0, imageSize.width, imageSize.height);
                g2d.drawLine(0, 0, imageSize.width, imageSize.height);
                g2d.drawLine(0, imageSize.height, imageSize.width, 0);
            }
            
        };
        Dimension dim = painter.getImageSize();
        
        ImageSize size = new ImageSize();
        size.setSizeInMillipoints(dim.width, dim.height);
        size.setResolution(imageManager.getImageContext().getSourceResolution());
        size.calcPixelsFromSize();
        
        ImageInfo info = new ImageInfo(null, null);
        info.setSize(size);
        return new ImageGraphics2D(info, painter);
    }
    
    /**
     * The application's main method.
     * @param args the command-line arguments
     */
    public static void main(String[] args) {
        try {
            ImageViewer app = new ImageViewer();
            if (args.length < 1) {
                throw new IllegalArgumentException("No filename given as application argument");
            }
            app.display(new File(args[0]));
        } catch (Throwable t) {
            t.printStackTrace();
            System.exit(-1);
        }
    }

}
