/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.draw2d;

import org.eclipse.draw2d.geometry.Point;

/**
 * A class which implements automatic horizontal and/or vertical scrolling for a single 
 * IFigure child. 
 * <p>
 * ScrollBar visibilites are represented by integer class constants:
 * <ul>
 * 		<li>NEVER: Never show the ScrollBar
 * 		<li>AUTOMATIC: Show as needed, when the ScrollPane can no longer contain its view
 * 		<li>ALWAYS: Always show the ScrollBar
 * </ul>
 * To use, instantiate a ScrollPane object and call its setView(IFigure) method passing 
 * the IFigure that is desired to have scrolling ability.
 */
public class ScrollPane
	extends Figure
{

/** Constant indicating to never show the ScrollBar */
public static final int NEVER = 0;
/** Constant indicating to show as needed, when the ScrollPane can't contain its view */
public static final int AUTOMATIC = 1;
/** Constant indicating to always show the ScrollBar */
public static final int ALWAYS = 2;

/** The viewport being scrolled */
protected Viewport viewport;
/** The horizontal scrollbar */
protected ScrollBar hBar;
/** The vertical scrollbar */
protected ScrollBar vBar;
private int
	hVisibility = AUTOMATIC,
	vVisibility = AUTOMATIC;

/**
 * Constructs a new ScrollPane with a ScrollPaneLayout.
 * 
 * @since 2.0
 */
public ScrollPane() {
	setLayoutManager(new ScrollPaneLayout());
}

/**
 * Creates a new horizontally oriented ScrollBar and adds it to this ScrollPane.
 * 
 * @since 2.0
 */
protected void createHorizontalScrollBar() {
	ScrollBar bar = new ScrollBar();
	bar.setHorizontal(true);
	setHorizontalScrollBar(bar);
}

/**
 * Creates a new Viewport and adds it to this ScrollPane.
 * 
 * @since 2.0
 */
protected void createViewport() {
	setViewport(new Viewport());
}

/**
 * Creates a new vertically oriented ScrollBar and adds it to this ScrollPane.
 * 
 * @since 2.0
 */
protected void createVerticalScrollBar() {
	ScrollBar bar = new ScrollBar();
	setVerticalScrollBar(bar);
}

/**
 * Returns the ScrollPane's horizontal ScrollBar.
 * 
 * @return the horizontal scrollbar
 * @since 2.0
 */
public ScrollBar getHorizontalScrollBar() {
	if (hBar == null)
		createHorizontalScrollBar();
	return hBar;
}

/**
 * Returns the visibility of the ScrollPane's horizontal ScrollBar. These are represented 
 * by the integer class constants {@link #NEVER}, {@link #AUTOMATIC}, and {@link #ALWAYS}.
 * The default is {@link #AUTOMATIC}.
 * 
 * @return the visiblity of the horizontal scrollbar
 * @since 2.0
 */
public int getHorizontalScrollBarVisibility() {
	return hVisibility;
}

/**
 * Returns the ScrollPane's vertical ScrollBar.
 * 
 * @return teh vertical scrollbar
 * @since 2.0
 */
public ScrollBar getVerticalScrollBar() {
	if (vBar == null)
		createVerticalScrollBar();
	return vBar;
}

/**
 * Returns the visibility of the ScrollPane's vertical ScrollBar. These are represented 
 * by the integer class constants {@link #NEVER}, {@link #AUTOMATIC}, and {@link #ALWAYS}.
 * The default is {@link #AUTOMATIC}.
 * 
 * @return the visibility of the vertical scrollbar
 * @since 2.0
 */
public int getVerticalScrollBarVisibility() {
	return vVisibility;
}

/**
 * Returns the contents of the viewport.
 * @return the contents of the viewport
 */
public IFigure getContents() {
	return getView();
}

/**
 * Returns the ScrollPane's view. The view is the IFigure that is the contents of the 
 * ScrollPane.
 * @return the contents
 * @deprecated use getContents()
 * @since 2.0
 */ 
public IFigure getView() {
	return getViewport().getContents();
}

/**
 * Returns the ScrollPane's {@link Viewport}.
 * 
 * @return the viewport
 * @since 2.0
 */ 
public Viewport getViewport() {
	if (viewport == null)
		createViewport();
	return viewport;
}

/**
 * Returns true because ScrollPanes are always opaque.
 * @see IFigure#isOpaque()
 */
public boolean isOpaque() {
	return true;
}

/**
 * Scrolls the Scrollpane horizontally x pixels from its left-most position.
 * 
 * @param x the amount to scroll horizontally
 * @since 2.0
 */
public void scrollHorizontalTo(int x) {
	getViewport().setHorizontalLocation(x);
}

/**
 * Scrolls the Scrollpane horizontally from its left-most position by location.x pixels 
 * and vertically from its top-most position by location.y pixels.
 * 
 * @param location the point to scroll to
 * @since 2.0
 */ 
public void scrollTo(Point location) {
	scrollHorizontalTo(location.x);
	scrollVerticalTo(location.y);
}

/**
 * Scrolls the Scrollpane vertically y pixels from its top-most position. 
 * 
 * @param y the amount to scroll vertically
 * @since 2.0
 */
public void scrollVerticalTo(int y) {
	getViewport().setVerticalLocation(y);
}

/**
 * Sets the contents of the current viewport.
 * @param figure the contents of the viewport
 */
public void setContents(IFigure figure) {
	setView(figure);
}

/**
 * Sets the ScrollPane's horizontal ScrollBar to the passed ScrollBar.
 * 
 * @param bar the new horizontal scrollbar
 * @since 2.0
 */
public void setHorizontalScrollBar(ScrollBar bar) {
	if (hBar != null) {
		remove(hBar);
		hBar.getRangeModel().removePropertyChangeListener(hBar);
	}
	hBar = bar;
	if (hBar != null) {
		add(hBar);
		hBar.setRangeModel(getViewport().getHorizontalRangeModel());
	}
}

/**
 * Sets the horizontal ScrollBar visibility of the ScrollPane to the passed value. These 
 * are represented by the integer class constants {@link #NEVER}, {@link #AUTOMATIC}, and 
 * {@link #ALWAYS}. The default is {@link #AUTOMATIC}.
 * 
 * @param v the new horizontal visibility
 * @since 2.0
 */
public void setHorizontalScrollBarVisibility(int v) {
	if (hVisibility == v) 
		return;
	hVisibility = v;
	revalidate();
}

/**
 * Sets both the horizontal and vertical ScrollBar visibilities of the ScrollPane to the 
 * passed value. These are represented by the integer class constants {@link #NEVER}, 
 * {@link #AUTOMATIC}, and {@link #ALWAYS}. The default is {@link #AUTOMATIC}.
 * 
 * @param v the new vertical and horizontal visibility
 * @since 2.0
 */
public void setScrollBarVisibility(int v) {
	setHorizontalScrollBarVisibility(v);
	setVerticalScrollBarVisibility(v);
}

/**
 * Sets the ScrollPane's vertical ScrollBar to the passed Scrollbar.
 * 
 * @param bar the new vertical scrollbar
 * @since 2.0
 */
public void setVerticalScrollBar(ScrollBar bar) {
	if (vBar != null) {
		remove(vBar);
		vBar.getRangeModel().removePropertyChangeListener(vBar);
	}
	vBar = bar;
	if (vBar != null) {
		add(vBar);
		vBar.setRangeModel(getViewport().getVerticalRangeModel());
	}
}

/**
 * Sets the vertical ScrollBar visibility of the ScrollPane to the passed value. These are 
 * represented by the integer class constants {@link #NEVER}, {@link #AUTOMATIC}, and 
 * {@link #ALWAYS}. The default is {@link #AUTOMATIC}.
 * 
 * @param v the new vertical scrollbar visibility
 * @since 2.0
 */
public void setVerticalScrollBarVisibility(int v) {
	if (vVisibility == v) 
		return;
	vVisibility = v;
	revalidate();
}

/**
 * Sets the ScrollPane's view to the passed IFigure. The view is the top-level IFigure 
 * which represents the contents of the ScrollPane.
 * @param figure the new contents
 * @deprecated call setContents(IFigure) instead
 * @since 2.0
 */
public void setView(IFigure figure) {
	getViewport().setContents(figure);
}

/**
 * Sets the ScrollPane's Viewport to the passed value.
 * 
 * @param vp the new viewport
 * @since 2.0
 */
public void setViewport(Viewport vp) {
	if (viewport != null)
		remove(viewport);
	viewport = vp;
	if (vp != null)
		add(vp, 0);
}

/**
 * @see IFigure#validate()
 */
public void validate() {
	super.validate();
	getHorizontalScrollBar().validate();
	getVerticalScrollBar().validate();
}

}
