package hiro.yoshioka.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public enum FileExtentionType {
	// -----------------------------------------------------------
	// MOVIE
	// -----------------------------------------------------------
	/** MPG */
	MPG("mpg", "(RIFF.*CDXAfmt|ｺ!|ｺD)"),
	/** AVI */
	AVI("avi", "RIFF.*AVI"),
	/** MOV */
	MOV("mov", "....oov...lmvhd"),
	/** RM */
	RM("rm", "RMF.*PROP2"),
	// -----------------------------------------------------------
	// IMAGE
	// -----------------------------------------------------------
	/** JPG */
	JPG("jpg", "(JFIF|Exif)"),
	/** PNG */
	PNG("png", "NG"),
	/** BMP */
	BMP("bmp", "^BM"),
	/** GIF */
	GIF("gif", "(GIF87a|GIF89a)"),
	/** TIF */
	TIF("tif", "II[*]"),
	// -----------------------------------------------------------
	// SOUND
	// -----------------------------------------------------------
	/** WAV */
	WAV("wav", "RIFF....WAVEfmt"),
	/** MP3 */
	MP3("mp3", "..鐃縦"),
	// -----------------------------------------------------------
	// OTHERS
	// -----------------------------------------------------------
	/** CDA */
	CDA("cda", "RIFF....CDDAfmt"),
	/** OGG */
	OGG("ogg", "OggS.*vorbis"),
	/** LZH */
	LZH("lzh", ".-lh5-"),
	/** ZIP */
	ZIP("zip", "PK"),
	/** EXE */
	EXE("exe", "This program cannot be run in DOS mode"),
	/** RAR */
	RAR("rar", "Rar!"),
	/** CAB */
	CAB("cab", "MSCF"),
	/** TGZ */
	TGZ("tgz", "1F 8B 08 00 00"),
	/** WMV */
	WMV("wmv", "0&"),
	/** PDF */
	PDF("pdf", "^%PDF"),
	/** OGM */
	OGM("ogm", "OggS........video...DIV3............OggS.........vorbis"),
	/** GZ */
	GZ("gz", "1F 8B 08 00 00"),
	/** TXT */
	TXT("txt", null);

	private String name;
	private Pattern pattern;

	private FileExtentionType(String name, String pattern) {
		this.name = name;
		if (pattern != null) {
			this.pattern = Pattern.compile(pattern, Pattern.MULTILINE);
		}
	}

	public boolean isImage() {
		switch (this) {
		case JPG:
		case PNG:
		case BMP:
		case GIF:
		case TIF:
			return true;
		}
		return false;
	}

	public String getName() {
		return name;
	}

	public static FileExtentionType parseByFile(File file) {
		if (file == null || !file.isFile()) {
			return null;
		}
		int idx = file.getName().lastIndexOf('.');
		if (idx >= 0 && idx < file.getName().length()) {
			String ext = file.getName().substring(idx + 1);
			for (FileExtentionType type : values()) {
				if (type.name.equalsIgnoreCase(ext)) {
					return type;
				}
			}
		} else {
			FileInputStream fi = null;

			try {
				fi = new FileInputStream(file); // stream will be auto closed
				String firstPattern = FileUtil.getText(fi, null, 256);
				return parse(firstPattern);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static FileExtentionType parse(String firstPattern) {
		for (FileExtentionType type : values()) {
			if (type.pattern == null) {
				continue;
			}
			Matcher m = type.pattern.matcher(firstPattern);
			if (m.find()) {
				return type;
			}
		}
		int controlCharCnt = 0;
		for (int i = 0; i < firstPattern.length(); i++) {
			if (Character.isISOControl(firstPattern.charAt(i))) {
				controlCharCnt++;
			}
		}
		if (controlCharCnt > 60) {
			return null;
		} else {
			return TXT;
		}
	}

	public static FileExtentionType parseByPath(String path) {
		path = path.toUpperCase();
		for (FileExtentionType type : values()) {
			if (path.endsWith("." + type.name)) {
				return type;
			}
		}
		return null;
	}
}