package jp.ac.naka.ec.entity.test;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import jp.ac.naka.ec.EntityCollaborator;
import jp.ac.naka.ec.entity.AbstractEntity;
import jp.ac.naka.ec.entity.EntityEvent;
import jp.ac.naka.ec.sensor.SensorData;
import jp.ac.naka.ec.sensor.SensorDataImpl;

/**
 *  シリアル通信のためのEntity．環境に応じてcommPortを変更する．
 * @author kasuya
 *
 */
public class SerialInterfaceEntity extends AbstractEntity implements SerialPortEventListener{

	String commPort = "COM3";
	int baud_rate = 9600;
	private OutputStream out;
	private BufferedReader comReader;
	SensorData sensor;
	
	public SerialInterfaceEntity() {
		// キーワードの追加
		addKeyword("sensor");
		try {
			CommPortIdentifier portIdentifier = CommPortIdentifier
					.getPortIdentifier(commPort);
			if (portIdentifier.isCurrentlyOwned()) {
				return;
			} else {
				// 名前とタイムアウトを指定
				CommPort commPort = portIdentifier.open(getClass().getName(),
						3000);

				if (commPort instanceof SerialPort) {
					SerialPort serialPort = (SerialPort) commPort;
					serialPort.setSerialPortParams(baud_rate,
							SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
							SerialPort.PARITY_NONE);
					serialPort.addEventListener(this);
					serialPort.notifyOnDataAvailable(true);
					InputStream in = serialPort.getInputStream();
					out = serialPort.getOutputStream();
					comReader = new BufferedReader(new InputStreamReader(in));
				} else {
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// SensorDataの利用例．TTLごとにNotifyで通知することができる．
		sensor = new SensorDataImpl();
		sensor.setName("Moxa");
		sensor.setDataName("toggle");
		sensor.setDataType(SensorData.DataType.Float);
		sensor.setMeasure("");
		setTTL(10);
		addSensorData(sensor);
	}
	
	
	@Override
	public void receiveMessage(EntityEvent e) {
		// TODO 自動生成されたメソッド・スタブ
	}

	public void serialEvent(SerialPortEvent event) {
		switch (event.getEventType()) {
		case SerialPortEvent.BI:
		case SerialPortEvent.OE:
		case SerialPortEvent.FE:
		case SerialPortEvent.PE:
		case SerialPortEvent.CD:
		case SerialPortEvent.CTS:
		case SerialPortEvent.DSR:
		case SerialPortEvent.RI:
		case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
			// Data Available 以外のイベントは処理しない
			break;
		case SerialPortEvent.DATA_AVAILABLE:
			// Data Available の処理
			String buffer = null;
			try {
				while (comReader.ready()) {
					// データの読み込み
					buffer = comReader.readLine();
					int index = buffer.indexOf(":");
					String value = buffer.substring(index+1);
					sensor.setData(value);
				//	System.out.println("> " + buffer);
					// 取得したデータをマルチキャストする．
					sendMessage(sensor.getData().toString());
				}
			} catch (IOException e) {
			}
			break;
		}
	}
	
public static void main(String[] args) {
		
		try {
			// フロントエンドの取得
			EntityCollaborator ec = EntityCollaborator.getInstance();
			// Sipの初期化
			ec.initiateSipCore(5060);
			// DHTの初期化
			ec.initiateDHT(3998);
			ec.addEntity(new SerialInterfaceEntity());
			ec.addEntity(new MessageDumperEntity());
		} catch (Exception e) {}
	}
}
