// Path: hive/src/main/java/com/esri/hadoop/hive/GeometryUtils.java
// public enum OGCType {
// 	UNKNOWN(0),
// 	ST_POINT(1),
// 	ST_LINESTRING(2),
// 	ST_POLYGON(3),
// 	ST_MULTIPOINT(4),
// 	ST_MULTILINESTRING(5),
// 	ST_MULTIPOLYGON(6);
// 		
// 	private final int index;
// 		
// 	OGCType(int index){
// 		this.index = index;
// 	}
// 		
// 	public int getIndex(){
// 		return this.index;
// 	}
// }


import java.util.EnumSet;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.ogc.OGCPoint;
import com.esri.hadoop.hive.GeometryUtils.OGCType;

	public Object evaluate(DeferredObject[] args) throws HiveException {
		double binSize = PrimitiveObjectInspectorUtils.getDouble(args[0].get(), oiBinSize);
		
		
		if (!binSizeIsConstant || bins == null) {
			bins = new BinUtils(binSize);
		} 
				
		Envelope env = new Envelope();
		
		if (oiBinId != null) {
			// argument 1 is a number, attempt to get the envelope with bin ID
			if (args[1].get() == null) {
				// null bin ID argument usually means the source point was null or failed to parse
				return null; 
			}
			
			long binId = PrimitiveObjectInspectorUtils.getLong(args[1].get(), oiBinId);
			bins.queryEnvelope(binId, env);
		} else {
			// argument 1 is a geometry, attempt to get the envelope with a point
			OGCPoint point = binPoint.getPoint(args);
			
			if (point == null) {
				return null;
			}
			
			bins.queryEnvelope(point.X(), point.Y(), env);
		}


// Path: hive/src/main/java/com/esri/hadoop/hive/GeometryUtils.java
// public enum OGCType {
// 	UNKNOWN(0),
// 	ST_POINT(1),
// 	ST_LINESTRING(2),
// 	ST_POLYGON(3),
// 	ST_MULTIPOINT(4),
// 	ST_MULTILINESTRING(5),
// 	ST_MULTIPOLYGON(6);
// 		
// 	private final int index;
// 		
// 	OGCType(int index){
// 		this.index = index;
// 	}
// 		
// 	public int getIndex(){
// 		return this.index;
// 	}
// }


// Path: hive/src/main/java/com/esri/hadoop/hive/ST_BinEnvelope.java
import java.util.EnumSet;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.ogc.OGCPoint;
import com.esri.hadoop.hive.GeometryUtils.OGCType;

	public Object evaluate(DeferredObject[] args) throws HiveException {
		double binSize = PrimitiveObjectInspectorUtils.getDouble(args[0].get(), oiBinSize);
		
		
		if (!binSizeIsConstant || bins == null) {
			bins = new BinUtils(binSize);
		} 
				
		Envelope env = new Envelope();
		
		if (oiBinId != null) {
			// argument 1 is a number, attempt to get the envelope with bin ID
			if (args[1].get() == null) {
				// null bin ID argument usually means the source point was null or failed to parse
				return null; 
			}
			
			long binId = PrimitiveObjectInspectorUtils.getLong(args[1].get(), oiBinId);
			bins.queryEnvelope(binId, env);
		} else {
			// argument 1 is a geometry, attempt to get the envelope with a point
			OGCPoint point = binPoint.getPoint(args);
			
			if (point == null) {
				return null;
			}
			
			bins.queryEnvelope(point.X(), point.Y(), env);
		}


		return GeometryUtils.geometryToEsriShapeBytesWritable(env, 0, OGCType.ST_POLYGON);
