// Copyright 1996, Marimba Inc. All Rights Reserved.


// @(#)ImageWidget.java, 1.35, 12/13/96





package marimba.gui;





import java.awt.*;





import marimba.persist.*;





/**


 * A widget that displays an image.


 *


 * @author	Arthur van Hoff


 * @version 	1.35, 12/13/96


 */


public class ImageWidget extends ResourceWidget {


    /**


     * The possible options for the mode.


     * @see #getModeOptions


     * @see #mode


     */


    public static Options  modeOptions = new Options();


    static {


	modeOptions.add("center", CENTER);


	modeOptions.add("scale", SCALE);


	modeOptions.add("proportional", PROPORTIONAL);


	modeOptions.add("topleft", TOPLEFT);


    }





    /**


     * The image displayed by this widget.


     * @see #getImageValue


     * @see #setValue


     */


    public Image  img;





    /**


     * An imageWidget can display its image centered, scaled or topleft.


     * @see #getMode


     * @see #setMode


     * @see #modeOptions


     */


    public int  mode = CENTER;





    /**


     * Constructor


     */


    public ImageWidget() {


	src = "~builder/archiv.gif";


    }





    /**


     * Get the properties of this widget.


     */


    public void getProperties(PropertyList list) {


	super.getProperties(list);


	list.setOption("mode", modeOptions, mode, CENTER);


    }





    /**


     * Set the properties of this widget.


     */


    public void setProperties(PropertyList list) {


	super.setProperties(list);


	mode = list.getOption("mode", modeOptions, CENTER);


	img = null;


    }





    /**


     * Get the possible options for the mode.


     * @see #modeOptions


     */


    public Options getModeOptions() {


	return modeOptions;


    }





    /**


     * Get the current mode.


     * @see #mode


     */


    public int getMode() {


	return mode;


    }





    /**


     * Set the current mode to center, scale or topleft.


     * @see #mode


     */


    public void setMode(int mode) {


	if (mode==CENTER || mode==SCALE || mode==PROPORTIONAL || mode==TOPLEFT) {


	    this.mode = mode;


	    repaint();


	}


    }





    /**


     * Get the current image resource string.


     * @see #img


     * @see #getStringValue


     * @see #getValue


     */


    public Image getImageValue() {


	return img;


    }





    /**


     * Get the current image resource string.


     * @see #img


     */


    public String getStringValue() {


	return src;


    }





    /**


     * Get the current image resource string.


     * @see #img


     */


    public Object getValue() {


	return getStringValue();


    }





    /**


     * Set the image, by specifying the source location or by


     * giving it an image object directly, in which case the


     * source location does not match the image anymore, unless


     * you do that manually.


     * @see #img


     */


    public void setValue(Object value) {


	if (value instanceof String) {


	    setValue((String)value);


	} else if (value instanceof Image) {


	    this.img = (Image)value;


	} else if (value == null) {


	    setValue((String)null);


	}


    }


    


    /**


     * Set the image.


     * @see #img


     */


    public void setValue(String value) {


	src = value;


	img = null;


	if (isShowing()) {


	    start();


	}


    }





    /**


     * Flush the image from the cache.


     */


    public void flush() {


	Presentation p = getPresentation();


	if (p != null) {


	    ImageCache.flush(p.getURL(src));


	    img = null;


	    if (isShowing()) {


		start();


	    }


	}


    }





    /**


     * Start loading the image if preload is set.


     */


    public void init() {


	if (preload) {


	    start();


	}


    }





    /**


     * Start loading the image.


     */


    public void start() {


	if ((img == null) && (src != null)) {


	    Image newimg = getImage(src);


	    switch (mode) {


	      case SCALE:


	      case PROPORTIONAL:


		if (Toolkit.getDefaultToolkit().prepareImage(newimg, width, height, this)) {


		    img = newimg;


		    repaint();


		}


		break;


	      default:


		if (Toolkit.getDefaultToolkit().prepareImage(newimg, -1, -1, this)) {


		    img = newimg;


		    repaint();


		}


	    }


	}


    }





    /**


     * Update the image.


     */


    public boolean imageUpdate(Image newimg, int flags, int x, int y, int w, int h) {


	if ((flags & ALLBITS) != 0) {


	    img = newimg;


	    repaint();


	    return false;


	}


	return (flags & ERROR) == 0;


    }





    /**


     * Paint the image.


     */


    public void paint(Graphics g) {


	if (img != null) {


	    switch (mode) {


	      case SCALE:


		g.drawImage(img, 0, 0, width, height, this);


		break;





	      case PROPORTIONAL:


		int  imgWidth = img.getWidth(null);


		int  imgHeight = img.getHeight(null);


		if ((width-imgWidth) < (height-imgHeight)) {


		    g.drawImage(img, 0, 0, width, (imgHeight*width)/imgWidth, this);


		} else {


		    g.drawImage(img, 0, 0, (imgWidth*height)/imgHeight, height, this);


		}


		break;





	      case CENTER:


		int w = img.getWidth(this);


		int h = img.getHeight(this);


		if ((w > 0) && (h > 0)) {


		    g.drawImage(img, (width - w) / 2 , (height - h) / 2, this);


		}


		break;





	      default:


		g.drawImage(img, 0, 0, this);


		break;


	    }


	}


    }   





    /**


     * Handle mouse events.


     */


    public boolean handleEvent(Event evt) {


	switch (evt.id) {


	  case Event.MOUSE_DOWN:


	    if ((evt.x >= 0) && (evt.x < width) && (evt.y >= 0) && (evt.y < height)) {


		action(evt.x, evt.y);


	    }


	    break;


	}


	return super.handleEvent(evt);


    }





    /**


     * The user has clicked in the image.


     */


    public void action(int x, int y) {


	postEvent(new Event(this, Event.ACTION_EVENT, new Point(x, y)));


    }





    /**


     * Debugging.


     */


    public void paramString(StringBuffer buf) {


	super.paramString(buf);


	buf.append(",mode=");


	buf.append(modeOptions.get(mode));


    }


}


