import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.MessageDigest;

import org.apache.commons.io.IOUtils;

public class WebCamTracker {
	private static final int DUR = 9999999;

	public static void main(String[] args) throws Exception {

		if (args.length < 1 || args.length > 4) {
			System.err.println("Usage: java WebCamTracker " + "<Webcam URL> "
					+ "<Output Directory> " + "<?Max Duration in Millis?> "
					+ "<?Delay between queries?>");
		}
		int delay = 500; // millis

		File directory = new File(args[1]);
		if (!directory.isDirectory()) {
			throw new Exception("Directory " + directory
					+ "must be a Directory!");
		}

		long duration = DUR;
		if (args.length > 2) {
			duration = Long.parseLong(args[2]);
		}
		if (args.length > 3) {
			delay = Integer.parseInt(args[3]);
		}

		int i = 0;
		File currentFile = getNextFileName(directory, i);
		long startTime = System.currentTimeMillis();
		while (System.currentTimeMillis() - startTime < duration) {
			System.out.println("Retrieving image " + i);
			try {
				writeDataFromUrl(new URL(args[0]), currentFile);
				System.out.println("Retrieved Image: " + i + " at "
						+ currentFile.getAbsolutePath());
				i++;
				currentFile = getNextFileName(directory, i);
				if (duration == DUR) {
					break;
				}
			} catch (Exception e) {
				// if we couldn't write it, just keep going.
				continue;
			} finally {
				System.out.println("test");
				Thread.sleep(delay);
			}

		}
		System.out.println("Retrieved " + (i - 1) + " Webcam Images.");

		RemoveDupes(directory);
	}

	private static File getNextFileName(File directory, int i) {
		return new File(directory, "image-" + seed(i) + ".jpg");
	}

	public static int RemoveDupes(File directory) throws Exception {
		File[] files = directory.listFiles();
		String lastchecksum = null;
		String currentChecksum;
		System.out.println("Scanning for dupes.");
		int deleted = 0;
		for (File f : files) {
			if (!f.isDirectory()) {
				currentChecksum = getMD5Checksum(f);
				if (currentChecksum.equals(lastchecksum)) {
					System.out.println("deleted: " + f.getName());
					deleted++;
				}
				lastchecksum = currentChecksum;
			}
		}
		System.out.println("Found & deleted " + deleted + " dupes.");
		return deleted;
	}

	public static byte[] createChecksum(File file) throws Exception {
		InputStream fis = new FileInputStream(file);

		byte[] buffer = new byte[1024];
		MessageDigest complete = MessageDigest.getInstance("MD5");
		int numRead;
		do {
			numRead = fis.read(buffer);
			if (numRead > 0) {
				complete.update(buffer, 0, numRead);
			}
		} while (numRead != -1);
		fis.close();
		return complete.digest();
	}

	// see this How-to for a faster way to convert
	// a byte array to a HEX string
	public static String getMD5Checksum(File file) throws Exception {
		byte[] b = createChecksum(file);
		String result = "";
		for (int i = 0; i < b.length; i++) {
			result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
		}
		return result;
	}

	private static String seed(int i) {
		return ((100000 + i) + "").substring(1);
	}

	private static void writeDataFromUrl(URL url, File file)
			throws FileNotFoundException, IOException {
		FileOutputStream out = new FileOutputStream(file);
		IOUtils.copy(url.openStream(), out);
		out.flush();
		out.close();
	}

}

