import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

import Six.Sixp.Client.*;
import Six.Sixp.Client.Error;

public class DataListener implements IRequestEventListener {
	private Boolean initDataDone;
	private IRequest request;
	private Boolean loggaData;
	private AtomicInteger numberOfUpdates;
	private ISession session;
	private Timer timer;
	
	public DataListener(ISession s) {
		initDataDone = false;
		request = null;
		loggaData = true;
		numberOfUpdates = new AtomicInteger();
		session = s;
	}

	public IRequest getRequest() {
		return request;
	}

	public void setRequest(IRequest request) {
		this.request = request;
	}

	public Boolean getLoggaData() {
		return loggaData;
	}

	public void setLoggaData(Boolean loggaData) {
		
		if (loggaData == false) {
			timer = new Timer();
			timer.scheduleAtFixedRate(new task(numberOfUpdates), 0,5000);
		} else {
			timer.cancel();
		}
		this.loggaData = loggaData;
	}
	
	public void Reset()
	{
		timer.cancel();
		initDataDone = false;
	}

	@Override
	public void OnClearTable(IRequest request) {
		System.out.println("OnClearTable ReqId:" + request.getId());
	}

	@Override
	public void OnDestroyed(IRequest request) {
		System.out.println("OnClearTable ReqId:" + request.getId());		
	}

	@Override
	public void OnError(IRequest request, Error errorCode, String errorMessage) {
        System.out.println("OnError ReqId:" + request.getId() + " (" + errorCode + ") " + errorMessage);	
	}

	@Override
	public void OnFieldSetReceived(IRequest request, FieldInfoSet fieldset) {
        System.out.println("OnFieldsetReceived");
	}

	@Override
	public void OnInitTable(IRequest request, int numRecords) {
        System.out.println("OnInitTable: Num records " + numRecords);
	}

	@Override
	public void OnRecordUpdate(IRequest request, Vector<Update> updates) {
		numberOfUpdates.addAndGet(updates.size());
		
		if (/*initDataDone &&*/ loggaData) {
			for (Update u : updates) {
				System.out.println("Type=" + u.GetUpdateType());
				System.out.println("RecId=" + u.GetRecordId());
				System.out.println("Key=" + u.GetKey());
				
				for (Field f : u.GetFields()) {
                    System.out.println(" (" + f.GetFieldInfo().GetFieldType() + ") " + f.GetFieldInfo().GetName() + "=" + f.GetValue());
                    
                    // To get the full news text, this is only applicable to news queries /rt/news and /hist/news
    				if (f.GetFieldInfo().GetName().contains("Text")) {
    					try {
    						this.request = session.CreateRequest(f.GetValue().toString(), AcceptFormat.Text, false, this);
    						System.out.println("FETCHING TEXT with request id " + this.request.getId());
    						this.request.ExecuteAsync();
    					}
    					catch (Exception ex) {
    						System.out.println("Exception fetching news text: " + ex.toString());
    					}
    				}
				}
				System.out.println();
			}
		}
	}

	@Override
	public void OnTableFilled(IRequest request) {
		initDataDone = true;
	}

	@Override
	public void OnText(IRequest request, String text) {
        System.out.println("\nTEXT on news request id " + request.getId() + "\n\nTEXT BODY: \n" + text);
	}
}

class task extends TimerTask {
	
	AtomicInteger refToCounter;
	int runTimes = 0;
	
	public task (AtomicInteger counter) {
		refToCounter = counter;
		refToCounter.set(0);
	}
	
    public void run() {
      runTimes++;
      System.out.println("Total number of updates: " + refToCounter.get());
      System.out.println("Updates per second: " + refToCounter.get()/(10*runTimes));
    }
  }
