/*
 *  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.
 */
/*
 * Caricature.java
 *
 * Created on April 8, 2006, 4:09 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package groovy.swing.binding.caricature;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

/**
 *
 * @author sky
 */
public class JCaricature extends JPanel {
    private Map/*<String,Image>*/ imageMap;
    
    private boolean empty;
    private int mouthStyle;
    private int faceStyle;
    private int hairStyle;
    private int eyeStyle;
    private int noseStyle;
    private int rotation;
    private float scale = 1.0f;
    
    public JCaricature() {
        if (imageMap == null) {
            imageMap = new HashMap/*<String,Image>*/(1);
            for (int i = 0; i < 5; i++) {
                getImage("face", i);
                getImage("hair", i);
                getImage("eyes", i);
                getImage("nose", i);
                getImage("mouth", i);
            }
        }
    }
    
    public void setEmpty(boolean empty) {
        if (this.empty != empty) {
            this.empty = empty;
            firePropertyChange("empty", !empty, empty);
            repaint();
        }
    }
    
    public boolean isEmpty() {
        return empty;
    }
    
    public void setRotation(int rotation) {
        int oldRotation = this.rotation;
        this.rotation = rotation;
        repaint();
        firePropertyChange("rotation", oldRotation, rotation);
    }
    
    public int getRotation() {
        return rotation;
    }
    
    public void setScale(float scale) {
        float oldScale = this.scale;
        this.scale = scale;
        repaint();
        firePropertyChange("scale", oldScale, scale);
    }
    
    public float getScale() {
        return scale;
    }
    
    public void setMouthStyle(int style) {
        int oldStyle = mouthStyle;
        mouthStyle = style;
        firePropertyChange("mouthStyle", oldStyle, style);
        repaint();
    }
    
    public int getMouthStyle() {
        return mouthStyle;
    }
    
    public void setFaceStyle(int style) {
        int oldStyle = faceStyle;
        faceStyle = style;
        firePropertyChange("faceStyle", oldStyle, style);
        repaint();
    }
    
    public int getFaceStyle() {
        return faceStyle;
    }
    
    public void setHairStyle(int style) {
        int oldStyle = hairStyle;
        hairStyle = style;
        firePropertyChange("hairStyle", oldStyle, style);
        repaint();
    }
    
    public int getHairStyle() {
        return hairStyle;
    }
    
    public void setEyeStyle(int style) {
        int oldStyle = eyeStyle;
        eyeStyle = style;
        firePropertyChange("eyeStyle", oldStyle, style);
        repaint();
    }
    
    public int getEyeStyle() {
        return eyeStyle;
    }
    
    public void setNoseStyle(int style) {
        int oldStyle = noseStyle;
        noseStyle = style;
        firePropertyChange("noseStyle", oldStyle, style);
        repaint();
    }
    
    public int getNoseStyle() {
        return noseStyle;
    }
    
    public Dimension getPreferredSize() {
        if (!isPreferredSizeSet()) {
            Image image = getImage("mouth", 0);
            return new Dimension(image.getWidth(null), image.getHeight(null));
        }
        return super.getPreferredSize();
    }
    
    public Dimension getMaximumSize() {
        if (!isMaximumSizeSet()) {
            return getPreferredSize();
        }
        return super.getMaximumSize();
    }
    
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (empty) {
            return;
        }
        Graphics2D g2 = (Graphics2D)g.create();
        Image image = getImage("face", getFaceStyle());
        int iw = image.getWidth(null);
        int ih = image.getHeight(null);
//        g2.translate(iw / 2, ih / 2);
        g2.translate(getWidth() / 2, getHeight() / 2);
        if (iw != getWidth()) {
            float forcedScale = (float)getWidth() / (float)iw;
            g2.scale(forcedScale, forcedScale);
        }
        float scale = getScale();
        if (scale != 1) {
            g2.scale((double)scale, (double)scale);
        }
        int rotation = getRotation();
        if (rotation != 0) {
            g2.rotate(Math.toRadians(rotation));
        }
        drawImage(g2, "face", getFaceStyle());
        drawImage(g2, "hair", getHairStyle());
        drawImage(g2, "eyes", getEyeStyle());
        drawImage(g2, "nose", getNoseStyle());
        drawImage(g2, "mouth", getMouthStyle());
        g2.dispose();
    }

    private void drawImage(Graphics g, String string, int i) {
        Image image = getImage(string, i);
        g.drawImage(image, -image.getWidth(null) / 2, -image.getHeight(null) / 2, null);
    }

    private Image getImage(String key, int style) {
        String imageName = key + (style + 1) + ".gif";
        Image image = (Image) imageMap.get(imageName);
        if (image == null) {
            System.err.println("name=" + imageName);
            URL imageLoc = getClass().getResource("resources/" + imageName);
            image = new ImageIcon(imageLoc).getImage();
            imageMap.put(imageName, image);
        }
        return image;
    }
}
