//- ****************************************************************************
//-
//- Copyright 2009 National Technology & Engineering Solutions of Sandia, LLC
//- (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
//- Government retains certain rights in this software.
//-
//- BSD Open Source License
//- All rights reserved.
//-
//- Redistribution and use in source and binary forms, with or without
//- modification, are permitted provided that the following conditions are met:
//-
//-   1. Redistributions of source code must retain the above copyright notice,
//-      this list of conditions and the following disclaimer.
//-
//-   2. Redistributions in binary form must reproduce the above copyright
//-      notice, this list of conditions and the following disclaimer in the
//-      documentation and/or other materials provided with the distribution.
//-
//-   3. Neither the name of the copyright holder nor the names of its
//-      contributors may be used to endorse or promote products derived from
//-      this software without specific prior written permission.
//-
//- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
//- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//- POSSIBILITY OF SUCH DAMAGE.
//-
//- ****************************************************************************


// SLBM JNI interface

#include "SlbmInterfaceJNI.h"
#include "SLBMGlobals.h"
#include "SlbmInterfaceToJNI.h"
#include "pglJavaUtil.h"
#include "InterpolatedProfile.h"
#include "Location.h"

#include <string>
#include <vector>

using namespace std;

using namespace slbm;


// make a quick function to convert ints to strings to avoid C++11 to_str()
string to_str(const int &i)
{
    ostringstream os;
    os << i;
    return os.str();
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
// SlbmInterfaceJNI typecast for use in finding the object with the slbm utility
// code.
//
// *****************************************************************************
extern "C" JNIEXPORT void* SlbmInterfaceJNI_Typecast(
    void *me, const string& dType)
{
  return me;
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to the SlbmInterfaceJNI Constructor (no args)
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_SlbmInterfaceNative(
    JNIEnv *env, jobject obj)
{
  // create a SlbmInterfaceJNI
  SlbmInterfaceToJNI* slbm = new SlbmInterfaceToJNI();

  // register this java SlbmInterfaceJNI object as associated with the new C++
  // SlbmInterfaceJNI object
  int id = pglJavaRegisterNewObject(env, obj, (void *)slbm);
  pglJavaRegisterCastFunction(env, obj, id, (void *)SlbmInterfaceJNI_Typecast);
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to the SlbmInterfaceJNI Constructor (1 arg)
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_SlbmInterfaceFixedEarthRadiusNative(
    JNIEnv *env, jobject obj, jdouble earthRadius)
{
  // create a SlbmInterfaceJNI
  SlbmInterfaceToJNI* slbm = new SlbmInterfaceToJNI(earthRadius);

  // register this java SlbmInterfaceJNI object as associated with the new C++
  // SlbmInterfaceJNI object
  int id = pglJavaRegisterNewObject(env, obj, (void *)slbm);
  pglJavaRegisterCastFunction(env, obj, id, (void *)SlbmInterfaceJNI_Typecast);
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to the SlbmInterfaceJNI Constructor (no args)
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_closeNative(
    JNIEnv *env, jobject obj)
{
  // create a SlbmInterfaceJNI
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    delete slbm;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to void SlbmInterfaceJNI::loadVelocityModel(string& modelFileName);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_loadVelocityModelNative(
    JNIEnv *env, jobject obj, jstring jmodelFileName)
{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    string modelFileName;
    pglJavaUTFToString(env, jmodelFileName, modelFileName);

    try
    {
        slbm->loadVelocityModel(modelFileName);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to void SlbmInterfaceJNI::saveVelocityModel(string& modelFileName);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_saveVelocityModelNative(
    JNIEnv *env, jobject obj, jstring jmodelFileName, jint format)
{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    string modelFileName;
    pglJavaUTFToString(env, jmodelFileName, modelFileName);

    try
    {
        slbm->saveVelocityModel(modelFileName, format);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    //cout << "Java_gov_sandia_gnem_slbmjni_SlbmInterface_saveVelocityModelNative  return" << endl;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		void specifyOutputDirectoryNative( String directoryName );
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_specifyOutputDirectoryNative(
    JNIEnv *env, jobject obj, jstring jmodelDirectory )

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    string modeldirectory;
    pglJavaUTFToString(env, jmodelDirectory, modeldirectory);

    try
    {
        slbm->specifyOutputDirectory( modeldirectory );
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		void saveVelocityModelBinaryNative()
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_saveVelocityModelBinaryNative(
    JNIEnv *env, jobject obj )

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->saveVelocityModelBinary();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to 
//	bool createGreatCircle(const string& phase,
//					const double& sourceLat,
//					const double& sourceLon,
//					const double& sourceDepth,
//					const double& receiverLat,
//					const double& receiverLon,
//					const double& receiverDepth);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_createGreatCircleNative(
    JNIEnv *env, jobject obj, jint phase, jdouble sourceLat, jdouble sourceLon, jdouble sourceDepth, 
    jdouble receiverLat, jdouble receiverLon, jdouble receiverDepth)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->createGreatCircle(
            phase,
            sourceLat,
            sourceLon,
            sourceDepth,
            receiverLat,
            receiverLon,
            receiverDepth);

    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to 
//	bool createGreatCircle(const string& phase,
//					const double& sourceLat,
//					const double& sourceLon,
//					const double& sourceDepth,
//					const double& receiverLat,
//					const double& receiverLon,
//					const double& receiverDepth);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_clearNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->clear();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	String getPhase();
//
// *****************************************************************************
extern "C" JNIEXPORT jstring JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getPhaseNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJavaString(env, slbm->getPhase());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	String toString(const int& verbosity);
//
// *****************************************************************************
extern "C" JNIEXPORT jstring JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_toStringNative(
    JNIEnv *env, jobject obj, jint verbosity)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJavaString(env, slbm->toString(verbosity));
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	bool getTravelTime(double& travelTime);
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getTravelTimeNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double tt;
        slbm->getTravelTime(tt);
        jdouble jtravelTime = tt;
        return jtravelTime;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		bool getTravelTimeComponents(double& tTotal, double& tSource, double& tReceiver, 
//			double& tHeadwave, double& tGradient);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getTravelTimeComponentsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double t[5];
        slbm->getTravelTimeComponents(t[0], t[1], t[2], t[3], t[4]);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, t, 5);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getDistance();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDistanceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->getDistance(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getSourceDistance();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getSourceDistanceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->getSourceDistance(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getReceiverDistance();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getReceiverDistanceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->getReceiverDistance(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getHeadwaveDistance();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getHeadwaveDistanceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->getHeadwaveDistance(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getHeadwaveDistanceKm();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getHeadwaveDistanceKmNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->getHeadwaveDistanceKm(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void computeWeights() { SlbmInterface::getWeights(nodes, weights); };
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_computeWeightsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        slbm->computeWeights();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void computeWeightsSource() { SlbmInterface::getWeightsSource(nodes, weights); };
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_computeWeightsSourceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        slbm->computeWeightsSource();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void computeWeightsReceiver() { SlbmInterface::getWeightsReceiver(nodes, weights); };
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_computeWeightsReceiverNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        slbm->computeWeightsReceiver();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void deleteWeights() { nodes.clear(); weights.clear(); };
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_deleteWeightsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        slbm->deleteWeights();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<int>& getWeightNodes() { return nodes; };
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getWeightNodesNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        return javaMakeJArrayOfIntFromVector(env, slbm->getWeightNodes());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& getWeights() { return weights; };
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getWeightsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        return javaMakeJArrayOfDoubleFromVector(env, slbm->getWeights());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}



// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void createQueryProfile(const double& lat, const double& lon);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_createQueryProfileNative(
    JNIEnv *env, jobject obj, jdouble lat, jdouble lon)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->createQueryProfile(lat, lon);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void deleteQueryProfile();
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_deleteQueryProfileNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->deleteQueryProfile();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	string getQueryNodeId(vector<int>& nodeIds);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getQueryNodeIdNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return javaMakeJArrayOfIntFromVector(env, slbm->getQueryNodeId());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const double* SlbmInterfaceJNI::getQueryCoefficient()
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getQueryCoefficientNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return javaMakeJArrayOfDoubleFromVector(env, slbm->getQueryCoefficient());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& SlbmInterfaceJNI::getQueryDepth()
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getQueryDepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJArrayOfDoubleFromDouble(env, slbm->getQueryDepth(), NLAYERS);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& SlbmInterfaceJNI::getQueryVelocity(const int& waveType)
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getQueryVelocityNative(
    JNIEnv *env, jobject obj, jint waveType)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJArrayOfDoubleFromDouble(env, slbm->getQueryVelocity(waveType), NLAYERS);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& SlbmInterfaceJNI::getQueryGradient()
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getQueryGradientNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJArrayOfDoubleFromDouble(env, slbm->getQueryGradient(), 2);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void accessGridProfile(const int& nodeId);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_accessGridProfileNative(
    JNIEnv *env, jobject obj, jint nodeId)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->accessGridProfile(nodeId);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double SlbmInterfaceJNI::getGridLat()
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGridLatNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getGridLat();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double SlbmInterfaceJNI::getGridLon()
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGridLonNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getGridLon();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& SlbmInterfaceJNI::getGridDepth()
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGridDepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        vector<double> depths;
        slbm->getGridDepth(depths);
        return javaMakeJArrayOfDoubleFromVector(env, depths);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& SlbmInterfaceJNI::getGridVelocity(const int& waveType)
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGridVelocityNative(
    JNIEnv *env, jobject obj, jint waveType)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double* v = new double[NLAYERS];
        slbm->getGridVelocity(waveType, v);
        jarray ret = pglJavaMakeJArrayOfDoubleFromDouble(env, v, NLAYERS);
        delete[] v;
        return ret;
        //return pglJavaMakeJArrayOfDoubleFromDouble(env, slbm->getGridVelocity(waveType), NLAYERS);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& SlbmInterfaceJNI::getGridGradient()
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGridGradientNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double* g = new double[2];
        slbm->getGridGradient(g);
        jarray ret = pglJavaMakeJArrayOfDoubleFromDouble(env, g, 2);
        delete[] g;
        return ret;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void SlbmInterfaceJNI::setGridDepth(double* depths)
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setGridDataNative(
    JNIEnv *env, jobject obj, jint jnodeid, jdoubleArray jdepths, jdoubleArray jpvelocities, jdoubleArray jsvelocities, jdoubleArray jgradients)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    // used to use vectors for this procedure, but started getting null pointer
    // exceptios that i could not get rid of.  Swtiching to arrays fixed it !?!?!?!?
    // sb. 2/2013
//	vector<double> depth;
//	javaMakeVectorOfDoubleFromJArray(env, jdepth, depth);

    int size, two;

    int nodeid = jnodeid;

    double depths[NLAYERS];
    javaMakeArrayOfDoubleFromJArray(env, jdepths, depths, NLAYERS, size);

    double pvelocities[NLAYERS];
    javaMakeArrayOfDoubleFromJArray(env, jpvelocities, pvelocities, NLAYERS, size);

    double svelocities[NLAYERS];
    javaMakeArrayOfDoubleFromJArray(env, jsvelocities, svelocities, NLAYERS, size);

    double gradients[2];
        javaMakeArrayOfDoubleFromJArray(env, jgradients, gradients, NLAYERS, two);

    try
    {
        slbm->setGridData(nodeid, depths, pvelocities, svelocities, gradients);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////	void SlbmInterfaceJNI::setGridVelocity(const int& waveType, double* velocity)
////
//// *****************************************************************************
//extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setGridDepthNative(
//	JNIEnv *env, jobject obj, jdoubleArray jdepths)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	vector<double> depths;
//	javaMakeVectorOfDoubleFromJArray(env, jdepths, depths);
//
//	try
//	{
//		slbm->setGridDepths(depths);
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//	}
//}
//
//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////	void SlbmInterfaceJNI::setGridVelocity(const int& waveType, double* velocity)
////
//// *****************************************************************************
//extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setGridVelocityNative(
//	JNIEnv *env, jobject obj, jint waveType, jdoubleArray jvelocity)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	vector<double> velocity;
//	javaMakeVectorOfDoubleFromJArray(env, jvelocity, velocity);
//
//	try
//	{
//		slbm->setGridVelocity(waveType, velocity);
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//	}
//}
//
//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////	void SlbmInterfaceJNI::setGridGradient(double* gradients)
////
//// *****************************************************************************
//extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setGridGradientNative(
//	JNIEnv *env, jobject obj, jdoubleArray jgradient)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	vector<double> gradient;
//	javaMakeVectorOfDoubleFromJArray(env, jgradient, gradient);
//
//	try
//	{
//		slbm->setGridGradient(gradient);
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//	}
//}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	string getGreatCirclePhase();
//
// *****************************************************************************
extern "C" JNIEXPORT jstring JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCirclePhaseNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJavaString(env, slbm->getGreatCirclePhase());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double getActualPathIncrement();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getActualPathIncrementNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getActualPathIncrement();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double getPathIncrement();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getPathIncrementNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getPathIncrement();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void setPathIncrement(double pathIncrement);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setPathIncrementNative(
    JNIEnv *env, jobject obj, jdouble pathIncrement)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->setPathIncrement(pathIncrement);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void getGreatCircleNeighbors(const int& i, int* nodeIds);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleNeighborsNative(
    JNIEnv *env, jobject obj, jint i)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int nodeId[100];
        int nCoefficients;
        slbm->getGreatCircleNeighbors(i, nodeId, nCoefficients);
        return pglJavaMakeJArrayOfIntFromInt(env, nodeId, nCoefficients);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const double*  getGreatCircleCoefficients(const int& i);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleCoefficientsNative(
    JNIEnv *env, jobject obj, jint i)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double coefficients[100];
        int nCoefficients;
        slbm->getGreatCircleCoefficients(i, coefficients, nCoefficients);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, coefficients, nCoefficients);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void getGreatCircleSourceDepth(double* depths, int& n);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleSourceDepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int n;
        double depths[NLAYERS];
        slbm->getGreatCircleSourceDepth(depths, n);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, depths, n);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void getGreatCircleReceiverDepth(double* depths, int& n);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleReceiverDepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int n;
        double depths[NLAYERS];
        slbm->getGreatCircleReceiverDepth(depths, n);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, depths, n);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double* getGreatCircleSourceVelocity(int& n);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleSourceVelocityNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int n;
        double* velocities = slbm->getGreatCircleSourceVelocity(n);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, velocities, n);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double* getGreatCircleReceiverVelocity(int& n);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleReceiverVelocityNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int n;
        double* velocities = slbm->getGreatCircleReceiverVelocity(n);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, velocities, n);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void getGreatCircleHeadwaveVelocity(vector<double>& velocities);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleHeadwaveVelocityNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        vector<double> hwv;
        slbm->getGreatCircleHeadwaveVelocity(hwv);
        return javaMakeJArrayOfDoubleFromVector(env, hwv);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void getGreatCircleHeadwaveGradient(vector<double>& gradients);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCircleHeadwaveGradientNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        vector<double> x;
        slbm->getGreatCircleHeadwaveGradient(x);
        return javaMakeJArrayOfDoubleFromVector(env, x);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void computeGreatCircleLocations()
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_computeGreatCircleLocationsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        slbm->computeGreatCircleLocations();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void computeGreatCirclePoints()
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_computeGreatCirclePointsNative(
    JNIEnv *env, jobject obj, jdouble sourceLat, jdouble sourceLon, 
    jdouble receiverLat, jdouble receiverLon, jint npoints, jboolean onCenters)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        slbm->computeGreatCirclePoints(
            sourceLat,
            sourceLon,
            receiverLat,
            receiverLon,
            npoints,
            onCenters);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void deleteGreatCirclePoints() 
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_deleteGreatCirclePointsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        slbm->deleteGreatCirclePoints();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& getGreatCirclePointsLat() 
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCirclePointsLatNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        return javaMakeJArrayOfDoubleFromVector(env, slbm->getGreatCirclePointsLat());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& getGreatCirclePointsLon() 
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCirclePointsLonNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        return javaMakeJArrayOfDoubleFromVector(env, slbm->getGreatCirclePointsLon());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	const vector<double>& getGreatCirclePointsDepth() 
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGreatCirclePointsDepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
    try
    {
        return javaMakeJArrayOfDoubleFromVector(env, slbm->getGreatCirclePointsDepth());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double* getCoefficients();
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getSourceCoefficientsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double coefficients[100];
        int nCoefficients;
        slbm->getGreatCircleObject()->getSourceProfile()->getCoefficients(coefficients, nCoefficients);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, coefficients, nCoefficients);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double* getCoefficients();
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getReceiverCoefficientsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double coefficients[100];
        int nCoefficients;
        slbm->getGreatCircleObject()->getReceiverProfile()->getCoefficients(coefficients, nCoefficients);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, coefficients, nCoefficients);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double* getNodeIds();
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getSourceNodeIdsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int nodes[100];
        int nCoefficients;
        slbm->getGreatCircleObject()->getSourceProfile()->getNodeIds(nodes, nCoefficients);
        return pglJavaMakeJArrayOfIntFromInt(env, nodes, nCoefficients);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double* getNodeIds();
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getReceiverNodeIdsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int nodes[100];
        int nCoefficients;
        slbm->getGreatCircleObject()->getReceiverProfile()->getNodeIds(nodes, nCoefficients);
        return pglJavaMakeJArrayOfIntFromInt(env, nodes, nCoefficients);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void SlbmInterfaceJNI::getTravelTimeUncertaintyPhaseDistance(const int& phase, const double& distance, double& uncert)
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getTravelTimeUncertaintyPhaseDistanceNative(
    JNIEnv *env, jobject obj, jint phase, jdouble distance)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double uncert;
        slbm->getTravelTimeUncertainty(phase, distance, uncert);
        return uncert;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//  void SlbmInterfaceJNI::getTravelTimeUncertainty(double& uncert)
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getTravelTimeUncertaintyNative(
    JNIEnv *env, jobject obj, jboolean calcRandomError)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env, obj, "SlbmInterfaceToJNI"));

    try
    {
        double uncert;
        slbm->getTravelTimeUncertainty(uncert, calcRandomError);
        return uncert;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void SlbmInterfaceJNI::getTravelTimeUncertainty1D(double& uncert)
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getTravelTimeUncertainty1DNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env, obj, "SlbmInterfaceToJNI"));

    try
    {
        double uncert;
        slbm->getTravelTimeUncertainty1D(uncert);
        return uncert;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void SlbmInterface::getZhaoParameters(double& Vm, double& Gm, double& H, double& C, double& Cm, int& udSign))
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getZhaoParametersNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        vector<double> x(5);
        int udSign;
        slbm->getZhaoParameters(x[0], x[1], x[2], x[3], x[4], udSign);
        return javaMakeJArrayOfDoubleFromVector(env, x);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void SlbmInterface::getPgLgComponents(double& tTotal, double& tTaup, double& tHeadwave)
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getPgLgComponentsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double t[7];
        slbm->getPgLgComponents(t[0], t[1], t[2], t[3], t[4], t[5], t[6]);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, t, 7);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void SlbmInterface::getZhaoParameters(double& Vm, double& Gm, double& H, double& C, double& Cm, int& udSign))
//
// *****************************************************************************
extern "C" JNIEXPORT jint JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getZhaoUdSignNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        vector<double> x(5);
        int udSign;
        slbm->getZhaoParameters(x[0], x[1], x[2], x[3], x[4], udSign);
        return udSign;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return 0;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int* getNodeNeighbors();
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getNodeNeighborsNative(
    JNIEnv *env, jobject obj, jint nodeID)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        vector<int> neighbors;
        slbm->getNodeNeighbors(nodeID, neighbors);
        return javaMakeJArrayOfIntFromVector(env, neighbors);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int* getActiveNodeNeighbors();
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getActiveNodeNeighborsNative(
    JNIEnv *env, jobject obj, jint nodeID)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        vector<int> neighbors;
        slbm->getActiveNodeNeighbors(nodeID, neighbors);
        return javaMakeJArrayOfIntFromVector(env, neighbors);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double getNodeSeparation(int node1, int node2);
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getNodeSeparationNative(
    JNIEnv *env, jobject obj, jint node1, jint node2)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble dist;
        slbm->getNodeSeparation(node1, node2, dist);
        return dist;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double getNodeAzimuth(int node1, int node2);
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getNodeAzimuthNative(
    JNIEnv *env, jobject obj, jint node1, jint node2)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble az;
        slbm->getNodeAzimuth(node1, node2, az);
        return az;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void initializeActiveNodes(latmin, lonmin, latmax, lonmax);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_initializeActiveNodesNative(
    JNIEnv *env, jobject obj, jdouble latmin, jdouble lonmin, jdouble latmax, jdouble lonmax)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->initializeActiveNodes(latmin, lonmin, latmax, lonmax);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int getNodeHitCount();
//
// *****************************************************************************
extern "C" JNIEXPORT jint JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getNodeHitCountNative(
    JNIEnv *env, jobject obj, jint nodeID)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        int i;
        slbm->getNodeHitCount(nodeID, i);
        return i;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	String getVersion();
//
// *****************************************************************************
extern "C" JNIEXPORT jstring JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getVersionNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJavaString(env, slbm->getVersion());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int getNActiveNodes();
//
// *****************************************************************************
extern "C" JNIEXPORT jint JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getNActiveNodesNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getNActiveNodes();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int getGridNodeId(int activeNodeId);
//
// *****************************************************************************
extern "C" JNIEXPORT jint JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getGridNodeIdNative(
    JNIEnv *env, jobject obj, jint activeNodeId)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getGridNodeId(activeNodeId);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int getActiveNodeId(int GridNodeId);
//
// *****************************************************************************
extern "C" JNIEXPORT jint JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getActiveNodeIdNative(
    JNIEnv *env, jobject obj, jint gridNodeId)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getActiveNodeId(gridNodeId);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int getNGridNodes();
//
// *****************************************************************************
extern "C" JNIEXPORT jint JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getNGridNodesNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getNGridNodes();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	int getNHeadWavePoints();
//
// *****************************************************************************
extern "C" JNIEXPORT jint JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getNHeadWavePointsNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return slbm->getNHeadWavePoints();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void setCHMax(double chmax);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setCHMaxNative(
    JNIEnv *env, jobject obj, jdouble chmax)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->setCHMax(chmax);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double getCHMax();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getCHMaxNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double chmax;
        slbm->getCHMax(chmax);
        return chmax;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double getAverageMantleVelocityNative( int type );

//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getAverageMantleVelocityNative(
    JNIEnv *env, jobject obj, jint type)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double velocity;
        slbm->getAverageMantleVelocity( type, velocity );
        return velocity;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	double setAverageMantleVelocityNative( int type, double velocity );
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setAverageMantleVelocityNative(
    JNIEnv *env, jobject obj, jint type, jdouble velocity )

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->setAverageMantleVelocity( type, velocity );
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		String getTessIdNative()
//
// *****************************************************************************
extern "C" JNIEXPORT jstring JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getTessIdNative(
    JNIEnv *env, jobject obj )

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        string str;
        slbm->getTessId(str);
        return pglJavaMakeJavaString(env, str);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	public double getFractionActive()
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getFractionActiveNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double fractionActive;
        slbm->getFractionActive(fractionActive);
        return fractionActive;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void setMaxDistance(double maxdistance);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setMaxDistanceNative(
    JNIEnv *env, jobject obj, jdouble maxdistance)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->setMaxDistance(maxdistance);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	public double getMaxDistance()
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getMaxDistanceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double maxDistance;
        slbm->getMaxDistance(maxDistance);
        return maxDistance;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void setMaxDepth(double maxdepth);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setMaxDepthNative(
    JNIEnv *env, jobject obj, jdouble maxdepth)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->setMaxDepth(maxdepth);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}
// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	public double getMaxDepth()
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getMaxDepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double maxDepth;
        slbm->getMaxDepth(maxDepth);
        return maxDepth;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return -1;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double get_dtt_dlat();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDttDlatNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->get_dtt_dlat(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double get_dtt_dlon();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDttDlonNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->get_dtt_dlon(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double get_dtt_ddepth();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDttDdepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->get_dtt_ddepth(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}

//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////		double get_dsh_ddist();
////
//// *****************************************************************************
//extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDshDdistNative(
//	JNIEnv *env, jobject obj)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	try
//	{
//		jdouble d;
//		slbm->get_dsh_ddist(d);
//		return d;
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//		return NULL;
//	}
//}
//
//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////		double get_dsh_dlat();
////
//// *****************************************************************************
//extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDshDlatNative(
//	JNIEnv *env, jobject obj)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	try
//	{
//		jdouble d;
//		slbm->get_dsh_dlat(d);
//		return d;
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//		return NULL;
//	}
//}
//
//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////		double get_dsh_dlon();
////
//// *****************************************************************************
//extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDshDlonNative(
//	JNIEnv *env, jobject obj)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	try
//	{
//		jdouble d;
//		slbm->get_dsh_dlon(d);
//		return d;
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//		return NULL;
//	}
//}
//
//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////		double get_dsh_ddepth();
////
//// *****************************************************************************
//extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDshDdepthNative(
//	JNIEnv *env, jobject obj)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	try
//	{
//		jdouble d;
//		slbm->get_dsh_ddepth(d);
//		return d;
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//		return NULL;
//	}
//}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getSlowness();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getSlownessNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        jdouble d;
        slbm->getSlowness(d);
        return d;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return (jdouble)NULL;
    }
}


// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getSlownessUncertainty(int phase, double distance);
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getSlownessUncertaintyNative(
    JNIEnv *env, jobject obj, jint phase, jdouble distance)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double uncert;
        slbm->getSlownessUncertainty(phase, distance, uncert);
        return uncert;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		void getPiercePointSource(double& lat, double& lon);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getPiercePointSourceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double lat_lon_depth[3];
        slbm->getPiercePointSource(lat_lon_depth[0], lat_lon_depth[1], lat_lon_depth[2]);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, lat_lon_depth, 3);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		void getPiercePointReceiver(double& lat, double& lon);
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getPiercePointReceiverNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double lat_lon_depth[3];
        slbm->getPiercePointReceiver(lat_lon_depth[0], lat_lon_depth[1], lat_lon_depth[2]);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, lat_lon_depth, 3);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
        return NULL;
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//		double getDelDistance();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDelDistanceNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double val;
        slbm->getDelDistance(val);
        return val;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//      double getDelDepth();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDelDepthNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double val;
        slbm->getDelDepth(val);
        return val;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void setDelDistance(double del_distance);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setDelDistanceNative(
    JNIEnv *env, jobject obj, jdouble del_distance)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->setDelDistance(del_distance);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	void setDelDistance(double del_distance);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setDelDepthNative(
    JNIEnv *env, jobject obj, jdouble del_depth)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->setDelDepth(del_depth);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }

}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//      double getRayParameter();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getRayParameterNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double val;
        slbm->getRayParameter(val);
        return val;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//      double getTurningRadius();
//
// *****************************************************************************
extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getTurningRadiusNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double val;
        slbm->getTurningRadius(val);
        return val;
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NA_VALUE;
}

//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////		double get_dtt_dlat();
////
//// *****************************************************************************
//extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDttDlatFastNative(
//	JNIEnv *env, jobject obj)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	try
//	{
//		jdouble d;
//		slbm->get_dtt_dlat_fast(d);
//		return d;
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//		return NULL;
//	}
//}
//
//// **** _FUNCTION DESCRIPTION_ *************************************************
////
////		double get_dtt_dlon_fast();
////
//// *****************************************************************************
//extern "C" JNIEXPORT jdouble JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDttDlonFastNative(
//	JNIEnv *env, jobject obj)
//
//{
//	SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));
//
//	try
//	{
//		jdouble d;
//		slbm->get_dtt_dlon_fast(d);
//		return d;
//	}
//	catch (SLBMException ex)
//	{
//		jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
//		env->ThrowNew(exceptionClass, ex.emessage.c_str());
//		return NULL;
//	}
//}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	getDistAz()
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getDistAzNative(
    JNIEnv *env, jobject obj, jdouble latA, jdouble lonA, jdouble latB, jdouble lonB, jdouble naValue)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double distAz[2];
        slbm->getDistAz(latA, lonA, latB, lonB, distAz[0], distAz[1], naValue);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, distAz, 2);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	movePoint()
//
// *****************************************************************************
extern "C" JNIEXPORT jarray JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_movePointNative(
    JNIEnv *env, jobject obj, jdouble latA, jdouble lonA, jdouble distance, jdouble azimuth)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        double b[2];
        slbm->movePoint(latA, lonA, distance, azimuth, b[0], b[1]);
        return pglJavaMakeJArrayOfDoubleFromDouble(env, b, 2);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to void SlbmInterfaceJNI::setInterpolatorType(string& interpolatorType);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_setInterpolatorTypeNative(
    JNIEnv *env, jobject obj, jstring jinterpolatorType)
{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    string interpolatorType;
    pglJavaUTFToString(env, jinterpolatorType, interpolatorType);

    try
    {
        slbm->setInterpolatorType(interpolatorType);
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
//	String getInterpolatorType();
//
// *****************************************************************************
extern "C" JNIEXPORT jstring JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_getInterpolatorTypeNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        return pglJavaMakeJavaString(env, slbm->getInterpolatorType());
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
    return NULL;
}

// **** _FUNCTION DESCRIPTION_ *************************************************
//
// Maps to
//	bool createGreatCircle(const string& phase,
//					const double& sourceLat,
//					const double& sourceLon,
//					const double& sourceDepth,
//					const double& receiverLat,
//					const double& receiverLon,
//					const double& receiverDepth);
//
// *****************************************************************************
extern "C" JNIEXPORT void JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_clearHitCountNative(
    JNIEnv *env, jobject obj)

{
    SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    try
    {
        slbm->clearNodeHitCount();
    }
    catch (SLBMException ex)
    {
        jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
        env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    }
}

extern "C" JNIEXPORT jboolean JNICALL Java_gov_sandia_gnem_slbmjni_SlbmInterface_modelsEqualNative(
    JNIEnv *env, jobject obj, jstring jmodelPath1, jstring jmodelPath2)
{
    string modelPath1;
    string modelPath2;
    pglJavaUTFToString(env, jmodelPath1, modelPath1);
    pglJavaUTFToString(env, jmodelPath2, modelPath2);
    return SlbmInterfaceToJNI::modelsEqual(modelPath1, modelPath2);
    // SlbmInterfaceToJNI* slbm = ((SlbmInterfaceToJNI *)pglJavaGetPointerFromObject(env,obj,"SlbmInterfaceToJNI"));

    // string modelFileName;
    // pglJavaUTFToString(env, jmodelFileName, modelFileName);

    // try
    // {
    //     slbm->loadVelocityModel(modelFileName);
    // }
    // catch (SLBMException ex)
    // {
    //     jclass exceptionClass = env->FindClass("gov/sandia/gnem/slbmjni/SLBMException");
    //     env->ThrowNew(exceptionClass, ("\nERROR " + to_str(ex.ecode) + ":" + ex.emessage).c_str());
    // }
}
