package org.eclipse.swt.widgets;

/*
 * Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
 * This file is made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 */

import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;

/**
 * This class is the abstract superclass of all classes which
 * represent controls that have standard scroll bars.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>H_SCROLL, V_SCROLL</dd>
 * <dt><b>Events:</b>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * IMPORTANT: This class is intended to be subclassed <em>only</em>
 * within the SWT implementation.
 * </p>
 */

public abstract class Scrollable extends Control {
	ScrollBar horizontalBar, verticalBar;

/**
 * Prevents uninitialized instances from being created outside the package.
 */
Scrollable () {
}

/**
 * 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>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#H_SCROLL
 * @see SWT#V_SCROLL
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Scrollable (Composite parent, int style) {
	super (parent, style);
}

int callWindowProc (int msg, int wParam, int lParam) {
	if (handle == 0) return 0;
	return OS.DefWindowProc (handle, msg, wParam, lParam);
}

/**
 * Given a desired <em>client area</em> for the receiver
 * (as described by the arguments), returns the bounding
 * rectangle which would be required to produce that client
 * area.
 * <p>
 * In other words, it returns a rectangle such that, if the
 * receiver's bounds were set to that rectangle, the area
 * of the receiver which is capable of displaying data
 * (that is, not covered by the "trimmings") would be the
 * rectangle described by the arguments (relative to the
 * receiver's parent).
 * </p>
 * 
 * @return the required bounds to produce the given client area
 *
 * @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>
 *
 * @see #getClientArea
 */
public Rectangle computeTrim (int x, int y, int width, int height) {
	checkWidget ();
	RECT rect = new RECT ();
	OS.SetRect (rect, x, y, x + width, y + height);
	int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	OS.AdjustWindowRectEx (rect, bits, false, OS.GetWindowLong (handle, OS.GWL_EXSTYLE));
	if (horizontalBar != null) rect.bottom += OS.GetSystemMetrics (OS.SM_CYHSCROLL);
	if (verticalBar != null) rect.right += OS.GetSystemMetrics (OS.SM_CXVSCROLL);
	int nWidth = rect.right - rect.left, nHeight = rect.bottom - rect.top;
	return new Rectangle (rect.left, rect.top, nWidth, nHeight);
}

ScrollBar createScrollBar (int type) {
	ScrollBar bar = new ScrollBar (this, type);
	if ((state & CANVAS) != 0) {
		bar.setMaximum (100);
		bar.setThumb (10);
	}
	return bar;
}

void createWidget () {
	super.createWidget ();
	if ((style & SWT.H_SCROLL) != 0) horizontalBar = createScrollBar (SWT.H_SCROLL);
	if ((style & SWT.V_SCROLL) != 0) verticalBar = createScrollBar (SWT.V_SCROLL);
}

/**
 * Returns a rectangle which describes the area of the
 * receiver which is capable of displaying data (that is,
 * not covered by the "trimmings").
 * 
 * @return the client area
 *
 * @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>
 *
 * @see #computeTrim
 */
public Rectangle getClientArea () {
	checkWidget ();
	if (parent != null && parent.hdwp != 0) {
		int oldHdwp = parent.hdwp;
		parent.hdwp = 0;
		OS.EndDeferWindowPos (oldHdwp);
		int count = parent.getChildrenCount ();
		parent.hdwp = OS.BeginDeferWindowPos (count);
	}
	RECT rect = new RECT ();
	OS.GetClientRect (handle, rect);
	return new Rectangle (0, 0, rect.right, rect.bottom);
}

/**
 * Returns the receiver's horizontal scroll bar if it has
 * one, and null if it does not.
 *
 * @return the horizontal scroll bar (or null)
 *
 * @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 ScrollBar getHorizontalBar () {
	checkWidget ();
	return horizontalBar;
}

/**
 * Returns the receiver's vertical scroll bar if it has
 * one, and null if it does not.
 *
 * @return the vertical scroll bar (or null)
 *
 * @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 ScrollBar getVerticalBar () {
	checkWidget ();
	return verticalBar;
}

void releaseWidget () {
	if (horizontalBar != null) horizontalBar.releaseWidget ();
	if (verticalBar != null) verticalBar.releaseWidget ();
	horizontalBar = verticalBar = null;
	super.releaseWidget ();
}

int widgetExtStyle () {
	return super.widgetExtStyle ();
	/*
	* This code is intentionally commented.  In future,
	* we may wish to support different standard Windows
	* edge styles.  The issue here is that not all of
	* these styles are available on the other platforms
	* this would need to be a hint.
	*/
//	if ((style & SWT.BORDER) != 0) return OS.WS_EX_CLIENTEDGE;
//	if ((style & SWT.SHADOW_IN) != 0) return OS.WS_EX_STATICEDGE;
//	return super.widgetExtStyle ();
}

int widgetStyle () {
	int bits = super.widgetStyle () | OS.WS_TABSTOP;
	if ((style & SWT.H_SCROLL) != 0) bits |= OS.WS_HSCROLL;
	if ((style & SWT.V_SCROLL) != 0) bits |= OS.WS_VSCROLL;
	return bits;
}

TCHAR windowClass () {
	return getDisplay ().windowClass;
}

int windowProc () {
	return getDisplay ().windowProc;
}

LRESULT WM_HSCROLL (int wParam, int lParam) {
	LRESULT result = super.WM_HSCROLL (wParam, lParam);
	if (result != null) return result;
	
	/*
	* Bug on WinCE.  lParam should be NULL when the message is not sent
	* by a scroll bar control, but it contains the handle to the window.
	* When the message is sent by a scroll bar control, it correctly
	* contains the handle to the scroll bar.  The fix is to check for
	* both.
	*/
	if ((lParam == 0 || lParam == handle) && horizontalBar != null) {
		result = wmScroll (OS.WM_HSCROLL, wParam, lParam);
		horizontalBar.wmScrollChild (wParam, lParam);
	}
	return result;
}

LRESULT WM_MOUSEWHEEL (int wParam, int lParam) {
	LRESULT result = super.WM_MOUSEWHEEL (wParam, lParam);
	if (result != null) return result;
	
	/*
	* Translate WM_MOUSEWHEEL to WM_VSCROLL or WM_HSCROLL.
	*/
	if ((state & CANVAS) != 0) {
		if ((wParam & (OS.MK_SHIFT | OS.MK_CONTROL)) != 0) return result;
		int delta = (short) (wParam >> 16);
		int code = delta < 0 ? OS.SB_LINEDOWN : OS.SB_LINEUP;
		delta = Math.abs (delta);
		if (delta < OS.WHEEL_DELTA) return result;
		if (verticalBar != null) {
			int [] value = new int [1];
   			OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, value, 0);
			int count = value [0] * delta / OS.WHEEL_DELTA;
			for (int i=0; i<count; i++) {
				OS.SendMessage (handle, OS.WM_VSCROLL, code, 0);
			}
			return LRESULT.ZERO;
		}
		if (horizontalBar != null) {
			int count = delta / OS.WHEEL_DELTA;
			for (int i=0; i<count; i++) {
				OS.SendMessage (handle, OS.WM_HSCROLL, code, 0);
			}
			return LRESULT.ZERO;
		}
		return result;
	}
		
	/*
	* When the native widget scrolls inside WM_MOUSEWHEEL, it
	* may or may not send a WM_VSCROLL or WM_HSCROLL to do the
	* actual scrolling.  This depends on the implementation of
	* each native widget.  In order to ensure that application
	* code is notified when the scroll bar moves, compare the
	* scroll bar position before and after the WM_MOUSEWHEEL.
	* If the native control sends a WM_VSCROLL or WM_HSCROLL,
	* then the application has already been notified.  If not
	* explicity send the event.
	*/
	int vPosition = verticalBar == null ? 0 : verticalBar.getSelection ();
	int hPosition = horizontalBar == null ? 0 : horizontalBar.getSelection ();
	int code = callWindowProc (OS.WM_MOUSEWHEEL, wParam, lParam);
	if (verticalBar != null) {
		if (verticalBar.getSelection () != vPosition) {
			Event event = new Event ();
			event.detail = SWT.DRAG; 
			verticalBar.sendEvent (SWT.Selection, event);
		}
	}
	if (horizontalBar != null) {
		if (horizontalBar.getSelection () != hPosition) {
			Event event = new Event ();
			event.detail = SWT.DRAG; 
			horizontalBar.sendEvent (SWT.Selection, event);
		}
	}
	return new LRESULT (code);
}

LRESULT WM_SIZE (int wParam, int lParam) {
	int code = callWindowProc (OS.WM_SIZE, wParam, lParam);
	super.WM_SIZE (wParam, lParam);
	// widget may be disposed at this point
	if (code == 0) return LRESULT.ZERO;
	return new LRESULT (code);
}

LRESULT WM_VSCROLL (int wParam, int lParam) {
	LRESULT result = super.WM_VSCROLL (wParam, lParam);
	if (result != null) return result;

	/*
	* Bug on WinCE.  lParam should be NULL when the message is not sent
	* by a scroll bar control, but it contains the handle to the window.
	* When the message is sent by a scroll bar control, it correctly
	* contains the handle to the scroll bar.  The fix is to check for
	* both.
	*/
	if ((lParam == 0 || lParam == handle) && (verticalBar != null)) {
		result = wmScroll (OS.WM_VSCROLL, wParam, lParam);
		verticalBar.wmScrollChild (wParam, lParam);
	}
	return result;
}

LRESULT wmScroll (int msg, int wParam, int lParam) {
	int type = OS.SB_HORZ;
	ScrollBar bar = horizontalBar;
	if (msg == OS.WM_VSCROLL) {
		type = OS.SB_VERT;
		bar = verticalBar;
	}
	if (bar == null) return null;
	SCROLLINFO info = new SCROLLINFO ();
	info.cbSize = SCROLLINFO.sizeof;
	info.fMask = OS.SIF_TRACKPOS | OS.SIF_POS | OS.SIF_RANGE;
	OS.GetScrollInfo (handle, type, info);
	info.fMask = OS.SIF_POS;
	int code = wParam & 0xFFFF;
	switch (code) {
		case OS.SB_ENDSCROLL:  return null;
		case OS.SB_THUMBTRACK:
		case OS.SB_THUMBPOSITION:
			/* 
			* Note: On WinCE, the value in SB_THUMBPOSITION is relative to nMin.
			* Same for SB_THUMBPOSITION 'except' for the very first thumb track
			* message which has the actual value of nMin. This is a problem when
			* nMin is not zero.
			*/
			info.nPos = info.nTrackPos;
			break;
		case OS.SB_TOP:
			info.nPos = info.nMin;
			break;
		case OS.SB_BOTTOM:
			info.nPos = info.nMax;
			break;
		case OS.SB_LINEDOWN:
			info.nPos += bar.getIncrement ();
			break;
		case OS.SB_LINEUP:
			int increment = bar.getIncrement ();
			info.nPos = Math.max (info.nMin, info.nPos - increment);
			break;
		case OS.SB_PAGEDOWN:
			info.nPos += bar.getPageIncrement ();
			break;
		case OS.SB_PAGEUP:
			int pageIncrement = bar.getPageIncrement ();
			info.nPos = Math.max (info.nMin, info.nPos - pageIncrement);
			break;
	}
	OS.SetScrollInfo (handle, type, info, true);
	return null;
}

}
