package open.dolphin.project;

import java.io.OutputStream;
import java.util.prefs.Preferences;
import javax.security.auth.Subject;
import open.dolphin.infomodel.UserModel;
import open.dolphin.utils.CombinedStringParser;
import open.dolphin.log.LogWriter;
import open.dolphin.security.EncryptUtil;

/**
 * プロジェクト情報管理クラス。
 *
 * @author  Kazushi Minagawa, Digital Globe, Inc.
 */
public class GlobalVariablesImplement implements java.io.Serializable {

    private Preferences prefs;
    private boolean valid;
    private DolphinPrincipal principal;
    private UserModel userModel;
    // FIXME: weak security
    private Subject subject;
    // Preferences のノード名
    private final String NODE_NAME = "/open/dolphin/project";
    // デフォルトのプロジェクト名
    private final String DEFAULT_PROJECT_NAME = "OpenDolphin";
    // User ID
    private final String DEFAULT_USER_ID = null;
    private final String DEFAULT_FACILITY_ID = null;
    // Server
    private final String DEFAULT_DB_ADDRESS = "localhost";
    private final int JBOSS_J2EE_PORT = 1099;
    // Claim
    private final boolean DEFAULT_SEND_CLAIM = false;
    private final boolean DEFAULT_SEND_DIAGNOSIS = true;
    private final String DEFAULT_CLAIM_HOST_NAME = "日医標準レセプト(ORCA)";
    private final String DEFAULT_CLAIM_ADDRESS = null;
    private final int DEFAULT_CLAIM_PORT = 5001;
    private final String DEFAULT_CLAIM_ENCODING = "UTF-8";
    private final boolean DEFAULT_USE_AS_PVTSERVER = true;
    private int DEFAULT_ORCA_CHARACTER_CODE = 0;
    // MML
    private final boolean DEFAULT_SEND_MML = false;
    private final String DEFAULT_MML_VERSION = "2.3";
    private final String DEFAULT_MML_ENCODING = "UTF-8";
    private final String DEFAULT_SEND_MML_ADDRESS = null;
    private final String DEFAULT_SEND_MML_DIRECTORY = null;
    // Update
    private final boolean DEFAULT_USE_PROXY = false;
    private final String DEFAULT_PROXY_HOST = null;
    private final int DEFAULT_PROXY_PORT = 8080;
    private final long DEFAULT_LAST_MODIFIED = 0L;
    private final String DEFAULT_DIRECTIONS = "なし,なし,なし,なし,なし,なし,なし,なし,なし,なし,なし,なし,なし,なし";

    /** ProjectStub を生成する。 */
    public GlobalVariablesImplement() {
        prefs = Preferences.userRoot().node(NODE_NAME);
    }

    /**
     * Preferencesを返す。
     * @return
     */
    public Preferences getPreferences() {
        return prefs;
    }

    /**
     * 設定ファイルが有効かどうかを返す。
     * @return 有効な時 true
     */
    public boolean isValid() {

        // UserTypeを判定する
        if (getUserType().equals(GlobalVariables.UserType.UNKNOWN)) {
            return false;
        }

        // UserIdとFacilityIdを確認する
        if (getUserId() == null || getFacilityId() == null) {
            return false;
        }

        // MML送信を行う場合の確認をする
        if (getSendMML() && (getUploaderIPAddress() == null || getUploadShareDirectory() == null)) {
            return false;
        }

        // ここまで来れば有効である
        valid = true;
        return valid;
    }

    public DolphinPrincipal getDolphinPrincipal() {
        return principal;
    }

    public void setDolphinPrincipal(DolphinPrincipal principal) {
        this.principal = principal;
    }

    /**
     * プロジェクト名を返す。
     * @return プロジェクト名 (Dolphin ASP, HOT, MAIKO, HANIWA ... etc)
     */
    public String getName() {
        return prefs.get(GlobalVariables.PROJECT_NAME, DEFAULT_PROJECT_NAME);
    }

    /**
     * プロジェクト名を返す。
     * @param projectName
     * @return プロジェクト名 (Dolphin ASP, HOT, MAIKO, HANIWA ... etc)
     */
    public void setName(String projectName) {
        prefs.put(GlobalVariables.PROJECT_NAME, projectName);
    }

    /**
     * ログインユーザ情報を返す。
     * @return Dolphinサーバに登録されているユーザ情報
     */
    public UserModel getUserModel() {
        return userModel;
    }

    /**
     * ログインユーザ情報を設定する。
     * @param userModel ログイン時にDolphinサーバから取得した情報
     */
    public void setUserModel(UserModel userModel) {
        this.userModel = userModel;
    }

    /**
     * ログイン画面用のUserIDを返す。
     * @return ログイン画面に表示するUserId
     */
    public String getUserId() {
        return prefs.get(GlobalVariables.USER_ID, DEFAULT_USER_ID);
    }

    /**
     * ログイン画面用のUserIDを設定する。
     * @param ログイン画面に表示するUserId
     */
    public void setUserId(String val) {
        prefs.put(GlobalVariables.USER_ID, val);
    }

    /**
     * ログイン画面用のFacilityIDを返す。
     * @return ログイン画面に表示するFacilityID
     */
    public String getFacilityId() {
        return prefs.get(GlobalVariables.FACILITY_ID, DEFAULT_FACILITY_ID);
    }

    /**
     * ログイン画面用のFacilityIDを設定する。
     * @param ログイン画面に表示するFacilityID
     */
    public void setFacilityId(String val) {
        prefs.put(GlobalVariables.FACILITY_ID, val);
    }

    /**
     * ORCA バージョンを返す。
     * @return ORCA バージョン
     */
    public String getOrcaVersion() {
        return prefs.get("orcaVersion", "40");
    }

    /**
     * ORCA バージョンを設定する。
     * @param ORCA バージョン
     */
    public void setOrcaVersion(String version) {
        prefs.put("orcaVersion", version);
    }

    /**
     * JMARICode を返す。
     * @return JMARI Code
     */
    public String getJMARICode() {
        return prefs.get("jmariCode", "JPN000000000000");
    }

    /**
     * JMARICode を返す。
     * @return JMARI Code
     */
    public void setJMARICode(String jamriCode) {
        prefs.put("jmariCode", jamriCode);
    }

    // UserType
    public GlobalVariables.UserType getUserType() {
        // Preference 情報がない場合は　UNKNOWN を返す
        // これは Project.isValid() で必ずテストされる
        String userType = prefs.get(GlobalVariables.USER_TYPE, GlobalVariables.UserType.UNKNOWN.toString());
        return GlobalVariables.UserType.valueOf(userType);
    }

    public void setUserType(GlobalVariables.UserType userType) {
        prefs.put(GlobalVariables.USER_TYPE, userType.toString());
    }

    public String getDbAddress() {
        return prefs.get(GlobalVariables.DB_ADDRESS, DEFAULT_DB_ADDRESS);
    }

    public void setDbAddress(String val) {
        prefs.put(GlobalVariables.DB_ADDRESS, val);
    }

    private byte[] getDbPassword() {
        return prefs.getByteArray(GlobalVariables.DB_PASSWORD, null);
    }

    public void setDbPassword(String pass) {
        if (pass.equals("")) {
            return;
        }
        prefs.putByteArray(GlobalVariables.DB_PASSWORD, EncryptUtil.encryptWithBlowfish(pass));
    }

    public String getDbPasswordWithoutHash() {

        byte[] encryptedPass = getDbPassword();

        if (encryptedPass == null) {
            return "";
        }
        return EncryptUtil.decodeWithBlowfish(encryptedPass);
    }

    public boolean getDbSSLState() {
        return prefs.getBoolean(GlobalVariables.DB_SSLSTATE, true);
    }

    public void setDbSSLState(boolean state) {
        prefs.putBoolean(GlobalVariables.DB_SSLSTATE, state);
    }

    public int getHostPort() {
        return prefs.getInt(GlobalVariables.HOST_PORT, JBOSS_J2EE_PORT);
    }

    /**
     *
     * @param val
     */
    public void setHostPort(int val) {
        prefs.putInt(GlobalVariables.HOST_PORT, val);
    }

    public String getPDFStore() {
        String defaultStore = GlobalConstants.getPDFDirectory();
        return prefs.get("pdfStore", defaultStore);
    }

    public void setPDFStore(String pdfStore) {
        prefs.put("pdfStore", pdfStore);
    }

    public int getFetchKarteCount() {
        return prefs.getInt(GlobalVariables.DOC_HISTORY_FETCHCOUNT, 1);
    }

    public void setFetchKarteCount(int cnt) {
        prefs.putInt(GlobalVariables.DOC_HISTORY_FETCHCOUNT, cnt);
    }

    /**
     *
     * @return
     */
    public boolean getScrollKarteV() {
        return prefs.getBoolean(GlobalVariables.KARTE_SCROLL_DIRECTION, true);
    }

    public void setScrollKarteV(boolean b) {
        prefs.putBoolean(GlobalVariables.KARTE_SCROLL_DIRECTION, b);
    }

    public boolean getAscendingKarte() {
        return prefs.getBoolean(GlobalVariables.DOC_HISTORY_ASCENDING, false);
    }

    public void setAscendingKarte(boolean b) {
        prefs.putBoolean(GlobalVariables.DOC_HISTORY_ASCENDING, b);
    }

    public int getKarteExtractionPeriod() {
        return prefs.getInt(GlobalVariables.DOC_HISTORY_PERIOD, -12);
    }

    public void setKarteExtractionPeriod(int period) {
        prefs.putInt(GlobalVariables.DOC_HISTORY_PERIOD, period);
    }

    public boolean getShowModifiedKarte() {
        return prefs.getBoolean(GlobalVariables.DOC_HISTORY_SHOWMODIFIED, false);
    }

    public void setShowModifiedKarte(boolean b) {
        prefs.putBoolean(GlobalVariables.DOC_HISTORY_SHOWMODIFIED, b);
    }

    public boolean getShowUnsendKarte() {
        return prefs.getBoolean(GlobalVariables.DOC_HISTORY_SHOWUNSEND, false);
    }

    /**
     *
     * @param b
     */
    public void setShowUnsendKarte(boolean b) {
        prefs.putBoolean(GlobalVariables.DOC_HISTORY_SHOWUNSEND, b);
    }

    public boolean getShowSendKarte() {
        return prefs.getBoolean(GlobalVariables.DOC_HISTORY_SHOWSEND, false);
    }

    public void setShowSendKarte(boolean b) {
        prefs.putBoolean(GlobalVariables.DOC_HISTORY_SHOWSEND, b);
    }

    /**
     *
     * @return
     */
    public boolean getShowNewestKarte() {
        return prefs.getBoolean(GlobalVariables.DOC_HISTORY_SHOWNEWEST, false);
    }

    public void setShowNewestKarte(boolean b) {
        prefs.putBoolean(GlobalVariables.DOC_HISTORY_SHOWNEWEST, b);
    }

    public boolean getAscendingDiagnosis() {
        return prefs.getBoolean(GlobalVariables.DIAGNOSIS_ASCENDING, false);
    }

    public void setAscendingDiagnosis(boolean b) {
        prefs.putBoolean(GlobalVariables.DIAGNOSIS_ASCENDING, b);
    }

    /**
     *
     * @return
     */
    public int getDiagnosisExtractionPeriod() {
        return prefs.getInt(GlobalVariables.DIAGNOSIS_PERIOD, 0);
    }

    public void setDiagnosisExtractionPeriod(int period) {
        prefs.putInt(GlobalVariables.DIAGNOSIS_PERIOD, period);
    }

    /**
     *
     * @param code
     */
    public void setCharacterCode(int code) {
        prefs.putInt(GlobalVariables.ORCA_CHARACTER_CODE, code);
    }

    public int getCharacterCode() {
        return prefs.getInt(GlobalVariables.ORCA_CHARACTER_CODE, DEFAULT_ORCA_CHARACTER_CODE);
    }

    public boolean isAutoOutcomeInput() {
        return prefs.getBoolean("autoOutcomeInput", false);
    }

    public void setAutoOutcomeInput(boolean b) {
        prefs.putBoolean("autoOutcomeInput", b);
    }

    public boolean isReplaceStamp() {
        return prefs.getBoolean("replaceStamp", false);
    }

    public void setReplaceStamp(boolean b) {
        prefs.putBoolean("replaceStamp", b);
    }

    public boolean isStampSpace() {
        return prefs.getBoolean("stampSpace", true);
    }

    public void setStampSpace(boolean b) {
        prefs.putBoolean("stampSpace", b);
    }

    /**
     *
     * @return
     */
    public boolean isLaboFold() {
        return prefs.getBoolean("laboFold", true);
    }

    public void setLaboFold(boolean b) {
        prefs.putBoolean("laboFold", b);
    }

    public String getDefaultZyozaiNum() {
        return prefs.get("defaultZyozaiNum", "3");
    }

    public void setDefaultZyozaiNum(String defaultZyozaiNum) {
        prefs.put("defaultZyozaiNum", defaultZyozaiNum);
    }

    public String getDefaultMizuyakuNum() {
        return prefs.get("defaultMizuyakuNum", "1");
    }

    /**
     *
     * @param defaultMizuyakuNum
     */
    public void setDefaultMizuyakuNum(String defaultMizuyakuNum) {
        prefs.put("defaultMizuyakuNum", defaultMizuyakuNum);
    }

    public String getDefaultSanyakuNum() {
        return prefs.get("defaultSanyakuNum", "1.0");
    }

    public void setDefaultSanyakuNum(String defaultSanyakuNum) {
        prefs.put("defaultSanyakuNum", defaultSanyakuNum);
    }

    public String getDefaultRpNum() {
        return prefs.get("defaultRpNum", "3");
    }

    public void setDefaultRpNum(String defaultRpNum) {
        prefs.put("defaultRpNum", defaultRpNum);
    }

    public int getLaboTestExtractionPeriod() {
        return prefs.getInt(GlobalVariables.LABOTEST_PERIOD, -6);
    }

    public void setLaboTestExtractionPeriod(int period) {
        prefs.putInt(GlobalVariables.LABOTEST_PERIOD, period);
    }

    public boolean getConfirmAtNew() {
        return prefs.getBoolean(GlobalVariables.KARTE_SHOW_CONFIRM_AT_NEW, true);
    }

    public void setConfirmAtNew(boolean b) {
        prefs.putBoolean(GlobalVariables.KARTE_SHOW_CONFIRM_AT_NEW, b);
    }

    /**
     *
     * @return
     */
    public int getCreateKarteMode() {
        return prefs.getInt(GlobalVariables.KARTE_CREATE_MODE, 0); // 0=emptyNew, 1=applyRp, 2=copyNew
    }

    public void setCreateKarteMode(int mode) {
        prefs.putInt(GlobalVariables.KARTE_CREATE_MODE, mode);
    }

    public boolean getPlaceKarteMode() {
        return prefs.getBoolean(GlobalVariables.KARTE_PLACE_MODE, true);
    }

    public void setPlaceKarteMode(boolean mode) {
        prefs.putBoolean(GlobalVariables.KARTE_PLACE_MODE, mode);
    }

    public boolean getConfirmAtSave() {
        return prefs.getBoolean(GlobalVariables.KARTE_SHOW_CONFIRM_AT_SAVE, true);
    }

    public void setConfirmAtSave(boolean b) {
        prefs.putBoolean(GlobalVariables.KARTE_SHOW_CONFIRM_AT_SAVE, b);
    }

    /**
     *
     * @return
     */
    public int getPrintKarteCount() {
        return prefs.getInt(GlobalVariables.KARTE_PRINT_COUNT, 0);
    }

    public void setPrintKarteCount(int cnt) {
        prefs.putInt(GlobalVariables.KARTE_PRINT_COUNT, cnt);
    }

    public int getSaveKarteMode() {
        return prefs.getInt(GlobalVariables.KARTE_SAVE_ACTION, 0); // 0=save 1=saveTmp
    }

    public void setSaveKarteMode(int mode) {
        prefs.putInt(GlobalVariables.KARTE_SAVE_ACTION, mode); // 0=save 1=saveTmp
    }

    // CLAIM関連情報
    /**
     * CLAIM 送信全体への設定を返す。
     * デフォルトが false になっているのは新規インストールの場合で ORCA 接続なしで
     * 使えるようにするため。
     * @param 送信する時 true
     */
    public boolean getSendClaim() {
        return prefs.getBoolean(GlobalVariables.SEND_CLAIM, DEFAULT_SEND_CLAIM);
    }

    public void setSendClaim(boolean b) {
        prefs.putBoolean(GlobalVariables.SEND_CLAIM, b);
    }

    /**
     * 保存時に CLAIM 送信を行うかどうかを返す。
     * @param 行う時 true
     */
    //  public boolean getSendClaimSave() {
    //      return prefs.getBoolean(GrobalVariables.SEND_CLAIM_SAVE, DEFAULT_SEND_CLAIM_SAVE);
    //  }
    //   public void setSendClaimSave(boolean b) {
    //       prefs.putBoolean(GrobalVariables.SEND_CLAIM_SAVE, b);
    //   }
    /**
     * 仮保存時に CLAIM 送信を行うかどうかを返す。
     * @param 行う時 true
     */
    //   public boolean getSendClaimTmp() {
    //       return prefs.getBoolean(GrobalVariables.SEND_CLAIM_TMP, DEFAULT_SEND_CLAIM_TMP);
    //   }
    //  public void setSendClaimTmp(boolean b) {
    //      prefs.putBoolean(GrobalVariables.SEND_CLAIM_TMP, b);
    //  }
    /**
     * 修正時に CLAIM 送信を行うかどうかを返す。
     * @param 行う時 true
     */
    //  public boolean getSendClaimModify() {
    //      return prefs.getBoolean(GrobalVariables.SEND_CLAIM_MODIFY, DEFAULT_SEND_CLAIM_MODIFY);
    //  }
    //  public void setSendClaimModify(boolean b) {
    //      prefs.putBoolean(GrobalVariables.SEND_CLAIM_MODIFY, b);
    //   }
    public String getDefaultKarteTitle() {
        return prefs.get("defaultKarteTitle", "経過記録");
    }

    public void setDefaultKarteTitle(String defaultKarteTitle) {
        prefs.put("defaultKarteTitle", defaultKarteTitle);
    }

    public boolean isUseTop15AsTitle() {
        return prefs.getBoolean("useTop15AsTitle", true);
    }

    public void setUseTop15AsTitle(boolean useTop15AsTitle) {
        prefs.putBoolean("useTop15AsTitle", useTop15AsTitle);
    }

    /**
     * 病名 CLAIM 送信を行うかどうかを返す。
     * @param 行う時 true
     */
    public boolean getSendDiagnosis() {
        return prefs.getBoolean(GlobalVariables.SEND_DIAGNOSIS, DEFAULT_SEND_DIAGNOSIS);
    }

    /**
     *
     * @param b
     */
    public void setSendDiagnosis(boolean b) {
        prefs.putBoolean(GlobalVariables.SEND_DIAGNOSIS, b);
    }

    /**
     *
     * @return
     */
    public String getClaimHostName() {
        return prefs.get(GlobalVariables.CLAIM_HOST_NAME, DEFAULT_CLAIM_HOST_NAME);
    }

    public void setClaimHostName(String b) {
        prefs.put(GlobalVariables.CLAIM_HOST_NAME, b);
    }

    public String getClaimEncoding() {
        return prefs.get(GlobalVariables.CLAIM_ENCODING, DEFAULT_CLAIM_ENCODING);
    }

    public void setClaimEncoding(String val) {
        prefs.put(GlobalVariables.CLAIM_ENCODING, val);
    }

    public String getClaimAddress() {
        return prefs.get(GlobalVariables.CLAIM_ADDRESS, DEFAULT_CLAIM_ADDRESS);
    }

    /**
     *
     * @param val
     */
    public void setClaimAddress(String val) {
        prefs.put(GlobalVariables.CLAIM_ADDRESS, val);
    }

    /**
     *
     * @return
     */
    public int getClaimPort() {
        return prefs.getInt(GlobalVariables.CLAIM_PORT, DEFAULT_CLAIM_PORT);
    }

    /**
     *
     * @param val
     */
    public void setClaimPort(int val) {
        prefs.putInt(GlobalVariables.CLAIM_PORT, val);
    }

    /**
     *
     * @param b
     */
    public void setUseAsPVTServer(boolean b) {
        prefs.putBoolean(GlobalVariables.USE_AS_PVT_SERVER, b);
    }

    public boolean getUseAsPVTServer() {
        return prefs.getBoolean(GlobalVariables.USE_AS_PVT_SERVER, DEFAULT_USE_AS_PVTSERVER);
    }

    //入院か否か
    public boolean getIsHospital() {
        return prefs.getBoolean(GlobalVariables.IS_HOSPITAL, false);
    }

    public void setIsHospital(boolean val) {
        prefs.putBoolean(GlobalVariables.IS_HOSPITAL, val);
    }

    public String getLetterGreetings() {
        return prefs.get(GlobalVariables.GREETINGS, "");
    }

    /**
     *
     * @param val
     */
    public void setLetterGreetings(String val) {
        prefs.put(GlobalVariables.GREETINGS, val);
    }

    //
    // AreaNetwork関連情報
    //
    /**
     *
     * @return
     */
    public boolean getJoinAreaNetwork() {
        return prefs.getBoolean(GlobalVariables.JOIN_AREA_NETWORK, false);		// 地域連携参加
    }

    public void setJoinAreaNetwork(boolean b) {
        prefs.putBoolean(GlobalVariables.JOIN_AREA_NETWORK, b);				// 地域連携参加
    }

    public String getAreaNetworkName() {
        return prefs.get(GlobalVariables.AREA_NETWORK_NAME, null);			// 地域連携名
    }

    public void setAreaNetworkName(String name) {
        prefs.put(GlobalVariables.AREA_NETWORK_NAME, name);				// 地域連携名
    }

    public String getAreaNetworkFacilityId() {
        return prefs.get(GlobalVariables.AREA_NETWORK_FACILITY_ID, null);		// 地域連携施設ID
    }

    public void setAreaNetworkFacilityId(String id) {
        prefs.put(GlobalVariables.AREA_NETWORK_FACILITY_ID, id);			// 地域連携施設ID
    }

    /**
     *
     * @return
     */
    public String getAreaNetworkCreatorId() {
        return prefs.get(GlobalVariables.AREA_NETWORK_CREATOR_ID, null);		// 地域連携CreatorID
    }

    public void setAreaNetworkCreatorId(String id) {
        prefs.put(GlobalVariables.AREA_NETWORK_CREATOR_ID, id);                         // 地域連携CreatorID
    }

    //
    // MML送信関連の情報
    //
    public boolean getSendMML() {
        return prefs.getBoolean(GlobalVariables.SEND_MML, DEFAULT_SEND_MML);
    }

    /**
     *
     * @param b
     */
    public void setSendMML(boolean b) {
        prefs.putBoolean(GlobalVariables.SEND_MML, b);
    }

    public String getMMLVersion() {
        return prefs.get(GlobalVariables.MML_VERSION, DEFAULT_MML_VERSION);
    }

    public void setMMLVersion(String b) {
        prefs.put(GlobalVariables.MML_VERSION, b);
    }

    /**
     *
     * @return
     */
    public String getMMLEncoding() {
        return prefs.get(GlobalVariables.MML_ENCODING, DEFAULT_MML_ENCODING);
    }

    public void setMMLEncoding(String val) {
        prefs.put(GlobalVariables.MML_ENCODING, val);
    }

    public boolean getMIMEEncoding() {
        return prefs.getBoolean("mimeEncoding", false);
    }

    public void setMIMEEncoding(boolean val) {
        prefs.putBoolean("mimeEncoding", val);
    }

    public String getUploaderIPAddress() {
        return prefs.get(GlobalVariables.SEND_MML_ADDRESS, DEFAULT_SEND_MML_ADDRESS);
    }

    public void setUploaderIPAddress(String val) {
        prefs.put(GlobalVariables.SEND_MML_ADDRESS, val);
    }

    public String getUploadShareDirectory() {
        return prefs.get(GlobalVariables.SEND_MML_DIRECTORY, DEFAULT_SEND_MML_DIRECTORY);
    }

    public void setUploadShareDirectory(String val) {
        prefs.put(GlobalVariables.SEND_MML_DIRECTORY, val);
    }

    //
    // Software Update 関連
    //
    public boolean getUseProxy() {
        return prefs.getBoolean(GlobalVariables.USE_PROXY, DEFAULT_USE_PROXY);
    }

    public void setUseProxy(boolean b) {
        prefs.putBoolean(GlobalVariables.USE_PROXY, b);
    }

    public String getProxyHost() {
        return prefs.get(GlobalVariables.PROXY_HOST, DEFAULT_PROXY_HOST);
    }

    /**
     *
     * @param val
     */
    public void setProxyHost(String val) {
        prefs.put(GlobalVariables.PROXY_HOST, val);
    }

    public int getProxyPort() {
        return prefs.getInt(GlobalVariables.PROXY_PORT, DEFAULT_PROXY_PORT);
    }

    public void setProxyPort(int val) {
        prefs.putInt(GlobalVariables.PROXY_PORT, val);
    }

    public long getLastModify() {
        return prefs.getLong(GlobalVariables.LAST_MODIFIED, DEFAULT_LAST_MODIFIED);
    }

    public void setLastModify(long val) {
        prefs.putLong(GlobalVariables.LAST_MODIFIED, val);
    }

    public CombinedStringParser getDirections() {
        String line_string = prefs.get(GlobalVariables.DIRECTIONS, DEFAULT_DIRECTIONS);
        return new CombinedStringParser(',', line_string);
    }

    public void setDirections(CombinedStringParser lines) {
        prefs.put(GlobalVariables.DIRECTIONS, lines.toCombinedString());
    }

    public String getDirection(int index) {
        String line_string = prefs.get(GlobalVariables.DIRECTIONS, DEFAULT_DIRECTIONS);
        CombinedStringParser line = new CombinedStringParser(',', line_string);
        return line.get(index);
    }

    public void setDirection(int index, String direction) {
        CombinedStringParser line = new CombinedStringParser(',', prefs.get(GlobalVariables.DIRECTIONS, DEFAULT_DIRECTIONS));
        line.set(index, direction);
        prefs.put(GlobalVariables.DIRECTIONS, line.toCombinedString());
    }

    public CombinedStringParser getCcDirections() {
        String line_string = prefs.get(GlobalVariables.CC_DIRECTIONS, DEFAULT_DIRECTIONS);
        return new CombinedStringParser(',', line_string);
    }

    public void setCcDirections(CombinedStringParser lines) {
        prefs.put(GlobalVariables.CC_DIRECTIONS, lines.toCombinedString());
    }

    public String getCcDirection(int index) {
        String line_string = prefs.get(GlobalVariables.CC_DIRECTIONS, DEFAULT_DIRECTIONS);
        CombinedStringParser line = new CombinedStringParser(',', line_string);
        return line.get(index);
    }

    public void setCcDirection(int index, String direction) {
        CombinedStringParser line = new CombinedStringParser(',', prefs.get(GlobalVariables.CC_DIRECTIONS, DEFAULT_DIRECTIONS));
        line.set(index, direction);
        prefs.put(GlobalVariables.CC_DIRECTIONS, line.toCombinedString());
    }

    public boolean getFepControl() {
        return prefs.getBoolean(GlobalVariables.FEP_CONTROL, true);
    }

    /**
     *
     * @param value
     */
    public void setFepControl(boolean value) {
        prefs.putBoolean(GlobalVariables.FEP_CONTROL, value);
    }

    public void exportSubtree(OutputStream os) {
        try {
            prefs.exportSubtree(os);
        } catch (Exception e) {
            LogWriter.error(getClass(), e);
        }
    }

    public void clear() {
        try {
            prefs.clear();
        } catch (Exception e) {
            LogWriter.error(getClass(), e);
        }
    }

    // FIXME: weak security
    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    // FIXME: weak security
    public Subject getSubject() {
        return this.subject;
    }

    public String getPreferencesPath() {
        return prefs.absolutePath();
    }
}
