// DTED0Convert.cpp : Defines the entry point for the console application.
//


#include <fstream.h>
#include <stdlib.h>	//atoi,atof
#include <stdio.h>

#include <atl.h>

#define TEMP_FILE_NAME ".\\TempData.tmp"
#define TEMP_FILE_NAME_COLORS ".\\TempDataColors.tmp"

enum enArgs {argProgramName,argFileName,argLatitudeMin,argLatitudeMax,argLongitudeMin,argLongitudeMax,
												argNumberRows,argNumberColumns,argTimeOfDay,argNumberArgs};

typedef struct sColor265_struct sColor265;
struct sColor265_struct 
{
	unsigned char ucRed;
	unsigned char ucGreen;
	unsigned char ucBlue;
	unsigned char ucAlpha;
};

sColor265 sc265Pseudocolor(int iAltitude);

int main(int argc, char* argv[])
{
	// check for arguments
	if ( argc != argNumberArgs ) 
	{
		cerr << "\n usage: " << "DTED0Convert(FileName,LatitudeMin,LatitudeMax,LongitudeMin,LongitudeMax,NumberColumns,NumberRows,TimeOfDay)" << endl;
		return(-1);
	}

	// process arguments
	double dLatitudeMin = atoi(argv[argLatitudeMin]);
	double dLatitudeMax = atoi(argv[argLatitudeMax]);
	double dLongitudeMin = atoi(argv[argLongitudeMin]);
	double dLongitudeMax = atoi(argv[argLongitudeMax]);
	int iNumberRows = atoi(argv[argNumberRows]);
	int iNumberColumns = atoi(argv[argNumberColumns]);
	double dTimeOfDay = atof(argv[argTimeOfDay]);

	// read in file
	int iDataSize = iNumberColumns*iNumberRows;

	FILE* fp1;
	FILE* fp2;
	FILE* fpColors;
	if ( !(fp1=fopen(argv[argFileName],"rb"))) {
		cerr << "\n error: Could not open '" << argv[argFileName] << "'" << endl;
		exit(-1);
	}
	if ( (fp2=fopen(TEMP_FILE_NAME,"wb")) == NULL ) {
		cerr << "\n error: Could not open '" << TEMP_FILE_NAME << "'" << endl;
		exit(-1);
	}
	if ( (fpColors=fopen(TEMP_FILE_NAME_COLORS,"wb")) == NULL ) {
		cerr << "\n error: Could not open '" << TEMP_FILE_NAME_COLORS << "'" << endl;
		exit(-1);
	}

	// need to convert the binary data file from 16 bit elements to 32 bit elements
	for(int iCountData=1;iCountData<iDataSize;iCountData++)
	{
		short sTemp = 0;
		if(fread( &sTemp, sizeof(short),1, fp1 )!=1)
		{
			cerr << "\n error: error encountered while reading data from: '" << argv[argFileName] << "'" << endl;
			unlink(TEMP_FILE_NAME);
			unlink(TEMP_FILE_NAME_COLORS);
			exit(-1);
		}
		int iTemp = (sTemp==-500)?(0):(sTemp);
		if(fwrite(&iTemp,sizeof(int),1,fp2) != 1)
		{
			cerr << "\n error: error encountered while writing data to: '" <<TEMP_FILE_NAME << "'" << endl;
			unlink(TEMP_FILE_NAME);
			unlink(TEMP_FILE_NAME_COLORS);
			exit(-1);
		}
		sColor265 sc265Temp = sc265Pseudocolor(iTemp);
		if(fwrite(&sc265Temp,sizeof(sColor265),1,fpColors) != 1)
		{
			cerr << "\n error: error encountered while writing color data to: '" <<TEMP_FILE_NAME_COLORS << "'" << endl;
			unlink(TEMP_FILE_NAME);
			unlink(TEMP_FILE_NAME_COLORS);
			exit(-1);
		}
	}
	fclose(fp1);
	fclose(fp2);
	fclose(fpColors);

	// convert the data
	cerr << "\nPhase 1: convert elevations\n" << endl;
	if (atl_elevation(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin, 
										TEMP_FILE_NAME,iNumberRows,iNumberColumns) == -1)  
	{
		cerr << "\n error:  error converting data!" << endl;
		unlink(TEMP_FILE_NAME);
//		return(-1);
	}

	// convert Pseudocolors
	double gamma = 1.0;
	cerr << "\nPhase 2: convert Pseudocolors\n" << endl;
	if (atl_elevation(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin, 
										TEMP_FILE_NAME,iNumberRows,iNumberColumns) == -1)  
	if (atl_color(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin, 
						TEMP_FILE_NAME_COLORS, iNumberRows,iNumberColumns, gamma) == -1)
	{
		unlink(TEMP_FILE_NAME);
		unlink(TEMP_FILE_NAME_COLORS);
//		return(-1);
	}

	unlink(TEMP_FILE_NAME);
	unlink(TEMP_FILE_NAME_COLORS);

	/***** calculate shading *****/

	// #default colors
	Atl_color color[2];
	// default color - dark	(shadows)
	color[0].red = 40; color[0].green = 55; color[0].blue = 20;  
	// default clor - light
	color[1].red = 140; color[1].green = 180;color[1].blue = 105;

	cerr << "\nPhase 3: calculate shading\n" << endl;
	if (atl_shading(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin, 
				  color, dTimeOfDay) == -1)  
	{
		cerr << "\n error:  error in calculating shading!" << endl;
//		exit(-1);
	}


	/***** elevation postprocessing *****/
	cerr << "\nPhase 4: elevation postprocessing\n" << endl;
	if (atl_elevation_post(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin) == -1)  
	{
		cerr << "\n error:  error in elevation postprocessing!" << endl;
//		exit(-1);
	}

	/***** 8 bit color postprocessing *****/
	cerr << "\nPhase 5: 8 bit color postprocessing\n" << endl;
	if (atl_color_post(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin, 
					 gamma, ATL_COLOR8|ATL_BLUE_WATER) == -1)  
	{
		cerr << "\n error: error in 8 bit color postprocessing!" << endl;
//		exit(-1);
	}

	cerr << "\nPhase 6: Converting multiple detail level terrain file into lower detail level files\n" << endl;
	if (atl_pclevels(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin) == -1)  
	{
		cerr << "\n error:  error converting multiple detail level terrain file into lower detail level files!" << endl;
	}

	cerr << "\nPhase 7: *** Processing Bitmap ***\n" << endl;
	char caFileNameBmp[1024];
	sprintf(caFileNameBmp,"%s.bmp",argv[argFileName]);
	if (atl_rasterfile(dLongitudeMin, dLatitudeMax,
						dLongitudeMax, dLatitudeMax, 
						dLongitudeMin, dLatitudeMin,
						dLongitudeMax, dLatitudeMin,
						caFileNameBmp,ATL_COLOR8) == -1)  
	{
		cerr << "\n error:  error converting multiple detail level terrain file into lower detail level files!" << endl;
//		exit(-1);
	}
	
	return(0);
}
	
sColor265 sc265Pseudocolor(int iAltitude)
{
	int foo, bar;

	sColor265 sc265Color;

	sc265Color.ucAlpha = 250;

	if ( iAltitude <= 10 )
	{
		// littoral zone
		foo = iAltitude*10;
		sc265Color.ucRed	= foo;
		sc265Color.ucGreen	= foo;
		sc265Color.ucBlue	= 200;
	}
	else if ( iAltitude <= 20 )
	{
		// beaches
		bar = 20.0*rand()/RAND_MAX - 10;
		sc265Color.ucRed	= 230 + bar; // 180
		sc265Color.ucGreen	= 215 + bar; // 150
		sc265Color.ucBlue	= 180 + bar; // 110
	}
	else // iAltitude > 20
	{
		iAltitude = iAltitude + 100*rand()/RAND_MAX - 50;
		if ( iAltitude <= 20 ) 
			iAltitude = 20;
		if ( iAltitude <= 500 )
		{
			// shades of green, light to dark
			foo = (5000 - 10*iAltitude)/48;
			bar = 20.0*rand()/RAND_MAX - 10;
			sc265Color.ucRed	= foo + 40;
			sc265Color.ucGreen	= foo * 0.6 + 180;
			sc265Color.ucBlue	= foo * 0.2 + 90 + bar;
		}
		else if ( iAltitude <= 2000 )
		{
			// shades of sand
			foo = (iAltitude-500)/150;
			bar = 20.0*rand()/RAND_MAX - 10;
			sc265Color.ucRed	= foo * 0.5 + 160 + 2*bar;
			sc265Color.ucGreen	= foo * 0.6 + 120 + bar;
			sc265Color.ucBlue	= foo * 0.8 + 70  + bar;
			}
		else if ( iAltitude <= 3500 )
		{
			// shades of gray, dark to light
			foo = (iAltitude-2000)/10;
			bar = 20.0*rand()/RAND_MAX - 10;
			foo += bar + 100;
			if ( foo > 250 ) foo = 250;
			sc265Color.ucRed	= foo;
			sc265Color.ucGreen	= foo;
			sc265Color.ucBlue	= foo;
		}
		else
		{
				// white
			bar = 20.0*rand()/RAND_MAX - 15;
			if ( bar > 0 ) bar = 0;
			sc265Color.ucRed	= 250 + bar;
			sc265Color.ucGreen	= 250 + bar;
			sc265Color.ucBlue	= 250 + bar;
		}
	}
	return(sc265Color);
}	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
