/*
 * Class:     com_sun_glass_ui_gtk_GtkPixels
 * Method:    _attachByte
 * Signature: (JIILjava/nio/ByteBuffer;[BI)V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_gtk_GtkPixels__1attachByte
  (JNIEnv * env, jobject obj, jlong ptr, jint w, jint h, jobject bytes, jbyteArray array, jint offset)
{
    (void)obj;

    jbyte *data;
    GdkPixbuf **pixbuf;
    guint8 *dataRGBA;
    
    if (array == NULL) {
        data = (jbyte*) env->GetDirectBufferAddress(bytes);
        assert((w*h*4 + offset) == env->GetDirectBufferCapacity(bytes));
    } else {
        assert((w*h*4 + offset) == env->GetArrayLength(array));
        data = (jbyte*) env->GetPrimitiveArrayCritical(array, 0);
    }

    pixbuf = (GdkPixbuf**)JLONG_TO_PTR(ptr);
    dataRGBA = convert_BGRA_to_RGBA((const int*)(data + offset), w*4, h);
    *pixbuf = gdk_pixbuf_new_from_data(dataRGBA, GDK_COLORSPACE_RGB, TRUE, 8,
                  w, h, w * 4, (GdkPixbufDestroyNotify) my_free, NULL);
    if (array != NULL) {
        env->ReleasePrimitiveArrayCritical(array, data, 0);
    }
}
static jobject dnd_target_get_image(JNIEnv *env)
{
    GdkPixbuf *buf;
    GInputStream *stream;
    jobject result = NULL;
    GdkAtom targets[] = {
        TARGET_MIME_PNG_ATOM,
        TARGET_MIME_JPEG_ATOM,
        TARGET_MIME_TIFF_ATOM,
        TARGET_MIME_BMP_ATOM,
        0};
    GdkAtom *cur_target = targets;
    selection_data_ctx ctx;

    while(*cur_target != 0 && result == NULL) {
        if (dnd_target_receive_data(env, *cur_target, &ctx)) {
            stream = g_memory_input_stream_new_from_data(ctx.data, ctx.length * (ctx.format / 8),
                    (GDestroyNotify)g_free);
            buf = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
            if (buf) {
                int w;
                int h;
                int stride;
                guchar *data;
                jbyteArray data_array;
                jobject buffer;

                if (!gdk_pixbuf_get_has_alpha(buf)) {
                    GdkPixbuf *tmp_buf = gdk_pixbuf_add_alpha(buf, FALSE, 0, 0, 0);
                    g_object_unref(buf);
                    buf = tmp_buf;
                }
                
                w = gdk_pixbuf_get_width(buf);
                h = gdk_pixbuf_get_height(buf);
                stride = gdk_pixbuf_get_rowstride(buf);
                data = gdk_pixbuf_get_pixels(buf);

                //Actually, we are converting RGBA to BGRA, but that's the same operation
                data = (guchar*) convert_BGRA_to_RGBA((int*) data, stride, h);
                data_array = env->NewByteArray(stride * h);
                env->SetByteArrayRegion(data_array, 0, stride*h, (jbyte*) data);

                buffer = env->CallStaticObjectMethod(jByteBufferCls, jByteBufferWrap, data_array);
                result = env->NewObject(jGtkPixelsCls, jGtkPixelsInit, w, h, buffer);

                g_object_unref(buf);
                g_free(data); // data from convert_BGRA_to_RGBA
            }
            g_object_unref(stream);
        }
        ++cur_target;
    }
    return result;
}
static jobject get_data_image(JNIEnv* env) {
    GdkPixbuf* pixbuf;
    guchar *data;
    jbyteArray data_array;
    jobject buffer, result;
    int w,h,stride;

    pixbuf = gtk_clipboard_wait_for_image(get_clipboard());
    if (pixbuf == NULL) {
        return NULL;
    }

    if (!gdk_pixbuf_get_has_alpha(pixbuf)) {
        GdkPixbuf *tmp_buf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0);
        g_object_unref(pixbuf);
        pixbuf = tmp_buf;
    }
    w = gdk_pixbuf_get_width(pixbuf);
    h = gdk_pixbuf_get_height(pixbuf);
    stride = gdk_pixbuf_get_rowstride(pixbuf);

    data = gdk_pixbuf_get_pixels(pixbuf);

    //Actually, we are converting RGBA to BGRA, but that's the same operation
    data = (guchar*) convert_BGRA_to_RGBA((int*)data, stride, h);

    data_array = env->NewByteArray(stride*h);
    EXCEPTION_OCCURED(env);
    env->SetByteArrayRegion(data_array, 0, stride*h, (jbyte*)data);
    EXCEPTION_OCCURED(env);

    buffer = env->CallStaticObjectMethod(jByteBufferCls, jByteBufferWrap, data_array);
    result = env->NewObject(jGtkPixelsCls, jGtkPixelsInit, w, h, buffer);
    EXCEPTION_OCCURED(env);

    g_free(data);
    g_object_unref(pixbuf);

    return result;

}