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


// @(#)RichTextBoxWidget.java, 1.38, 12/20/96





package marimba.gui;





import java.awt.*;





import marimba.persist.*;


import marimba.text.*;





/**


 * A rich text widget.


 *


 * @author	Jonathan Payne


 * @version 	1.38, 12/20/96


 */


public class RichTextBoxWidget extends TextWidget {


    /**


     * The textview that is used for rich text boxes.


     * The actual text processing is done by this textview.


     */


    public TextView view;





    /**


     * The text that is currently in the rich text box.


     */


    public Text text;





    /**


     * The vertical scrollbar that can be used in


     * rich text boxes.


     * @see #hasScrollbar


     * @see #getScrollbar


     * @see #setScrollbar


     */


    public ScrollbarWidget vsbar;





    /**


     * The scrollbar can be made filled.


     * @see #getFillsbar


     * @see #setFillsbar


     */


    public boolean fillsbar;








    /**


     * Constructor


     */


    public RichTextBoxWidget() {


	add(view = newTextView());


	text = view.getTextValue();


	view.setScrollbar(vsbar);


    }





    /**


     * Get the properties of this widget.


     */


    public void getProperties(PropertyList list) {


	super.getProperties(list);


	list.setBoolean("scrollbar", vsbar != null, false);


	view.getTextProperties(list);


	list.setBoolean("fillsbar", fillsbar, false);


    }





    /**


     * Don't save the children of this container.


     */


    public void getChildProperties(PropertyList list) {


    }





    /**


     * Set the properties of this widget.


     */


    public void setProperties(PropertyList list) {


	super.setProperties(list);


	fillsbar = list.getBoolean("fillsbar", false);


	setScrollbar(list.getBoolean("scrollbar", false));


	add(view);


	view.setTextProperties(list);


    }





    /**


     * Get the style options.


     */


    public Options getStyleOptions() {


	return view.styleOptions;


    }





    /**


     * Get the align options.


     */


    public Options getAlignOptions() {


	return view.alignOptions;


    }





    /**


     * Get the wrap options.


     */


    public Options getWrapOptions() {


	return view.wrapOptions;


    }





    /**


     * Check whether the scrollbar is filled.


     * @see #fillsbar


     */


    public boolean getFillsbar() {


	return fillsbar;


    }





    /**


     * Fill the scrollbar or not.


     * @see #fillsbar


     */


    public void setFillsbar(boolean fillsbar) {


	this.fillsbar = fillsbar;


	if (vsbar != null) {


	    vsbar.setFilled(fillsbar);


	}


    }





    /**


     * Set the foreground color.


     */


    public void setForeground(Color c) {


	super.setForeground(c);


	invalidate();


    }





    public String getRichText() {


	return view.getRichText();


    }





    public TextView newTextView() {


	return new TextView();


    }





    public Dimension preferredSize() {


	validate();


	return view.preferredSize();


    }





    /**


     * Get the editor.


     */


    public String getEditor() {


	return view.getEditor();


    }





    /**


     * Set the editor.


     */


    public void setEditor(Object editor) {


	super.setEditor(editor);


	view.setEditor(editor);


    }





    /**


     * Get the value of the text.


     */


    public String getText() {


	return text.toString();


    }





    /**


     * Sets the value for the text.


     */


    public void setText(String str) {


	text.clear();


	if (str != null) {


	    append(str);


	}


    }





    /**


     * Get the Text object associated with this view.


     */


    public Text getTextValue() {


	return text;


    }





    /**


     * Get the TextView object associated with this widget.


     */


    public TextView getTextViewValue() {


	return view;


    }





    /**


     * Disable this text


     */


    public void disable(boolean disabled) {


	super.disable(disabled);


	view.disable(disabled);


    }





    /**


     * Make this text editable.


     */


    public void setEditable(boolean editable) {


	super.setEditable(editable);


	view.setEditable(editable);


    }





    /**


     * Check whether the RichTextBox displays a scrollbar.


     * @see #vsbar


     */


    public boolean hasScrollbar() {


	return (vsbar != null);


    }





    /**


     * Let the RichTextBox use a scrollbar or not.


     * @see #vsbar


     */


    public void setScrollbar(boolean scrollbar) {


	if (scrollbar) {


	    if (vsbar == null) {


		vsbar = new ScrollbarWidget(VERTICAL);


		vsbar.setAutoSetValue(false);


		vsbar.setConstrained(false);


	    }


	} else if (vsbar != null) {


	    remove(vsbar);


	    vsbar = null;


	}


	view.setScrollbar(vsbar);


	if (vsbar != null) {


	    add(vsbar);


	    vsbar.setFilled(fillsbar);


	}


    }





    /**


     * Get the vertical scrollbar.


     * @see #vsbar


     */


    public ScrollbarWidget getScrollbar() {


	return vsbar;


    }





    /**


     * Set the vertical scrollbar.


     * @see #vsbar


     */


    public void setScrollbar(ScrollbarWidget vsbar) {


	if (vsbar != null && vsbar != this.vsbar) {


	    vsbar.setOrientation(VERTICAL);


	    vsbar.setAutoSetValue(false);


	    vsbar.setConstrained(false);


	    this.vsbar = vsbar;


	    add(vsbar);


	} else if (this.vsbar != null) {


	    remove(this.vsbar);


	    this.vsbar = null;


	}


	view.setScrollbar(this.vsbar);


    }





    /**


     * Check whether the text is being saved.


     * @see #setSavetext


     */


    public boolean getSavetext() {


	return view.getSavetext();


    }





    /**


     * Let the text be saved or not.


     * @see #setSavetext


     */


    public void setSavetext(boolean savetext) {


	view.setSavetext(savetext);


    }





    /**


     * Check whether the text can be selected.


     */


    public boolean getSelections() {


	return view.getSelections();


    }





    /**


     * Allow or forbid selections.


     */


    public void setSelections(boolean selections) {


	view.setSelections(selections);


    }





    /**


     * Check whether the text can scroll.


     */


    public boolean getScrolling() {


	return view.getScrolling();


    }





    /**


     * Allow or forbid scrolling of the text.


     */


    public void setScrolling(boolean scrolling) {


	view.setScrolling(scrolling);


    }





    /**


     * Get the inset of the rich text box.


     */


    public int getInset() {


	return view.getInset();


    }





    /**


     * Set the inset of the rich text box.


     */


    public void setInset(int inset) {


	view.setInset(inset);


	add(view);


    }





    /**


     * Get the color of the caret.


     */


    public Color getCaretColor() {


	return view.getCaretColor();


    }





    /**


     * Set the color of the caret.


     */


    public void setCaretColor(Color caretColor) {


	view.setCaretColor(caretColor);


    }





    /**


     * Get the shadow color.


     */


    public Color getShadowColor() {


	return view.getShadowColor();


    }





    /**


     * Set the shadow color.


     */


    public void setShadowColor(Color shadowColor) {


	view.setShadowColor(shadowColor);


    }





    /**


     * Get the length of the text.


     */


    public int getLength() {


	return text.length();


    }





    /**


     * Return the start of the selection.


     */


    public int getSelStart() {


	return view.getSelectionStart();


    }





    /**


     * Return the end of the selection.


     */


    public int getSelEnd() {


	return view.getSelectionEnd();


    }





    /**


     * Get the selected part of the text.


     */


    public String getSelected() {


	return view.getSelection();


    }





    /**


     * Clear the text.


     */


    public void clear() {


	setText(null);


    }





    /**


     * Clear the current selection.


     */


    public void delete() {


	view.deleteSelection();


    }





    /**


     * Insert a character. This wil first clear the selecton, before


     * inserting the character.


     */


    public void insert(char ch) {


	view.insert(ch);


    }





    /**


     * Insert a string at the current cursor position.


     */


    public void insert(String str) {


	view.insert(str);


    }





    /**


     * Append to the end of text.


     */


    public void append(char ch) {


	text.insert(ch, text.length());


    }





    /**


     * Append to the end of text.


     */


    public void append(String str) {


	text.insert(str, text.length());


    }





    public void appendStyle(String str, int face, Color c) {


	StyleChange sc = new StyleChange();


	if ((face & Font.BOLD) != 0) {


	    sc.makeBold();


	}


	if ((face & Font.ITALIC) != 0) {


	    sc.makeItalic();


	}


	if (c != null) {


	    sc.setColor(c);


	}


	int pos = text.length();


	text.insert(str, pos);


	text.applyStyleChange(sc, pos, pos + str.length());


    }





    /**


     * This widget is not interested in the character focus.


     */


    public boolean focusInterest() {


	return false;


    }





    /**


     * Select the entire text.


     */


    public void selectAll() {


	view.select(0, text.length());


    }





    /**


     * Select a portion of the text.


     */


    public void select(int selStart, int selEnd) {


	view.select(selStart, selEnd, 1);


    }





    /**


     * Select a portion of the text. Depth controls character (1),


     * word (2), and line selection (3).


     */


    public void select(int selStart, int selEnd, int depth) {


	view.select(selStart, selEnd, depth);


    }





    /**


     * Focus on a character position.


     */


    public void focus(int pos) {


	view.setCaret(pos);


    }





    /**


     * Layout


     */


    public void layout() {


	if (vsbar == null) {


	    view.reshape(0, 0, width, height);


	} else {


	    view.reshape(0, 0, width - 15, height);


	    vsbar.reshape(width - 15, 0, 15, height);


	}


    }





    public void invalidate() {


	super.invalidate();


	view.invalidate();


    }





    /**


     * Get the current style.


     */


    public int getStyle() {


	return view.getStyle();


    }





    /**


     * Set the style.


     */


    public void setStyle(int style) {


	view.setStyle(style);


    }





    /**


     * Get the current align of the text.


     */


    public int getAlign() {


	return view.getAlign();


    }





    /**


     * Set the alignment.


     */


    public void setAlign(int align) {


	if (align != getAlign()) {


	    view.setAlign(align);


	    add(view);


	}


    }





    /**


     * Get the current wrap.


     * Returns a widgetConstant: CHAR, WORD, TRUNCATE.


     */


    public int getWrap() {


	return view.getWrap();


    }





    /**


     * Set the wrap.


     * Expects a widgetConstant: CHAR, WORD, TRUNCATE.


     */


    public void setWrap(int wrap) {


	if (wrap != getWrap()) {


	    view.setWrap(wrap);


	    add(view);


	}


    }





    /**


     * Request focus


     */


    public void requestFocus() {


	view.requestFocus();


    }





    /**


     * Checks whether the given event is within the text view.


     */


    protected boolean eventInText(Event evt) {


	return (evt.target == view && evt.x > 0 && evt.x < view.width && evt.y > 0 && evt.y < view.height);


    }





    /**


     * Forward events to the right widget during editing.


     */


    public boolean handleEvent(Event evt) {


	if (editor != null) {


	    return view.handleEvent(evt);


	}


	if (evt.target == vsbar) {


	    Integer v = ((Integer) evt.arg);


	    if (v == null)


		return true;


	    int value = v.intValue();


	    switch (evt.id) {


	      case Event.SCROLL_ABSOLUTE:


		view.scrollAbsolute(value, 5);


		return true;





	      case Event.SCROLL_PAGE_DOWN:


	      case Event.SCROLL_PAGE_UP:


		view.scrollPage(evt.id == Event.SCROLL_PAGE_DOWN ? 1 : -1);


		break;


 


	      case Event.SCROLL_LINE_UP:


	      case Event.SCROLL_LINE_DOWN:


		view.scrollLine(evt.id == Event.SCROLL_LINE_DOWN ? 1 : -1);


		break;


	    }


	} else {


	    switch (evt.id) {


		case Event.MOUSE_EXIT:


		    if (editable && !disabled && evt.target == view) {


			resetCursor();


		    }


		    break;


	    }


	}





	return super.handleEvent(evt);


    }


}


