// vim: set ts=8 :
// Here's how this works:
//
// The video can be called in two different ways -- via FB Connect or via user-supplied name (either directly or indirectly from an MO::user).
//
// In the FB Connect case, fetch_and_record is called on a successful "connect".  If it gets a first and last name (the minimum required to
// display the video), it $.posts them back to the server asynchronously and calls data_ready once the post succeeds.
//
// For the non-FB case, the name is either supplied by the user or comes from the first_name and last_name globals, populated in index.html
// from the user's MO::user hash.  In either case, these are $.post'd to the server and data_ready is called on success.
//
// To trigger the XML load and start the video, we call loadAndPlay on the SWF.  Unfortunately for us, that function only becomes available
// sometime _after_ the SWF has actually loaded, so once we have the data and the SWF has loaded, we need to poll until the loadAndPlay
// method appears.
//

// Make console.log not crash IE
if ( !window.console ) {
    window.console = { log: function() {} }
}

var api_key = '0fb889bc8e5b3eff7aa13b6ad80254d3';
var api;

var movie_done = 0;
var data_done = 0;

var fb_init_ran = 0;

FB.init(api_key, "xd_receiver.html", { ifUserConnected: auto_launch_fb_video, ifUserNotConnected: not_connected, doNotUseCachedConnectState: 'true' });
FB.ensureInit(get_api);

function not_connected() {
    fb_init_ran = 1;
    if (window.name_hash) { // hope it's set by now
        var picker = Math.random() > .5 ? 1 : 0;
        $.post('saw_nothing.pl', { 'direct_to_video': picker, 'have_name': name_hash})
        if (picker) {
            launch_normal_video({ 'first_name': first_name, 'last_name': last_name})
        } else {
            $('#dialog').dialog('open');
            $.post( 'saw_first_shadow.pl' );
        }
    }
    else {
        $('#dialog').dialog('open');
        $.post( 'saw_first_shadow.pl' );
    }
}

function get_api() { 
    api = FB.Facebook.apiClient;
}

function launch_fb_video() {
    $('#dialog').dialog('close');
    fetch_and_record(0);
}

function manually_launch_fb_video(uid) {
    $('#dialog').dialog('close');
    fetch_and_record(2, uid);
}

function auto_launch_fb_video(uid) {
    var autolaunch = 1;

    if (fb_init_ran) {
         autolaunch = 2;
    }

    $('#dialog').dialog('close');
    fetch_and_record(autolaunch, uid);
}

function launch_normal_video(data) {
    $('#dialog').dialog('close');
    $('#dialog_nofb').dialog('close');
    $('.full_name').html(data.first_name + " " + data.last_name);
    $('.first_name').html(data.first_name);
    $('.last_name').html(data.last_name);
    bv_id = data.bv_id;

    data_ready(data);
}

function fetch_and_record(autolaunch, uid) {
    load_fb_hacks();

    var sequencer = new FB.BatchSequencer;
    
    var self_fql = "select first_name, last_name, hometown_location, affiliations, work_history, education_history from user where uid =" + uid;
    var pendingSelfResult = api.fql_query(self_fql, sequencer);
    
    var friend_fql = "select name from user where uid in (select uid2 from friend where uid1 = " + uid + ") order by rand() limit 3";
    var pendingFriendResult = api.fql_query(friend_fql, sequencer);
    
    var photo_fql = "select src_big, src_big_height, src_big_width from photo where aid in (select aid from album where owner = " + uid + " and name = 'Profile Pictures')";
    var pendingPhotoResult = api.fql_query(photo_fql, sequencer);

    $(document).oneTime('5s', 'fb_alarm', fb_failed);

    sequencer.execute(function() {
	    var results = new Array();

            if (pendingSelfResult.exception) {
                $.post('exception.pl', { "e": "SelfResultException" + pendingSelfResult.exception })
            }
                
	    if (pendingSelfResult.result) {
		results.push({ self: pendingSelfResult.result });
		myself = pendingSelfResult.result[0];
                if (!myself.first_name || !myself.last_name) {
			$('#dialog').dialog('close'); 
			$('#dialog_nofb').dialog('open'); 
			$.post( 'saw_second_shadow.pl' );
			$('input,textarea,select,a').blur();
			return false; 
                }
                else {
 			// IE fails at FBML.  Take matters into our own hands.
                        $('span.first_name').text(myself.first_name);
                        $('span.last_name').text(myself.last_name);
                        $('span.full_name').text(myself.first_name + ' ' + myself.last_name);
		}
	    }

            if (pendingFriendResult.exception) {
                $.post('exception.pl', { "e": "FriendResultException: " + pendingFriendResult.exception })
            }
	    
	    if (pendingFriendResult.result) {
		results.push({ friend: pendingFriendResult.result });
	    }

            if (pendingPhotoResult.exception) {
                $.post('exception.pl', { "e": "PhotoResultException: " + pendingPhotoResult.exception })
            }
	    
	    if (pendingPhotoResult.result) {
		results.push({ photo: pendingPhotoResult.result });
	    }

            // if we didn't get any data, we failed
            if ( results.length > 0 ) {
		results.push({ 'autolaunch': autolaunch });

                // hashed_id and rc are set in index.html
                $.post(
                    'fb_record.pl?id=' + window.hashed_id + '&rc=' + window.rc,
                    {json: JSON.stringify(results)}, data_ready, "json"
                );
            }
            else {
                fb_failed()
            }
	});
}

function launch_video() {
	if (movie_done == 1 && data_done == 1) {
      $(document).everyTime('400ms', "check_and_launch", check_and_launch, 10);
	}
}

function swf_loaded(e) {
	if (e.success == true) {
		movie_done = 1;
	}

	launch_video();
}

function data_ready(data) {
        bv_id = data.bv_id;

	$(document).stopTime("fb_alarm");
	data_done = 1;

	launch_video();
}

function check_and_launch() {
	if ($('#viralVideo').get(0).loadDataUrlAndPlay) {
		$(document).stopTime("check_and_launch");
		$('#viralVideo').get(0).loadDataUrlAndPlay('http://beck.cnnbcvideo.com/name.xml' + (bv_id ? '?bv_id=' + bv_id : ''));
	}
}

function fb_failed() {
	$('#dialog').dialog('close'); 
	$('#dialog_nofb').dialog('open'); 
	$.post( 'saw_second_shadow.pl' );
	$('input,textarea,select,a').blur();
	return false;
}

function load_fb_hacks() {
  var old_deserialize = FB.JSON.deserialize;
  FB.JSON.deserialize = function (json) {
    var res;
    var log_err = function (msg) { 
        $.post('exception.pl', {"e": "Error: " + msg + " JSON: " + json}) }
    try {
      res = old_deserialize(json, true);
    } catch (err) {
      // log_err('failed on deserialize(json, true)');
      try {
        res = old_deserialize(json, false);
      } catch (err) {
        // log_err('failed on deserialize(json, false)');
        try {
          res = jQuery.parseJSON(json);
        } catch (err) {
          // log_err('failed on jQuery.parseJSON(json)');
          try {
            res = jQuery.parseJSON(json.replace(/\\'/, "'"));
          } catch (err) {
            // log_err('failed on jQuery.parseJSON(json_with_removed_quote_escapes)');
            try {
              res = (function (window, document, top, self) {
                return eval('('+json+')');
              })(null, null, null, null);
            } catch (err) {
              log_err('Failed to parse JSON, giving up');
              // throw the norm
              res = old_deserialize(json, true);
            }
          }
        }
      }
    }
    return res;
  };
};
