/* This file is part of Wattzap Community Edition. * * Wattzap Community Edtion is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Wattzap Community Edition is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Wattzap. If not, see <http://www.gnu.org/licenses/>. */ package com.wattzap.model; import java.awt.Rectangle; import java.io.File; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import java.util.UUID; import uk.co.caprica.vlcj.logger.Logger; import com.wattzap.controller.MessageBus; import com.wattzap.controller.Messages; import com.wattzap.model.dto.WorkoutData; import com.wattzap.model.power.Power; import com.wattzap.model.power.PowerProfiles; import com.wattzap.utils.TcxWriter; import com.wattzap.view.Workouts; /** * Singleton helper to read/write user preferences to a backing store * * @author David George / 15 September 2013 * (C) Copyright 2013-2015 */ public enum UserPreferences { INSTANCE; private Power powerProfile; String user; private final DataStore ds; private static int evalTime = 240; private static String workingDirectory = null; private static String userDataDirectory = null; private static final String cryptKey = "afghanistanbananastan"; private static final double LBSTOKG = 0.45359237; private ResourceBundle messages; private boolean antEnabled = true; private UserPreferences() { user = System.getProperty("user.name"); String wd = getWD(); ds = new DataStore(wd, cryptKey); Locale currentLocale = getLocale(); messages = ResourceBundle.getBundle("MessageBundle", currentLocale); // check User data directories exist String udDir = getUserDataDirectory(); File f = new File(udDir + TcxWriter.WORKOUTDIR); if (!f.exists()) { f.mkdirs(); Logger.info("created " + udDir); } f = new File(udDir + Workouts.IMPORTDIR); if (!f.exists()) { f.mkdirs(); Logger.info("created " + udDir); } } public void setAntEnabled(boolean v) { antEnabled = v; } public boolean isAntEnabled() { return antEnabled; } public void addWorkout(WorkoutData data) { ds.saveWorkOut(user, data); } public void updateWorkout(WorkoutData data) { ds.updateWorkout(user, data); } public WorkoutData getWorkout(String name) { return ds.getWorkout(user, name); } public void deleteWorkout(String name) { ds.deleteWorkout(user, name); } public List<WorkoutData> listWorkouts() { return ds.listWorkouts(user); } public String getDBVersion() { return get("", "dbVersion", "1.2"); } public void setDBVersion(String v) { set("", "dbVersion", v); } public Rectangle getMainBounds() { int width = getInt("", "mainWidth", 1200); int height = getInt("", "mainHeight", 650); int x = getInt("", "mainX", 0); int y = getInt("", "mainY", 0); Rectangle r = new Rectangle(x, y, width, height); return r; } public void setMainBounds(Rectangle r) { setInt("", "mainHeight", r.height); setInt("", "mainWidth", r.width); setInt("", "mainX", r.x); setInt("", "mainY", r.y); } public Rectangle getVideoBounds() { int width = getInt("", "videoWidth", 800); int height = getInt("", "videoHeight", 600); int x = getInt("", "videoX", 0); int y = getInt("", "videoY", 650); Rectangle r = new Rectangle(x, y, width, height); return r; } public void setVideoBounds(Rectangle r) { setInt("", "videoHeight", r.height); setInt("", "videoWidth", r.width); setInt("", "videoX", r.x); setInt("", "videoY", r.y); } public double getWeight() { if (this.isMetric()) { return getDouble("weight", 80.0); } else { // convert to lbs return getDouble("weight", 80.0) / LBSTOKG; } } public double getWeightKG() { return getDouble("weight", 80.0); } // always store as kg public void setWeight(double weight) { if (this.isMetric()) { setDouble("weight", weight); } else { // convert from lbs setDouble("weight", weight * LBSTOKG); } } public double getBikeWeight() { if (this.isMetric()) { return getDouble("bikeweight", 10.0); } else { // convert from lbs return getDouble("bikeweight", 10.0) / LBSTOKG; } } public double getTotalWeight() { return getDouble("weight", 80.0) + getDouble("bikeweight", 10.0); } // always store as kg public void setBikeWeight(double weight) { if (this.isMetric()) { setDouble("bikeweight", weight); } else { // convert to lbs setDouble("bikeweight", weight * LBSTOKG); } } // 2133 is 700Cx23 public int getWheelsize() { return getInt(user, "wheelsize", 2133); } public double getWheelSizeCM() { return getInt(user, "wheelsize", 2133) / 10.0; } public void setWheelsize(int wheelsize) { setInt(user, "wheelsize", wheelsize); } public int getMaxHR() { return getInt(user, "maxhr", 0); } public void setMaxHR(int maxhr) { setInt(user, "maxhr", maxhr); } public int getMaxPower() { return getInt(user, "maxpower", 0); } public void setMaxPower(int maxPower) { setInt(user, "maxpower", maxPower); } public boolean isMetric() { return getBoolean("units", true); } public void setUnits(boolean value) { setBoolean("units", value); } // For automatic screen shots public boolean isScreenshot() { return getBoolean("screenshot", false); } public void setScreenshot(boolean value) { setBoolean("screenshot", value); } // Social public String getSLUser() { return get(user, "sl_user", ""); } public void setSLUser(String slUser) { set(user, "sl_user", slUser); } public String getSLPass() { return get(user, "sl_pass", ""); } public void setSLPass(String slPass) { set(user, "sl_pass", slPass); } // ANT public boolean isANTUSB() { return getBoolean("antusbm", false); } public void setAntUSBM(boolean value) { setBoolean("antusbm", value); } public boolean isDebug() { return getBoolean("debug", false); } public void setDebug(boolean value) { setBoolean("debug", value); } public boolean isVirtualPower() { return getBoolean("virtualPower", false); } public void setVirtualPower(boolean value) { setBoolean("virtualPower", value); } public void setLocale(String value) { set(user, "locale", value); messages = ResourceBundle.getBundle("MessageBundle", getLocale()); MessageBus.INSTANCE.send(Messages.LOCALE, null); } public Locale getLocale() { String iso3 = get(user, "locale", Locale.getDefault().getISO3Language()); Locale locale = new Locale(iso3); return locale; } public Power getPowerProfile() { String profile = get(user, "profile", "Tacx Satori / Blue Motion"); if (powerProfile == null) { PowerProfiles pp = PowerProfiles.INSTANCE; powerProfile = pp.getProfile(profile); } return powerProfile; } public void setPowerProfile(String profile) { String p = get(user, "profile", null); if (!profile.equals(p)) { set(user, "profile", profile); PowerProfiles pp = PowerProfiles.INSTANCE; powerProfile = pp.getProfile(profile); } } public int getResistance() { int i = getInt(user, "resistance", 1); return i; } public void setResistance(int r) { setInt(user, "resistance", r); } public int getSCId() { int i = getInt(user, "sandcId", 0); return i; } public void setSCId(int i) { setInt(user, "sandcId", i); } public int getSpeedId() { return getInt(user, "speedId", 0); } public void setSpeedId(int i) { setInt(user, "speedId", i); } public int getCadenceId() { return getInt(user, "cadenceId", 0); } public void setCadenceId(int i) { setInt(user, "cadenceId", i); } public int getPowerId() { return getInt(user, "powerId", 0); } public void setPowerId(int i) { setInt(user, "powerId", i); } public int getPowerSmoothing() { return getInt(user, "powerSmooth", 0); } public void setPowerSmooth(int i) { setInt(user, "powerSmooth", i); } public int getHRMId() { return getInt(user, "hrmid", 0); } public void setHRMId(int i) { setInt(user, "hrmid", i); } /** Registration Stuff **/ public String getSerial() { String id = get("", "ssn", null); if (id == null) { // not yet initialized id = UUID.randomUUID().toString(); set("", "ssn", id); } return id; } public boolean isRegistered() { if (get("", "rsnn", null) == null) { return false; } return true; } public String getRegistrationKey() { return get("", "rsnn", null); } public void setRegistrationKey(String key) { set("", "rsnn", key); } public int getEvalTime() { int i = getIntCrypt("", "evalTime", evalTime); if (i < 0) { return 0; } return i; } public void setEvalTime(int t) { setIntCrypt("", "evalTime", t); } public String getRouteDir() { return get("", "videoLocation", this.getWD() + "/Routes"); } public void setRouteDir(String s) { set("", "videoLocation", s); } public String getTrainingDir() { return get("", "trainingLocation", this.getWD() + "/Trainings"); } public void setTrainingDir(String s) { set("", "trainingLocation", s); } // Data Access Functions private double getDouble(String key, double d) { String v = ds.getProp(user, key); if (v != null) { try { d = Double.parseDouble(v); } catch (Exception e) { e.printStackTrace(); } } return d; } private void setDouble(String key, double d) { ds.insertProp(user, key, Double.toString(d)); } private int getInt(String user, String key, int i) { String v = ds.getProp(user, key); if (v != null) { try { i = Integer.parseInt(v); } catch (Exception e) { e.printStackTrace(); } } return i; } private int getIntCrypt(String user, String key, int i) { String v = ds.getPropCrypt(user, key); if (v != null) { try { i = Integer.parseInt(v); } catch (Exception e) { e.printStackTrace(); } } return i; } private void setInt(String user, String key, int i) { ds.insertProp(user, key, Integer.toString(i)); } private void setIntCrypt(String user, String key, int i) { ds.insertPropCrypt(user, key, Integer.toString(i)); } private boolean getBoolean(String key, boolean b) { String v = ds.getProp(user, key); if (v != null) { try { b = Boolean.parseBoolean(v); } catch (Exception e) { e.printStackTrace(); } } return b; } private void setBoolean(String key, boolean b) { ds.insertProp(user, key, Boolean.toString(b)); } private String get(String user, String key, String s) { String v = ds.getProp(user, key); if (v != null) { s = v; } return s; } private void set(String user, String key, String s) { ds.insertProp(user, key, s); } public void shutDown() { ds.close(); } /* * Stores common data files: database logfile Videos Trainings * * These directories are created by the Windows/Unix installer * * On Windows 7: C:\ProgramData\Wattzap On Windows XP: C:\Documents and * Settings\All Users\Application Data\Wattzap On Unix: ??? $home/.wattzap */ public String getWD() { if (workingDirectory == null) { // here, we assign the name of the OS, according to Java, to a // variable... String OS = (System.getProperty("os.name")).toUpperCase(); // to determine what the workingDirectory is. // if it is some version of Windows if (OS.contains("WIN")) { // it is simply the location of the "AppData" folder workingDirectory = System.getenv("ALLUSERSPROFILE"); if (OS.contains("WINDOWS XP")) { workingDirectory += "/Application Data/Wattzap"; } else { workingDirectory += "/Wattzap"; } } else { // in either case, we would start in the user's home directory workingDirectory = System.getProperty("user.home") + "/.wattzap"; } } return workingDirectory; } /* * Stores User dependent data Workouts * * On Windows 7: C:\Users\$user\AppData\Roaming\Wattzap On Windows XP: * C:\Documents & Settings\$user\AppData\Wattzap On Unix: ??? $home/.wattzap */ public String getUserDataDirectory() { if (userDataDirectory == null) { // here, we assign the name of the OS, according to Java, to a // variable... String OS = (System.getProperty("os.name")).toUpperCase(); // to determine what the workingDirectory is. // if it is some version of Windows if (OS.contains("WIN")) { // it is simply the location of the "AppData" folder userDataDirectory = System.getenv("APPDATA") + "/Wattzap"; } else { // in either case, we would start in the user's home directory userDataDirectory = System.getProperty("user.home") + "/wattzap"; } } return userDataDirectory; } // Hack For UTF resources public String getString(String key) { String val = messages.getString(key); try { return new String(val.getBytes("ISO-8859-1"), "UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /* * Reset certain properties to their defaults. */ public void factoryReset() { Rectangle r = new Rectangle(0, 0, 800, 600); setVideoBounds(r); r = new Rectangle(10, 10, 800, 400); this.setMainBounds(r); } }