require './queue.rb'

def run(infile, outfile, columns, method = :avg, win_len = 3)
	raise "Window length must be odd" unless win_len % 2 == 1
	
	h = File.open(outfile, 'w')
	values = columns.map { NumericQueue.new }
	values.each { |q| q.sorting = true } if method == :med
	row_queue = Queue.new
	row_count = 0
	IO.foreach(infile) { |row|
		row_queue.push row.strip
		row_count += 1
		data = row.split(',')
		columns.length.times { |i|
			c_id = columns[i]
			values[i].push data[c_id].to_f
			values[i].pop unless row_count <= win_len
		}
		if win_len / 2 < row_count
			new = (values.map {|i| i.send(method)}).join(',')
			h.write "#{row_queue.pop},#{new}\n"
		end
	}
	
	while not row_queue.empty?
		values.each { |q| q.pop }
		new = (values.map {|i| i.send(method)}).join(',')
		h.write "#{row_queue.pop},#{new}\n"
	end
end

def runavg infile, outfile, columns, win_len = 3
	run(infile, outfile, columns, :avg, win_len)
end

def runsum infile, outfile, columns, win_len = 3
	run(infile, outfile, columns, :sum, win_len)
end

def runmin infile, outfile, columns, win_len = 3
	run(infile, outfile, columns, :min, win_len)
end

def runmax infile, outfile, columns, win_len = 3
	run(infile, outfile, columns, :max, win_len)
end

def runmed infile, outfile, columns, win_len = 3
	run(infile, outfile, columns, :med, win_len)
end
