#!/usr/bin/ruby

require 'rubygems'
require 'levenshtein'

categories = ["first_name", "middle_name", "pounds", "ounces", "inches", "day", "hour", "minute"]

work_guesses = {
	'Loren Bland' => {
    :first_name => 'Jacklyn',
    :middle_name => 'Lainer',
    :pounds => 7,
    :ounces => 4,
    :inches => 18.7,
    :day => 23,
    :hour => 21,
    :minute => 25
	},
	'Nick Lassonde' => {
		:first_name => 'Pink',
		:middle_name => 'Shrimp',
		:pounds => 7,
		:ounces => 10,
		:inches => 18,
		:day => 27,
		:hour => 17,
		:minute => 23
	},
	'Charlie Bosson' => {
		:first_name 	=> 'Aeioulz',
    :middle_name	=> 'Aeioumr',
    :pounds 			=> 7,
    :ounces				=> 10,
    :inches				=> 18,
    :day					=> 24,
    :hour					=> 3,
    :minute				=> 23
	},
	'Kevin Hartsock' => {
		:first_name 	=> 'Maria',
		:middle_name	=> 'Faith',
		:pounds 			=> 8,
		:ounces				=> 3,
		:inches				=> 20.1,
		:day					=> 21,
		:hour					=> 12,
		:minute				=> 5
	},
	'Mike Sheffey' => {
		:first_name 	=> 'Madison',
		:middle_name	=> 'Anne',
		:pounds 			=> 7,
		:ounces				=> 0,
		:inches				=> 20,
		:day					=> 27,
		:hour					=> 16,
		:minute				=> 35
	}
}

social_network_guesses = {
	'Andi Ardisone' => {
		:first_name 	=> 'Madison',
		:middle_name	=> 'Emma',
		:pounds 			=> 8,
		:ounces				=> 2,
		:inches				=> 19.6,
		:day					=> 23,
		:hour					=> 17,
		:minute				=> 27
	},
	'Gay Roby' => {
		:first_name 	=> 'Tiffany',
		:middle_name	=> 'Gail',
		:pounds 			=> 8,
		:ounces				=> 0,
		:inches				=> 21.75,
		:day					=> 18,
		:hour					=> 17,
		:minute				=> 23
	},
	'Ben Roby' => {
		:first_name 	=> 'Amelia',
		:middle_name	=> 'Elizabeth',
		:pounds 			=> 7,
		:ounces				=> 8,
		:inches				=> 16,
		:day					=> 20,
		:hour					=> 17,
		:minute				=> 23
	},
	'Erin Sells' => {
		:first_name 	=> 'Lauryn',
		:middle_name	=> 'Hannah',
		:pounds 			=> 8,
		:ounces				=> 2,
		:inches				=> 18,
		:day					=> 21,
		:hour					=> 0,
		:minute				=> 47
	},
	'Elizabeth Hess' => {
		:first_name 	=> 'Olivia',
		:middle_name	=> 'Rose',
		:pounds 			=> 8,
		:ounces				=> 7,
		:inches				=> 20,
		:day					=> 22,
		:hour					=> 5,
		:minute				=> 43
	}
}

actual = {
	:first_name => 'Kairi',
	:middle_name => 'Faith',
	:pounds => 7,
	:ounces => 12,
	:inches => 19,
	:day => 18,
	:hour => 1,
	:minute => 16
}

print '<h1>'
guesses = if ARGV[0] == 'w'
	print "Work Leauge"
	work_guesses
elsif ARGV[0] == 's'
	print "Social Network League"
	social_network_guesses
else
	print "World Series"
	world_series = {}
	work_guesses.each_pair {|k,v| world_series[k] = v }
	social_network_guesses.each_pair {|k,v| world_series[k] = v }
	world_series
end
puts '</h1>', ''

n_space = actual.keys.length
vectors = {}
guesses.keys.each {|guesser| vectors[guesser] = {}}
actual.each_pair do |key, actual_value|
	guesses.each_pair do |guesser, guesser_guesses|
		guessed_value = guesser_guesses[key]
		
		distance = if actual_value.respond_to? :-
			(guessed_value - actual_value).abs
		else
			guessed_value.downcase!
			actual_value.downcase!
			
			Levenshtein.distance(guessed_value, actual_value)
		end
		
		vectors[guesser][key] = distance.to_f
	end
end

average_distances = {}
if ARGV[1] == '--curve'
	categories.each do |category|
		cat = category.to_sym
		average_distances[cat] = []
		vectors.each_pair do |guesser, distances|
			distance = distances[cat]
			average_distances[cat] << distance
		end
	end
	puts '## Average Distance'
	categories.each do |cat_str|
		category = cat_str.to_sym
		arr = average_distances[category]
		#average_distances[category] = sum / guesses.keys.count
		average_distances[category] = arr.sort[arr.length/2]
		puts "- *#{category}*: #{average_distances[category]}"
	end
	puts
else
	categories.each {|category| average_distances[category.to_sym] = 1.0}
end

records = []
vectors.each_pair do |guesser, distances|
	record = []
	record << '## ' + guesser
	all_distances = []
	categories.each do |category|
		key = category.to_sym
		key_distance = distances[key]
		counts_as = ''
		counts_as = '(counts double)' if key == :first_name
		counts_as = '(counts double)' if key == :middle_name
		record << "- *#{key}*: guessed **#{guesses[guesser][key]}**, which was off by **#{key_distance}** #{counts_as}"
		all_distances << key_distance * average_distances[key]
	end
	
	all_distances << distances[:first_name] * average_distances[:first_name]
	all_distances << distances[:middle_name] * average_distances[:middle_name]
	
	vector_length = Math.sqrt(all_distances.inject(0) do |total, key_distance|
		total + key_distance ** 2
	end)
	record << ['', "### Distance: #{vector_length}", '']
	records << [vector_length, record.flatten.join("\n")]
end

records.sort.each {|r| puts r.last, ''}