/*******************************************************************************
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 * 
 * Contact Info:
 * 	Bruce Donald
 * 	Duke University
 * 	Department of Computer Science
 * 	Levine Science Research Center (LSRC)
 * 	Durham
 * 	NC 27708-0129 
 * 	USA
 * 	brd@cs.duke.edu
 * 
 * Copyright (C) 2011 Jeffrey W. Martin and Bruce R. Donald
 * 
 * <signature of Bruce Donald>, April 2011
 * Bruce Donald, Professor of Computer Science
 ******************************************************************************/


#include <jni.h>

#include "cgal.h"
#include "shotCgal.h"
#include "global.h"
#include "types.h"
#include "Storage.h"


#define CLASS						Java_edu_duke_donaldLab_jdshot_disco_cgal_Box
#define Box_init					CLASSFN( CLASS, init )
#define Box_cleanup					CLASSFN( CLASS, cleanup )
#define Box_getXMin					CLASSFN( CLASS, getXMin )
#define Box_getXMax					CLASSFN( CLASS, getXMax )
#define Box_getYMin					CLASSFN( CLASS, getYMin )
#define Box_getYMax					CLASSFN( CLASS, getYMax )
#define Box_expand					CLASSFN( CLASS, expand )


static Storage<Bbox_2> g_boxes( CGALCLASS( "Box" ), true );


void boxesCleanup( JNIEnv *jvm )
{
	g_boxes.cleanupAll( jvm );
}

Bbox_2 *getBox( JNIEnv *jvm, jobject self )
{
	return g_boxes.get( jvm, self );
}

jobject newBox( JNIEnv *jvm, const Bbox_2 &box )
{
	return g_boxes.addNew( jvm, new Bbox_2( box ) );
}

JNIEXPORT void JNICALL Box_init( JNIEnv *jvm, jobject self, jdouble xmin, jdouble xmax, jdouble ymin, jdouble ymax )
{
	START_SIGNAL_HANDLING
	{
		// build and store the box
		Bbox_2 *pNativeBox = new Bbox_2( xmin, ymin, xmax, ymax );
		g_boxes.add( jvm, self, pNativeBox );
	}
	STOP_SIGNAL_HANDLING
}

JNIEXPORT void JNICALL Box_cleanup( JNIEnv *jvm, jclass c, jint id )
{
	START_SIGNAL_HANDLING
	{
		if( !g_boxes.cleanup( id ) )
		{
			throwException( jvm, "Box cleanup failure!" );
		}
	}
	STOP_SIGNAL_HANDLING
}

JNIEXPORT jdouble JNICALL Box_getXMin( JNIEnv *jvm, jobject self )
{
	START_SIGNAL_HANDLING
	{
		Bbox_2 *pBox = getBox( jvm, self );
		return pBox->xmin();
	}
	STOP_SIGNAL_HANDLING
	return std::numeric_limits<double>::quiet_NaN();
}

JNIEXPORT jdouble JNICALL Box_getXMax( JNIEnv *jvm, jobject self )
{
	START_SIGNAL_HANDLING
	{
		Bbox_2 *pBox = getBox( jvm, self );
		return pBox->xmax();
	}
	STOP_SIGNAL_HANDLING
	return std::numeric_limits<double>::quiet_NaN();
}

JNIEXPORT jdouble JNICALL Box_getYMin( JNIEnv *jvm, jobject self )
{
	START_SIGNAL_HANDLING
	{
		Bbox_2 *pBox = getBox( jvm, self );
		return pBox->ymin();
	}
	STOP_SIGNAL_HANDLING
	return std::numeric_limits<double>::quiet_NaN();
}

JNIEXPORT jdouble JNICALL Box_getYMax( JNIEnv *jvm, jobject self )
{
	START_SIGNAL_HANDLING
	{
		Bbox_2 *pBox = getBox( jvm, self );
		return pBox->ymax();
	}
	STOP_SIGNAL_HANDLING
	return std::numeric_limits<double>::quiet_NaN();
}

JNIEXPORT void JNICALL Box_expand( JNIEnv *jvm, jobject self, jobject box )
{
	START_SIGNAL_HANDLING
	{
		Bbox_2 *pBoxSelf = getBox( jvm, self );
		Bbox_2 *pBoxOther = getBox( jvm, box );
		(*pBoxSelf) = (*pBoxSelf) + *pBoxOther;
	}
	STOP_SIGNAL_HANDLING
}
