package jp.hasc.hasctool.ui.views;

import java.io.StringReader;

import jp.hasc.hasctool.core.data.VectorSignalMessage;
import jp.hasc.hasctool.core.messaging.MessageProcessor;
import jp.hasc.hasctool.core.runtime.RuntimeContext;
import jp.hasc.hasctool.core.runtime.filter.file.CSVToVectorFilter;
import jp.hasc.hasctool.core.runtime.source.LineReaderSource;
import jp.hasc.hasctool.ui.util.UIUtil;

import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

public class WaveEditor extends AbstractWaveEditor {
	/** logger for this class */
	private final static org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
			.getLog(WaveEditor.class);
	
	@Override
	protected void onUpdateWaveEditorViewContents(String editorText) throws Exception {
		long pos=waveViewWidget_.getViewTimeMax();
		waveViewWidget_.preventUpdates(true);
		
		//
		RuntimeContext context=new RuntimeContext();
		
		// setup blocks
		LineReaderSource lr=new LineReaderSource();
		lr.setReader(new StringReader(editorText));
		lr.setup(context);
		//
		CSVToVectorFilter csvToVector=new CSVToVectorFilter();
		csvToVector.setup(context);
		
		// setup connections
		lr.getOutputPort().connect(csvToVector.getInputPort());
		csvToVector.getOutputPort().connect(waveViewWidget_.getInputPort());
		
		// execute
		/*
		context.startTasks();
		if (!context.awaitTasksTermination(DEFAULT_TASK_TIMEOUT)) throw new RuntimeException("timeout");
		*/
		// UIスレッドで直接実行
		try{
			lr.runDirect();
		}catch(Throwable th) {
			UIUtil.showMessageDialog(getSite().getShell(), "[Error]\n"+th.toString());
			LOG.warn("Throwable",th);
		}
		
		//
		waveViewWidget_.preventUpdates(false);
		waveViewWidget_.setViewTimeMax(pos);
	}
	
	@Override
	protected void createWaveEditorPage() {
		super.createWaveEditorPage();
		//
		final WaveViewWidget wv = getWaveViewWidget();
		ToolBar toolBar = wv.getToolBar();
		{
			ToolItem ti=new ToolItem(toolBar, SWT.NONE);
			ti.setText("?t");
			ti.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					// WaveViewで選んだ時刻をテキストエディタ上で表示
					if (wv.getTimeMarkerBegin()==null) {
						UIUtil.showMessageDialog(getSite().getShell(), "Please select a time or a time range.");
						return;
					}
					long t0=wv.getTimeMarkerBegin();
					long t1=wv.getTimeMarkerEnd()!=null?wv.getTimeMarkerEnd():t0;
					//
					SourceViewer tv=(SourceViewer) textEditor_.getAdapter(ITextOperationTarget.class);
					StyledText tw = tv.getTextWidget();
					try{
						int[] pos=searchCharPos(tw,new long[]{t0,t1});
						tw.setSelection(pos[0],pos[1]);
					}catch(Throwable th) {
						UIUtil.showMessageDialog(getSite().getShell(), "[Error]\n"+th.toString());
						LOG.warn("Throwable",th);
					}
					setActivePage(textEditorPageIndex_);
				}

				private int[] searchCharPos(StyledText tw, final long[] ts) throws InterruptedException {
					final int[] result=new int[ts.length];
					//final int[] charPos=new int[]{0};
					for(int i=0;i<result.length;++i) result[i]=-1;
					//
					RuntimeContext context=new RuntimeContext();
					
					// setup blocks
					final CharPosLineReaderSource lr=new CharPosLineReaderSource();
					lr.setSourceText(tw.getText());
					lr.setup(context);
					//
					CSVToVectorFilter csvToVector=new CSVToVectorFilter();
					csvToVector.setup(context);
					//
					/*
					MessageProcessor stringCounter = new MessageProcessor() {
						@Override
						public void processMessage(Object message) throws InterruptedException {
							if (message instanceof String) {
								charPos[0]+=((String)message).length()+1;
							}
						}
					};
					*/
					MessageProcessor sink = new MessageProcessor() {
						@Override
						public void processMessage(Object message) throws InterruptedException {
							if (message instanceof VectorSignalMessage) {
								VectorSignalMessage sig = (VectorSignalMessage) message;
								for(int i=0;i<result.length;++i) {
									if (result[i]==-1 && sig.getTime()>=ts[i]) {
										// 同期しているはず
										result[i]=lr.getPosCurrentLineBegins();
									}
								}
							}
						}
					};
					
					// setup connections
					lr.getOutputPort().connect(csvToVector.getInputPort());
					//lr.getOutputPort().connect(stringCounter);
					csvToVector.getOutputPort().connect(sink);
					
					// execute
					lr.runDirect();
					
					//
					for(int i=0;i<result.length;++i) {
						// 末尾
						if (result[i]==-1) result[i]=tw.getCharCount();
					}
					
					return result;
				}
			});
		}    
	}  

}
