function playTimeMgr ( mapMgr ) {
	this.job = undefined;
	this.center = false;
	this.status;
	this.mgr = mapMgr;
	//---- update timing
	var timer = 0;
	var updTime = 5000;
	var nUpd = 1;
	var updStartAt = 0;
	this.method;
	this.updateCycle = 3000;
	this.nextOptimizer = 0;

	this.initTracking = function ( delay ) {
		this.delay = delay;
		this.speed = 1;
		this.job = "tracking";
		this.status = "run"
	}
	
	this.initPlayback = function ( speed ) {
		this.job = "playback";
		this.speed = speed;
		this.status = "run"
	}
	
	this.stopped = function() {
		return this.status != "run";
	}
	
	this.tripsAreCreated = function ( ) {
		if ( this.job == "playback" ) {
			this.startTime = new Date ( this.mgr.tripMgr.startTime().getTime());
			this.endTime = new Date ( this.mgr.tripMgr.endTime().getTime());
			this.timeLine = new Date ( this.startTime.getTime());
		}
		else {
			this.timeLine = new Date( now() - this.delay * 1000 );
			this.mgr.setCurrentLocation(this.updateTime());
		}
		if ( this.center )
			this.mgr.tripMgr.centerTrip();
	}
	
	this.updateTime = function ( ) {
		if ( this.job == "tracking" ) {
			this.timeLine.setTime( now() - this.delay * 1000 );
		}
		else if ( this.job == "playback" ) {
			if ( !this.stopped() )
				this.timeLine.setTime(this.timeLine.getTime()+this.updateCycle * this.speed);
		}
		return this.timeLine;
	}

	this.startUpdates = function ( method ) {
		if ( timer ) {
			alert("attemp to start a timer while another timer is running");
			return;
		}
		this.method = method;
		this.startTimer();
	}
	this.beginUpdate = function() {
		if ( updStartAt ) return false;
		updStartAt = now();
		return true;
	}
	this.endUpdate = function() {
		updTime += now() - updStartAt;
		if ( this.resetCycle() ) 
			this.restartTimer();
		updStartAt = 0;
		nUpd++;
		var element;
		if ( element = _$('hertz') ) {
			var hertz = Math.round(10000/this.updateCycle) / 10;
			element.innerHTML = hertz + "Hz";
		}
		if ( element = _$('zoom') )
			element.innerHTML = this.mgr.zoom();
		if ( this.center ) {
			this.mgr.tripMgr.centerTrip();
			this.center = false;
		}
	}
	this.optimumInterval = function() {
		var pause = Math.round(Math.pow(2,18 - this.mgr.zoom()) * 20 / this.speed);
		var timeSpentForUpdate = updTime / nUpd;
		updTime =  nUpd = 0;
		return Math.min ( Math.max ( timeSpentForUpdate + pause, 60 ), 5000 );
	}
	this.resetCycle = function( ) {
		if ( now() < this.nextOptimizer )
			return false;
		this.nextOptimizer = now() + 2000;
		var opt = this.optimumInterval();
		if ( opt > this.updateCycle || opt < 0.9 * this.updateCycle ) {
			this.updateCycle = Math.round ( opt * 1.05);
			return true;
		}
		return false;
	}
	this.restartTimer = function() {
		this.cancelTimer();
		this.startTimer();
	}
	this.startTimer = function() {
		timer = window.setInterval( this.method, this.updateCycle);
	}
	this.cancelTimer = function() {
		if ( timer == 0 )	return;
		window.clearInterval(timer);
		timer = 0;
	}
	this.setSpeed = function ( speed ) {
		this.speed = speed;
	}
	
}
