package org.petschko.lib;

import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;

/**
 * Author: Peter Dragicevic [peter-91@hotmail.de]
 * Authors-Website: http://petschko.org/
 * Date: 23.12.2016
 * Time: 04:44
 * Update: -
 * Version: 0.0.1
 *
 * Notes: UserPref Class
 */
public abstract class UserPref {
	private Properties properties = null;
	private String filePath;

	/**
	 * UserPrefs Constructor
	 *
	 * @param filePath - File-Path to UserPref-File
	 */
	public UserPref(@Nullable String filePath) {
		this.setFilePath(filePath);

		if(filePath != null)
			this.load();
	}

	/**
	 * Returns the Properties Object
	 *
	 * @return - Properties Object
	 */
	private Properties getProperties() {
		return properties;
	}

	/**
	 * Sets the Properties Object
	 *
	 * @param properties - Properties Object
	 */
	protected void setProperties(Properties properties) {
		this.properties = properties;
	}

	/**
	 * Returns the File-Path of the Properties File
	 *
	 * @return - File-Path of the Properties File or null if not set
	 */
	public String getFilePath() {
		return filePath;
	}

	/**
	 * Sets the File-Path of the Properties File
	 *
	 * @param filePath - File-Path of the Properties File
	 */
	public void setFilePath(@Nullable String filePath) {
		this.filePath = filePath;
	}

	/**
	 * Loads the Properties of the User from a File
	 *
	 * @return - true of Properties where loaded else false
	 */
	public boolean load() {
		if(this.getFilePath() == null)
			return this.loadDefaults();

		if(! File.existsFile(this.getFilePath()))
			return this.loadDefaults();

		// Try to read the File
		Properties p = new Properties();
		Reader reader;
		try {
			reader = new FileReader(this.getFilePath());
			p.load(reader);
		} catch(Exception e) {
			e.printStackTrace();

			return loadDefaults();
		} finally {
			this.setProperties(p);
		}

		return true;
	}

	/**
	 * Loads the Default settings
	 *
	 * @return - true if the Properties where loaded correctly
	 */
	public abstract boolean loadDefaults();

	/**
	 * Saves the Properties of the User to a File
	 *
	 * @return - true if the Save was successful else false
	 */
	public boolean save() {
		if(this.getFilePath() == null || this.getProperties() == null)
			return false;

		// Check if File Exists if not try to create it
		if(! File.existsFile(this.getFilePath(), true))
			return false;

		try {
			FileWriter fileWriter = new FileWriter(this.getFilePath());
			this.getProperties().store(fileWriter, "User Config File");
		} catch(IOException e) {
			e.printStackTrace();

			return false;
		}

		return true;
	}

	/**
	 * Returns the requested Property-Value with a Fallback-Value
	 * @param configKey - Property-Key (Name)
	 * @return - Property-Value
	 */
	public String getConfig(@NotNull String configKey) {
		return getConfig(configKey, null);
	}

	/**
	 * Returns the requested Property-Value or the Fallback-Value
	 *
	 * @param configKey - Property-Key (Name)
	 * @param fallbackValue - Fallback-Value if the Key is not set or null to ignore
	 * @return - Property-Value
	 */
	public String getConfig(@NotNull String configKey, @Nullable String fallbackValue) {
		if(this.getProperties() == null)
			this.load();

		if(fallbackValue == null)
			return this.getProperties().getProperty(configKey);

		return this.getProperties().getProperty(configKey, fallbackValue);
	}

	/**
	 * Sets a Value to the Properties Object
	 *
	 * @param configKey - Property-Key (Name)
	 * @param newValue - New Value for this Properties-Key
	 */
	public void setConfig(@NotNull String configKey, @NotNull String newValue) {
		if(this.getProperties() == null)
			this.load();

		this.getProperties().setProperty(configKey, newValue);
	}
}

@@ -3433,16 +3433,163 @@
 gKey);%0A%0A
+%09%09// Try to add the Property if not exists%0A%09%09if(this.getProperties().getProperty(configKey) == null)%0A%09%09%09this.setConfig(configKey, fallbackValue);%0A%0A
 %09%09return

Add values if they not exists and a fallback value is given