/*
 * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "awt_Toolkit.h"
#include "awt_Scrollbar.h"
#include "awt_Canvas.h"
#include "awt_Window.h"

/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
 */

/***********************************************************************/
// struct for _SetValues() method
struct SetValuesStruct {
    jobject scrollbar;
    jint value;
    jint visible;
    jint min, max;

};
/************************************************************************
 * AwtScrollbar fields
 */

jfieldID AwtScrollbar::lineIncrementID;
jfieldID AwtScrollbar::pageIncrementID;
jfieldID AwtScrollbar::orientationID;

BOOL     AwtScrollbar::ms_isInsideMouseFilter = FALSE;
int      AwtScrollbar::ms_instanceCounter = 0;
HHOOK    AwtScrollbar::ms_hMouseFilter;

/************************************************************************
 * AwtScrollbar methods
 */

AwtScrollbar::AwtScrollbar() {
    m_orientation = SB_HORZ;
    m_lineIncr = 0;
    m_pageIncr = 0;
    m_prevCallback = NULL;
    m_prevCallbackPos = 0;
    ms_instanceCounter++;

    /*
     * Fix for 4515085.
     * Use the hook to process WM_LBUTTONUP message.
     */
    if (AwtScrollbar::ms_instanceCounter == 1) {
        AwtScrollbar::ms_hMouseFilter =
            ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtScrollbar::MouseFilter,
                               0, AwtToolkit::MainThread());
    }
}

AwtScrollbar::~AwtScrollbar()
{
}

void AwtScrollbar::Dispose()
{
    if (--ms_instanceCounter == 0) {
        ::UnhookWindowsHookEx(ms_hMouseFilter);
    }
    AwtComponent::Dispose();
}

LPCTSTR
AwtScrollbar::GetClassName() {
    return TEXT("SCROLLBAR");  /* System provided scrollbar class */
}

/* Create a new AwtScrollbar object and window.   */
AwtScrollbar *
AwtScrollbar::Create(jobject peer, jobject parent)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject target = NULL;
    AwtScrollbar* c = NULL;

    try {
        if (env->EnsureLocalCapacity(1) < 0) {
            return NULL;
        }

        PDATA pData;
        AwtCanvas* awtParent;
        JNI_CHECK_PEER_GOTO(parent, done);

        awtParent = (AwtCanvas*)pData;
        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);

        target = env->GetObjectField(peer, AwtObject::targetID);
        JNI_CHECK_NULL_GOTO(target, "null target", done);

        c = new AwtScrollbar();

        {
            jint orientation =
                env->GetIntField(target, AwtScrollbar::orientationID);
            c->m_orientation = (orientation == java_awt_Scrollbar_VERTICAL) ?
                SB_VERT : SB_HORZ;
            c->m_lineIncr =
                env->GetIntField(target, AwtScrollbar::lineIncrementID);
            c->m_pageIncr =
                env->GetIntField(target, AwtScrollbar::pageIncrementID);

            DWORD style = WS_CHILD | WS_CLIPSIBLINGS |
                c->m_orientation;/* Note: SB_ and SBS_ are the same here */

            jint x = env->GetIntField(target, AwtComponent::xID);
            jint y = env->GetIntField(target, AwtComponent::yID);
            jint width = env->GetIntField(target, AwtComponent::widthID);
            jint height = env->GetIntField(target, AwtComponent::heightID);

            c->CreateHWnd(env, L"", style, 0,
                          x, y, width, height,
                          awtParent->GetHWnd(),
                          reinterpret_cast<HMENU>(static_cast<INT_PTR>(
                awtParent->CreateControlID())),
                          ::GetSysColor(COLOR_SCROLLBAR),
                          ::GetSysColor(COLOR_SCROLLBAR),
                          peer);
            c->m_backgroundColorSet = TRUE;
            /* suppress inheriting parent's color. */
            c->UpdateBackground(env, target);
        }
    } catch (...) {
        env->DeleteLocalRef(target);
        throw;
    }

done:
    env->DeleteLocalRef(target);
    return c;
}

LRESULT CALLBACK
AwtScrollbar::MouseFilter(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (((UINT)wParam == WM_LBUTTONUP || (UINT)wParam == WM_MOUSEMOVE) &&
        ms_isInsideMouseFilter != TRUE &&
        nCode >= 0)
    {
        HWND hwnd = ((PMOUSEHOOKSTRUCT)lParam)->hwnd;
        AwtComponent *comp = AwtComponent::GetComponent(hwnd);

        if (comp != NULL && comp->IsScrollbar()) {
            MSG msg;
            LPMSG lpMsg = (LPMSG)&msg;
            UINT msgID = (UINT)wParam;

            ms_isInsideMouseFilter = TRUE;

            // Peek the message to get wParam containing the message's flags.
            // <::PeekMessage> will call this hook again. To prevent recursive
            // processing the <ms_isInsideMouseFilter> flag is used.
            // Calling <::PeekMessage> is not so good desision but is the only one
            // found to get those flags (used further in Java event creation).
            // WARNING! If you are about to add new hook of WM_MOUSE type make
            // it ready for recursive call, otherwise modify this one.
            if (::PeekMessage(lpMsg, hwnd, msgID, msgID, PM_NOREMOVE)) {
                comp->WindowProc(msgID, lpMsg->wParam, lpMsg->lParam);
            }

            ms_isInsideMouseFilter = FALSE;
        }
    }
    return ::CallNextHookEx(AwtScrollbar::ms_hMouseFilter, nCode, wParam, lParam);
}


LRESULT
AwtScrollbar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    // Delegate real work to super
    LRESULT retValue = AwtComponent::WindowProc(message, wParam, lParam);

    // After-hooks for workarounds
    switch (message) {

      // Work around a windows bug described in KB article Q73839.
      // Need to update focus indicator on scrollbar if thumb
      // proportion or thumb position was changed.

      case WM_SIZE:
      case SBM_SETSCROLLINFO:
      case SBM_SETRANGE:
      case SBM_SETRANGEREDRAW:
          if (AwtComponent::sm_focusOwner == GetHWnd()) {
              UpdateFocusIndicator();
          }
          break;
    }

    return retValue;
}

MsgRouting
AwtScrollbar::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
{
    if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) {
        retVal = HTCLIENT;
        return mrConsume;
    }
    return AwtComponent::WmNcHitTest(x, y, retVal);
}

// Fix for a race condition when the WM_LBUTTONUP is picked by the AWT
// message loop before(!) the windows internal message loop for the
// scrollbar is started in response to WM_LBUTTONDOWN.  See KB article
// Q102552.
//
// Note that WM_LBUTTONUP is processed by the windows internal message
// loop.  May be we can synthesize a MOUSE_RELEASED event but that
// seems kludgey, so we'd better left this as is for now.

MsgRouting
AwtScrollbar::WmMouseDown(UINT flags, int x, int y, int button)
{
    // We pass the WM_LBUTTONDOWN up to Java, but we process it
    // immediately as well to avoid the race.  Later when this press
    // event returns to us wrapped into a WM_AWT_HANDLE_EVENT we
    // ignore it in the HandleEvent below.  This means that we can not
    // consume the mouse press in the Java world.

    MsgRouting usualRoute = AwtComponent::WmMouseDown(flags, x, y, button);

    if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) {
        return mrConsume;
    }

    if (button == LEFT_BUTTON)
        return mrDoDefault;    // Force immediate processing to avoid the race.
    else
        return usualRoute;
}

MsgRouting
AwtScrollbar::HandleEvent(MSG *msg, BOOL synthetic)
{
    // SCROLLBAR control doesn't cause activation on mouse/key events,
    // so we can safely (for synthetic focus) pass them to the system proc.

    if (IsFocusingMouseMessage(msg)) {
        // Left button press was already routed to default window
        // procedure in the WmMouseDown above.  Propagating synthetic
        // press seems like a bad idea as internal message loop
        // doesn't know how to unwrap synthetic release.
        delete msg;
        return mrConsume;
    }
    return AwtComponent::HandleEvent(msg, synthetic);
}

// Work around a windows bug descrbed in KB article Q73839.  Reset
// focus on scrollbars to update focus indicator.  The article advises
// to disable/enable the scrollbar.
void
AwtScrollbar::UpdateFocusIndicator()
{
    if (IsFocusable()) {
        // todo: doesn't work
        SendMessage((WPARAM)ESB_DISABLE_BOTH);
        SendMessage((WPARAM)ESB_ENABLE_BOTH);
    }
}

// In a windows app one would call SetScrollInfo from WM_[HV]SCROLL
// handler directly.  Since we call SetScrollInfo from Java world
// after scroll handler is over next WM_[HV]SCROLL event can be
// delivered before SetScrollInfo was called in response to the
// previous one and thus we would fire exactly the same event which
// will only contribute to the growth of the backlog of scroll events.

const char * const AwtScrollbar::SbNlineDown = "lineDown";
const char * const AwtScrollbar::SbNlineUp   = "lineUp";
const char * const AwtScrollbar::SbNpageDown = "pageDown";
const char * const AwtScrollbar::SbNpageUp   = "pageUp";
const char * const AwtScrollbar::SbNdrag     = "drag";
const char * const AwtScrollbar::SbNdragEnd  = "dragEnd";
const char * const AwtScrollbar::SbNwarp     = "warp";

inline void
AwtScrollbar::DoScrollCallbackCoalesce(const char* methodName, int newPos)
{
    if (methodName == m_prevCallback && newPos == m_prevCallbackPos) {
        DTRACE_PRINTLN2("AwtScrollbar: ignoring duplicate callback %s(%d)",
                        methodName, newPos);
    }
    else {
        DoCallback(methodName, "(I)V", newPos);
        m_prevCallback = methodName;
        m_prevCallbackPos = newPos;
    }
}


MsgRouting
AwtScrollbar::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar)
{
    int minVal, maxVal;    // scrollbar range
    int minPos, maxPos;    // thumb positions (max depends on visible amount)
    int curPos, newPos;

    // For drags we have old (static) and new (dynamic) thumb positions
    int dragP = (scrollCode == SB_THUMBTRACK
              || scrollCode == SB_THUMBPOSITION);
    int thumbPos;

    SCROLLINFO si;
    si.cbSize = sizeof si;
    si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;

    // From, _Win32 Programming_, by Rector and Newcommer, p. 185:
    // "In some of the older documentation on Win32 scroll bars,
    // including that published by Microsoft, you may read that
    // you *cannot* obtain the scroll position while in a handler.
    // The SIF_TRACKPOS flag was added after this documentation
    // was published.  Beware of this older documentation; it may
    // have other obsolete features."
    if (dragP) {
        si.fMask |= SIF_TRACKPOS;
    }

    VERIFY(::GetScrollInfo(GetHWnd(), SB_CTL, &si));
    curPos = si.nPos;
    minPos = minVal = si.nMin;

    // Upper bound of the range.  Note that adding 1 here is safe
    // and won't cause a wrap, since we have substracted 1 in the
    // SetValues above.
    maxVal = si.nMax + 1;

    // Meaningful maximum position is maximum - visible.
    maxPos = maxVal - si.nPage;

    // XXX: Documentation for SBM_SETRANGE says that scrollbar
    // range is limited by MAXLONG, which is 2**31, but when a
    // scroll range is greater than that, thumbPos is reported
    // incorrectly due to integer arithmetic wrap(s).
    thumbPos = dragP ? si.nTrackPos : curPos;

    // NB: Beware arithmetic wrap when calculating newPos
    switch (scrollCode) {

      case SB_LINEUP:
          if ((__int64)curPos - m_lineIncr > minPos)
              newPos = curPos - m_lineIncr;
          else
              newPos = minPos;
          if (newPos != curPos)
              DoScrollCallbackCoalesce(SbNlineUp, newPos);
          break;

      case SB_LINEDOWN:
          if ((__int64)curPos + m_lineIncr < maxPos)
              newPos = curPos + m_lineIncr;
          else
              newPos = maxPos;
          if (newPos != curPos)
              DoScrollCallbackCoalesce(SbNlineDown, newPos);
          break;

      case SB_PAGEUP:
          if ((__int64)curPos - m_pageIncr > minPos)
              newPos = curPos - m_pageIncr;
          else
              newPos = minPos;
          if (newPos != curPos)
              DoScrollCallbackCoalesce(SbNpageUp, newPos);
          break;

      case SB_PAGEDOWN:
          if ((__int64)curPos + m_pageIncr < maxPos)
              newPos = curPos + m_pageIncr;
          else
              newPos = maxPos;
          if (newPos != curPos)
              DoScrollCallbackCoalesce(SbNpageDown, newPos);
          break;

      case SB_TOP:
          if (minPos != curPos)
              DoScrollCallbackCoalesce(SbNwarp, minPos);
          break;

      case SB_BOTTOM:
          if (maxPos != curPos)
              DoScrollCallbackCoalesce(SbNwarp, maxPos);
          break;

      case SB_THUMBTRACK:
          if (thumbPos != curPos)
              DoScrollCallbackCoalesce(SbNdrag, thumbPos);
          break;

      case SB_THUMBPOSITION:
          DoScrollCallbackCoalesce(SbNdragEnd, thumbPos);
          break;

      case SB_ENDSCROLL:
          // reset book-keeping info
          m_prevCallback = NULL;
          break;
    }
    return mrDoDefault;
}

MsgRouting
AwtScrollbar::WmHScroll(UINT scrollCode, UINT pos, HWND hScrollbar)
{
    return WmVScroll(scrollCode, pos, hScrollbar);
}

void AwtScrollbar::_SetValues(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetValuesStruct *svs = (SetValuesStruct *)param;
    jobject self = svs->scrollbar;

    SCROLLINFO si;
    si.cbSize = sizeof si;
    si.fMask  = SIF_POS | SIF_PAGE | SIF_RANGE;
    si.nMin   = svs->min;
    si.nMax   = svs->max - 1;
    si.nPage  = svs->visible;
    si.nPos   = svs->value;

    AwtScrollbar *sb = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    sb = (AwtScrollbar *)pData;
    if (::IsWindow(sb->GetHWnd()))
    {
        BOOL update_p = ::IsWindowEnabled(sb->GetHWnd()); // don't redraw if disabled
        DTRACE_PRINTLN5("AwtScrollbar::SetValues(val = %d, vis = %d,"//(ctd.)
                        " min = %d, max = %d)%s",
            svs->value, svs->visible, svs->min, svs->max,
            update_p ? "" : " - NOT redrawing");
        ::SetScrollInfo(sb->GetHWnd(), SB_CTL, &si, update_p);
    }
ret:
    env->DeleteGlobalRef(self);

    delete svs;
}

/************************************************************************
 * Scrollbar native methods
 */

extern "C" {

/*
 * Class:     java_awt_Scrollbar
 * Method:    initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_awt_Scrollbar_initIDs(JNIEnv *env, jclass cls)
{
    TRY;

    AwtScrollbar::lineIncrementID = env->GetFieldID(cls, "lineIncrement", "I");
    AwtScrollbar::pageIncrementID = env->GetFieldID(cls, "pageIncrement", "I");
    AwtScrollbar::orientationID = env->GetFieldID(cls, "orientation", "I");

    DASSERT(AwtScrollbar::lineIncrementID != NULL);
    DASSERT(AwtScrollbar::pageIncrementID != NULL);
    DASSERT(AwtScrollbar::orientationID != NULL);

    CATCH_BAD_ALLOC;
}

} /* extern "C" */


/************************************************************************
 * WScrollbarPeer native methods
 */

extern "C" {

/*
 * Class:     sun_awt_windows_WScrollbarPeer
 * Method:    setValues
 * Signature: (IIII)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_setValues(JNIEnv *env, jobject self,
                                              jint value, jint visible,
                                              jint minimum, jint maximum)
{
    TRY;

    SetValuesStruct *svs = new SetValuesStruct;
    svs->scrollbar = env->NewGlobalRef(self);
    svs->value = value;
    svs->visible = visible;
    svs->min = minimum;
    svs->max = maximum;

    AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetValues, svs);
    // global ref and svs are deleted in _SetValues

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WScrollbarPeer
 * Method:    setLineIncrement
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_setLineIncrement(JNIEnv *env, jobject self,
                                                     jint increment)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtScrollbar* c = (AwtScrollbar*)pData;
    c->SetLineIncrement(increment);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WScrollbarPeer
 * Method:    setPageIncrement
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_setPageIncrement(JNIEnv *env, jobject self,
                                                     jint increment)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtScrollbar* c = (AwtScrollbar*)pData;
    c->SetPageIncrement(increment);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WScrollbarPeer
 * Method:    create
 * Signature: (Lsun/awt/windows/WComponentPeer;)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_create(JNIEnv *env, jobject self,
                                           jobject parent)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(parent);
    AwtToolkit::CreateComponent(self, parent,
                                (AwtToolkit::ComponentFactory)
                                AwtScrollbar::Create);
    JNI_CHECK_PEER_CREATION_RETURN(self);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WScrollbarPeer
 * Method:    getScrollbarSize
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WScrollbarPeer_getScrollbarSize(JNIEnv *env, jclass clazz, jint orientation)
{
    if (orientation == java_awt_Scrollbar_VERTICAL) {
        return ::GetSystemMetrics(SM_CXVSCROLL);
    } else {
        return ::GetSystemMetrics(SM_CYHSCROLL);
    }
}

} /* extern "C" */
