import se.datadosen.jalbum.*;

import java.awt.*;
import java.awt.image.BufferedImage;

import java.util.*;

/**
 * JAlbum filter that makes sure that all images/thumbnails get the same shape
 * as specified by image size or thumbnail size. The effect is accomplished by cropping.
 * Always use with "prescale" attribute
 * @author David Ekholm, Datadosen 2003
 * @version 1.0
 */
public class FixedShapeFilter implements JAFilter, ModifiesSize {
    public String getName() {
        return "Fixed shape filter";
    }

    // Implements JAFilter
    public String getDescription() {
        return "Makes all images the same fixed shape set by the user interface by cropping them if needed";
    }

    // Implements JAFilter
    public BufferedImage filter(BufferedImage bi, java.util.Map vars) {
        Dimension sDim = new Dimension(bi.getWidth(), bi.getHeight());

        AlbumBean engine = (AlbumBean)vars.get("engine");
        int stage = (vars.get("stage") != null) ? ((Integer)vars.get("stage")).intValue() : 4;
        Dimension dDim = (stage >= 4) ? parseSize(engine.getThumbSize())
                                      : parseSize(engine.getImageSize());

        double sAspekt = ((double)sDim.width) / sDim.height;
        double dAspekt = ((double)dDim.width) / dDim.height;

        if (sAspekt > dAspekt) { // Crop image to the left and right to fit

            int newWidth = (int)(dAspekt * sDim.height);

            return bi.getSubimage((sDim.width - newWidth) / 2, 0, newWidth, sDim.height);
        } else if (sAspekt < dAspekt) { // Crop image to the top and bottom to fit

            int newHeight = (int)(sDim.width / dAspekt);

            return bi.getSubimage(0, (sDim.height - newHeight) / 6, sDim.width, newHeight);
        } else {
            return bi; // Already right shape
        }
    }

    private Dimension parseSize(String sizeString) {
        String size = sizeString.toLowerCase();
        StringTokenizer tokens = new StringTokenizer(size, "x ");
        int w;
        int h;
        w = Integer.parseInt(tokens.nextToken());
        h = Integer.parseInt(tokens.nextToken());

        return new Dimension(w, h);
    }

    // Implements ModifiesSize
    public Dimension getModifiedSize(Dimension originalSize, Map vars) {
        AlbumBean engine = (AlbumBean)vars.get("engine");
        int stage = (vars.get("stage") != null) ? ((Integer)vars.get("stage")).intValue() : 4;

        return (stage >= 4) ? parseSize(engine.getThumbSize()) : parseSize(engine.getImageSize());
    }
}
