package org.reprap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.Properties;
import java.util.Enumeration;
import java.util.List;
import java.util.ArrayList;
import javax.media.j3d.Appearance;
import javax.media.j3d.Material;
import javax.vecmath.Color3f;
import org.reprap.utilities.Debug;
/**
* A single centralised repository of the current preference settings. This also
* implements (almost) a singleton for easy global access. If there are no current
* preferences fallback distribution defaults are used.
*/
public class Preferences {
private static final String propsFile = "reprap.properties";
private static final String propsFolder = ".reprap";
private static final String propsFileDist = "reprap.properties.dist";
private static Preferences globalPrefs = null;
Properties fallbackPreferences;
Properties mainPreferences;
/*
* This section deals with internal (i.e. not RepRap machine, but this code or
* physics) precisions and accuracies - it should probably
* get its data from the properties file...
*/
private static final int grid = 100; // Click outline polygons to a...
private static final double gridRes = 1.0/grid; // ...10 micron grid
private static final double lessGridSquare = gridRes*gridRes*0.01; // Small squared size of a gridsquare
private static final double tiny = 1.0e-12; // A small number
private static final double swell = 1.01; // Quad tree swell factor
private static final double machineResolution = 0.1; // RepRap step size in mm - should
// derive this from Axis1Scale and Axis2Scale
private static final double absoluteZero = -273;
private static final double inToMM = 25.4;
private static final Color3f black = new Color3f(0, 0, 0);
public static int grid() { return grid; }
public static double gridRes() { return gridRes; }
public static double lessGridSquare() { return lessGridSquare; }
public static double tiny() { return tiny; }
public static double swell() { return swell; }
public static double inchesToMillimetres() { return inToMM; }
public static double machineResolution() { return machineResolution; }
public static double absoluteZero() { return absoluteZero; }
public static Appearance unselectedApp()
{
Color3f unselectedColour = null;
try
{
unselectedColour = new Color3f((float)Preferences.loadGlobalDouble("UnselectedColourR(0..1)"),
(float)Preferences.loadGlobalDouble("UnselectedColourG(0..1)"),
(float)Preferences.loadGlobalDouble("UnselectedColourB(0..1)"));
} catch (Exception ex)
{
ex.printStackTrace();
}
Appearance unselectedApp = new Appearance();
unselectedApp.setMaterial(new
Material(unselectedColour, black, unselectedColour, black, 0f));
return unselectedApp;
}
// Main preferences constructor
public Preferences() throws IOException {
fallbackPreferences = new Properties();
mainPreferences = new Properties();
URL fallbackUrl = ClassLoader.getSystemResource(propsFileDist);
// Construct URL of user properties file
String path = new String(System.getProperty("user.home") + File.separatorChar +
propsFolder + File.separatorChar + propsFile);
File mainFile = new File(path);
URL mainUrl = mainFile.toURL();
if (fallbackUrl == null && !mainFile.exists())
throw new IOException("Cannot load RepRap properties file or default "+propsFileDist);
if (fallbackUrl != null)
fallbackPreferences.load(fallbackUrl.openStream());
if (mainFile.exists())
{
mainPreferences.load(mainUrl.openStream());
if(fallbackUrl != null)
comparePreferences();
} else
{
// If we don't have a local preferences file copy the default
// file into it.
mainPreferences.load(fallbackUrl.openStream());
save();
}
}
/**
* Compare the users preferences with the distribution one and report any
* different names.
*/
private void comparePreferences()
{
Enumeration usersLot = mainPreferences.propertyNames();
Enumeration distLot = fallbackPreferences.propertyNames();
String result = "";
int count = 0;
while(usersLot.hasMoreElements())
{
String next = (String)usersLot.nextElement();
if (!fallbackPreferences.containsKey(next))
{
result += " " + next + "\n";
count++;
}
}
if(count > 0)
{
result = "Your preferences file contains:\n" + result + "which ";
if(count > 1)
result += "are";
else
result += "is";
result += " not in the distribution preferences file.";
Debug.d(result);
}
result = "";
count = 0;
while(distLot.hasMoreElements())
{
String next = (String)distLot.nextElement();
if (!mainPreferences.containsKey(next))
{
result += " " + next + "\n";
count++;
}
}
if(count > 0)
{
result = "The distribution preferences file contains:\n" + result + "which ";
if(count > 1)
result += "are";
else
result += "is";
result += " not in your preferences file.";
Debug.d(result);
}
}
public void save() throws FileNotFoundException, IOException {
String savePath = new String(System.getProperty("user.home") + File.separatorChar +
propsFolder + File.separatorChar);
File f = new File(savePath + File.separatorChar + propsFile);
if (!f.exists()) {
// No properties file exists, so we will create one and try again
// We'll put the properties file in the .reprap folder,
// under the user's home folder.
File p = new File(savePath);
if (!p.isDirectory()) // Create .reprap folder if necessary
p.mkdirs();
}
OutputStream output = new FileOutputStream(f);
mainPreferences.store(output, "Reprap properties http://reprap.org/");
}
public String loadString(String name) {
if (mainPreferences.containsKey(name))
return mainPreferences.getProperty(name);
if (fallbackPreferences.containsKey(name))
return fallbackPreferences.getProperty(name);
System.err.println("RepRap preference: " + name + " not found in either preference file.");
return null;
}
public int loadInt(String name) {
String strVal = loadString(name);
return Integer.parseInt(strVal);
}
public double loadDouble(String name) {
String strVal = loadString(name);
return Double.parseDouble(strVal);
}
public boolean loadBool(String name) {
String strVal = loadString(name);
if (strVal == null) return false;
if (strVal.length() == 0) return false;
if (strVal.compareToIgnoreCase("true") == 0) return true;
return false;
}
synchronized private static void initIfNeeded() throws IOException {
if (globalPrefs == null)
globalPrefs = new Preferences();
}
public static String loadGlobalString(String name) throws IOException {
initIfNeeded();
return globalPrefs.loadString(name);
}
public static int loadGlobalInt(String name) throws IOException {
initIfNeeded();
return globalPrefs.loadInt(name);
}
public static double loadGlobalDouble(String name) throws IOException {
initIfNeeded();
return globalPrefs.loadDouble(name);
}
public static boolean loadGlobalBool(String name) throws IOException {
initIfNeeded();
return globalPrefs.loadBool(name);
}
public static void saveGlobal() throws IOException {
initIfNeeded();
globalPrefs.save();
}
public static Preferences getGlobalPreferences() throws IOException {
initIfNeeded();
return globalPrefs;
}
/**
* Set a new value
* @param name
* @param value
* @throws IOException
*/
public static void setGlobalString(String name, String value) throws IOException {
initIfNeeded();
globalPrefs.setString(name, value);
}
public static void setGlobalBool(String name, boolean value) throws IOException {
initIfNeeded();
globalPrefs.setString(name, value ? "true" : "false");
}
/**
* @param name
* @param value
*/
private void setString(String name, String value) {
mainPreferences.setProperty(name, value);
}
/**
* @return an array of all the names of all the materials in extruders
* @throws IOException
*/
public static String[] allMaterials() throws IOException
{
int extruderCount = globalPrefs.loadInt("NumberOfExtruders");
String[] result = new String[extruderCount];
for(int i = 0; i < extruderCount; i++)
{
String prefix = "Extruder" + i + "_";
result[i] = globalPrefs.loadString(prefix + "MaterialType(name)");
}
return result;
}
public static String[] startsWith(String prefix) throws IOException
{
initIfNeeded();
Enumeration allOfThem = globalPrefs.mainPreferences.propertyNames();
List r = new ArrayList();
while(allOfThem.hasMoreElements())
{
String next = (String)allOfThem.nextElement();
if(next.startsWith(prefix))
r.add(next);
}
String[] result = new String[r.size()];
for(int i = 0; i < r.size(); i++)
result[i] = (String)r.get(i);
return result;
}
public static String[] notStartsWith(String prefix) throws IOException
{
initIfNeeded();
Enumeration allOfThem = globalPrefs.mainPreferences.propertyNames();
List r = new ArrayList();
while(allOfThem.hasMoreElements())
{
String next = (String)allOfThem.nextElement();
if(!next.startsWith(prefix))
r.add(next);
}
String[] result = new String[r.size()];
for(int i = 0; i < r.size(); i++)
result[i] = (String)r.get(i);
return result;
}
}