/*
 * ConfigManager.java
 *
 * Copyright (C) 2006 - 2007 Martin Slota
 *
 * This program 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 2 of the License, or (at your option) any later
 * version.
 *
 * This program 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
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/*
 * History:
 * v0.1 (2007-02-17): initial version
 * v0.1.1 (2007-02-17):
 * - initial implementation from the evolp-prop project
 * v0.9.0 (2007-05-07):
 * - added a class description
 *
 * TODO docs
 * PENDING create a junit test
 */

package lp.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * Manages configuration options.
 *
 * @author Martin Slota
 * @version 0.9.0
 */
public class ConfigManager extends Properties {
	private static final char SEP = File.separatorChar;
	
	// FIXME this should be done with System.getProperty("os.name").equals("Linux")
	// but maybe there will be access right problems in the webapp
	public static final String CONFIG_NAME = (SEP == '/') ? ".evolp.properties"
			: "_evolp.properties";
	
	public static final File USER_CONFIG;
	
	public static final File CURRENT_DIR_CONFIG;
	
	static {
		File user;
		File current;
		try {
			user = new File(System.getProperty("user.home") + SEP + CONFIG_NAME);
			current = new File(System.getProperty("user.home") + SEP
					+ CONFIG_NAME);
		} catch (Exception e) {
			user = null;
			current = null;
		}
		USER_CONFIG = user;
		CURRENT_DIR_CONFIG = current;
	}
	
	public ConfigManager() {
		final String suffix = (SEP == '/') ? "" : ".exe";
		defaults = new Properties();
		defaults.setProperty("location.dlv", "dlv" + suffix);
		defaults.setProperty("location.lparse", "lparse" + suffix);
		defaults.setProperty("location.smodels", "smodels" + suffix);
		defaults.setProperty("aspsolver", "smodels");
		defaults.setProperty("quiet", "false");
		defaults.setProperty("maxModels", "0");
	}
	
	public void loadConfig(File configFile) throws IOException {
		loadFromXML(new FileInputStream(configFile));
	}
	
	public void loadConfig(String configFilename) throws IOException {
		loadConfig(new File(configFilename));
	}
	
	public void loadUserConfig() throws IOException {
		if (USER_CONFIG.exists() && USER_CONFIG.canRead())
			loadConfig(USER_CONFIG);
	}
	
	public void loadCurrentDirConfig() throws IOException {
		if (CURRENT_DIR_CONFIG.exists() && CURRENT_DIR_CONFIG.canRead())
			loadConfig(CURRENT_DIR_CONFIG);
	}
	
	public void saveConfig(File configFile) throws IOException {
		Properties toStore = new Properties();
		for (String name : sortedPropertyNames()) {
			toStore.setProperty(name, getProperty(name));
		}
		toStore.storeToXML(
				new FileOutputStream(configFile),
				"This file contains "
				+ "settings for the implementation of transformational "
				+ "semantics for Evolving Logic Programs; "
				+ "see http://slotik.medovnicek.sk/thesis/ for details");
	}
	
	public void saveConfig(String configFilename) throws IOException {
		saveConfig(new File(configFilename));
	}
	
	public SortedSet<String> sortedPropertyNames() {
		SortedSet<String> result = new TreeSet<String>();
		Enumeration names = propertyNames();
		while (names.hasMoreElements())
			result.add((String) names.nextElement());
		return result;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		for (String key : sortedPropertyNames()) {
			sb.append(key + ": \"" + getProperty(key) + "\"\n");
		}
		return sb.toString();
	}
}