require 'thread' #for Queue

class DataWriter
	attr_accessor :interval, :buffer

	def initialize dir = '.'
		@out = {
			'ecg' => File.new("#{dir}/ecg.csv", 'w'),
			'implantAcceleration' => File.new("#{dir}/implant_axis.csv", 'w'),
			'collarAcceleration' => File.new("#{dir}/collar_axis.csv", 'w'),
			'implantBattery' => File.new("#{dir}/implant_battery.csv", 'w'),
			'collarBattery' => File.new("#{dir}/collar_battery.csv", 'w'),
			'implantTemperature' => File.new("#{dir}/implant_temp.csv", 'w'),
			'collarTemperature' => File.new("#{dir}/collar_temp.csv", 'w')
		}

		@interval = {
			'ecg' => 1 / 341,
			'implantAcceleration' => 1 / 16,
			'collarAcceleration' => 1 / 16,
			'implantBattery' => 1.0,
			'collarBattery' => 1.0,
			'implantTemperature' => 1.0,
			'collarTemperature' => 1.0
		}

		@buffer = {
			'ecg' => [],
			'implantAcceleration' => [Queue.new, Queue.new, Queue.new],
			'collarAcceleration' => [Queue.new, Queue.new, Queue.new],
			'implantBattery' => [],
			'collarBattery' => [],
			'implantTemperature' => [],
			'collarTemperature' => []
		}
		
		@time = 0
		
		clearRowCount
	end
	
	def clearRowCount
		@rowCount = { #row count keeps track of written rows since last time syncronisation (or interval update)
			'ecg' => 0,
			'implantAcceleration' => 0,
			'collarAcceleration' => 0,
			'implantBattery' => 0,
			'collarBattery' => 0,
			'implantTemperature' => 0,
			'collarTemperature' => 0
		}
	end
	
	def setTime t
		flush
		@time = t.to_i
		clearRowCount
	end
	
	#@todo: flush on interval update
	
	def flush
		%w{implantAcceleration collarAcceleration}.each { |key|
			while(@buffer[key].all? {|q| not q.empty?})
				@out[key].write((@time + @rowCount[key] * @interval[key]).to_s + ",")
#				puts "[DBG] @rowCount[#{key}] = #{@rowCount[key]}"
#				puts "[DBG] @interval[#{key}] = #{@interval[key]}"
				@out[key].write(((@buffer[key].map {|q| q.pop.to_s}).join ',') + "\r\n")
				@rowCount[key] += 1
			end
		}
		
		%w{ecg implantBattery collarBattery implantTemperature collarTemperature}.each { |key|
			@buffer[key].each { |v|
				@out[key].write "#{@time + @rowCount[key] * @interval[key]}, #{v}\r\n"
				@rowCount[key] += 1
			}
			@buffer[key] = []
		}
	end
end
