package unileipzig.isys.neuronviz.streamer;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;

import unileipzig.isys.neuronviz.kernel.DataEvent;
import unileipzig.isys.neuronviz.kernel.DataStreamer;

public class FileInputStreamer extends DataStreamer
{
	private long lineNum = 0;
	private String fileName;

	public FileInputStreamer(String fileName) throws FileNotFoundException
	{
		this.fileName = fileName;
		setInputStream(new FileInputStream(this.fileName));
		
		setStreamingMode(DataStreamer.FILE_MODE);
	}
	
	/**
	 * setzt dataReader auf die Datenzeile lineNumber
	 * @param lineNumber
	 * @return true wenn erfolgreich auf die Zeile gesetzt
	 */
	public boolean gotoDataLine(int lineNumber)
	{
		boolean allDataRead = false;
		try
		{
			resetStream();
			
			String s = null;
			while(actualLine<lineNumber)
			{
				if(dataReader.ready())
				{
					s = dataReader.readLine();
					actualLine++;
				}
			}
			allDataRead = true;
			notifyData(new DataEvent(this, s));
		} catch (Exception e)
		{
			System.out.println("Error while trying to go to line #"+lineNumber+": " + e.getMessage());
		}
		return allDataRead;
	}
	
	/**
	 * determins the number of lines available in the stream and stores it in lineNum
	 * @return number of lines in the stream
	 */
	private long calcLineNum()
	{
		lineNum = 0;
		try
		{
			while(dataReader.ready())
			{
				dataReader.readLine();
				lineNum++;
			}

			// reset stream to the start
			resetStream();
			
		} catch (Exception e)
		{
			System.out.println("Error while determing line number: " + e.getMessage());
		}
		
		return lineNum;
	}
	
	public long getLineNum()
	{
		return this.lineNum;
	}

	public void setInputStream(InputStream in)
	{
		dataReader = new BufferedReader(new InputStreamReader(in));
		calcLineNum();
	}
	
	private void resetStream() throws Exception
	{
		dataReader = new BufferedReader(new InputStreamReader(new FileInputStream(this.fileName)));
		this.actualLine = 0;
	}
}
