package jp.hasc.hasctool.core.runtime.filter.file;

import java.util.concurrent.TimeUnit;

import jp.hasc.hasctool.core.data.SignalMessage;
import jp.hasc.hasctool.core.data.VectorSignalMessage;
import jp.hasc.hasctool.core.data.VectorSignalMessages;
import jp.hasc.hasctool.core.runtime.annotation.PortInfo;
import jp.hasc.hasctool.core.runtime.annotation.RuntimeBeanInfo;
import jp.hasc.hasctool.core.runtime.filter.AbstractFilter;
import jp.hasc.hasctool.core.util.CSVUtil;

/**
 * CSVの文字列系列をパースして、VectorSignalMessageとして出力するフィルタです
 * @author iwasaki
 */
@RuntimeBeanInfo(
		inputPorts = { @PortInfo(name = "inputPort", classes = {String.class}) },
		outputPorts = { @PortInfo(name = "outputPort", classes = {VectorSignalMessage.class}) }
)
public class CSVToVectorFilter extends AbstractFilter {
	
	private int timeColumnIndex_ = 0;
	private double timeUnitSeconds_ = 1.0;

	protected void processRow(String row) throws InterruptedException {
		if (row.startsWith("#")) {
			outputMessage(row);
		}else if (row.isEmpty()) {
			// NOP
		}else{
			String[] columns = CSVUtil.parseCSVRecord(row);
			double[] vec=new double[columns.length-1];
			int tci=(timeColumnIndex_+columns.length)%columns.length; // -1なら、最後の要素
			double dtime=0;
			for(int i=0;i<columns.length;++i) {
				double val=getColumnAsDouble(columns[i]);
				if (i<tci) vec[i]=val;
				else if (i==tci) dtime=val;
				else vec[i-1]=val;
			}
			long ltime=SignalMessage.TIME_UNIT.convert((long)(dtime*timeUnitSeconds_*1000000), TimeUnit.MICROSECONDS);
			// output
			outputMessage(VectorSignalMessages.create(ltime, vec, false));
		}
	}
	
	protected double getColumnAsDouble(String column) {
		column=column.trim();
		if (column.startsWith("\"") &&column.endsWith("\"")) column=column.substring(1,column.length()-1);
		return Double.parseDouble(column);
	}
	
	//
	public int getTimeColumnIndex() {
		return timeColumnIndex_;
	}

	public void setTimeColumnIndex(int timeColumnIndex) {
		timeColumnIndex_ = timeColumnIndex;
	}

	public double getTimeUnitSeconds() {
		return timeUnitSeconds_;
	}

	public void setTimeUnitSeconds(double timeUnitSeconds) {
		timeUnitSeconds_ = timeUnitSeconds;
	}

	@Override
	public void processMessage(Object message) throws InterruptedException {
		if (message instanceof String) {
			processRow((String)message);
		}else{
			outputMessage(message);
		}
	}
}
