/*
 * Copyright 1999-2007 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.
 */

//#define USE_ERROR
//#define USE_TRACE


#include <jni.h>
#include "SoundDefs.h"
#include "PlatformMidi.h"
#include "Utilities.h"
// for strcpy
#include <string.h>
#include "com_sun_media_sound_MidiOutDeviceProvider.h"


#define MAX_STRING_LENGTH 128


JNIEXPORT jint JNICALL
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetNumDevices(JNIEnv* e, jobject thisObj) {

    INT32 numDevices = 0;

    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetNumDevices.\n");

#if USE_PLATFORM_MIDI_OUT == TRUE
    numDevices = MIDI_OUT_GetNumDevices();
#endif

    TRACE1("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetNumDevices returning %d.\n", (int) numDevices);
    return (jint) numDevices;
}


JNIEXPORT jstring JNICALL
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetName(JNIEnv* e, jobject thisObj, jint index) {

    char name[MAX_STRING_LENGTH + 1];
    jstring jString = NULL;

    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetName.\n");
    name[0] = 0;

#if USE_PLATFORM_MIDI_OUT == TRUE
    MIDI_OUT_GetDeviceName((INT32)index, name, (UINT32)MAX_STRING_LENGTH);
#endif

    if (name[0] == 0) {
        strcpy(name, "Unknown name");
    }
    jString = (*e)->NewStringUTF(e, name);
    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetName completed.\n");
    return jString;
}


JNIEXPORT jstring JNICALL
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVendor(JNIEnv* e, jobject thisObj, jint index) {

    char name[MAX_STRING_LENGTH + 1];
    jstring jString = NULL;

    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVendor.\n");
    name[0] = 0;

#if USE_PLATFORM_MIDI_OUT == TRUE
    MIDI_OUT_GetDeviceVendor((INT32)index, name, (UINT32)MAX_STRING_LENGTH);
#endif

    if (name[0] == 0) {
        strcpy(name, "Unknown vendor");
    }
    jString = (*e)->NewStringUTF(e, name);
    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVendor completed.\n");
    return jString;
}


JNIEXPORT jstring JNICALL
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetDescription(JNIEnv* e, jobject thisObj, jint index) {

    char name[MAX_STRING_LENGTH + 1];
    jstring jString = NULL;

    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetDescription.\n");
    name[0] = 0;

#if USE_PLATFORM_MIDI_OUT == TRUE
    MIDI_OUT_GetDeviceDescription((INT32)index, name, (UINT32)MAX_STRING_LENGTH);
#endif

    if (name[0] == 0) {
        strcpy(name, "No details available");
    }
    jString = (*e)->NewStringUTF(e, name);
    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetDescription completed.\n");
    return jString;
}


JNIEXPORT jstring JNICALL
Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVersion(JNIEnv* e, jobject thisObj, jint index) {

    char name[MAX_STRING_LENGTH + 1];
    jstring jString = NULL;

    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVersion.\n");
    name[0] = 0;

#if USE_PLATFORM_MIDI_OUT == TRUE
    MIDI_OUT_GetDeviceVersion((INT32)index, name, (UINT32)MAX_STRING_LENGTH);
#endif
    if (name[0] == 0) {
        strcpy(name, "Unknown version");
    }
    jString = (*e)->NewStringUTF(e, name);

    TRACE0("Java_com_sun_media_sound_MidiOutDeviceProvider_nGetVersion completed.\n");

    return jString;
}
