require './min_max.rb'

#@TODO: what to do on parallel events (if there are any)?
def event_combiner datafile, eventfile, outfile, time_column = 0, event_file_structure = { 'time' => 0, 'duration' => 1, 'event1' => 2, 'event2' => 3 }, event_file_separator = "\t"
	eh = File.open(eventfile, 'r')
	oh = File.open(outfile, 'w')
	active_events = []
	waiting_event = (eh.eof?)?nil:(eh.readline.strip.split(event_file_separator).map { |i| i.to_f })
	next_event_ending_time = nil
	
	IO.foreach(datafile) { |row|
		time = row.split(',')[0].to_f
		
		# Update active events in case that one or more of those events have ended.
		if (not next_event_ending_time.nil?) && next_event_ending_time < time
			active_events.delete_if { |event|
				event[event_file_structure['time']] + event[event_file_structure['duration']] <= time
			}
			next_event_ending_time = nil
		end
		
		# Read new ongoing events to active events until events end or the next one is an upcoming event.
		while (not waiting_event.nil?) && waiting_event[event_file_structure['time']] < time
			puts waiting_event.inspect
			if time < waiting_event[event_file_structure['time']] + waiting_event[event_file_structure['duration']]
				active_events << waiting_event
			end #otherwise just ignore waiting event: it has already ended
			waiting_event = (eh.eof?)?nil:(eh.readline.strip.split(event_file_separator).map { |i| i.to_f })
			next_event_ending_time = nil
		end
		
		# Update record of next event ending time if there are ongoing events.
		if next_event_ending_time.nil? && (not active_events.empty?)
			next_event_ending_time = find_min(active_events.map {|e| e[event_file_structure['time']] + e[event_file_structure['duration']]})
		end
		
		# Write output. In case of parallel activities picks the first one.
		if active_events.empty?
			oh.write("#{row.strip},0,0\n")
		else
			oh.write("#{row.strip},#{active_events[0][event_file_structure['event1']]},#{active_events[0][event_file_structure['event2']]}\n")
		end
	}
end


