/*******************************************************************************
 * Copyright (c) 2011 Laurent CARON
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation
 *******************************************************************************/
package org.mihalis.opal.switchButton;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.mihalis.opal.utils.SWTGraphicUtil;

/**
 * Instances of this class are simple switch button.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>(none)</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Selection</dd>
 * </dl>
 */
public class SwitchButton extends Canvas {

	/** Selection. */
	private boolean selection;

	/** Text displayed for the selected value (default = "On"). */
	private String textForSelect;

	/** Text displayed for the unselected value (default = "Off"). */
	private String textForUnselect;

	/** Text corresponding to the button (default is ""). */
	private String text;

	/**
	 * If true, display round rectangles instead of rectangles (default value is
	 * true).
	 */
	private boolean round;

	/**
	 * if not null, displays a rectangle (or a round rectangle) around the whole
	 * widget. Default value is null.
	 */
	private Color borderColor;

	/**
	 * if not null, displays a glow effect when the mouse is over the widget.
	 * Default value is null.
	 */
	private Color focusColor;

	/** Colors when the button is selected. */
	private Color selectedForegroundColor, selectedBackgroundColor;

	/** Colors when the button is not selected. */
	private Color unselectedForegroundColor, unselectedBackgroundColor;

	/** Colors for the button. */
	private Color buttonBorderColor, buttonBackgroundColor1, buttonBackgroundColor2;

	/** Gap between the button and the text (default value is 5). */
	private int gap = 5;

	/** Margin inside the button (default is 5). */
	private int insideMarginX = 5;

	/** Margin inside the button (default is 5). */
	private int insideMarginY = 5;

	/** Arc of rounded rectangles (default is 3). */
	private int arc = 3;

	/** Graphical context for this button. */
	private GC gc;

	/** List of selection listeners. */
	private final List<SelectionListener> listOfSelectionListeners;

	/** True when the mouse entered the widget. */
	private boolean mouseInside;

	/**
	 * Constructs a new instance of this class given its parent and a style
	 * value describing its behavior and appearance.
	 * <p>
	 * The style value is either one of the style constants defined in class
	 * <code>SWT</code> which is applicable to instances of this class, or must
	 * be built by <em>bitwise OR</em>'ing together (that is, using the
	 * <code>int</code> "|" operator) two or more of those <code>SWT</code>
	 * style constants. The class description lists the style constants that are
	 * applicable to the class. Style bits are also inherited from superclasses.
	 * </p>
	 *
	 * @param parent a composite control which will be the parent of the new
	 *            instance (cannot be null)
	 * @param style the style of control to construct
	 *
	 * @exception IllegalArgumentException
	 *                <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
	 *                </ul>
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the parent</li>
	 *                </ul>
	 *
	 */
	public SwitchButton(final Composite parent, final int style) {
		super(parent, style | SWT.DOUBLE_BUFFERED);

		selection = false;
		text = "";
		textForSelect = "On";
		textForUnselect = "Off";
		round = true;
		borderColor = null;
		focusColor = getDisplay().getSystemColor(SWT.COLOR_YELLOW);
		selectedForegroundColor = getDisplay().getSystemColor(SWT.COLOR_WHITE);
		selectedBackgroundColor = SWTGraphicUtil.getDefaultColor(this, 0, 112, 195);
		unselectedForegroundColor = getDisplay().getSystemColor(SWT.COLOR_BLACK);
		unselectedBackgroundColor = SWTGraphicUtil.getDefaultColor(this, 203, 203, 203);
		buttonBorderColor = SWTGraphicUtil.getDefaultColor(this, 96, 96, 96);
		buttonBackgroundColor1 = SWTGraphicUtil.getDefaultColor(this, 254, 254, 254);
		buttonBackgroundColor2 = SWTGraphicUtil.getDefaultColor(this, 192, 192, 192);

		listOfSelectionListeners = new ArrayList<SelectionListener>();

		addPaintListener(new PaintListener() {
			@Override
			public void paintControl(final PaintEvent event) {
				SwitchButton.this.onPaint(event);
			}
		});

		addMouseListener(new MouseAdapter() {

			/**
			 * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent)
			 */
			@Override
			public void mouseUp(final MouseEvent e) {
				if (SwitchButton.this.fireSelectionListeners(e)) {
					selection = !selection;
					SwitchButton.this.redraw();

					// notify listeners that were registered via
					// Widget#addListener
					SwitchButton.this.notifyListeners(SWT.Selection, new Event());

				}
			}

		});

		mouseInside = false;
		addMouseTrackListener(new MouseTrackListener() {

			@Override
			public void mouseHover(final MouseEvent e) {
				mouseInside = true;
				SwitchButton.this.redraw();
			}

			@Override
			public void mouseExit(final MouseEvent e) {
				mouseInside = false;
				SwitchButton.this.redraw();
			}

			@Override
			public void mouseEnter(final MouseEvent e) {
				mouseInside = true;
				SwitchButton.this.redraw();
			}
		});

	}

	/**
	 * Paint the widget.
	 *
	 * @param event paint event
	 */
	private void onPaint(final PaintEvent event) {
		final Rectangle rect = getClientArea();
		if (rect.width == 0 || rect.height == 0) {
			return;
		}
		gc = event.gc;
		gc.setAntialias(SWT.ON);

		final Point buttonSize = computeButtonSize();
		drawSwitchButton(buttonSize);
		drawText(buttonSize);

		if (borderColor != null) {
			drawBorder();
		}

	}

	/**
	 * Draw the switch button.
	 *
	 * @param buttonSize size of the button
	 */
	private void drawSwitchButton(final Point buttonSize) {
		// Draw the background of the button
		gc.setForeground(buttonBorderColor);
		if (round) {
			gc.drawRoundRectangle(2, 2, buttonSize.x, buttonSize.y, arc, arc);
		} else {
			gc.drawRectangle(2, 2, buttonSize.x, buttonSize.y);
		}

		drawRightPart(buttonSize);
		drawLeftPart(buttonSize);
		gc.setClipping(getClientArea());
		drawToggleButton(buttonSize);
	}

	/**
	 * Draw the right part of the button.
	 *
	 * @param buttonSize size of the button
	 */
	private void drawRightPart(final Point buttonSize) {
		gc.setForeground(selectedBackgroundColor);
		gc.setBackground(selectedBackgroundColor);
		gc.setClipping(3, 3, buttonSize.x / 2, buttonSize.y - 1);
		if (round) {
			gc.fillRoundRectangle(2, 2, buttonSize.x, buttonSize.y, arc, arc);
		} else {
			gc.fillRectangle(2, 2, buttonSize.x, buttonSize.y);
		}
		gc.setForeground(selectedForegroundColor);
		final Point textSize = gc.textExtent(textForSelect);
		gc.drawString(textForSelect, (buttonSize.x / 2 - textSize.x) / 2 + arc, (buttonSize.y - textSize.y) / 2 + arc);
	}

	/**
	 * Draw the left part of the button.
	 *
	 * @param buttonSize size of the button
	 */
	private void drawLeftPart(final Point buttonSize) {
		gc.setForeground(unselectedBackgroundColor);
		gc.setBackground(unselectedBackgroundColor);
		gc.setClipping(buttonSize.x / 2 + 3, 3, buttonSize.x / 2, buttonSize.y - 1);
		if (round) {
			gc.fillRoundRectangle(2, 2, buttonSize.x, buttonSize.y, arc, arc);
		} else {
			gc.fillRectangle(2, 2, buttonSize.x, buttonSize.y);
		}
		gc.setForeground(unselectedForegroundColor);
		final Point textSize = gc.textExtent(textForUnselect);

		gc.drawString(textForUnselect, buttonSize.x / 2 + (buttonSize.x / 2 - textSize.x) / 2 + arc, //
				(buttonSize.y - textSize.y) / 2 + arc);
	}

	/**
	 * Draw the toggle button.
	 *
	 * @param buttonSize size of the button
	 */
	private void drawToggleButton(final Point buttonSize) {
		gc.setForeground(buttonBackgroundColor1);
		gc.setBackground(buttonBackgroundColor2);
		if (selection) {
			gc.fillGradientRectangle(arc, arc, buttonSize.x / 2, buttonSize.y, true);
		} else {
			gc.fillGradientRectangle(buttonSize.x / 2, arc, buttonSize.x / 2 + 2, buttonSize.y - 1, true);
		}

		gc.setForeground(buttonBorderColor);
		if (selection) {
			gc.drawRoundRectangle(2, 2, buttonSize.x / 2, buttonSize.y, arc, arc);
		} else {
			gc.drawRoundRectangle(buttonSize.x / 2, 2, buttonSize.x / 2 + 2, buttonSize.y, arc, arc);
		}

		if (focusColor != null && mouseInside) {
			gc.setForeground(focusColor);
			gc.setLineWidth(2);
			if (selection) {
				gc.drawRoundRectangle(3, 3, buttonSize.x / 2, buttonSize.y - 1, 3, 3);
			} else {
				gc.drawRoundRectangle(buttonSize.x / 2 + 1, 3, buttonSize.x / 2, buttonSize.y - 2, 3, 3);
			}
			gc.setLineWidth(1);
		}

	}

	/**
	 * Compute button size.
	 *
	 * @return the button size
	 */
	private Point computeButtonSize() {
		// Compute size for the left part
		final Point sizeForLeftPart = gc.stringExtent(textForSelect);
		// Compute size for the right part
		final Point sizeForRightPart = gc.stringExtent(textForUnselect);

		// Compute whole size
		final int width = Math.max(sizeForLeftPart.x, sizeForRightPart.x) * 2 + 2 * insideMarginX;
		final int height = Math.max(sizeForLeftPart.y, sizeForRightPart.y) + 2 * insideMarginY;

		return new Point(width, height);
	}

	/**
	 * Draws the text besides the button.
	 *
	 * @param buttonSize whole size of the button
	 */
	private void drawText(final Point buttonSize) {
		gc.setForeground(getForeground());
		gc.setBackground(getBackground());

		final int widgetHeight = this.computeSize(0, 0, true).y;
		final int textHeight = gc.stringExtent(text).y;
		final int x = 2 + buttonSize.x + gap;

		gc.drawString(text, x, (widgetHeight - textHeight) / 2);
	}

	/**
	 * Draw (eventually) the border around the button.
	 */
	private void drawBorder() {
		if (borderColor == null) {
			return;
		}

		gc.setForeground(borderColor);
		final Point temp = this.computeSize(0, 0, false);
		if (round) {
			gc.drawRoundRectangle(0, 0, temp.x - 2, temp.y - 2, 3, 3);
		} else {
			gc.drawRectangle(0, 0, temp.x - 2, temp.y - 2);
		}

	}

	/**
	 * Fire the selection listeners.
	 *
	 * @param mouseEvent mouse event
	 * @return true if the selection could be changed, false otherwise
	 */
	private boolean fireSelectionListeners(final MouseEvent mouseEvent) {
		for (final SelectionListener listener : listOfSelectionListeners) {
			final Event event = new Event();

			event.button = mouseEvent.button;
			event.display = getDisplay();
			event.item = null;
			event.widget = this;
			event.data = null;
			event.time = mouseEvent.time;
			event.x = mouseEvent.x;
			event.y = mouseEvent.y;

			final SelectionEvent selEvent = new SelectionEvent(event);
			listener.widgetSelected(selEvent);
			if (!selEvent.doit) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Adds the listener to the collection of listeners who will be notified
	 * when the control is selected by the user, by sending it one of the
	 * messages defined in the <code>SelectionListener</code> interface.
	 * <p>
	 * <code>widgetSelected</code> is called when the control is selected by the
	 * user. <code>widgetDefaultSelected</code> is not called.
	 * </p>
	 *
	 * @param listener the listener which should be notified
	 * @see SelectionListener
	 * @see #removeSelectionListener
	 * @see SelectionEvent
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void addSelectionListener(final SelectionListener listener) {
		checkWidget();
		if (listener == null) {
			SWT.error(SWT.ERROR_NULL_ARGUMENT);
		}
		listOfSelectionListeners.add(listener);
	}

	/**
	 * Removes the listener from the collection of listeners who will be
	 * notified when the control is selected by the user.
	 *
	 * @param listener the listener which should no longer be notified
	 * @see SelectionListener
	 * @see #addSelectionListener
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void removeSelectionListener(final SelectionListener listener) {
		checkWidget();
		if (listener == null) {
			SWT.error(SWT.ERROR_NULL_ARGUMENT);
		}
		listOfSelectionListeners.remove(listener);
	}

	/**
	 * Compute size.
	 *
	 * @param wHint the w hint
	 * @param hHint the h hint
	 * @param changed the changed
	 * @return the point
	 * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
	 */
	@Override
	public Point computeSize(final int wHint, final int hHint, final boolean changed) {
		checkWidget();
		boolean disposeGC = false;
		if (gc == null || gc.isDisposed()) {
			gc = new GC(this);
			disposeGC = true;
		}

		final Point buttonSize = computeButtonSize();
		int width = buttonSize.x;
		int height = buttonSize.y;

		if (text != null && text.trim().length() > 0) {
			final Point textSize = gc.textExtent(text);
			width += textSize.x + gap + 1;
		}

		width += 4;
		height += 6;

		if (disposeGC) {
			gc.dispose();
		}

		return new Point(width, height);
	}

	/**
	 * Gets the selection.
	 *
	 * @return the selection state of the button
	 */
	public boolean getSelection() {
		checkWidget();
		return selection;
	}

	/**
	 * Sets the selection.
	 *
	 * @param selection the selection state of the button
	 */
	public void setSelection(final boolean selection) {
		checkWidget();
		this.selection = selection;
	}

	/**
	 * Gets the text displayed for the selected value (default = "On").
	 *
	 * @return the text used to display the selection
	 */
	public String getTextForSelect() {
		checkWidget();
		return textForSelect;
	}

	/**
	 * Sets the text displayed for the selected value (default = "On").
	 *
	 * @param textForSelect the text used to display the selection
	 */
	public void setTextForSelect(final String textForSelect) {
		checkWidget();
		this.textForSelect = textForSelect;
	}

	/**
	 * Gets the text displayed for the unselected value (default = "Off").
	 *
	 * @return the text used to display the unselected option
	 */
	public String getTextForUnselect() {
		checkWidget();
		return textForUnselect;
	}

	/**
	 * Sets the text displayed for the unselected value (default = "Off").
	 *
	 * @param textForUnselect the text used to display the unselected option
	 */
	public void setTextForUnselect(final String textForUnselect) {
		checkWidget();
		this.textForUnselect = textForUnselect;
	}

	/**
	 * Gets the text corresponding to the button (default is "").
	 *
	 * @return the text displayed in the widget
	 */
	public String getText() {
		checkWidget();
		return text;
	}

	/**
	 * Sets the text corresponding to the button (default is "").
	 *
	 * @param text the new text corresponding to the button (default is "")
	 */
	public void setText(final String text) {
		checkWidget();
		this.text = text;
	}

	/**
	 * Checks if is if true, display round rectangles instead of rectangles
	 * (default value is true).
	 *
	 * @return the round flag
	 */
	public boolean isRound() {
		checkWidget();
		return round;
	}

	/**
	 * Sets the if true, display round rectangles instead of rectangles (default
	 * value is true).
	 *
	 * @param round the round flag to set. If true, the widget is composed of
	 *            round rectangle instead of rectangles
	 */
	public void setRound(final boolean round) {
		checkWidget();
		this.round = round;
	}

	/**
	 * Gets the if not null, displays a rectangle (or a round rectangle) around
	 * the whole widget.
	 *
	 * @return the border's color. If null, no border is displayed
	 */
	public Color getBorderColor() {
		checkWidget();
		return borderColor;
	}

	/**
	 * Sets the if not null, displays a rectangle (or a round rectangle) around
	 * the whole widget.
	 *
	 * @param borderColor the border's color. If null, no border is displayed.
	 */
	public void setBorderColor(final Color borderColor) {
		checkWidget();
		this.borderColor = borderColor;
	}

	/**
	 * Gets the if not null, displays a glow effect when the mouse is over the
	 * widget.
	 *
	 * @return the focus color. If null, no focus effect is displayed.
	 */
	public Color getFocusColor() {
		checkWidget();
		return focusColor;
	}

	/**
	 * Sets the if not null, displays a glow effect when the mouse is over the
	 * widget.
	 *
	 * @param focusColor the focus color to set. If null, no focus effect is
	 *            displayed.
	 */
	public void setFocusColor(final Color focusColor) {
		checkWidget();
		this.focusColor = focusColor;
	}

	/**
	 * Gets the colors when the button is selected.
	 *
	 * @return the foreground color of the left part of the widget (selection is
	 *         on)
	 */
	public Color getSelectedForegroundColor() {
		checkWidget();
		return selectedForegroundColor;
	}

	/**
	 * Sets the colors when the button is selected.
	 *
	 * @param selectedForegroundColor the new colors when the button is selected
	 */
	public void setSelectedForegroundColor(final Color selectedForegroundColor) {
		checkWidget();
		this.selectedForegroundColor = selectedForegroundColor;
	}

	/**
	 * Gets the colors when the button is selected.
	 *
	 * @return the background color of the left part of the widget (selection is
	 *         on)
	 */
	public Color getSelectedBackgroundColor() {
		checkWidget();
		return selectedBackgroundColor;
	}

	/**
	 * Sets the colors when the button is selected.
	 *
	 * @param selectedBackgroundColor the new colors when the button is selected
	 */
	public void setSelectedBackgroundColor(final Color selectedBackgroundColor) {
		checkWidget();
		this.selectedBackgroundColor = selectedBackgroundColor;
	}

	/**
	 * Gets the colors when the button is not selected.
	 *
	 * @return the foreground color of the left part of the widget (selection is
	 *         on)
	 */
	public Color getUnselectedForegroundColor() {
		checkWidget();
		return unselectedForegroundColor;
	}

	/**
	 * Sets the colors when the button is not selected.
	 *
	 * @param unselectedForegroundColor the foreground color of the left part of
	 *            the widget (selection is on)
	 */
	public void setUnselectedForegroundColor(final Color unselectedForegroundColor) {
		checkWidget();
		this.unselectedForegroundColor = unselectedForegroundColor;
	}

	/**
	 * Gets the colors when the button is not selected.
	 *
	 * @return the background color of the left part of the widget (selection is
	 *         on)
	 */
	public Color getUnselectedBackgroundColor() {
		checkWidget();
		return unselectedBackgroundColor;
	}

	/**
	 * Sets the colors when the button is not selected.
	 *
	 * @param unselectedBackgroundColor the background color of the left part of
	 *            the widget (selection is on)
	 */
	public void setUnselectedBackgroundColor(final Color unselectedBackgroundColor) {
		checkWidget();
		this.unselectedBackgroundColor = unselectedBackgroundColor;
	}

	/**
	 * Gets the colors for the button.
	 *
	 * @return the border color of the switch button
	 */
	public Color getButtonBorderColor() {
		checkWidget();
		return buttonBorderColor;
	}

	/**
	 * Sets the colors for the button.
	 *
	 * @param buttonBorderColor the border color of the switch button
	 */
	public void setButtonBorderColor(final Color buttonBorderColor) {
		checkWidget();
		this.buttonBorderColor = buttonBorderColor;
	}

	/**
	 * Gets the colors for the button.
	 *
	 * @return the first color of the toggle button
	 */
	public Color getButtonBackgroundColor1() {
		checkWidget();
		return buttonBackgroundColor1;
	}

	/**
	 * Sets the colors for the button.
	 *
	 * @param buttonBackgroundColor1 the first color of the toggle button
	 */
	public void setButtonBackgroundColor1(final Color buttonBackgroundColor1) {
		checkWidget();
		this.buttonBackgroundColor1 = buttonBackgroundColor1;
	}

	/**
	 * Gets the colors for the button.
	 *
	 * @return the second color of the toggle button
	 */
	public Color getButtonBackgroundColor2() {
		checkWidget();
		return buttonBackgroundColor2;
	}

	/**
	 * Sets the colors for the button.
	 *
	 * @param buttonBackgroundColor2 the second color of the toggle button
	 */
	public void setButtonBackgroundColor2(final Color buttonBackgroundColor2) {
		checkWidget();
		this.buttonBackgroundColor2 = buttonBackgroundColor2;
	}

	/**
	 * Gets the gap between the button and the text (default value is 5).
	 *
	 * @return the gap value
	 */
	public int getGap() {
		checkWidget();
		return gap;
	}

	/**
	 * Sets the gap between the button and the text (default value is 5).
	 *
	 * @param gap the gap value to set
	 */
	public void setGap(final int gap) {
		checkWidget();
		this.gap = gap;
	}

	/**
	 * Gets the inside margin.
	 *
	 * @return the margin value
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public Point getInsideMargin() {
		checkWidget();
		return new Point(insideMarginX, insideMarginY);
	}

	/**
	 * Sets the inside margin.
	 *
	 * @param insideMarginX the new margin value (horizontal)
	 * @param insideMarginY the new margin value (vertical)
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setInsideMargin(final int insideMarginX, final int insideMarginY) {
		checkWidget();
		this.insideMarginX = insideMarginX;
		this.insideMarginY = insideMarginY;
	}

	/**
	 * Sets the inside margin.
	 *
	 * @param insideMargin the new margin value
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setInsideMargin(final Point insideMargin) {
		checkWidget();
		insideMarginX = insideMargin.x;
		insideMarginY = insideMargin.y;
	}

	/**
	 * Gets the arc of rounded rectangles (default is 3).
	 *
	 * @return the arc value
	 */
	public int getArc() {
		checkWidget();
		return arc;
	}

	/**
	 * Sets the arc of rounded rectangles (default is 3).
	 *
	 * @param arc the arc value to set
	 */
	public void setArc(final int arc) {
		checkWidget();
		this.arc = arc;
	}

}
