package yukihane.inqubus.config;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import yukihane.inqubus.cookie.Cookie.BrowserType;

public enum Config {

    INSTANCE;

    public enum CookieBrowser {

        MSIE {

            @Override
            public BrowserType toBrowserType() {
                return BrowserType.MSIE;
            }
        }, FIREFOX {

            @Override
            public BrowserType toBrowserType() {
                return BrowserType.FIREFOX;
            }
        }, CHROME {

            @Override
            public BrowserType toBrowserType() {
                return BrowserType.CHROME;
            }
        }, CHROMIUM {

            @Override
            public BrowserType toBrowserType() {
                return BrowserType.CHROMIUM;
            }
        }, OPERA {

            @Override
            public BrowserType toBrowserType() {
                return BrowserType.OPERA;
            }
        }, OTHER {

            @Override
            public BrowserType toBrowserType() {
                return BrowserType.OTHER;
            }
        };

        public abstract BrowserType toBrowserType();
    }
    private final XMLConfiguration config = new XMLConfiguration();

    void clear() {
        config.clear();
    }

    /*
     * ネットワーク - アカウント
     */
    private static final String LOGIN_NEED = "network.login";

    public boolean getNeedsLogin() {
        return config.getBoolean(LOGIN_NEED, true);
    }

    public void setNeedsLogin(boolean s) {
        config.setProperty(LOGIN_NEED, s);
    }
    private static final String ACCOUNT_ID = "network.account.id";

    public String getId() {
        return config.getString(ACCOUNT_ID, "");
    }

    public void setId(String s) {
        config.setProperty(ACCOUNT_ID, s);
    }
    private static final String ACCOUNT_PASSWORD = "network.account.password";

    public String getPassword() {
        return config.getString(ACCOUNT_PASSWORD, "");
    }

    public void setPassword(String s) {
        config.setProperty(ACCOUNT_PASSWORD, s);
    }
    private static final String COOKIE_BROWSER = "network.cookie.browser";

    public CookieBrowser getCookieBrowser() {
        final String str = config.getString(COOKIE_BROWSER, CookieBrowser.MSIE.name());
        return CookieBrowser.valueOf(str);
    }

    public void setCookieBrowser(CookieBrowser s) {
        config.setProperty(COOKIE_BROWSER, s.name());
    }
    private static final String COOKIE_DIR = "network.cookie.dir";

    public String getCookieDir() {
        return config.getString(COOKIE_DIR, "");
    }

    public void setCookieDir(String s) {
        config.setProperty(COOKIE_DIR, s);
    }
    /*
     * ネットワーク - プロキシ
     */
    private static final String PROXY_USE = "network.proxy.use";

    public boolean getProxyUse() {
        return config.getBoolean(PROXY_USE, false);
    }

    public void setProxyUse(boolean s) {
        config.setProperty(PROXY_USE, s);
    }
    private static final String PROXY_HOST = "network.proxy.host";

    public String getProxyHost() {
        return config.getString(PROXY_HOST, "localhost");
    }

    public void setProxyHost(String s) {
        config.setProperty(PROXY_HOST, s);
    }
    private static final String PROXY_PORT = "network.proxy.port";

    public String getProxyPort() {
        return config.getString(PROXY_PORT, "8080");
    }

    public void setProxyPort(String s) {
        config.setProperty(PROXY_PORT, s);
    }

    /*
     * ファイル - 動画
     */
    private static final String FILE_VIDEO_DIR = "file.video.dir";

    public String getVideoDir() {
        return config.getString(FILE_VIDEO_DIR, "_video");
    }

    public void setVideoDir(String s) {
        config.setProperty(FILE_VIDEO_DIR, s);
    }
    private static final String FILE_VIDEO_FILENAME = "file.video.filename";

    public String getVideoFileNamePattern() {
        return config.getString(FILE_VIDEO_FILENAME, "[{id}]{title}");
    }

    public void setVideoFileNamePattern(String s) {
        config.setProperty(FILE_VIDEO_FILENAME, s.toString());
    }
    private static final String FILE_VIDEO_LOCAL = "file.video.local";

    public boolean getVideoUseLocal() {
        return config.getBoolean(FILE_VIDEO_LOCAL, false);
    }

    public void setVideoUseLocal(boolean s) {
        config.setProperty(FILE_VIDEO_LOCAL, s);
    }

    /*
     * ファイル - コメント
     */
    private static final String FILE_COMMENT_DIR = "file.comment.dir";

    public String getCommentDir() {
        return config.getString(FILE_COMMENT_DIR, "_comment");
    }

    public void setCommentDir(String s) {
        config.setProperty(FILE_COMMENT_DIR, s);
    }
    private static final String FILE_COMMENT_FILENAME = "file.comment.filename";

    public String getCommentFileNamePattern() {
        return config.getString(FILE_COMMENT_FILENAME, "[{id}]{title}");
    }

    public void setCommentFileNamePattern(String s) {
        config.setProperty(FILE_COMMENT_FILENAME, s.toString());
    }
    private static final String FILE_COMMENT_LOCAL = "file.comment.local";

    public boolean getCommentUseLocal() {
        return config.getBoolean(FILE_COMMENT_LOCAL, false);
    }

    public void setCommentUseLocal(boolean s) {
        config.setProperty(FILE_COMMENT_LOCAL, s);
    }
    /*
     * ファイル - 変換動画
     */
    private static final String FILE_OUTPUT_DIR = "file.output.dir";

    public String getOutputDir() {
        return config.getString(FILE_OUTPUT_DIR, "__converted");
    }

    public void setOutputDir(String s) {
        config.setProperty(FILE_OUTPUT_DIR, s);
    }
    private static final String FILE_OUTPUT_FILENAME = "file.output.filename";

    public String getOutputFileNamePattern() {
        return config.getString(FILE_OUTPUT_FILENAME, "{filename}");
    }

    public void setOutputFileNamePattern(String s) {
        config.setProperty(FILE_OUTPUT_FILENAME, s.toString());
    }
    private static final String FILE_OUTPUT_ENABLE = "file.output.enable";

    public boolean getOutputEnable() {
        return config.getBoolean(FILE_OUTPUT_ENABLE, true);
    }

    public void setOutputEnable(boolean s) {
        config.setProperty(FILE_OUTPUT_ENABLE, s);
    }
    private static final String FILE_OUTPUT_COMMENT_OVERLAY = "file.output.comment_overlay";

    public boolean getOutputCommentOverlay() {
        return config.getBoolean(FILE_OUTPUT_COMMENT_OVERLAY, true);
    }

    public void setOutputCommentOverlay(boolean s) {
        config.setProperty(FILE_OUTPUT_COMMENT_OVERLAY, s);
    }
    private static final String FILE_OUTPUT_DISPLAY_PROGRESS = "file.output.display";

    public boolean getOutputDisplayProgress() {
        return config.getBoolean(FILE_OUTPUT_DISPLAY_PROGRESS, true);
    }

    public void setOutputDisplayProgress(boolean s) {
        config.setProperty(FILE_OUTPUT_DISPLAY_PROGRESS, s);
    }

    /*
     * コメント
     */
    private static final String COMMENT_DOWNLOAD_OWNER_ONLY = "comment.download.owneronly";

    public boolean getCommentOwnerOnly() {
        return config.getBoolean(COMMENT_DOWNLOAD_OWNER_ONLY, false);
    }

    public void setCommentOwnerOnly(boolean s) {
        config.setProperty(COMMENT_DOWNLOAD_OWNER_ONLY, s);
    }
    private static final String COMMENT_SIZE_AUTOSIZE = "comment.size.autosize";

    public boolean getCommentSizeAutosize() {
        return config.getBoolean(COMMENT_SIZE_AUTOSIZE, true);
    }

    public void setCommentSizeAutosize(boolean s) {
        config.setProperty(COMMENT_SIZE_AUTOSIZE, s);
    }
    private static final String COMMENT_SIZE_MANUAL = "comment.size.manual";

    public String getCommentSizeManual() {
        return config.getString(COMMENT_SIZE_MANUAL, "");
    }

    public void setCommentSizeManual(String s) {
        config.setProperty(COMMENT_SIZE_MANUAL, s);
    }
    private static final String COMMENT_MIN_DISABLED = "comment.minutesize.disable";

    public boolean getCommentMinDisabled() {
        return config.getBoolean(COMMENT_MIN_DISABLED, false);
    }

    public void setCommentMinDisabled(boolean s) {
        config.setProperty(COMMENT_MIN_DISABLED, s);
    }
    private static final String COMMENT_MIN_SIZE_AUTOSIZE = "comment.minutesize.autosize";

    public boolean getCommentMinSizeAutosize() {
        return config.getBoolean(COMMENT_MIN_SIZE_AUTOSIZE, true);
    }

    public void setCommentMinSizeAutosize(boolean s) {
        config.setProperty(COMMENT_MIN_SIZE_AUTOSIZE, s);
    }
    private static final String COMMENT_MIN_SIZE_MANUAL = "comment.minutesize.manual";

    public String getCommentMinSizeManual() {
        return config.getString(COMMENT_MIN_SIZE_MANUAL, "");
    }

    public void setCommentMinSizeManual(String s) {
        config.setProperty(COMMENT_MIN_SIZE_MANUAL, s);
    }
    private static final String COMMENT_DISPLAY_MAX_SIZE_DEFAULT = "comment.displaysize.default";

    public boolean getCommentDisplaySizeDefault() {
        return config.getBoolean(COMMENT_DISPLAY_MAX_SIZE_DEFAULT, true);
    }

    public void setCommentDisplaySizeDefault(boolean s) {
        config.setProperty(COMMENT_DISPLAY_MAX_SIZE_DEFAULT, s);
    }
    private static final String COMMENT_DISPLAY_MAX_SIZE_MANUAL = "comment.displaysize.manual";

    public String getCommentDisplaySizeManual() {
        return config.getString(COMMENT_DISPLAY_MAX_SIZE_MANUAL, "");
    }

    public void setCommentDisplaySizeManual(String s) {
        config.setProperty(COMMENT_DISPLAY_MAX_SIZE_MANUAL, s);
    }
    private static final String COMMENT_FONTPATH = "comment.fontpath";

    public String getFontPath() {
        return config.getString(COMMENT_FONTPATH, "C:/Windows/Fonts/msgothic.ttc");
    }

    public void setFontPath(String s) {
        config.setProperty(COMMENT_FONTPATH, s);
    }
    private static final String COMMENT_FONT_INDEX = "comment.fontindex";

    public String getFontIndex() {
        return config.getString(COMMENT_FONT_INDEX, "1");
    }

    public void setFontIndex(String s) {
        config.setProperty(COMMENT_FONT_INDEX, s);
    }
    private static final String COMMENT_FONT_SHADOW = "comment.fontshadow";

    public int getFontShadow() {
        return config.getInt(COMMENT_FONT_SHADOW, 1);
    }

    public void setFontShadow(int s) {
        config.setProperty(COMMENT_FONT_SHADOW, s);
    }
    private static final String COMMENT_FONT_SIZING_DISABLE = "comment.font_no_sizing";

    public boolean getFontSizeArrangeDisable() {
        return config.getBoolean(COMMENT_FONT_SIZING_DISABLE, false);
    }

    public void setFontSizeArrangeDisable(boolean s) {
        config.setProperty(COMMENT_FONT_SIZING_DISABLE, s);
    }
    private static final String COMMENT_FONT_OPAQUE = "comment.opaque";

    public boolean getCommentOpaque() {
        return config.getBoolean(COMMENT_FONT_OPAQUE, false);
    }

    public void setCommentOpaque(boolean s) {
        config.setProperty(COMMENT_FONT_OPAQUE, s);
    }
    private static final String FFMPEG_PATH = "ffmpeg.path";

    public String getFfmpegPath() {
        return config.getString(FFMPEG_PATH, "bin/ffmpeg.exe");
    }

    public void setFfmpegPath(String s) {
        config.setProperty(FFMPEG_PATH, s);
    }
    private static final String FFMPEG_DLLPATH = "ffmpeg.dllpath";

    public String getFfmpegDllPath() {
        return config.getString(FFMPEG_DLLPATH, "bin/nicovideo.dll");
    }

    public void setFfmpegDllPath(String s) {
        config.setProperty(FFMPEG_DLLPATH, s);
    }
    private static final String MEDIAINFO_PATH = "ffmpeg.mediainfopath";

    public String getMediaInfoPath() {
        return config.getString(MEDIAINFO_PATH, "bin/MediaInfo.exe");
    }

    public void setMediaInfoPath(String s) {
        config.setProperty(MEDIAINFO_PATH, s);
    }
    private static final String FFMPEG_PARAM_OPTIONFILE = "ffmpeg.param.optionfile";

    public String getFfmpegOptionFile() {
        return config.getString(FFMPEG_PARAM_OPTIONFILE, null);
    }

    public void setFfmpegOptionFile(String s) {
        config.setProperty(FFMPEG_PARAM_OPTIONFILE, s);
    }
    private static final String FFMPEG_PARAM_EXT = "ffmpeg.param.ext";

    public String getFfmpegExtension() {
        return config.getString(FFMPEG_PARAM_EXT, ".m4v");
    }

    public void setFfmpegExtension(String s) {
        config.setProperty(FFMPEG_PARAM_EXT, s);
    }
    private static final String FFMPEG_PARAM_MAIN = "ffmpeg.param.main";

    public String getFfmpegMainOption() {
        return config.getString(FFMPEG_PARAM_MAIN, "");
    }

    public void setFfmpegMainOption(String s) {
        config.setProperty(FFMPEG_PARAM_MAIN, s);
    }
    private static final String FFMPEG_PARAM_IN = "ffmpeg.param.in";

    public String getFfmpegInOption() {
        return config.getString(FFMPEG_PARAM_IN, "");
    }

    public void setFfmpegInOption(String s) {
        config.setProperty(FFMPEG_PARAM_IN, s);
    }
    private static final String FFMPEG_PARAM_OUT = "ffmpeg.param.out";

    public String getFfmpegOutOption() {
        return config.getString(FFMPEG_PARAM_OUT,
                "-f ipod -g 150 -qcomp 0.7 -qmin 20 -qmax 30 -qdiff 4 -subq 6 -me_range 16 -i_qfactor 0.714286");
    }

    public void setFfmpegOutOption(String s) {
        config.setProperty(FFMPEG_PARAM_OUT, s);
    }
    private static final String FFMPEG_PARAM_AV = "ffmpeg.param.av";

    public String getFfmpegAvOption() {
        return config.getString(FFMPEG_PARAM_AV, "");
    }

    public void setFfmpegAvOption(String s) {
        config.setProperty(FFMPEG_PARAM_AV, s);
    }
    private static final String FFMPEG_PARAM_RESIZE = "ffmpeg.param.resize";

    public boolean getFfmpegResizeEnable() {
        return config.getBoolean(FFMPEG_PARAM_RESIZE, false);
    }

    public void setFfmpegResizeEnable(boolean s) {
        config.setProperty(FFMPEG_PARAM_RESIZE, s);
    }
    private static final String FFMPEG_PARAM_RESIZE_WIDTH = "ffmpeg.param.resize_width";

    public String getFfmpegResizeWidth() {
        return config.getString(FFMPEG_PARAM_RESIZE_WIDTH, "480");
    }

    public void setFfmpegResizeWidth(String s) {
        config.setProperty(FFMPEG_PARAM_RESIZE_WIDTH, s);
    }
    private static final String FFMPEG_PARAM_RESIZE_HEIGHT = "ffmpeg.param.resize_height";

    public String getFfmpegResizeHeight() {
        return config.getString(FFMPEG_PARAM_RESIZE_HEIGHT, "320");
    }

    public void setFfmpegResizeHeight(String s) {
        config.setProperty(FFMPEG_PARAM_RESIZE_HEIGHT, s);
    }
    private static final String FFMPEG_PARAM_KEEP_ASPECT = "ffmpeg.param.keep_aspect";

    public boolean getFfmpegKeepAspect() {
        return config.getBoolean(FFMPEG_PARAM_KEEP_ASPECT, true);
    }

    public void setFfmpegKeepAspect(boolean s) {
        config.setProperty(FFMPEG_PARAM_KEEP_ASPECT, s);
    }
    private static final String DISPLAY_CONVERTING = "convert.display_converting";

    public boolean getFfmpegDisplayConverting() {
        return config.getBoolean(DISPLAY_CONVERTING, true);
    }

    public void setFfmpegDisplayConverting(boolean s) {
        config.setProperty(DISPLAY_CONVERTING, s);
    }
    private static final String DLL_DISABLE = "convert.dll_disabled";

    public boolean getFfmpegDllDisabled() {
        return config.getBoolean(DLL_DISABLE, false);
    }

    public void setFfmpegDllDisabled(boolean s) {
        config.setProperty(DLL_DISABLE, s);
    }
    private static final String NG_WORD = "ng.word";

    @SuppressWarnings("unchecked")
    public List<String> getNgWords() {
        return config.getList(NG_WORD, new ArrayList<String>(0));
    }

    public void setNgWords(List<String> s) {
        config.setProperty(NG_WORD, s);
    }
    private static final String NG_ID = "ng.id";

    @SuppressWarnings("unchecked")
    public List<String> getNgIds() {
        return config.getList(NG_ID, new ArrayList<String>(0));
    }

    public void setNgIds(List<String> s) {
        config.setProperty(NG_ID, s);
    }

    /*
     * 検索
     */
    private static final String SEARCH_VIDEO = "search.video";

    @SuppressWarnings("unchecked")
    public List<String> getSearchVideoDirs() {
        return config.getList(SEARCH_VIDEO, new ArrayList<String>(1));
    }

    public void setSearchVideoDirs(List<String> s) {
        config.setProperty(SEARCH_VIDEO, s);
    }
    private static final String SEARCH_COMMENT = "search.comment";

    @SuppressWarnings("unchecked")
    public List<String> getSearchCommentDirs() {
        return config.getList(SEARCH_COMMENT, new ArrayList<String>(1));
    }

    public void setSearchCommentDirs(List<String> s) {
        config.setProperty(SEARCH_COMMENT, s);
    }

    /*
     * システム
     */
    private static final String SYSTEM_DOWNLOAD_THREAD = "system.download.thread";

    public int getSystemDownloadThread() {
        return config.getInt(SYSTEM_DOWNLOAD_THREAD, 1);
    }

    public void setSystemDownloadThread(int s) {
        config.setProperty(SYSTEM_DOWNLOAD_THREAD, s);
    }
    private static final String SYSTEM_DOWNLOAD_WAIT = "system.download.wait";

    public int getSystemDownloadWait() {
        return config.getInt(SYSTEM_DOWNLOAD_WAIT, 30);
    }

    public void setSystemDownloadWait(int s) {
        config.setProperty(SYSTEM_DOWNLOAD_WAIT, s);
    }
    private static final String SYSTEM_CONVERT_THREAD = "system.convert.thread";

    public int getSystemConvertThread() {
        return config.getInt(SYSTEM_CONVERT_THREAD, 2);
    }

    public void setSystemConvertThread(int s) {
        config.setProperty(SYSTEM_CONVERT_THREAD, s);
    }
    private static final String SYSTEM_TEMPDIR = "system.tempdir";

    public String getSystemTempDir() {
        return config.getString(SYSTEM_TEMPDIR, "tmp");
    }

    public void setSystemTempDir(String s) {
        config.setProperty(SYSTEM_TEMPDIR, s);
    }
    private static final String SYSTEM_WINDOW_WIDTH = "system.window.width";

    public int getSystemWindowWidth() {
        return config.getInt(SYSTEM_WINDOW_WIDTH, -1);
    }

    public void setSystemWindowWidth(int s) {
        config.setProperty(SYSTEM_WINDOW_WIDTH, s);
    }
    private static final String SYSTEM_WINDOW_HEIGHT = "system.window.height";

    public int getSystemWindowHeight() {
        return config.getInt(SYSTEM_WINDOW_HEIGHT, -1);
    }

    public void setSystemWindowHeight(int s) {
        config.setProperty(SYSTEM_WINDOW_HEIGHT, s);
    }
    private static final String SYSTEM_WINDOW_POS_X = "system.window.posx";

    public int getSystemWindowPosX() {
        return config.getInt(SYSTEM_WINDOW_POS_X, Integer.MIN_VALUE / 2);
    }

    public void setSystemWindowPosX(int s) {
        config.setProperty(SYSTEM_WINDOW_POS_X, s);
    }
    private static final String SYSTEM_WINDOW_POS_Y = "system.window.posy";

    public int getSystemWindowPosY() {
        return config.getInt(SYSTEM_WINDOW_POS_Y, Integer.MIN_VALUE / 2);
    }

    public void setSystemWindowPosY(int s) {
        config.setProperty(SYSTEM_WINDOW_POS_Y, s);
    }
    private static final String SYSTEM_COLUMN_ID = "system.column.id";

    public int getSystemColumnId() {
        return config.getInt(SYSTEM_COLUMN_ID, -1);
    }

    public void setSystemColumnId(int s) {
        config.setProperty(SYSTEM_COLUMN_ID, s);
    }
    private static final String SYSTEM_COLUMN_VIDEO = "system.column.video";

    public int getSystemColumnVideo() {
        return config.getInt(SYSTEM_COLUMN_VIDEO, -1);
    }

    public void setSystemColumnVideo(int s) {
        config.setProperty(SYSTEM_COLUMN_VIDEO, s);
    }
    private static final String SYSTEM_COLUMN_COMMENT = "system.column.comment";

    public int getSystemColumnComment() {
        return config.getInt(SYSTEM_COLUMN_COMMENT, -1);
    }

    public void setSystemColumnComment(int s) {
        config.setProperty(SYSTEM_COLUMN_COMMENT, s);
    }
    private static final String SYSTEM_COLUMN_CONVERT = "system.column.convert";

    public int getSystemColumnConvert() {
        return config.getInt(SYSTEM_COLUMN_CONVERT, -1);
    }

    public void setSystemColumnConvert(int s) {
        config.setProperty(SYSTEM_COLUMN_CONVERT, s);
    }
    private static final String SYSTEM_COLUMN_STATUS = "system.column.status";

    public int getSystemColumnStatus() {
        return config.getInt(SYSTEM_COLUMN_STATUS, -1);
    }

    public void setSystemColumnStatus(int s) {
        config.setProperty(SYSTEM_COLUMN_STATUS, s);
    }

    /*
     *
     */
    public void load(String fileName) throws ConfigurationException {
        config.setFileName(fileName);
        config.load();
    }

    public void save(File file) throws ConfigurationException {
        config.setFile(file);
        save();
    }

    public void save() throws ConfigurationException {
        config.save();
    }
}
