/**
 * 
 */
package edu.uprm.walsaip.vte.core.loader.terrain;

// import static java.lang.System.err;
import static java.lang.System.out;

import java.io.File;

import edu.uprm.walsaip.vte.core.datatypes.terrain.ElevationData;
import edu.uprm.walsaip.vte.core.datatypes.terrain.VTEInfo;
import edu.uprm.walsaip.vte.core.loader.FileLoaderInfo;



/**
 * 
 * @author Ricardo Veguilla (veguilla@ece.uprm.edu)
 * 
 */
public class DEMFileLoader implements TerrainFileLoader {
	private static String extensionList[] = { "dem" };

	public static final String ID = DEMFileLoader.class.getSimpleName();
	public static final String Type = TerrainFileLoader.ID;

	public static final FileLoaderInfo<DEMFileLoader> MODULE_INFO = new FileLoaderInfo<DEMFileLoader>() {
		
		protected void setInfo() {
			name = DEMFileLoader.ID;
			description = "DEM file";
			moduleClass = DEMFileLoader.class;
			extensionList = DEMFileLoader.extensionList;
			supported = true;
		}
	};
	
	


	protected DEMFileLoader() {
		super();
	}

	public void read(ElevationData data,VTEInfo info,File file) {
	
		out.printf("Reading terrain file...");

	
		DEMHandeler handeler = new DEMHandeler(file.getAbsolutePath());

		int width = handeler.getColumns();
		int height = handeler.getRows();

		short bytesPerPoint = handeler.getDatasize();
		boolean dataIsFloat = (handeler.getFloatingPointFlag() == 1);
		boolean dataIsInt = (!dataIsFloat && bytesPerPoint == 4);
		boolean dataIsShort = (!dataIsFloat && bytesPerPoint == 2);
		short horizontalUnits = handeler.getHorizontalUnits();
		short utmZone = handeler.getUTMZone();
		short datum = handeler.getDatum();
		float scale = handeler.getScale();
		if (scale == 0.0)
			scale = 1.0f;
		
		boolean externalProjection = (handeler.getExternalProjection() != 0);
		
		
		if (false) {
		out.println("Dimensions: " + width + " " + height);
		out.println("Bytes per point: " + bytesPerPoint);
		if (dataIsFloat)
			out.println("Data type: float");
		else if (dataIsInt)
			out.println("Data type: int");
		else
			out.println("Data type: short");

		switch (horizontalUnits) {
		case 0:
			out.println("Horizontal units: Degrees");
			break;
		case 1:
			out.println("Horizontal units: Meters");
			break;
		case 2:
			out
					.println("Horizontal units: Feet (International, 0.3048 meters)");
			break;
		case 3:
			out
					.println("Horizontal units: Feet (U.S. Survey, 1200/3937 meters)");
			break;
		}
		out.println("UTM zone: " + utmZone);

		out.println("Geodetic Datum Code: " + datum);

		out.println("Left Extend: " + handeler.getLeftExtent());

		out.println("Right Extend: " + handeler.getRightExtent());

		out.println("Bottom Extend: " + handeler.getBottomExtent());

		out.println("Top Extend: " + handeler.getTopExtent());

		if (externalProjection)
			out.println("Require External projection: Yes");
		else
			out.println("Require External projection: No");

		out.println("Scale (Vertical units in meters): " + scale);

		}
		
		


		float sampleElevation = 0;
		int[][] elevationDataDEM = (handeler.getElevationData());
		for (int x = 0; x < width; x++) {

			for (int y = 0; y < height; y++) {

				if (dataIsFloat)
					sampleElevation = elevationDataDEM[x][y];
				else if (dataIsInt)
					sampleElevation = (float) elevationDataDEM[x][y];
				else if (dataIsShort)
					sampleElevation = (float) elevationDataDEM[x][y];


				data.putSample(x, y, 0,sampleElevation);

			}

		}

		out.println("done");

	}

}
