/*
 *  Copyright (C) 2006  Takashi Kasuya <kasuya@sfc.keio.ac.jp>
 *
 * This library is free software; you can redistribute it and/or
 *　modify it under the terms of the GNU Lesser General Public
 *　License as published by the Free Software Foundation; either
 *　version 2.1 of the License, or (at your option) any later version.
 *　This library 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
 *　Lesser General Public License for more details.
 *
 *　You should have received a copy of the GNU Lesser General Public
 *　License along with this library; if not, write to the Free Software
 *　Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package jp.ac.naka.ec.sip.pidf;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import javax.sip.address.URI;

/**
 * RFC参照のこと
 * @author Takashi Kasuya
 *
 */
public class Tuple {
	public String id = "";
	public Status status = new Status(); // 必須
	private float priority = 100f; // 0.000 - 1.00
	/*
	 * Entityが削除の対象であるか？Statusタグの中に入れる。 
	 */
	private boolean alive = true;
	// public String note = "";
	List<String> notes;

	Hashtable<String, String> extension;

	public URI contact; // EntityのユニークなURI
	public String timestamp; // 更新時刻

	/*
	 * 
	 */
	public Tuple() {

	}

	/**
	 * 
	 * @param note
	 */
	public void addNote(String note) {
		if (note == null) {
			//throw new NullPointerException("Note is null.");
			return;
		}
		if (notes == null) {
			this.notes = new ArrayList<String>();
		}
		this.notes.add(note);
	}

	/**
	 * @return the removed
	 */
	public boolean isAlived() {
		return alive;
	}

	/**
	 * @param removed the removed to set
	 */
	public void setAlive(boolean alive) {
		this.alive = alive;
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		StringBuilder stBuffer = new StringBuilder();
		stBuffer.append(status.toString());

		if (extension != null) {
			Enumeration keys = extension.keys();
			String key, value;
			while (keys.hasMoreElements()) {
				key = (String) keys.nextElement();
				value = (String) extension.get(key);
				stBuffer.append("<" + key + ">");
				stBuffer.append(value);
				stBuffer.append("</" + key + ">\r\n");
			}
		}
		if (contact != null) {
			if (priority == 100f) {
				stBuffer.append("<contact>");
			} else {
				stBuffer.append("<contact priority=");
				stBuffer.append('"');
				stBuffer.append(priority);
				stBuffer.append('"');
				stBuffer.append(">");
			}

			stBuffer.append(contact.toString());
			stBuffer.append("</contact>\r\n");
		}
		if (notes != null) {
			for (String note : notes) {
				stBuffer.append("<note>");
				stBuffer.append(note);
				stBuffer.append("</note>\r\n");
			}
		}
		if (timestamp != null && !(timestamp.equals(""))) {
			stBuffer.append("<timestamp>");
			stBuffer.append(timestamp);
			stBuffer.append("</timestamp>\r\n");
		}
		/*
		if (id != null && !(id.equals(""))) {
			stBuffer.append("<id>");
			stBuffer.append(id);
			stBuffer.append("</id>\r\n");
		}*/

		return stBuffer.toString();
	}

	/**
	 * 
	 * @param key
	 * @param obj
	 */
	public void putExtension(String key, Object obj) {
		if (extension == null) {
			extension = new Hashtable<String, String>();
		}
		extension.put(key, obj.toString());
	}

	/**
	 * 
	 * @param key
	 * @return
	 */
	public Object getExtension (String key) {
		if (extension == null) {
			throw new NullPointerException("Extension is null!");
		}
		return extension.get(key);
	}
	
	/**
	 * 
	 * @author Takashi Kasuya
	 *
	 */
	class Status {
		Basic basic = Basic.OPEN; // Open or Close
		
		public String toString() {
			StringBuilder stBuffer = new StringBuilder();
			stBuffer.append("<status>\r\n\t");
			stBuffer.append("<alive>");
			String value = alive ? "YES" : "NO";
			stBuffer.append(value);
			/*
			stBuffer.append("<basic>");
			switch (status.basic) {
			case OPEN:
				stBuffer.append("OPEN");
				break;
			case CLOSE:
				stBuffer.append("CLOSED");
				break;
			}
			stBuffer.append("</basic>\r\n");*/
			stBuffer.append("</alive>");
			stBuffer.append("</status>\r\n");
			return stBuffer.toString();
		}
	}

	/**
	 * 
	 * @author Takashi Kasuya
	 *
	 */
	public enum Basic {
		OPEN, CLOSE
	}

	
	/**
	 * 
	 * @return
	 */
	public float getPriority() {
		return priority;
	}

	/**
	 * 
	 * @param priority
	 */
	public void setPriority(float priority) {
		if (priority < 0f || priority > 1f) {
			System.err.println("Priority must be between 0.0 to 1.0.");
			return;
		}
		this.priority = priority;
	}
}
