/* JAlbum tool that adjust image orientation by rotating images */

import se.datadosen.jalbum.*;
import se.datadosen.util.*;
import se.datadosen.imaging.exif.*;
import com.drew.metadata.*;
import com.drew.metadata.exif.*;
import com.drew.metadata.jpeg.*;
import com.drew.metadata.iptc.*;
import com.drew.lang.Rational;
import com.drew.imaging.jpeg.*;
import photoorganizer.formats.*;	// Rotation code

// Global variables
int nProcessed = 0;
int totalFiles = 0;
int nErrors = 0;
Exception lastException = null;
File errorFile = null;

static final int LEFT_ROTATED = 6;
static final int NOT_ROTATED = 1;
static final int RIGHT_ROTATED = 8;

ProgressDialog progress = new ProgressDialog(null, "Adjusting image orientation", false);

void doRotate(File f, int operation) {
	long lastModified = f.lastModified();
	StrippedJpeg source = new StrippedJpeg(f);
	File tmpFile = File.createTempFile("JAlbum", "JPG");
	source.transform(tmpFile.getAbsolutePath(), operation);
	IO.copyFile(tmpFile, f);
	tmpFile.delete();
	f.setLastModified(lastModified);
}

void processFile(File f) {
	Metadata imageInfo = JpegMetadataReader.readMetadata(f);
	if (imageInfo.containsDirectory(ExifDirectory.class) && imageInfo.containsDirectory(JpegDirectory.class)) {
		Directory exif = imageInfo.getDirectory(ExifDirectory.class);
		Directory jpeg = imageInfo.getDirectory(JpegDirectory.class);
		int orientation = exif.getInt(ExifDirectory.TAG_ORIENTATION);
		int width = jpeg.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
		int height = jpeg.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT);
		//System.out.println(f.getName() + " " + orientation + " width: " + width + " height: " + height);

		if (width > height) {	// Not already rotated
			switch (orientation) {
			case LEFT_ROTATED:
				doRotate(f, StrippedJpeg.ROT_90);
				break;
			case RIGHT_ROTATED:
				doRotate(f, StrippedJpeg.ROT_270);
				break;
			}
		}
	}
}

void processDir(File dir) {
	File[] files = engine.listFiles(dir, true, rootOutputDirectory);
	for (File f : files) {
		if (f.isDirectory()) processDir(f);
		else {
			AlbumBeanEvent eventObject = new AlbumBeanEvent(this, dir,
			 "Processing files ", 0, totalFiles, nProcessed+1, totalFiles);
			progress.imageProcessingStarted(eventObject);
			try {
				processFile(f);
			}
			catch (Exception ex) {
				System.err.println(ex);
				nErrors++;
				lastException = ex;
				errorFile = f;
			}
			progress.imageProcessingFinished(eventObject);
			if (eventObject.isAborted()) throw new OperationAbortedException("");
			nProcessed++;
		}
	}
}


void processAlbum() {
	progress.show();
	totalFiles = engine.countFiles(rootImageDirectory);
	processDir(rootImageDirectory);
	//progress.setVisible(false);

}

// Execution starts here

msg =
"This script will rotate images in the image directory so their orientation\n" +
"corresponds to the information stored by the camera.\n" +
"The rotation algorithm is non-lossy, but MAY CORRUPT IMAGES!\n" +
"Keep backups before proceeding!";
int option = JOptionPane.showConfirmDialog(window, msg, "Adjust image orientation", JOptionPane.OK_OPTION|JOptionPane.CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
if (option != JOptionPane.YES_OPTION) return;

processAlbum();

if (nErrors > 0)
	JOptionPane.showMessageDialog(window, "" + nErrors + " errors occured during file processing. Last error was: " + lastException + "\nLast file: " + errorFile, "Error report", JOptionPane.WARNING_MESSAGE);
