/*
 * This file is part of the DistSim distributed simulation framework (client)
 * Copyright (C) 2007 Ulf Hermann
 *
 * 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.
 */
package brn.distsim.client.data;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

public class GroupStringParameters extends
		DbBackedProperties<GroupStringParameters.Parameter> {

	public final static String TABLE_NAME = "group_string_params";

	public class Parameter extends DbBackedProperties.Property {

		protected Parameter next;

		protected Parameter prev;

		private Parameter(String name, String value, Parameter next) {
			super(name, value);
			this.next = next;
			if (next != null)
				next.prev = this;
		}

		public Parameter getNext() {
			return next;
		}

		public void performDbInsert(int groupId) throws SQLException {
			id = groupId;
			statement.execute("INSERT INTO " + TABLE_NAME + " VALUES ('" + id
					+ "', '" + name + "', '" + value + "');");
		}

		public void performDbDelete() throws SQLException {
			statement.execute("DELETE FROM " + TABLE_NAME + " WHERE groupId='"
					+ id + "' AND name='" + name + "' AND value='" + value + "';");
		}

		public void performDbUpdate() throws SQLException {
			statement.execute("REPLACE INTO " + TABLE_NAME + " VALUES ('" + id
					+ "', '" + name + "', '" + value + "');");
		}
	}

	public GroupStringParameters(Connection definitions, int groupId) {
		super(definitions, groupId);
	}

	public GroupStringParameters(GroupStringParameters other) {
		super(other);
	}

	public GroupStringParameters(Connection db, int id, ResultSet set)
			throws SQLException {
		super(db, id, set);
	}

	@Override
	protected Parameter getEmptyDependent() {
		return new Parameter(null, null, null);
	}

	@Override
	protected Parameter getDependent(ResultSet data) throws SQLException {
		String name = data.getString("name");
		Parameter next = entries.get(name);
		Parameter ret = new Parameter(name, data.getString("value"), next);
		entries.put(name, ret);
		return ret;
	}

	@Override
	protected Parameter getDependent(Parameter other) {
		return new Parameter(other.name, other.value, entries.get(other.name));
	}

	@Override
	public void loadFromDb() throws SQLException {
		ResultSet params = statement.executeQuery("SELECT * FROM " + TABLE_NAME
				+ " WHERE groupId=" + id + ";");
		super.loadFromDb(params);
	}

	public static List<String> getNames(Connection db, int studyId)
			throws SQLException {
		ResultSet names = db
				.createStatement()
				.executeQuery(
						"SELECT DISTINCT name FROM "
								+ TABLE_NAME
								+ " WHERE groupId in (SELECT id FROM groups WHERE studyId="
								+ studyId + ") ORDER BY name;");
		return namesToList(names);
	}

	public void add(String name, String string) {
		Parameter par = entries.get(name);
		while (par != null) {
			if (par.value == string)
				return;
			par = par.next;
		}
		super.add(new Parameter(name, string, entries.get(name)));
	}

	public Parameter remove(Parameter par) {
		dependentData.remove(par);
		removeInChangeTrackers(par);
		boolean updateEntries = false;
		if (entries.get(par.name) == par) {
			updateEntries = true;
			entries.remove(par.name);
		}
		if (par.prev != null) {
			par.prev.next = par.next;
			if (updateEntries) {
				entries.put(par.name, par.prev);
				updateEntries = false;
			}
		}
		if (par.next != null) {
			par.next.prev = par.prev;
			if (updateEntries)
				entries.put(par.name, par.next);
		}
		return par;
	}

	public Parameter remove(String name) {
		Parameter first = super.remove(name);
		if (first != null) {
			Parameter gone = first.next;
			while (gone != null) {
				remove(gone);
				gone = gone.next;
			}
		}
		return first;
	}

	protected void loadFromDb(ResultSet data) throws SQLException {
		dependentData.clear();
		updated.clear();
		deleted.clear();
		inserted.clear();
		while (data.next()) {
			Parameter entry = getDependent(data);
			dependentData.add(entry);
			entries.put(entry.getName(), entry);
		}
	}

	public Parameter remove(int pos) {
		return remove(dependentData.get(pos));
	}

}
