/*
 *  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.entity;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import jp.ac.naka.ec.EventDispatcher;
import jp.ac.naka.ec.db.TupleSpaceAdapter;
import jp.ac.naka.ec.entity.EntityEvent.EventType;

/**
 * Entity実装のためのヘルパークラス。一番最初にinitが呼ばれることに注意。
 * 抽象メソッドであるreceiveMessageも実装する必要あり。ここは後に変える予定。
 * 
 * @author Takashi Kasuya
 */
public abstract class AbstractEntity extends EntityImpl {

	public static EventDispatcher dispatcher = TupleSpaceAdapter.getInstance();
	private static Log logger = LogFactory.getLog(AbstractEntity.class);

	/**
	 * 
	 *
	 */
	public AbstractEntity() {
		super();
		// 必ず最初に呼ばれる
		init();
	}

	/**
	 * ユーザ実装Entityがインスタンス化された後に呼ばれるメソッド。
	 * 初期化はここで行ってください。
	 *
	 */
	public abstract void init();

	/*
	 * (non-Javadoc)
	 * @see jp.ac.naka.ec.entity.EntityImpl#receiveMessage(jp.ac.naka.ec.entity.EntityEvent)
	 */
	public abstract void receiveMessage(EntityEvent e);

	/*
	 * (non-Javadoc)
	 * @see jp.ac.naka.ec.entity.EntityImpl#sendOffer(net.sourceforge.jsdp.SessionDescription, jp.ac.naka.ec.entity.Entity)
	 */
	@Override
	public boolean sendOffer(net.sourceforge.jsdp.SessionDescription sdp,
			Entity target) {
		if (sdp == null) {
			logger.warn("SDP is null");
			return false;
		}
		if (!this.isLocal()) {
			return false;
		}
		EntityEvent evt = new EntityEvent(sdp, target, this);
		evt.setEventType(EventType.OFFER);
		dispatcher.dispatchEvent(evt);
		return true;
	}

	/*
	 * (non-Javadoc)
	 * @see jp.ac.naka.ec.entity.EntityImpl#sendMessage(java.lang.String)
	 */
	public void sendMessage(String msg)  {
		EntityContainer target = getContainer();
		EntityEvent e = new EntityEvent(msg, target, this);
		e.setBroadcast(true);
		dispatcher.dispatchEvent(e);
	}

	/*
	 * (non-Javadoc)
	 * @see jp.ac.naka.ec.entity.EntityImpl#sendMessage(java.lang.String, java.lang.String)
	 */
	public void sendMessage(String msg, String targetName) {
		if (!hasParent()) {
			throw new NullPointerException("Container is null!!");
		}
		Entity target = getContainer().getEntity(targetName);
		if (target == null) {
			// TODO 外部Entity
			logger.warn("Invalid URI : " + targetName);
			return;
		}
		EntityEvent e = new EntityEvent(msg, target, this);
		dispatcher.dispatchEvent(e);
	}

	/*
	 * (non-Javadoc)
	 * @see jp.ac.naka.ec.entity.EntityImpl#sendMessage(java.lang.String, jp.ac.naka.ec.entity.EntityListener)
	 */
	public void sendMessage(String msg, EntityListener target) {
		if (!hasParent()) {
			throw new NullPointerException("Container is null!!");
		}
		EntityEvent e = new EntityEvent(msg, target, this);
		dispatcher.dispatchEvent(e);
	}

	
	public boolean sendBye(EntityListener target)  {
		EntityEvent evt = new EntityEvent(target, this, EventType.BYE);
		dispatcher.dispatchEvent(evt);
		return true;
	}
}
