#!/usr/bin/ruby

#require 'yaml'
require 'rubygems'
require 'flickr'

require 'osx/cocoa'
include OSX
OSX.require_framework 'ScriptingBridge'

# set up Flickr and check we're authed

API_KEY       = ""
SHARED_SECRET = ""
flickr_id     = ""

# config - aspirational, this

tags_direction = "in" # "out", "both"
meta_direction = "both" # "in", "out"

# utility AppleScript debugging method
def dump( thingy )
  puts thingy.to_s
  ( thingy.class.objc_instance_methods - SBApplication.objc_instance_methods ).sort.each do |m|
    puts " * #{ m }"
  end
end

# cache auth details

dir = File.expand_path '~/.flickr-match'
`mkdir -p #{dir}` unless File.exist?(dir)

flickr = Flickr.new(File.join(dir, 'rflickr.cache'), API_KEY, SHARED_SECRET)
unless flickr.auth.token
  flickr.auth.getFrob
  url = flickr.auth.login_link
  puts "You must visit #{url} to authorize this application.  Press enter "+
      'when you have done so. This is the only time you will have to do this.'
  gets
  flickr.auth.getToken
  flickr.auth.cache_token
  puts "OK, thanks. Rerun this script and it should go from there."
  exit
end

# get Flickr photos now authed

fphoto_lookup = Hash.new

fphotos = flickr.photos.search(flickr_id, nil, nil, nil, nil, nil, nil, nil, 
                              nil, 'date_upload, date_taken, o_dims', '100')
# TODO map
fphotos.each do |photo|
  fphoto_lookup[photo.datetaken.to_i] = photo
end

# puts fphoto_lookup

# now loop through photo information

iPhoto = SBApplication.applicationWithBundleIdentifier_("com.apple.iPhoto")

iPhoto.photos.each do |photo| # cleverer- search for photos with a given date?
                              # maybe if we can fix the predicate select bug
  name = photo.name
  # keywords = photo.keywords
  taken = photo.date
  epoch = taken.timeIntervalSince1970.to_i
  tagged = false;
  flickr_tags = Hash.new

  if (fphoto_lookup.has_key?(epoch))
    # get the corresponding Flickr photo and put out some info 
    fphoto = fphoto_lookup[epoch]
    puts("photo "+name.to_s+" matches "+fphoto.id)
    #puts("      "+fphoto_lookup[epoch].url+" taken on")
    #puts("      "+taken.to_s+"\n")

    # get the Flickr-side tags
    flickr_tags = fphoto.tags.reject{ |k| k.raw.to_s.match(':.+=') }
    flickr_tags = flickr_tags.map{ |k| k.raw.to_s }
    #puts ("   - '"+flickr_tags.join("', '")+"'") 

    # get the iPhoto-side keywords
    iphoto_keys = photo.keywords.arrayByApplyingSelector("name")
    if iphoto_keys.containsObject("flickr")
      # note it then remove it so that we can sync what's left with Flickr
      tagged = true
      iphoto_keys.removeObject("flickr")
    end
    #puts ("   + '"+iphoto_keys.componentsJoinedByString("', '")+"'") 
    #puts ("   + and is tagged 'Flickr'? "+tagged.to_s.capitalize)
    
    # add Flickr keyword if necessary (TODO add all keywords(!)
    if !tagged
      # iPhoto.activate
      photo.select
  
      # because ScriptingBridge appears broken, we hand this off to AS.
      # sigh.
      # photo.assignKeywordString("flickr")
      `osascript -e 'tell application "iPhoto" to assign keyword string "flickr"'`

      puts ("    + locally tagged 'flickr'");
      
    end

    # add tags for local paths (TODO sync iPhoto keywords)
    tags = Array.new;
    home = File.expand_path '~'

    tags << '"file:name='+photo.imageFilename.to_s+'"'
    tags << '"file:location='+photo.imagePath.to_s.sub(home, "~")+'"'

    # would like to add original, but AppleScript doesn't expose it, sigh
    # could hackily reveal using System Events and query Finder. Ugh.
    
    flickr.photos.addTags(fphoto.id, tags)
    puts ("    - tagged with "+tags.join(" "))
  end
end
