package org.kne.cloud.clock;

import java.util.concurrent.locks.ReentrantLock;

public class AdjustedNanoClock {
private ReentrantLock lock=new ReentrantLock();
	
	
	public ReentrantLock getLock() {
		return lock;
	}

	
	private volatile long delta=0;
	private volatile long accuracy=Long.MAX_VALUE;
	private boolean unsetted=true;
	public long getCurrentTime() {
		return System.nanoTime()+delta;
	}
	public AdjustedNanoClock(long delta) {
		super();
		this.delta = delta;
	}
	public AdjustedNanoClock() {
	}
	@Override
	public String toString() {
		return "AdjustedNanoClock [delta=" + delta + ", accuracy=" + accuracy + "]";
	}
	public long getDelta() {
		return delta;
	}
	public void setDelta(long delta) {
		this.delta = delta;
	}
	public void setCurrentTime(long curr) {
		delta=curr-System.nanoTime();
	}
	public void setCurrentTime2(long curr) {
		if(unsetted) {
			unsetted=false;
			delta=curr-System.nanoTime();
		}else {
		delta=(delta*9+ curr-System.nanoTime())/10;
		}
	}
	public long getAccuracy() {
		return accuracy;
	}
	public void calibrate(long delta,long taccurace) {
		if(accuracy==Long.MAX_VALUE||taccurace<= accuracy) {
			accuracy=taccurace;
			unsetted=false;
			this.delta=delta;
			//System.out.println(delta+" "+currentTime+" "+taccurace);
		}else {
			accuracy=(accuracy*9999+taccurace)/10000;
		} 
	}
	public void calibrate2(long delta,long taccurace) {
		if(accuracy==Long.MAX_VALUE||taccurace<= accuracy) {
			accuracy=taccurace;	
			if(unsetted) {
				unsetted=false;
				this.delta=delta;
			}else {
				this.delta=(this.delta*9+delta)/10;
			}
			//System.out.println(delta+" "+currentTime+" "+taccurace);
		}else {
			accuracy=(accuracy*9999+taccurace)/10000;
		}
	}
	
}
