/*
* Copyright (C) 2013-2017 たんらる
*/
package fourthline.mabiicco;
import java.awt.Rectangle;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.InvalidPropertiesFormatException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.function.Consumer;
import fourthline.mabiicco.ui.PianoRollView;
import fourthline.mmlTools.optimizer.MMLStringOptimizer;
public final class MabiIccoProperties {
private final Properties properties = new Properties();
private final String configFile = "config.properties";
private static final MabiIccoProperties instance = new MabiIccoProperties();
/** 最近開いたファイル */
private static final String RECENT_FILE = "app.recent_file";
/** DLSファイル */
public final Property<String> dls_file = new StringProperty("app.dls_file", AppResource.appText("default.dls_file"));
/** ウィンドウ最大化 */
public final Property<Boolean> windowMaximize = new BooleanProperty("window.maximize", false);
/** ウィンドウ位置 x座標 */
private static final String WINDOW_X = "window.x";
/** ウィンドウ位置 y座標 */
private static final String WINDOW_Y = "window.y";
/** ウィンドウ位置 幅 */
private static final String WINDOW_WIDTH = "window.width";
/** ウィンドウ位置 高さ */
private static final String WINDOW_HEIGHT = "window.height";
/** ピアノロール表示の高さスケール */
private static final String HEIGHT_SCALE = "view.pianoRoll.heightScale";
/** クリック再生機能の有効/無効 */
public final Property<Boolean> enableClickPlay = new BooleanProperty("function.enable_click_play", true);
/** マーカー表示の有効/無効 */
public final Property<Boolean> enableViewMarker = new BooleanProperty("function.enable_view_marker", true);
/** 編集モード. 非編集時はアクティブパートなし, MMLのTextPanel非表示. */
public final Property<Boolean> enableEdit = new BooleanProperty("function.enable_edit", true);
/** 音源境界 */
public final Property<Boolean> viewRange = new BooleanProperty("view.pianoRoll.range", true);
/** すべての音量を表示 */
public final Property<Boolean> showAllVelocity = new BooleanProperty("view.pianoRoll.show_all_velocity", false);
/** 音量線 */
public final Property<Boolean> viewVelocityLine = new BooleanProperty("view.velocity.line", true);
/** ノートクリックによるアクティブパート切り替え */
public final Property<Boolean> activePartSwitch = new BooleanProperty("function.active_part_switch", false);
/** MML最適化 */
public final Property<Boolean> enableMMLOptimize = new BooleanProperty("function.mml_optimize", true, (t) -> MMLStringOptimizer.setOptSkip(!t.booleanValue()));
/** Midi Device */
public final Property<String> midiInputDevice = new StringProperty("midi.input_device");
/** Midi キーボード 和音入力 */
public final Property<Boolean> midiChordInput = new BooleanProperty("midi.chord_input", false);
/** ファイル履歴 */
public static final int MAX_FILE_HISTORY = 8;
private static final String FILE_HISTORY = "file.history";
public static MabiIccoProperties getInstance() {
return instance;
}
private MabiIccoProperties() {
try {
properties.load(new FileInputStream(configFile));
initFileHistory();
} catch (InvalidPropertiesFormatException e) {
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
private void save() {
try {
properties.store(new FileOutputStream(configFile), "");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getRecentFile() {
String str = properties.getProperty(RECENT_FILE, "");
return str;
}
public void setRecentFile(String path) {
properties.setProperty(RECENT_FILE, path);
save();
}
public List<File> getDlsFile() {
String str = dls_file.get();
String filenames[] = str.split(",");
ArrayList<File> fileArray = new ArrayList<>();
for (String filename : filenames) {
fileArray.add(new File(filename));
}
return fileArray;
}
public void setDlsFile(File fileArray[]) {
StringBuilder sb = new StringBuilder();
if (fileArray != null) {
for (File file : fileArray) {
sb.append(file.getPath()).append(',');
}
sb.deleteCharAt(sb.length()-1);
}
dls_file.set(sb.toString());
}
public Rectangle getWindowRect() {
String x = properties.getProperty(WINDOW_X, "-1");
String y = properties.getProperty(WINDOW_Y, "-1");
String width = properties.getProperty(WINDOW_WIDTH, "-1");
String height = properties.getProperty(WINDOW_HEIGHT, "-1");
Rectangle rect = new Rectangle(
Integer.parseInt(x),
Integer.parseInt(y),
Integer.parseInt(width),
Integer.parseInt(height)
);
return rect;
}
public void setWindowRect(Rectangle rect) {
properties.setProperty(WINDOW_X, Integer.toString((int)rect.getX()));
properties.setProperty(WINDOW_Y, Integer.toString((int)rect.getY()));
properties.setProperty(WINDOW_WIDTH, Integer.toString((int)rect.getWidth()));
properties.setProperty(WINDOW_HEIGHT, Integer.toString((int)rect.getHeight()));
save();
}
public int getPianoRollViewHeightScaleProperty() {
String s = properties.getProperty(HEIGHT_SCALE, "1");
int index = Integer.parseInt(s);
if ( (index < 0) || (index >= PianoRollView.NOTE_HEIGHT_TABLE.length) ) {
index = 1;
}
return index;
}
public void setPianoRollViewHeightScaleProperty(int index) {
properties.setProperty(HEIGHT_SCALE, ""+index);
save();
}
private final LinkedList<File> fileHistory = new LinkedList<>();
private void initFileHistory() {
for (int i = 0; i < MAX_FILE_HISTORY; i++) {
String s = properties.getProperty(FILE_HISTORY+i);
if (s != null) {
fileHistory.addLast( new File(s) );
}
}
}
public File[] getFileHistory() {
File list[] = new File[ fileHistory.size() ];
return fileHistory.toArray( list );
}
public void setFileHistory(File file) {
if (fileHistory.contains(file)) {
fileHistory.remove(file);
}
fileHistory.addFirst(file);
while (fileHistory.size() > MAX_FILE_HISTORY) {
fileHistory.removeLast();
}
for (int i = 0; i < fileHistory.size(); i++) {
properties.setProperty(FILE_HISTORY+i, fileHistory.get(i).getAbsolutePath());
}
save();
}
public interface Property<T> {
public void set(T value);
public T get();
}
private final class StringProperty implements Property<String> {
private final String name;
private final String defaultValue;
private StringProperty(String name) {
this(name, "");
}
private StringProperty(String name, String defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
}
@Override
public void set(String value) {
properties.setProperty(name, value);
save();
}
@Override
public String get() {
String str = properties.getProperty(name, defaultValue);
return str;
}
}
private final class BooleanProperty implements Property<Boolean> {
private final String name;
private final String defaultValue;
private final Consumer<Boolean> optDo;
private BooleanProperty(String name, boolean defaultValue) {
this(name, defaultValue, null);
}
private BooleanProperty(String name, boolean defaultValue, Consumer<Boolean> optDo) {
this.name = name;
this.defaultValue = Boolean.toString(defaultValue);
this.optDo = optDo;
}
@Override
public void set(Boolean b) {
properties.setProperty(name, Boolean.toString(b));
save();
if (optDo != null) {
optDo.accept(b);
}
}
@Override
public Boolean get() {
String str = properties.getProperty(name, defaultValue);
Boolean value = Boolean.parseBoolean(str);
if (optDo != null) {
optDo.accept(value);
}
return value;
}
}
}