require 'rubygems'
require 'mini_exiftool'

# Author: Erik L. Underbjerg (erik@underbjerg.dk)

# This script requires the exiftool binary (in your path) and the mini_exiftool gem.
# Install them if you haven't already
# Check out http://miniexiftool.rubyforge.org/files/Tutorial.html
# and http://www.sno.phy.queensu.ca/~phil/exiftool/

EXTENSIONS = [".cr2", ".crw", ".jpg", ".jpeg"]

@total_pics = 0
RESULTS = {}
RESULTS_BY_LENS = {}

def register(focal_length, lens)
  if RESULTS[focal_length].nil?
    RESULTS[focal_length] = 1
  else
    RESULTS[focal_length] += 1
  end
  
  RESULTS_BY_LENS[lens] = {} if RESULTS_BY_LENS[lens].nil?
  if RESULTS_BY_LENS[lens][focal_length].nil?
    RESULTS_BY_LENS[lens][focal_length] = 1
  else
    RESULTS_BY_LENS[lens][focal_length] += 1
  end
  
  @total_pics += 1
end

def process(file)
  if EXTENSIONS.include?(File.extname(file).downcase)
    photo = MiniExiftool.new file
    focal = photo['FocalLength'].to_s
    lens = photo['LensType'].to_s
    cam = photo['Model'].to_s
    if cam.include?("400D") || cam.include?("300D") || cam.include?("50D") # Filter by camera model
      puts "#{focal} (#{cam} / #{lens})"
      register(focal.to_i, lens)
    else
      puts "IGNORED: #{focal} (#{cam} / #{lens})"
    end
    print_results
  end  
end

def print_results
  puts "---"
  puts "#{@total_pics} images processed"

  RESULTS.sort.each do |val|
    puts "#{val[0].to_s.rjust(30)} : #{val[1]}"
  end

  puts "---"
end

def store_results(file)
  lenses = RESULTS_BY_LENS.keys.sort
  
  File.open(file, 'w') do |f|
    f.puts "Total results,"
    f.puts "Focal length, Total count, " + lenses.join(", ")
    RESULTS.sort.each do |val|
      res = "#{val[0]}, #{val[1]}"
      lenses.each do |lens|
        res += ", " + RESULTS_BY_LENS[lens][val[0]].to_s
      end
      f.puts res + "\n"
    end
    
    lenses.each do |lens|
      f.puts ","
      f.puts "#{lens},"
      f.puts "Focal length, Count"
      RESULTS_BY_LENS[lens].sort.each do |val|
        f.puts "#{val[0]}, #{val[1]}\n"
      end
    end
  end
end

def traverse_path(path)
  puts "Traversing #{path}"
  Dir.foreach(path) do |entry|
    unless entry == "." || entry == ".."
      file = File.join(path, entry)
      if File.directory?(file)
        traverse_path(file)
      else
        process(file)
      end
    end
  end
  puts "Done traversing #{path}. Results so far: "
  print_results
end


if ARGV.size == 2

  path = ARGV[0]
  result_file = ARGV[1]

  traverse_path(path)
  
  store_results(result_file)
else
  
  puts "Usage: exif_reader.rb <path> <resultfile>"
  
end

