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


// @(#)PopupWidget.java, 1.19, 11/07/96





package marimba.gui;





import java.awt.*;





/**


 * This class represents a widget that can be temporarily


 * shown ontop of everything else.


 *


 * @author	Arthur van Hoff


 * @version 	1.19, 11/07/96


 */


public class PopupWidget extends GroupWidget {


    /**


     * The player in which this widget is embedded.


     */


    PlayerPanel player;





    /**


     * Create a popup.


     */


    public PopupWidget() {


	visible = false;


	transparent = false;


	lineMode = RAISED;


	fillMode = SOLID;


    }





    /**


     * True if the player is set.


     */


    public boolean isShowing() {


	PlayerPanel player = this.player;


	return (player != null) ? player.showing : super.isShowing();


    }





    /**


     * Get the player.


     */


    public PlayerPanel getPlayerPanel() {


	PlayerPanel player = this.player;


	return (player != null) ? player : super.getPlayerPanel();


    }





    /**


     * This will repaint part of the screen.


     */


    public void repaintParent(long tm, int x, int y, int width, int height) {


	PlayerPanel player = this.player;


	if (player != null) {


	    player.repaint(tm, x, y, width, height);


	} else {


	    super.repaintParent(tm, x, y, width, height);


	}


    }





    /**


     * This will repaint part of the screen.


     */


    public void repaint(long tm, int x, int y, int width, int height) {


	PlayerPanel player = this.player;


	if (player == null) {


	    super.repaint(tm, x, y, width, height);


	    return;


	}





	if (visible) {


	    if ((x += tx) < 0) {


		width += x;


		x = 0;


	    }


	    if (x + width > this.width) {


		width = this.width - x;


	    }


	    if (width > 0) {


		if ((y += ty) < 0) {


		    height += y;


		    y = 0;


		}


		if (y + height > this.height) {


		    height = this.height - y;


		}


		if (height > 0) {


		    player.repaint(tm, this, this, this.x + x, this.y + y, width, height);


		}


	    }


	}


    }





    /**


     * Repaint a specific widget.


     */


    void repaint(long tm, Widget w, Widget c, int x, int y, int width, int height) {


	PlayerPanel player = this.player;


	if (player == null) {


	    super.repaint(tm, w, c, x, y, width, height);


	    return;


	}





	if (visible) {


	    if ((x += tx) < 0) {


		width += x;


		x = 0;


	    }


	    if (x + width > this.width) {


		width = this.width - x;


	    }


	    if (width > 0) {


		if ((y += ty) < 0) {


		    height += y;


		    y = 0;


		}


		if (y + height > this.height) {


		    height = this.height - y;


		}


		if (height > 0) {


		    int i = 0;


		    while ((i < nwidgets) && (widgets[i++] != c));


		    while (i < nwidgets) {


			Widget ww = widgets[i++];


			if (ww.visible && ww.overlap(x, y, width, height)) {


			    player.repaint(tm, this, this, this.x + x, this.y + y, width, height);


			    return;


			}


		    }


		    player.repaint(tm, w, this, this.x + x, this.y + y, width, height);


		}


	    }


	}


    }





    /**


     * Replace the widget with a newer version. This means installing


     * a new version in the player when appropriate.


     */


    public void replace(Widget newWidget) {


	PlayerPanel player = this.player;


	if (player != null) {





	    PopupWidget pw = (PopupWidget)newWidget;


	    for (int i = player.nwidgets ; i-- > 0 ;) {


		if (player.widgets[i] == this) {


		    player.widgets[i] = pw;


		}


	    }


	    pw.player = player;


	}


	super.replace(newWidget);


    }





    /**


     * Show the Popup Widget.


     */


    public void popup(Widget parent, int x, int y) {


	popup(parent, x, y, width, height);


    }


    


    /**


     * Show the Popup Widget.


     */


    public void popup(Widget parent, int x, int y, int width, int height) {


	PlayerPanel player = parent.getPlayerPanel();


	if (player != null) {


	    // Remove from old parent


	    if (this.player != null) {


		popdown();


	    }





	    // translate coordinates


	    for (Widget w = parent ; w != null ; w = w.parent) {


		x += w.x + w.tx;


		y += w.y + w.ty;


		if (w instanceof PopupWidget) {


		    break;


		}


	    }





	    this.parent = parent;


	    reshape(x, y, width, height);


	    player.add(this);


	}


    }





    /**


     * Fit the menu in the visible area of the parent window.


     */


    public void fit() {


	int x = this.x;


	int y = this.y;


	Dimension d = player.size();


	if (x + width > d.width) {


	    x = d.width - width;


	}


	if (x < 0) {


	    x = 0;


	}


	if (y + height > d.height) {


	    y = d.height - height;


	}


	if (y < 0) {


	    y = 0;


	}


	move(x, y);


    }





    /**


     * Hide the PopupWidget.


     */


    public void popdown() {


	PlayerPanel player = this.player;


	if (player != null) {


	    player.remove(this);


	}


    }





    /**


     * Post an event to this widget. If the widget does not


     * handle the event, it is passed to the parent.


     */


    public boolean postEvent(Event evt) {


	Widget parent = this.parent;


	if (handleEvent(evt)) {


	    return true;


	}


	if (parent != null) {


	    switch (evt.id) {


	      case REST_EVENT:


	      case WAKE_EVENT:


		break;





	      default:


		evt.translate(x + tx, y + ty);


		


		// translate coordinates


		for (Widget w = parent ; w != null ; w = w.parent) {


		    evt.translate(-(w.x + w.tx), -(w.y + w.ty));


		    if (w instanceof PopupWidget) {


			break;


		    }


		}





		return parent.postEvent(evt);


	    }


	}


	if (player != null) {


	    evt.translate(x + tx, y + ty);


	    return player.postEvent(evt);


	}


	return false;


    }





    /**


     * For debugging only.


     */


    public void paramString(StringBuffer buf) {


	super.paramString(buf);


	if (player == null) {


	    buf.append(",noplayer");


	}


    }


}


