/**
 * $Id: SeriesTracker.js 290 2018-03-06 17:25:35Z patrick $
 */
// TO-DO: Local storage, persistence?

define( [ 'Job', 'util' ], function( Job, util ) {
	
	SeriesTracker = function( key ) {
		Job.call( this, key );
		
		this.series = [];
		this.maxlen = 20;
		this.min = this.max = null;
		this.interval = 1;
		this.intervalCount = 0;

		this.wrappedJob = undefined;
		this.ref = undefined;
	}

	SeriesTracker.prototype = Object.create(Job.prototype);
    SeriesTracker.prototype.constructor = SeriesTracker;

	SeriesTracker.prototype.toString = function() {
		return "[" + this.constructor.name + ":" + this.key + "]";
	}
	
	SeriesTracker.prototype.getBusName = function() {
		return this.toString();
	}
	
	SeriesTracker.prototype.getSeries = function() {
		return this.series;
	}
	
	SeriesTracker.prototype.getMinMax = function() {
		return { min: this.min, max: this.max };
	}
	
	SeriesTracker.prototype.resetMinMax = function() {
		if ( this.series.length ) {
			this.min = this.max = this.series[0];
			for (var ix=1; ix<this.series.length; ++ix) {
				var v = this.series[ix];
				if (v == null) continue;
				if ( v < this.min ) this.min = v;
				if ( v > this.max ) this.max = v;
			}
		} else
			this.min = this.max = null;
	}
	
	SeriesTracker.prototype.setSeriesLength = function( m ) {
		this.maxlen = m;
		while ( this.series.length > m ) this.series.shift();
	}
	
	SeriesTracker.prototype.setInterval = function( i ) {
		this.interval = i > 1 ? i : 1;
	}
	
	SeriesTracker.prototype.wrap = function( job, ref ) {
		// util.log(4, "Wrapping " + job);
		this.wrappedJob = job;
		this.ref = ref;
		job.addObserver( this );
		job.start();
	}

	SeriesTracker.prototype.start = function() {
		// SeriesTracker doesn't actually do anything on its own, it just responds to its child series.
		// Make sure the child is running.
		this.wrappedJob.start();
	}

	SeriesTracker.prototype.run = function() {
		// tick. Nothing to do here.
	}
	
	SeriesTracker.prototype.addValue = function( val ) {
		if ( this.series.length >= this.maxlen )
			this.series.shift();
		if ( val === undefined || val === null )
			this.series.push( null );
		else {
			this.series.push( parseFloat(val) );
			if ( this.min === null || val < this.min ) this.min = val;
			if ( this.max === null || val > this.max ) this.max = val;
		}
	}
	
	SeriesTracker.prototype.messageNotify = function( msg ) {
		// We are an observer for the wrapped job. Take the value passed, add it to the series,
		// then notify OUR observers.
		var data = msg.value;
		var job = msg.arguments[0]; // ???FIXME -- why? Let's pass notifier as an argument
		// console.log('notify' + ', count=' + this.intervalCount + ', interval=' + this.interval);
		try {
			if ( this.intervalCount++ == 0 ) {
				var val = parseFloat( job.resolve( this.ref ) );
				// console.log(this.toString() + ': Adding value ' + val + ', intervalCount is ' + this.intervalCount + ', interval is ' + this.interval);
				this.addValue( val );
				this.notifyObservers( this.series );
			}
			this.intervalCount %= this.interval;
		}
		catch (e) {
			throw e;
		}
	}

	return SeriesTracker;

}); // define
