#include "shapefil.h"
#include <stdio.h>

double atof();

double latitude;
double longitude;
int test_size=1;

struct bBox 
{
double xMin;
double yMin;
double xMax;
double yMax;
};

int main( int argc, char ** argv )

{
    SHPHandle	hSHP;
    SHPHandle	newSHP;
    int			nShapeType, nEntities, i, iPart;
    const char	*pszPlus;
    double		adfMinBound[4], adfMaxBound[4];
    double *xpr,*ypr;
    unsigned long l;
	// DBF Stuff
	DBFHandle   hDBF;
	DBFHandle   newDBF;
	int         *panWidth, iRecord;
	char        szFormat[32], szField[1024], *pszFilename = NULL;
	int         nWidth, nDecimals;
	int         bHeader = 0;
	int         bRaw = 0;
	int         bMultiLine = 0;
	char        szTitle[12];
	// Polygon test stuff
//	double		latitude,longitude;
	int			name_field=1;
	struct bBox bound[107449];
char buffer[512];
	float x,y;
	double maxArea;
    
/* Display a usage message. */
	printf("argc = %d\n",argc);
    if( argc != 4 )
    {
		printf( "%s shp_file name_field new_bBox_file\n",argv[0] );
		exit( 1 );
    }

	name_field = atoi(argv[2]);
	// new bounding box files are argv[2]
//	latitude = atof(argv[3]);
//	longitude = atof(argv[4]);
	printf("latitude = %lf  longitude = %lf\n",latitude,longitude);
	
/* Open the passed shapefile. */
    hSHP = SHPOpen( argv[1], "rb" );

    if( hSHP == NULL )
    {
		printf( "Unable to open:%s\n", argv[1] );
		exit( 1 );
    }

#if 1
/* Open DBF file associated with shapefile. */
	pszFilename = argv[1];	// DBF
	hDBF = DBFOpen( pszFilename, "rb" );
	if( hDBF == NULL )
		{
			printf( "DBFOpen(%s,\"r\") failed.\n", argv[1] );
			exit( 2 );
		}
/* Warn user that DBF file doesn't contain anything */
	if( DBFGetFieldCount(hDBF) == 0 )
		{
		printf( "There are no fields in this table!\n" );
		exit( 3 );
		}
#endif

/*      Print out the file bounds.                                      */
    SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );

#if 1
    printf( "Shapefile Type: %s   # of Shapes: %d\n\n",
            SHPTypeName( nShapeType ), nEntities );
#endif

#if 0
		// Check to makesure we are dealing with a polygon shapefile
		if ( nShapeType%5 == 0 )
				{
				printf("Polygon File\n");
				} else {
				printf("Not a polygon File!\n");
				return 1;
				}
#endif

//load_test_points();

//latitude=44.0365;		// highway 61
//longitude=-91.64817;

//latitude[0]=45.52299;
//longitude[0] = -122.6699;

    
    printf( "File Bounds: (%12.3f,%12.3f,%lg,%lg)\n"
            "         to  (%12.3f,%12.3f,%lg,%lg)\n",
            adfMinBound[0], 
            adfMinBound[1], 
            adfMinBound[2], 
            adfMinBound[3], 
            adfMaxBound[0], 
            adfMaxBound[1], 
            adfMaxBound[2], 
            adfMaxBound[3] );

#if 0
printf("(Point to test) Latitude: %04.3f Longitude: %04.3f\n",latitude[0],longitude[0]);

		if ( longitude[0] < adfMinBound[1]   || longitude[0] > adfMaxBound[1]
			|| latitude[0] < adfMinBound[0] || latitude[0] > adfMaxBound[0] )
			{
			fprintf(stdout,"Test point is outside of file bounds.\n");
			exit(10);
			}
#endif
    
/* -------------------------------------------------------------------- */
/*		Skim over the list of shapes, printing all the vertices.		*/
/* -------------------------------------------------------------------- */
    for( i = 0; i < nEntities ; i++ )
    {
		int				j;
        SHPObject		*psShape;

	//	double thisArea=0;

		psShape = SHPReadObject( hSHP, i );
#if 0
		printf( "\nShape:%d (%s)  nVertices=%d, nParts=%d\n"
                "  Bounds:(%12.3f,%12.3f, %lg, %lg)\n"
                "      to (%12.3f,%12.3f, %lg, %lg)\n",
				i, SHPTypeName(psShape->nSHPType),
                psShape->nVertices, psShape->nParts,
                psShape->dfXMin, psShape->dfYMin,
                psShape->dfZMin, psShape->dfMMin,
                psShape->dfXMax, psShape->dfYMax,
                psShape->dfZMax, psShape->dfMMax );
#endif
#if 1
bound[i].xMin = psShape->dfXMin; 
bound[i].yMin = psShape->dfYMin; 
bound[i].xMax = psShape->dfXMax; 
bound[i].yMax = psShape->dfYMax; 
#endif

#if 0
// Calculate the area of this bounding box
thisArea = ( fabs(bound[i].xMax) - fabs(bound[i].xMin) ) * ( fabs(bound[i].yMax) - fabs(bound[i].yMin) );


if ( thisArea > maxArea )
	maxArea = thisArea;
#endif


//			(longitude[x] > psShape->dfXMax) || 
//			(latitude[x] < psShape->dfYMin) || 
//			(latitude[x] > psShape->dfYMax) ) )

		SHPDestroyObject( psShape );
	}
printf("Maximum area of bounding box  = %f\n",maxArea);
printf("Bounding box information loaded ... now awaiting latitude longitude pairs\n");

//printf("Shape 10000 bounds to:\n\t(%12.3f, %12.3f)\n\t(%12.3f, %12.3f)\n",
//				bound[10000].xMin,bound[10000].yMin,bound[10000].xMax,bound[10000].yMax);




#if 0
while ( (0 != fgets(buffer,512,stdin)) )
	{
	x = 0;
	y = 0;	
			
	sscanf(buffer,"%f%f",&x,&y);
	latitude = (double) x;
	longitude = (double) y;


    for( i = 0; i < (nEntities); i++ )
    {
	if ( ( longitude <= bound[i].xMax ) && (longitude >= bound[i].xMin) &&
		( latitude <= bound[i].yMax ) && (latitude >= bound[i].yMin ) )
			{
			printf("Latitude: %lf Longitude: %lf\n",latitude,longitude);
			fprintf(stdout,"\tFell within bounding box for: ");
		   	printf("Object %d (%s)\n\n",i,DBFReadStringAttribute( hDBF, i, name_field ));
			}
		}
	}
#endif		
//printf("waiting ... press control d to continue and close shapefile\n");

//load_test_points();
    SHPClose( hSHP );
#ifdef USE_DBMALLOC
    malloc_dump(2);
#endif

// Create DBF file
newDBF = DBFCreate(argv[3]);
DBFAddField(newDBF, "OBJ_NO",FTInteger,10,0);

// Create Shapefile
newSHP = SHPCreate(argv[3], SHPT_POLYGON );


for( i = 0; i < nEntities ; i++ )
//for( i = 0; i < 100 ; i++ )
	{
	double xPoints[4] = { bound[i].xMin, bound[i].xMax, bound[i].xMax, bound[i].xMin };
	double yPoints[4] = { bound[i].yMax, bound[i].yMax, bound[i].yMin, bound[i].yMin };

	xpr = xPoints;
	ypr = yPoints;

	if ( ! DBFWriteIntegerAttribute(  newDBF, i, 0, i ) )
		printf("problem writting DBF entry %d\n",i);

	if ( ! SHPWriteObject( newSHP, -1, SHPCreateSimpleObject(SHPT_POLYGON, 4, xpr, ypr, 0 ) ) )
		printf("problem writting SHP entry %d\n",i);

	
	}

DBFClose( newDBF );
SHPClose( newSHP );




    exit( 0 );
}
