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

import jp.hasc.hasctool.core.data.LabelSignalMessage;
import jp.hasc.hasctool.core.data.ObjectSignalMessage;
import jp.hasc.hasctool.core.data.SignalMessage;
import jp.hasc.hasctool.core.data.VectorSignalMessage;
import jp.hasc.hasctool.core.messaging.MessageProcessor;
import jp.hasc.hasctool.core.runtime.annotation.PortInfo;
import jp.hasc.hasctool.core.runtime.annotation.RuntimeBeanInfo;
import jp.hasc.hasctool.core.runtime.filter.interpolator.AbstractMultipleInputsFilter;
import jp.hasc.hasctool.core.runtime.filter.interpolator.MessageArrayInterpolator;
import jp.hasc.hasctool.core.runtime.filter.interpolator.LinearVectorInterporator;
import jp.hasc.hasctool.core.runtime.filter.interpolator.SignalInterpolator;

/**
 * WaveViewに入力するために、VectorSignalMessageとLabelSignalMessageの時刻を同期して統合するフィルタです。
 * @author iwasaki
 */
@RuntimeBeanInfo(
		inputPorts = {
				@PortInfo(name = "vectorInputPort", classes = {VectorSignalMessage.class}), 
				@PortInfo(name = "labelInputPort", classes = {LabelSignalMessage.class}) },
		outputPorts = { @PortInfo(name = "outputPort", classes = {ObjectSignalMessage.class}) }
)
public class ConcatenateVectorAndLabelFilter extends
		AbstractMultipleInputsFilter {
	
	public static final int PORT_VECTOR=0;
	public static final int PORT_LABEL=1;
	public static final int PORTS_NUM=2;
	
	private boolean relativeTime_ = false;
	public void setOutputByRelativeTime(boolean t) { relativeTime_=t; }
	
	public ConcatenateVectorAndLabelFilter() {
		super();
		//
		setInputPortCount(PORTS_NUM);
	}
	
	public MessageProcessor getVectorInputPort() { return getInputPort(PORT_VECTOR); }

	public MessageProcessor getLabelInputPort() { return getInputPort(PORT_LABEL); }
	
	@Override
	public SignalInterpolator createSignalInterpolator(int portIndex) {
		switch(portIndex) {
		case PORT_VECTOR:
			return new LinearVectorInterporator();
		case PORT_LABEL:
			return new MessageArrayInterpolator();
		default:
			throw new RuntimeException();
		}
	}
	
	private boolean first_=true;
	private long startTime_;

	@Override
	protected void processSignalMessages(long time, SignalMessage[] messages)
			throws InterruptedException {
		if (relativeTime_) {
			VectorSignalMessage vec=(VectorSignalMessage) messages[PORT_VECTOR];
			if (first_) {
				first_=false;
				startTime_=time;
			}
			ObjectSignalMessage lblsMsg=(ObjectSignalMessage) messages[PORT_LABEL];
			SignalMessage[] lbls=(SignalMessage[])lblsMsg.getValue();
			SignalMessage[] newLbls=new SignalMessage[lbls.length];
			for(int i=0;i<lbls.length;++i) {
				newLbls[i]=lbls[i].createDelayedElement(-startTime_);
			}
			SignalMessage[] newMsgs=new SignalMessage[]{
					vec.createDelayedElement(-startTime_),
					new ObjectSignalMessage(lblsMsg.getTime()-startTime_, newLbls)
			};
			outputMessage(new ObjectSignalMessage(time, newMsgs));
		}else{
			outputMessage(new ObjectSignalMessage(time, messages));
		}
	}

}
