/*
 * Copyright (c) 2008 Aza Raskin (http://azarask.in/blog)
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

var SocialHistory = function() {

  // associative array of sites we're interested in
  // { site: [variations1, variation2...], site: [ ... }
  var sites = {
    "f": ["http://www.facebook.com/", "https://login.facebook.com/login.php", "http://www.facebook.com/home.php"]
    //"f": ["http://www.facebook.com/"]
  };

  var visited = {};

  function getStyle(el, scopeDoc,styleProp) {
    if (el.currentStyle)
      var y = el.currentStyle[styleProp];
    else if (window.getComputedStyle)
      var y = scopeDoc.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
    return y;
  }
  
  function remove( el ) {
    el.parentNode.removeChild( el );
  }
  
  // Code inspired by:
  // bindzus.wordpress.com/2007/12/24/adding-dynamic-contents-to-iframes
  function createIframe() {
    var iframe = document.createElement("iframe");
    iframe.style.position   = "absolute";
    iframe.style.visibility = "hidden";

    document.body.appendChild(iframe);

    // Firefox, Opera
    if (iframe.contentDocument)   iframe.doc = iframe.contentDocument;
    // Internet Explorer
    else if(iframe.contentWindow) iframe.doc = iframe.contentWindow.document;

    // Magic: Force creation of the body (which is null by default in IE).
    // Also force the styles of visited/not-visted links.
    iframe.doc.open();
  	iframe.doc.write('<style>');
  	iframe.doc.write("a{color: #000000; display:none;}");  	
  	iframe.doc.write("a:visited {color: #FF0000; display:inline;}");  	
  	iframe.doc.write('</style>');
    iframe.doc.close();
    
    // Return the iframe: iframe.doc contains the iframe.
    return iframe;
  }  

  // create the iframe, insert links, check them, then remove the iframe
  var iframe = createIframe();

  function embedLinkInIframe( href, text ) {
    var a = iframe.doc.createElement("a");
    a.href      = href;
    a.innerHTML = site;
    iframe.doc.body.appendChild( a );
  }

  // add links to each site
  for (var site in sites) {
    var urls = sites[site];
    for( var i=0; i<urls.length; i++ ) {
      // You have to create elements in the scope of the iframe for IE.
      embedLinkInIframe( urls[i], site );
      
      // Automatically try variations of the URLS with and without the "www"
      if( urls[i].match(/www\./) ){
        var sansWWW = urls[i].replace(/www\./, "");
        embedLinkInIframe( sansWWW, site );
      } else {
        // 2 = 1 for length of string + 1 for slice offset
        var httpLen = urls[i].indexOf("//") + 2;
        var withWWW = urls[i].substring(0, httpLen ) + "www." + urls[i].substring( httpLen );
        embedLinkInIframe( withWWW, site );
      }
    }
  }
    
  var links = iframe.doc.body.childNodes;
  for( var i=0; i<links.length; i++) {
    // Handle both Firefox/Safari, and IE (respectively)
    var displayValue = getStyle(links[i], iframe.doc, "display");
    var didVisit = displayValue != "none";
      
    if( didVisit ){
      visited[ links[i].innerHTML ] = true;
    }
  }

  // done; remove the iframe
  remove( iframe );
  
  return new (function(){
    var usedSites = [];
    for( var site in visited ){
      usedSites.push( site );
    }
    
    // Return an array of visited sites.
    this.visitedSites = function() {
      return usedSites;
    }
    
    // Return true/false. If we didn't check the site, return -1.
    this.doesVisit = function( site ) {
      if( typeof( sites[site] ) == "undefined" )
        return -1;
      return typeof( visited[site] ) != "undefined";
    }
    
    var checkedSites = [];
    for( var site in sites ){
      checkedSites.push( site );
    }
    // Return a list of the sites checked.
    this.checkedSites = function(){
      return checkedSites;
    }
  })();
}

/*
Looks to see if the browser has been to facebook and adjusts the
hidden field appropriately.
*/
function sniffFacebook() {
  var been = false;
  try {
    var sl = SocialHistory();
    var list = sl.visitedSites();
    if (list[0] == 'f') {
      been = true;
    }
  }
  catch(e) {
  }
  return been;
}


var FacebookConnectClass = new Class ({

  initialize: function(apiKey, callbackConnected, callbackNotConnected, source) {
    this.apiKey      = apiKey;
    this.connected   = false;
    this.session     = null;
    this.source      = source;

    // accounts for pages that changed document.domain: use a script that also has that change.
    if(window.documentDomainChanged && document.domain == 'tripadvisor.com') {
        this.receiver    = 'facebook_xd_receiver_mod.htm';
    }
    else {
        this.receiver    = 'facebook_xd_receiver.htm';
    }

    // mess with scope to make the requirefeatures method do the right thing
    var receiver = this.receiver;
    FB_RequireFeatures(["XFBML"], function() {
      FB.Facebook.init(apiKey, receiver, { 'doNotUseCachedConnectState' : true});
      FB.ensureInit(function() {
        FB.Connect.ifUserConnected(callbackConnected, callbackNotConnected);
        });
      });
  },

  loadSession: function() {
    this.session = FB.Facebook.get_sessionState().result;
  },

  promptConnect: function(callback) {
    var connect = this;
    FB.Connect.requireSession( function() {
      connect.connected = true;

      connect.session = new Object(FB.Facebook.get_sessionState().result);

      callback();
    })
  },

  isConnected : function() {
    return this.connected;
  },

  getFacebookId : function() {
    if (!this.session) this.loadSession();

    if (this.session) {
      return this.session.uid;
    }
    else {
      return null;
    }
  },

  getSessionKey : function() {
    if (!this.session) this.loadSession();

    if (this.session) {
      return this.session.session_key;
    }
    else {
      return null;
    }
  },

  addOtherParams: function(params) {
    params.add('flow_source',     this.source);
  },

  addAuthParams: function(params) {
    if (!this.session) this.loadSession();
    if (!this.session) return false;

    params.add('expires',     this.session.expires);
    params.add('secret',      this.session.secret);
    params.add('session_key', this.session.session_key);
    params.add('sig',         this.session.sig);
    params.add('uid',         this.session.uid);
    return true;
  },

  renderFBML : function() {
    FB_RequireFeatures(["XFBML"]);
  },

  sendFeed : function(feedId, feedData, doneCallback) {
    FB.Connect.showFeedDialog(feedId, feedData, null, null, 
                                FB.FeedStorySize.shortStory, null, doneCallback);

  }

});

// callback to perform when we're done with facebook connect
var facebookConnect_doneAction = null;

// lightbox id
var facebookConnect_lightbox = null;

// dialogs
var dialogs = null;

// facebook connect
var facebookConnect = null;

// begin connect flow
function beginConnectFlow(source)
{
  dialogs = {'default'         : $('fbConnectDefault'),
             'taPrompt'        : $('fbConnectTaPrompt'),
             'error'           : $('fbConnectError'),
             'mergePrompt'     : $('fbConnectMergePrompt'),
             'mergeDisclaimer' : $('fbConnectMergeDisclaimer'),
             'processing'      : $('fbConnectProcessing')};

  selectDialog('processing', 'Establishing connection to Facebook...');
  facebookConnect = new FacebookConnectClass(facebookConnectApiKey, handlePassiveConnect, promptForConnect, source);
}

// deprecated; left for backwards compat during bounce
function registerFacebookConnectFlow(flow, doneAction) {
  requestFacebookConnectPopup(flow, doneAction);
}

// pop up ajax when page finishes loading
function requestFacebookConnectPopup(flow, doneAction, source, category) {
  window.addEvent('domready', function() {
      try {
        popupFacebookConnect(flow, doneAction, source, category);
      }
      catch(e) {
      }
    });
}

// popup facebook connect
// flow          = which flow to pass to the FacebookConnect servlet
// doneAction    = callback to call once we're done with the connectAction, or on failure
// source        = source of connect action - used for tracking
function popupFacebookConnect(flow, doneAction, source, category) {
  facebookConnect_doneAction  = doneAction;

  new Ajax("/FacebookConnect?Action=BEGIN_FLOW&flow=" + flow + "&flow_category=" + category, 
      {
        onComplete: function(e) { showFBConnectLightbox(e); beginConnectFlow(source); }, 
        onFailure: function(e) { if (facebookConnect_doneAction) facebookConnect_doneAction(); },
        evalScripts: true
      }
  ).request();
}

// Display the content in a simple lightbox with deactivate behavior
function showFBConnectLightbox(txt) {
  // hide any flyout that's open
  if (window.flyout) window.flyout.hide();
  // if there is a currently visible lightbox, close it
  if (window.lightbox) {
    window.lightbox.deactivate();
  } 
  
  var ops = {};
  if (facebookConnect_doneAction) ops.onHide = facebookConnect_doneAction;
  ta.overlays.showInLightbox(txt, ops);
}

// add params for forum feeds
function addForumFeedParams(params) {
  var postLocationId = $('geoId').value;
  var postSubject    = $('subject').value;
  var postBody       = $('message').value;
  var postUrl        = $('showTopicUrl').value;
  var replyUrl       = $('postReplyUrl').value;
  var newPostUrl     = $('newTopicUrl').value;

  params.add('post_locationid', postLocationId);
  if (postSubject) {
    params.add('post_subject', postSubject);  // subject
  }
  params.add('post_body',     postBody);      // contents of post body
  params.add('post_url',      postUrl);       // link to post
  if (replyUrl) {
    params.add('reply_url',     replyUrl);    // post page anchored to reply
  }
  params.add('new_post_url',  newPostUrl);    // link to make a new post in this forum
}

//add params for review feed
function addMetaFeedParams(params) {
  if(currentItinData) {
    for(var i in currentItinData) {
	  params.add(i,  currentItinData[i]);
    }
  }
}

// add params for review feed
function addReviewFeedParams(params) {
  params.add('review_id',  reviewId);    // id of the review for which to show the feed
}
