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

import jp.hasc.hasctool.core.data.ScalarSignalMessage;
import jp.hasc.hasctool.core.data.VectorSignalMessages;
import jp.hasc.hasctool.core.runtime.RuntimeContext;
import jp.hasc.hasctool.core.runtime.filter.AbstractFilter;

/**
 * AbstractFilterを使ったフィルタ
 * ベクトルの各要素に対して窓関数を適用する
 * @author hiro, iwasaki
 */
public abstract class AbstractWindowFunctionFilter extends AbstractFilter {

	private long[] time_;//入力時間
	private double[] sampleData_;//入力
	private int next_;//現在の位置
	private boolean fill_;
	protected int length_;//サンプルデータの数

	@Override
	public void setup(RuntimeContext context) {
		super.setup(context);
		time_=new long[length_];
		sampleData_ = new double[length_];
		next_ = 0;
		fill_ = false;
	}

	public void setSampleNum(int samplenum) {
		length_=samplenum;
	}

	private void setTime(long time){
		time_[next_] = time;	
	}
	
	protected void setdata(double data){
		sampleData_[next_] = data;
		next_ = (next_+1)%length_;
	}

	@Override
	public void processMessage(Object message) throws InterruptedException {
		if (message instanceof ScalarSignalMessage) {
			// ScalarSignalMessageの場合
			ScalarSignalMessage ssig=(ScalarSignalMessage)message;
			setTime(ssig.getTime());
			this.setdata(ssig.getScalarValue());
			if(next_ == 0 && !(fill_)){
				fill_ = true;
			}
			if(fill_){
				long stime = time_[next_];
				double[] newValue = windowFunction(sampleData_, next_);
				// 結果を出力
				outputMessage(VectorSignalMessages.create(stime, newValue));
			}
		}else{
			outputMessage(message);
		}
	}

	protected abstract double[] windowFunction(double[] input, int index);

}
