/*
 * Copyright (c) 1996, 2005, 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_Label.h"
#include "awt_Canvas.h"
#include "awt_Win32GraphicsDevice.h"

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

/***********************************************************************/
// Struct for _SetText() method
struct SetTextStruct {
    jobject label;
    jstring text;
};
// Struct for _SetAlignment() method
struct SetAlignmentStruct {
    jobject label;
    jint alignment;
};
/************************************************************************
 * AwtLabel fields
 */

jfieldID AwtLabel::textID;
jfieldID AwtLabel::alignmentID;


/************************************************************************
 * AwtLabel methods
 */

AwtLabel::AwtLabel() {
    m_needPaint = FALSE;
}

LPCTSTR AwtLabel::GetClassName() {
    return TEXT("SunAwtLabel");
}

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

    jobject target = NULL;
    AwtLabel* awtLabel = 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, "awtParent", done);
        target  = env->GetObjectField(labelPeer, AwtObject::targetID);
        JNI_CHECK_NULL_GOTO(target, "target", done);

        awtLabel = new AwtLabel();

        {
            DWORD style = WS_CHILD | WS_CLIPSIBLINGS;

            DWORD exStyle = 0;
            if (GetRTLReadingOrder())
                exStyle |= WS_EX_RTLREADING;

            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);
            awtLabel->CreateHWnd(env, L"", style, exStyle,
                                 x, y, width, height,
                                 awtParent->GetHWnd(),
                                 NULL,
                                 ::GetSysColor(COLOR_WINDOWTEXT),
                                 ::GetSysColor(COLOR_BTNFACE),
                                 labelPeer);
        }
    } catch (...) {
        env->DeleteLocalRef(target);
        throw;
    }

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

void AwtLabel::DoPaint(HDC hDC, RECT& r)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 &&
        m_peerObject != NULL && m_callbacksEnabled) {

        if (env->EnsureLocalCapacity(3) < 0)
            return;
        long x,y;
        SIZE size;

        /* self is sun.awt.windows.WLabelPeer  */

        jobject self = GetPeer(env);
        DASSERT(self);

        /* target is java.awt.Label */
        jobject target = env->GetObjectField(self, AwtObject::targetID);
        jobject font = GET_FONT(target, self);
        jstring text = (jstring)env->GetObjectField(target, AwtLabel::textID);

        size = AwtFont::getMFStringSize(hDC, font, text);
        ::SetTextColor(hDC, GetColor());
        /* Redraw whole label to eliminate display noise during resizing. */
        VERIFY(::GetClientRect(GetHWnd(), &r));
        VERIFY(::FillRect (hDC, &r, GetBackgroundBrush()));
        y = (r.top + r.bottom - size.cy) / 2;

        jint alignment = env->GetIntField(target, AwtLabel::alignmentID);
        switch (alignment) {
           case java_awt_Label_LEFT:
              x = r.left + 2;
              break;
          case java_awt_Label_CENTER:
              x = (r.left + r.right - size.cx) / 2;
              break;
          case java_awt_Label_RIGHT:
              x = r.right - 2 - size.cx;
              break;
        }
        /* draw string */
        if (isEnabled()) {
            AwtComponent::DrawWindowText(hDC, font, text, x, y);
        } else {
            AwtComponent::DrawGrayText(hDC, font, text, x, y);
        }
        DoCallback("handlePaint", "(IIII)V",
                   r.left, r.top, r.right-r.left, r.bottom-r.top);
        env->DeleteLocalRef(target);
        env->DeleteLocalRef(font);
        env->DeleteLocalRef(text);
    }
}

void AwtLabel::LazyPaint()
{
    if (m_callbacksEnabled && m_needPaint ) {
        ::InvalidateRect(GetHWnd(), NULL, TRUE);
        m_needPaint = FALSE;
    }
}

void AwtLabel::Enable(BOOL bEnable)
{
    ::EnableWindow(GetHWnd(), bEnable);
    // Fix for Bug #4038881 Labels don't enable and disable properly
    // Fix for Bug #4096745 disable()/enable() make AWT components blink
    // This fix is moved from awt_Component.cpp for Bug #4096745
    ::InvalidateRect(GetHWnd(), NULL, FALSE);
    CriticalSection::Lock l(GetLock());
    VerifyState();
}


MsgRouting AwtLabel::WmEraseBkgnd(HDC hDC, BOOL& didErase)
{
    RECT r;

    ::GetClipBox(hDC, &r);
    ::FillRect(hDC, &r, this->GetBackgroundBrush());
    didErase = TRUE;
    return mrConsume;
}

MsgRouting AwtLabel::WmPaint(HDC)
{
    PAINTSTRUCT ps;
    HDC hDC = ::BeginPaint(GetHWnd(), &ps);/* the passed-in HDC is ignored. */
    DASSERT(hDC);

    /* fix for 4408606 - incorrect color palette used in 256 color mode */

    int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
    AwtWin32GraphicsDevice::SelectPalette(hDC, screen);

    RECT& r = ps.rcPaint;
    if (!m_callbacksEnabled) {
        m_needPaint = TRUE;
    } else {
        DoPaint(hDC, r);
    }
    VERIFY(::EndPaint(GetHWnd(), &ps));
    return mrConsume;
}

MsgRouting AwtLabel::WmPrintClient(HDC hDC, LPARAM)
{
    RECT r;

    // obtain valid DC from GDI stack
    ::RestoreDC(hDC, -1);

    ::GetClipBox(hDC, &r);
    DoPaint(hDC, r);
    return mrConsume;
}

void AwtLabel::_SetText(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetTextStruct *sts = (SetTextStruct *)param;
    jobject self = sts->label;
    jstring text = sts->text;

    AwtLabel *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtLabel *)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        l->SetText(JavaStringBuffer(env, text));
        VERIFY(::InvalidateRect(l->GetHWnd(), NULL, TRUE));
    }
ret:
    env->DeleteGlobalRef(self);
    env->DeleteGlobalRef(text);

    delete sts;
}

void AwtLabel::_SetAlignment(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetAlignmentStruct *sas = (SetAlignmentStruct *)param;
    jobject self = sas->label;
    jint alignment = sas->alignment;

    AwtLabel *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtLabel *)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        /*
         * alignment argument of multifont label is referred to in
         * WmDrawItem method
         */

        VERIFY(::InvalidateRect(l->GetHWnd(), NULL, TRUE));
    }
ret:
    env->DeleteGlobalRef(self);

    delete sas;
}

void AwtLabel::_LazyPaint(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    AwtLabel *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtLabel *)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        l->LazyPaint();
    }
ret:
    env->DeleteGlobalRef(self);
}


/************************************************************************
 * Label native methods
 */

extern "C" {

JNIEXPORT void JNICALL
Java_java_awt_Label_initIDs(JNIEnv *env, jclass cls)
{
    TRY;

    /* init field ids */
    AwtLabel::textID = env->GetFieldID(cls, "text", "Ljava/lang/String;");
    AwtLabel::alignmentID = env->GetFieldID(cls, "alignment", "I");

    DASSERT(AwtLabel::textID != NULL);
    DASSERT(AwtLabel::alignmentID != NULL);

    CATCH_BAD_ALLOC;
}

} /* extern "C" */


/************************************************************************
 * WLabelPeer native methods
 */

extern "C" {

/*
 * Class:     sun_awt_windows_WLabelPeer
 * Method:    setText
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WLabelPeer_setText(JNIEnv *env, jobject self,
                                        jstring text)
{
    TRY;

    SetTextStruct *sts = new SetTextStruct;
    sts->label = env->NewGlobalRef(self);
    sts->text = (jstring)env->NewGlobalRef(text);

    AwtToolkit::GetInstance().SyncCall(AwtLabel::_SetText, sts);
    // global refs and sts are deleted in _SetText()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WLabelPeer
 * Method:    setAlignment
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WLabelPeer_setAlignment(JNIEnv *env, jobject self,
                                             jint alignment)
{
    TRY;

    SetAlignmentStruct *sas = new SetAlignmentStruct;
    sas->label = env->NewGlobalRef(self);
    sas->alignment = alignment;

    AwtToolkit::GetInstance().SyncCall(AwtLabel::_SetAlignment, sas);
    // global ref and sas are deleted in _SetAlignment

    CATCH_BAD_ALLOC;
}

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

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

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WLabelPeer
 * Method:    lazyPaint
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WLabelPeer_lazyPaint(JNIEnv *env, jobject self)
{
    TRY;

    jobject selfGlobalRef = env->NewGlobalRef(self);

    AwtToolkit::GetInstance().SyncCall(AwtLabel::_LazyPaint, (void *)selfGlobalRef);
    // selfGlobalRef is deleted in _LazyPaint

    CATCH_BAD_ALLOC;
}

} /* export "C" */
