/*
 * Copyright 1996-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#ifdef HEADLESS
    #error This file should not be included in headless library
#endif

#include "awt_p.h"
#include "java_awt_Component.h"
#include "sun_awt_motif_MComponentPeer.h"

#include "awt_Component.h"


#include <jni.h>
#include <jni_util.h>
#include <jawt_md.h>

extern struct MComponentPeerIDs mComponentPeerIDs;
extern struct ComponentIDs componentIDs;
#ifndef XAWT
extern AwtGraphicsConfigDataPtr
getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);
#endif

#ifdef XAWT
#include "awt_GraphicsEnv.h"
extern jfieldID windowID;
extern jfieldID targetID;
extern jfieldID graphicsConfigID;
extern jfieldID drawStateID;
extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
#endif

/*
 * Lock the surface of the target component for native rendering.
 * When finished drawing, the surface must be unlocked with
 * Unlock().  This function returns a bitmask with one or more of the
 * following values:
 *
 * JAWT_LOCK_ERROR - When an error has occurred and the surface could not
 * be locked.
 *
 * JAWT_LOCK_CLIP_CHANGED - When the clip region has changed.
 *
 * JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed.
 *
 * JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed
 */
JNIEXPORT jint JNICALL awt_DrawingSurface_Lock(JAWT_DrawingSurface* ds)
{
    JNIEnv* env;
    jobject target, peer;
    jclass componentClass;
    jint drawState;

    if (ds == NULL) {
#ifdef DEBUG
        fprintf(stderr, "Drawing Surface is NULL\n");
#endif
        return (jint)JAWT_LOCK_ERROR;
    }
    env = ds->env;
    target = ds->target;

    /* Make sure the target is a java.awt.Component */
    componentClass = (*env)->FindClass(env, "java/awt/Component");
    if (!(*env)->IsInstanceOf(env, target, componentClass)) {
#ifdef DEBUG
            fprintf(stderr, "Target is not a component\n");
#endif
        return (jint)JAWT_LOCK_ERROR;
        }

    if (!awtLockInited) {
        return (jint)JAWT_LOCK_ERROR;
    }
    AWT_LOCK();

    /* Get the peer of the target component */
    peer = (*env)->GetObjectField(env, target, componentIDs.peer);
    if (JNU_IsNull(env, peer)) {
#ifdef DEBUG
        fprintf(stderr, "Component peer is NULL\n");
#endif
                AWT_FLUSH_UNLOCK();
        return (jint)JAWT_LOCK_ERROR;
    }

#ifndef XAWT
    drawState = (*env)->GetIntField(env, peer, mComponentPeerIDs.drawState);
    (*env)->SetIntField(env, peer, mComponentPeerIDs.drawState, 0);
#else
   drawState = (*env)->GetIntField(env, peer, drawStateID);
    (*env)->SetIntField(env, peer, drawStateID, 0);
#endif
    return drawState;
}

JNIEXPORT int32_t JNICALL
    awt_GetColor(JAWT_DrawingSurface* ds, int32_t r, int32_t g, int32_t b)
{
    JNIEnv* env;
    jobject target, peer;
    jclass componentClass;
    AwtGraphicsConfigDataPtr adata;
    int32_t result;
#ifdef XAWT
     jobject gc_object;
#endif
    if (ds == NULL) {
#ifdef DEBUG
        fprintf(stderr, "Drawing Surface is NULL\n");
#endif
        return (int32_t) 0;
    }

    env = ds->env;
    target = ds->target;

    /* Make sure the target is a java.awt.Component */
    componentClass = (*env)->FindClass(env, "java/awt/Component");
    if (!(*env)->IsInstanceOf(env, target, componentClass)) {
#ifdef DEBUG
        fprintf(stderr, "DrawingSurface target must be a component\n");
#endif
        return (int32_t) 0;
    }

    if (!awtLockInited) {
        return (int32_t) 0;
    }

    AWT_LOCK();

    /* Get the peer of the target component */
    peer = (*env)->GetObjectField(env, target, componentIDs.peer);
    if (JNU_IsNull(env, peer)) {
#ifdef DEBUG
        fprintf(stderr, "Component peer is NULL\n");
#endif
        AWT_UNLOCK();
        return (int32_t) 0;
    }
#ifndef XAWT
    adata = getGraphicsConfigFromComponentPeer(env, peer);
#else
     /* GraphicsConfiguration object of MComponentPeer */
    gc_object = (*env)->GetObjectField(env, peer, graphicsConfigID);

    if (gc_object != NULL) {
        adata = (AwtGraphicsConfigDataPtr)
            JNU_GetLongFieldAsPtr(env, gc_object,
                                  x11GraphicsConfigIDs.aData);
    } else {
        adata = getDefaultConfig(DefaultScreen(awt_display));
    }
#endif

    result = adata->AwtColorMatch(r, g, b, adata);
        AWT_UNLOCK();
        return result;
}

/*
 * Get the drawing surface info.
 * The value returned may be cached, but the values may change if
 * additional calls to Lock() or Unlock() are made.
 * Lock() must be called before this can return a valid value.
 * Returns NULL if an error has occurred.
 * When finished with the returned value, FreeDrawingSurfaceInfo must be
 * called.
 */
JNIEXPORT JAWT_DrawingSurfaceInfo* JNICALL
awt_DrawingSurface_GetDrawingSurfaceInfo(JAWT_DrawingSurface* ds)
{
    JNIEnv* env;
    jobject target, peer;
    jclass componentClass;
    JAWT_X11DrawingSurfaceInfo* px;
    JAWT_DrawingSurfaceInfo* p;
#ifndef XAWT
    struct ComponentData *cdata;
#endif
    XWindowAttributes attrs;

    if (ds == NULL) {
#ifdef DEBUG
        fprintf(stderr, "Drawing Surface is NULL\n");
#endif
        return NULL;
    }

    env = ds->env;
    target = ds->target;

    /* Make sure the target is a java.awt.Component */
    componentClass = (*env)->FindClass(env, "java/awt/Component");
    if (!(*env)->IsInstanceOf(env, target, componentClass)) {
#ifdef DEBUG
        fprintf(stderr, "DrawingSurface target must be a component\n");
#endif
        return NULL;
        }

    if (!awtLockInited) {
        return NULL;
    }

    AWT_LOCK();

    /* Get the peer of the target component */
    peer = (*env)->GetObjectField(env, target, componentIDs.peer);
    if (JNU_IsNull(env, peer)) {
#ifdef DEBUG
        fprintf(stderr, "Component peer is NULL\n");
#endif
                AWT_UNLOCK();
        return NULL;
    }

#ifndef XAWT
    /* Get the component data from the peer */
    cdata = (struct ComponentData *)
        JNU_GetLongFieldAsPtr(env, peer, mComponentPeerIDs.pData);
    if (cdata == NULL) {
#ifdef DEBUG
        fprintf(stderr, "Component data is NULL\n");
#endif
                AWT_UNLOCK();
        return NULL;
    }
#endif

        AWT_UNLOCK();

    /* Allocate platform-specific data */
    px = (JAWT_X11DrawingSurfaceInfo*)
        malloc(sizeof(JAWT_X11DrawingSurfaceInfo));

    /* Set drawable and display */
#ifndef XAWT
    px->drawable = XtWindow(cdata->widget);
#else
    px->drawable = JNU_GetLongFieldAsPtr(env, peer, windowID);
#endif
    px->display = awt_display;

    /* Get window attributes to set other values */
    XGetWindowAttributes(awt_display, (Window)(px->drawable), &attrs);

    /* Set the other values */
    px->visualID = XVisualIDFromVisual(attrs.visual);
    px->colormapID = attrs.colormap;
    px->depth = attrs.depth;
    px->GetAWTColor = awt_GetColor;

    /* Allocate and initialize platform-independent data */
    p = (JAWT_DrawingSurfaceInfo*)malloc(sizeof(JAWT_DrawingSurfaceInfo));
    p->platformInfo = px;
    p->ds = ds;
    p->bounds.x = (*env)->GetIntField(env, target, componentIDs.x);
    p->bounds.y = (*env)->GetIntField(env, target, componentIDs.y);
    p->bounds.width = (*env)->GetIntField(env, target, componentIDs.width);
    p->bounds.height = (*env)->GetIntField(env, target, componentIDs.height);
    p->clipSize = 1;
    p->clip = &(p->bounds);

    /* Return our new structure */
    return p;
}

/*
 * Free the drawing surface info.
 */
JNIEXPORT void JNICALL
awt_DrawingSurface_FreeDrawingSurfaceInfo(JAWT_DrawingSurfaceInfo* dsi)
{
    if (dsi == NULL ) {
#ifdef DEBUG
        fprintf(stderr, "Drawing Surface Info is NULL\n");
#endif
    }
    free(dsi->platformInfo);
    free(dsi);
}

/*
 * Unlock the drawing surface of the target component for native rendering.
 */
JNIEXPORT void JNICALL awt_DrawingSurface_Unlock(JAWT_DrawingSurface* ds)
{
    JNIEnv* env;
    if (ds == NULL) {
#ifdef DEBUG
        fprintf(stderr, "Drawing Surface is NULL\n");
#endif
        return;
    }
    env = ds->env;
    AWT_FLUSH_UNLOCK();
}

JNIEXPORT JAWT_DrawingSurface* JNICALL
    awt_GetDrawingSurface(JNIEnv* env, jobject target)
{
    jclass componentClass;
    JAWT_DrawingSurface* p;

    /* Make sure the target component is a java.awt.Component */
    componentClass = (*env)->FindClass(env, "java/awt/Component");
    if (!(*env)->IsInstanceOf(env, target, componentClass)) {
#ifdef DEBUG
        fprintf(stderr,
            "GetDrawingSurface target must be a java.awt.Component\n");
#endif
        return NULL;
    }

    p = (JAWT_DrawingSurface*)malloc(sizeof(JAWT_DrawingSurface));
    p->env = env;
    p->target = (*env)->NewGlobalRef(env, target);
    p->Lock = awt_DrawingSurface_Lock;
    p->GetDrawingSurfaceInfo = awt_DrawingSurface_GetDrawingSurfaceInfo;
    p->FreeDrawingSurfaceInfo = awt_DrawingSurface_FreeDrawingSurfaceInfo;
    p->Unlock = awt_DrawingSurface_Unlock;
    return p;
}

JNIEXPORT void JNICALL
    awt_FreeDrawingSurface(JAWT_DrawingSurface* ds)
{
    JNIEnv* env;

    if (ds == NULL ) {
#ifdef DEBUG
        fprintf(stderr, "Drawing Surface is NULL\n");
#endif
        return;
    }
    env = ds->env;
    (*env)->DeleteGlobalRef(env, ds->target);
    free(ds);
}

JNIEXPORT void JNICALL
    awt_Lock(JNIEnv* env)
{
    if (awtLockInited) {
        AWT_LOCK();
    }
}

JNIEXPORT void JNICALL
    awt_Unlock(JNIEnv* env)
{
    if (awtLockInited) {
        AWT_FLUSH_UNLOCK();
    }
}

JNIEXPORT jobject JNICALL
    awt_GetComponent(JNIEnv* env, void* platformInfo)
{
    Window window = (Window)platformInfo;
    Widget widget = NULL;
    jobject peer = NULL;
    jobject target = NULL;

    AWT_LOCK();

#ifndef XAWT
    if (window != None) {
        widget = XtWindowToWidget(awt_display, window);
    }

    if (widget != NULL) {
        XtVaGetValues (widget, XmNuserData, &peer, NULL);
    }

    if (peer != NULL) {
        target = (*env)->GetObjectField(env, peer, mComponentPeerIDs.target);
    }
#else
    target =  (*env)->GetObjectField(env, peer, targetID);
#endif

    if (target == NULL) {
        JNU_ThrowNullPointerException(env, "NullPointerException");
        AWT_UNLOCK();
        return (jobject)NULL;
    }


    AWT_UNLOCK();

    return target;
}
