/*******************************************************************************
 * 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
 ******************************************************************************/


package edu.duke.donaldLab.jdshot.disco.cgal;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import edu.duke.donaldLab.share.geom.Vector2;

public class Box extends AbstractCleanable implements Serializable
{
	/**************************
	 *   Definitions
	 **************************/
	
	private static final long serialVersionUID = -6742712402374735723L;
	
	
	/**************************
	 *   Data Members
	 **************************/
	
	private static Cleaner m_cleaner;
	
	
	/**************************
	 *   Constructors
	 **************************/
	
	static
	{
		m_cleaner = new Cleaner( )
		{
			@Override
			public void cleanup( int id )
			{
				Box.cleanup( id );
			}
		};
	}
	
	public Box( double xmin, double xmax, double ymin, double ymax )
	{
		super( m_cleaner );
		ShotCgal.addReference( this, m_cleaner );
		init( xmin, xmax, ymin, ymax );
	}
	
	public Box( Box other )
	{
		super( m_cleaner );
		ShotCgal.addReference( this, m_cleaner );
		init( other.getXMin(), other.getXMax(), other.getYMin(), other.getYMax() );
	}
	
	@SuppressWarnings( "unused" )
	private Box( int id, long pointer )
	{
		// used by native methods
		super( id, pointer, m_cleaner );
		ShotCgal.addReference( this, m_cleaner );
	}
	
	
	/**************************
	 *   Static Methods
	 **************************/
	
	public static native void cleanup( int id );
	
	
	/**************************
	 *   Methods
	 **************************/
	
	public native double getXMin( );
	public native double getXMax( );
	public native double getYMin( );
	public native double getYMax( );
	public native void expand( Box box );
	
	public double getWidth( )
	{
		return getXMax() - getXMin();
	}
	
	public double getHeight( )
	{
		return getYMax() - getYMin();
	}
	
	public boolean containsPoint( Vector2 point )
	{
		return containsPoint( point.x, point.y );
	}
	
	public boolean containsPoint( double x, double y )
	{
		return x >= getXMin() && x <= getXMax() && y >= getYMin() && y <= getYMax();
	}
	
	public boolean intersects( Box other )
	{
		return other.containsPoint( getXMin(), getYMin() )
			|| other.containsPoint( getXMin(), getYMax() )
			|| other.containsPoint( getXMax(), getYMin() )
			|| other.containsPoint( getXMax(), getYMax() );
	}
	
	
	/**************************
	 *   Functions
	 **************************/
	
	private native void init( double xmin, double xmax, double ymin, double ymax );
	
	private void writeObject( ObjectOutputStream out )
	throws IOException
	{
		out.writeDouble( getXMin() );
		out.writeDouble( getXMax() );
		out.writeDouble( getYMin() );
		out.writeDouble( getYMax() );
	}
	
	private void readObject( ObjectInputStream in )
	throws IOException, ClassNotFoundException
	{
		setCleaner( m_cleaner );
		ShotCgal.addReference( this, m_cleaner );
		init(
			in.readDouble(),
			in.readDouble(),
			in.readDouble(),
			in.readDouble()
		);
	}
}
