/*
 * Copyright (c) 1999, 2014, 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.h"
#include "awt_PrintDialog.h"
#include "awt_Dialog.h"
#include "awt_PrintControl.h"
#include "awt_Window.h"
#include "ComCtl32Util.h"
#include <sun_awt_windows_WPrintDialog.h>
#include <sun_awt_windows_WPrintDialogPeer.h>

jfieldID AwtPrintDialog::controlID;
jfieldID AwtPrintDialog::parentID;

jmethodID AwtPrintDialog::setHWndMID;

BOOL
AwtPrintDialog::PrintDlg(LPPRINTDLG data) {
    return static_cast<BOOL>(reinterpret_cast<INT_PTR>(
        AwtToolkit::GetInstance().InvokeFunction(
            reinterpret_cast<void *(*)(void *)>(::PrintDlg), data)));
}

LRESULT CALLBACK PrintDialogWndProc(HWND hWnd, UINT message,
                                    WPARAM wParam, LPARAM lParam)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    switch (message) {
        case WM_COMMAND: {
            if ((LOWORD(wParam) == IDOK) ||
                (LOWORD(wParam) == IDCANCEL))
            {
                // If we recieve on of these two notifications, the dialog
                // is about to be closed. It's time to unblock all the
                // windows blocked by this dialog, as doing so from the
                // WM_DESTROY handler is too late
                jobject peer = (jobject)(::GetProp(hWnd, ModalDialogPeerProp));
                env->CallVoidMethod(peer, AwtPrintDialog::setHWndMID, (jlong)0);
            }
            break;
        }
    }

    WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp));
    return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam);
}

static UINT_PTR CALLBACK
PrintDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    TRY;

    switch(uiMsg) {
        case WM_INITDIALOG: {
            PRINTDLG *pd = (PRINTDLG *)lParam;
            jobject peer = (jobject)(pd->lCustData);
            env->CallVoidMethod(peer, AwtPrintDialog::setHWndMID,
                                (jlong)hdlg);
            ::SetProp(hdlg, ModalDialogPeerProp, reinterpret_cast<HANDLE>(peer));

            // fix for 4632159 - disable CS_SAVEBITS
            DWORD style = ::GetClassLong(hdlg, GCL_STYLE);
            ::SetClassLong(hdlg,GCL_STYLE, style & ~CS_SAVEBITS);

            ::SetFocus(hdlg); // will not break synthetic focus as hdlg is a native toplevel

            // set appropriate icon for parentless dialogs
            jobject awtParent = env->GetObjectField(peer, AwtPrintDialog::parentID);
            if (awtParent == NULL) {
                ::SendMessage(hdlg, WM_SETICON, (WPARAM)ICON_BIG,
                              (LPARAM)AwtToolkit::GetInstance().GetAwtIcon());
            } else {
                env->DeleteLocalRef(awtParent);
            }

            // subclass dialog's parent to receive additional messages
            WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(hdlg,
                                                                           PrintDialogWndProc);
            ::SetProp(hdlg, NativeDialogWndProcProp, reinterpret_cast<HANDLE>(lpfnWndProc));

            break;
        }
        case WM_DESTROY: {
            WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hdlg, NativeDialogWndProcProp));
            ComCtl32Util::GetInstance().UnsubclassHWND(hdlg,
                                                       PrintDialogWndProc,
                                                       lpfnWndProc);
            ::RemoveProp(hdlg, ModalDialogPeerProp);
            ::RemoveProp(hdlg, NativeDialogWndProcProp);
            break;
        }
    }
    return FALSE;

    CATCH_BAD_ALLOC_RET(TRUE);
}

void AwtPrintDialog::_ToFront(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;
    HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID));
    if (::IsWindow(hdlg))
    {
        ::SetWindowPos(hdlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    }

    env->DeleteGlobalRef(self);
}

void AwtPrintDialog::_ToBack(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;
    HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID));
    if (::IsWindow(hdlg))
    {
        ::SetWindowPos(hdlg, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
    }

    env->DeleteGlobalRef(self);
}


extern "C" {
JNIEXPORT void JNICALL
Java_sun_awt_windows_WPrintDialog_initIDs(JNIEnv *env, jclass cls)
{
    TRY;

    AwtPrintDialog::controlID =
        env->GetFieldID(cls, "pjob", "Ljava/awt/print/PrinterJob;");
    DASSERT(AwtPrintDialog::controlID != NULL);

    AwtPrintControl::initIDs(env, cls);

    CATCH_BAD_ALLOC;
}

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

    AwtPrintDialog::parentID =
        env->GetFieldID(cls, "parent", "Lsun/awt/windows/WComponentPeer;");
    DASSERT(AwtPrintDialog::parentID != NULL);
    CHECK_NULL(AwtPrintDialog::parentID);

    AwtPrintDialog::setHWndMID =
        env->GetMethodID(cls, "setHWnd", "(J)V");
    DASSERT(AwtPrintDialog::setHWndMID != NULL);
    CHECK_NULL(AwtPrintDialog::setHWndMID);

    CATCH_BAD_ALLOC;
}

JNIEXPORT jboolean JNICALL
Java_sun_awt_windows_WPrintDialogPeer__1show(JNIEnv *env, jobject peer)
{
    TRY;

    jboolean result = JNI_FALSE;

    // as peer object is used later on another thread, create a global ref
    jobject peerGlobalRef = env->NewGlobalRef(peer);
    DASSERT(peerGlobalRef != NULL);
    CHECK_NULL_RETURN(peerGlobalRef, 0);
    jobject target = env->GetObjectField(peerGlobalRef, AwtObject::targetID);
    DASSERT(target != NULL);
    if (target == NULL) {
        env->DeleteGlobalRef(peerGlobalRef);
        return 0;
    }
    jobject parent = env->GetObjectField(peerGlobalRef, AwtPrintDialog::parentID);
    jobject control = env->GetObjectField(target, AwtPrintDialog::controlID);
    DASSERT(control != NULL);
    if (control == NULL) {
        env->DeleteGlobalRef(peerGlobalRef);
        env->DeleteLocalRef(target);
        if (parent != NULL) {
          env->DeleteLocalRef(parent);
        }
        return 0;
    }

    AwtComponent *awtParent = (parent != NULL) ? (AwtComponent *)JNI_GET_PDATA(parent) : NULL;
    HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL;

    PRINTDLG pd;
    memset(&pd, 0, sizeof(PRINTDLG));
    pd.lStructSize = sizeof(PRINTDLG);
    pd.lCustData = (LPARAM)peerGlobalRef;
    BOOL ret;
    try {
        ret = AwtPrintControl::InitPrintDialog(env, control, pd);
    } catch (std::bad_alloc&) {
        env->DeleteGlobalRef(peerGlobalRef);
        env->DeleteLocalRef(target);
        if (parent != NULL) {
          env->DeleteLocalRef(parent);
        }
        env->DeleteLocalRef(control);
        throw;
    }
    if (!ret) {
        /* Couldn't use the printer, or spooler isn't running
         * Call Page dialog with ' PD_RETURNDEFAULT' so it doesn't try
         * to show the dialog, but does prompt the user to install a printer.
         * If this returns false, then they declined and we just return.
         */
        pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
        ret = AwtPrintDialog::PrintDlg(&pd);
    }
    if (!ret) {
      result = JNI_FALSE;
    }
    else
    {
      pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDialogHookProc;
      pd.lpfnSetupHook = (LPSETUPHOOKPROC)PrintDialogHookProc;
      pd.Flags |= PD_ENABLESETUPHOOK | PD_ENABLEPRINTHOOK;
      /*
          Fix for 6488834.
          To disable Win32 native parent modality we have to set
          hwndOwner field to either NULL or some hidden window. For
          parentless dialogs we use NULL to show them in the taskbar,
          and for all other dialogs AwtToolkit's HWND is used.
      */
      if (awtParent != NULL)
      {
          pd.hwndOwner = AwtToolkit::GetInstance().GetHWnd();
      }
      else
      {
          pd.hwndOwner = NULL;
      }

      AwtDialog::CheckInstallModalHook();

      BOOL ret = AwtPrintDialog::PrintDlg(&pd);
      if (ret)
      {
        AwtPrintControl::UpdateAttributes(env, control, pd);
        result = JNI_TRUE;
      }
      else
      {
        result = JNI_FALSE;
      }

      DASSERT(env->GetLongField(peer, AwtComponent::hwndID) == 0L);

      AwtDialog::CheckUninstallModalHook();

      AwtDialog::ModalActivateNextWindow(NULL, target, peer);
    }

    env->DeleteGlobalRef(peerGlobalRef);
    env->DeleteLocalRef(target);
    if (parent != NULL) {
      env->DeleteLocalRef(parent);
    }
    env->DeleteLocalRef(control);

    return result;

    CATCH_BAD_ALLOC_RET(0);
}

JNIEXPORT void JNICALL
Java_sun_awt_windows_WPrintDialogPeer_toFront(JNIEnv *env, jobject peer)
{
    TRY;

    AwtToolkit::GetInstance().SyncCall(AwtPrintDialog::_ToFront,
                                       (void *)(env->NewGlobalRef(peer)));
    // global ref is deleted in _ToFront

    CATCH_BAD_ALLOC;
}

JNIEXPORT void JNICALL
Java_sun_awt_windows_WPrintDialogPeer_toBack(JNIEnv *env, jobject peer)
{
    TRY;

    AwtToolkit::GetInstance().SyncCall(AwtPrintDialog::_ToBack,
                                       (void *)(env->NewGlobalRef(peer)));
    // global ref is deleted in _ToBack

    CATCH_BAD_ALLOC;
}

} /* extern "C" */
