Cobalt = window.Cobalt || {};
Cobalt.Social = Cobalt.Social || {};

/*
 * Cobalt.Social.ShareThis
 *  Object for "Share This" links and support routines
 *
 *  ShareThis: a constructor for a handy object to hold common information,
 *    e.g., for multiple ShareThis links on a page.
 *
 *    Synopsis:
 *      var shr = new ShareThis([obj]);
 *
 *    Parameters:
 *      obj:    an object that holds any arbitrary properties. If no
 *              obj is provided, the default new object returned by
 *              the constructor is
 *                {
 *                  location:     // href of the current window
 *                }
 *
 *  --------------------------------------------------------------------
 *  Public methods:
 *  --------------------------------------------------------------------
 *    shortenUrl: URL shortening. Note that shortening is not
 *      guaranteed to be successful.
 *
 *      Synopsis:
 *        shortenUrl(longUrl, callback)
 *
 *      Parameters:
 *        longUrl:  URL to be shortened by the Bit.ly URL shortening service
 *        callback: function to be run when Bit.ly has completed its work.
 *                  It is called with a single argument, the short URL. If
 *                  Bit.ly was unsuccessful (e.g., timed out), the original
 *                  URL is passed to callback.
 *
 *  --------------------------------------------------------------------
 *    PopupWindow: a constructor for a popup window object
 *
 *      Synopsis:
 *        win = new PopupWindow([url],[popupParams])
 *
 *      Parameters:
 *        url:      URL of the new window. May be an empty string, or null
 *        popupParams:
 *                  new window parameters; if empty or null, defaults to
 *                    width=950,height=650,scrollbars=yes,status=no,location=no,resizable=yes
 *
 *      Instance method:
 *        win.redirect(url):  if the initial url given to the constructor
 *          was empty/null, it's allowed to retarget the popup window to
 *          a url given to this method
 *
 *  --------------------------------------------------------------------
 *    setup: currently used internally only.
 *
 *  --------------------------------------------------------------------
 *    PostToFacebook: pop open a window to post a string and URL to a
 *      Facebook user's wall.
 *
 *      Synopsis:
 *        PostToFacebook(url,postText[,windowRef])
 *
 *      Parameters:
 *        url:      URL to post to Facebook. (Should be in clear text; it
 *                  will be URI-encoded.)
 *        postText: initial text to send with the post. (Note that Facebook
 *                  seems to ignore this.)
 *        windowRef:
 *                  already opened window (e.g., from PopupWindow); if null,
 *                  a new window is opened
 *
 *  --------------------------------------------------------------------
 *    PostToTwitter: pop open a window to post a string (often with a URL)
 *      to a Twitter user's feed.
 *
 *      Synopsis:
 *        PostToTwitter(postText[,windowRef])
 *
 *      Parameters:
 *        postText: text to send with the post. If this is a URL, or 
 *                  contains a URL, it might be necessary to shorten it, 
 *                  as Twitter posts are restricted to 140 characters.
 *        windowRef:
 *                  already opened window (e.g., from PopupWindow); if null,
 *                  a new window is opened
 *
 *  --------------------------------------------------------------------
 *    EmailAFriend: pop up an overlay div with the email a friend form
 *
 *      Synopsis:
 *        EmailAFriend([url])
 *
 *      Parameters:
 *        url:      URL of page to be referenced in the email. If empty
 *                  or omitted, the email references the current page URL.
 *
 */


(function(jQuery) {
  Cobalt.Social.ShareThis  = ShareThis;
  ShareThis.shortenUrl     = shortenUrl;
  ShareThis.PopupWindow    = PopupWindow;
  ShareThis.setup          = setup;
  ShareThis.postToFacebook = postToFacebook;
  ShareThis.postToTwitter  = postToTwitter;
  ShareThis.emailAFriend   = emailAFriend;

  var BITLY_API_SCRIPT = 'http://bit.ly/javascript-api.js?version=latest&login=cobalt&apiKey=R_120c5e481588abb04d47969ddefff464'
     ,BITLY_TIMEOUT = 5000
     ,shortUrlCache = {}
     ,nextId = 0;

  function urlPath(url) { return url.replace(/\?.*/g,''); }
  function urlQuery(url) {
    var queryIx = url.indexOf('?'),
        queryString = (queryIx < 0) ? '' : url.slice(queryIx+1);
    return new Cobalt.Core.Util.queryString(queryString);
  }

  function dbgmsg(userMsg) {
    return;
    if (document.location.hash.indexOf('debug=true') < 0) return;
    var x = new Date;
    var msgHead = x.getMinutes() + ':' + x.getSeconds() + "." + x.getMilliseconds( ) + " - ";
    var msgDiv = document.getElementById('LoggerDiv');
    if (!msgDiv) {
      msgDiv = document.createElement('pre');
      msgDiv.id = 'LoggerDiv';
      msgDiv.style.textAlign = 'left';
      msgDiv.style.backgroundColor = '#f0f0f0';
      msgDiv.style.color = '#000000';
      document.body.insertBefore(msgDiv,document.body.firstChild);
    }
    try {
      if (msgDiv) msgDiv.appendChild(document.createTextNode(msgHead+userMsg+"\r\n"));
      if (typeof console != 'undefined') console.log(msgHead,userMsg);
    } catch(e) {alert(e.message)};
  }

  function PopupWindow(url,popupParams) {
    this.url = url || '';
    popupParams = popupParams || "width=950,height=650,scrollbars=yes,status=no,location=no,resizable=yes";
    this.win = window.open(this.url,'',popupParams);
    if (this.url != '') this.redirect(this.url);
  }

  PopupWindow.prototype.redirect = function(url) {
    if (this.win == null) {
      setTimeout(function() {this.redirect(url)},100);
    } else {
      if (this.url != url) this.win.document.location = url;
      this.win.focus();
    }
  };

  function shortenUrl(longUrl,onShortened) {
    var callback = 'shortenUrl_' + (nextId++),
        timeoutRef = null,
        shortUrl;

    function cached(url) { return (longUrl in shortUrlCache) ? shortUrlCache[longUrl] : false; }
    function cache(longUrl,shortUrl) { shortUrlCache[longUrl] = shortUrl; }

    if (shortUrl = cached(longUrl)) {
      // don't request re-shortening for the same URL
      dbgmsg("shortenUrl: returning cached: '" + shortUrlCache[longUrl] + "' for longUrl: '" + longUrl + "'");
      onShortened(shortUrl);
      return;
    }
    var BitlyCB_callback = function(data) {
      var returnName;
      if (timeoutRef) {                         // Bitly returned in time to fire the callback
        clearTimeout(timeoutRef);               // ensure the timeout routine doesn't run
        timeoutRef = null;
        try {
          for (var r in data.results) {         // Results are keyed by longUrl: grab the first one.
            returnName = (data.results[r]["shortUrl"].toString());
            break;
          }
        } catch(e) {
          dbgmsg("Bitly error");
          returnName = longUrl;
        }
        delete window.BitlyCB[callback];        // cleanup
        if (returnName != longUrl)
          cache(longUrl,returnName);            // cache it for quick return on subsequent requests
        onShortened(returnName);
      }
    };
    timeoutRef = setTimeout(function() {
      dbgmsg("BitlyClient failed");
      onShortened(longUrl);
      timeoutRef = null;
    },BITLY_TIMEOUT);
    Cobalt.require('BitlyClient',BITLY_API_SCRIPT,function() {
      try {
        window.BitlyCB[callback] = BitlyCB_callback;                    
        BitlyClient.shorten(longUrl, 'BitlyCB.'+callback);
      } catch(e) {
        dbgmsg('Shorten error:' + e.message);
      };
    });
  }

  function ShareThis(args) {
    jQuery.extend(this,{location:window.location.href},args);
  }

  function postToFacebook(url,postText,win) {
    var newwin = win || new PopupWindow;
    newwin.redirect('http://www.facebook.com/share.php?u=' + encodeURIComponent(url) +
      '&t=' + encodeURIComponent(postText || ''));
  }

  function postToTwitter(postText,win) {
    var newwin = win || new PopupWindow;
    newwin.redirect('http://twitter.com/home?status=' + (postText || ''));
  }
  
  function emailAFriend(url) {
    Cobalt.require('EmailAFriend',window.assetServerUrl + '/common/js/emailAFriend.js',function() {
      var eaf = EmailAFriend.getInstance();
      if (url) eaf.getUrl = function() {    // define a URL getter just for this "instance" (Ha! it's a singleton!)
        delete eaf.getUrl;                  // remove the getter after it's been used, & revert to prototype URL getter
        return url;
      };
      eaf.open();  
    });
  }

  function setupForVehicleDetails() {
    if (typeof ContextManager == 'undefined') {
      dbgmsg("Waiting ...");
      setTimeout(setupForVehicleDetails,150);
      return;
    }
    var sessionId = 'dummySession',
        vinNum = 'dummyVIN',
        isLive = true;

    try {
      if (isLive = ContextManager.isLive()) {
        sessionId = ContextManager.getSessionId();
        vinNum = ContextManager.getVin();
      }
    } catch(e) {}
    
    function initiatePixelTag(type,pageName) {
      if (isLive) {
        Cobalt.require('SocialMediaEventHandler',window.assetServerUrl + '/common/js/SocialMediaEventHandler.js',function() {
          (new SocialMediaEventHandler()).initiatePixelTag(type,pageName);
        });
      }
    }
    function linkParams(siteKey,vinNum,sessId) {
      return {
         "cs:pro": "csm"
        ,"cs:e":  siteKey
        ,"cs:i:vin": vinNum
        ,"cs:rv": sessId
      }
    }
    function canonicalUrl(location,paramMap) {
      var path = urlPath(location),
          query = urlQuery(location);
      dbgmsg("canonicalUrl: from location='" + location + "',\r\n path='" + path + "'\r\n query='" + query.toString() + "'");
      for (var key in paramMap) {
        query.removeParam(key);
        if (paramMap[key] != null) query.setParam(key,paramMap[key]);
      }
      dbgmsg("canonicalUrl: returning '" + path + '?' + query.toString() + "'");
      return path + '?' + query.toString();
    }
  
    var shareThis = new ShareThis({
       sessionId:    sessionId
      ,vinNumber:    vinNum
      ,pixelTracker: initiatePixelTag
      ,pageName:     "VehicleDetails"
      ,linkParams:   linkParams
    });

    dbgmsg("Ready to initialize");
    // Note: currently, link selectors are hard-coded:
    //    <elm class="shareToSocialMedia"><a class="facebook"> ... (etc.)
    // We select these elements immediately, because this script is placed
    //    at the end of the document. If that changes, use (document).ready.
    function clickFacebook(obj) {
      try {
        var longUrl = canonicalUrl(obj.location,obj.linkParams('fb',obj.vinNumber,obj.sessionId));
        var win = new PopupWindow();
        shortenUrl(longUrl,function(shortUrl) {
          obj.pixelTracker('fb',obj.pageName);
          win.redirect('http://www.facebook.com/share.php?u=' + encodeURIComponent(shortUrl) +
                       '&t=' + encodeURIComponent(jQuery.trim(document.title)));
        })
      } catch(e) {}
      return false;
    }
    function clickTwitter(obj) {
      function reshorten(url,description) {
        var path = urlPath(url),
            query = urlQuery(url),
            removables = ['cs:rv','cs:i:vin','cs:e'];
        function fullLen() { return (path.length + 1 + query.toString().length) + description.length; }
        function removeParams(param) { query.removeParam(param); query.removeParam(escape(param)); }

        while ((fullLen() > 140) && (removables.length > 0)) removeParams(removables.shift());
        while (fullLen() > 140 && (description.length > 8)) description = description.slice(0,-1);
        if (description.length <= 8) description = 'Cool Car!';
        if (fullLen() > 140) removeParams('cs:pro');
        return {url: path + "?" + query.toString(), description: description};
      }
      try {
        var longUrl = canonicalUrl(obj.location,obj.linkParams('tw',obj.vinNumber,obj.sessionId));
        var description = jQuery.trim(document.title);
        description = jQuery.trim(description.substring(0,Math.min(description.length,118)));
        var win = new PopupWindow();
        shortenUrl(longUrl,function(shortUrl) {
          if (shortUrl == longUrl) {
            var shorterUrlObj = reshorten(shortUrl,description);
            shortUrl = shorterUrlObj.url;
            description = shorterUrlObj.description;
          }
          obj.pixelTracker('tw',obj.pageName);
          win.redirect("http://twitter.com/home?status=" + shortUrl + " " + encodeURIComponent(description));
        });
      } catch(e) {}
      return false;
    }
    function clickEmail(obj,target) {
      obj.pixelTracker("email",obj.pageName);
      var vehicleId = target.rel.replace(/^vehicleId:/,'');
	  var element = document.getElementById("detailTabsContainer");
      EmailAFriend.getInstance().open(element,element,vehicleId);
      return false;
    }
    function clickPrint(obj) {
      function getVehicleId() {
        var vId = "";
        try {vId = Cobalt.Website.Data.VehicleDetailDataManager.getVehicleId();} catch(e) {};
        return vId;
      }
      obj.pixelTracker("print",obj.pageName);
      var printUrl = pageUrlUtility.getBaseHref() + "details_printPageRedesign.do?pageName=VehicleDetails&id=" + getVehicleId();
      new PopupWindow(printUrl,'width=800,height=900,scrollbars=yes,status=no,titlebar=no,resizable=yes,location=no,menubar=no,toolbar=no');
      return false;
    }
    function clickFaves(obj) {
      var bookmarkUrl = obj.location,
          bookmarkTitle = jQuery.trim(document.title);
      try {
        obj.pixelTracker("faves",obj.pageName);
        dbgmsg("addFavorites: title='" + bookmarkTitle + "'; url='" + bookmarkUrl + "'");
        while(true) {
          try {window.sidebar.addPanel(bookmarkTitle, bookmarkUrl,""); break;} catch(e) {}
          try {window.external.AddFavorite(bookmarkUrl, bookmarkTitle); break;} catch(e) {}
          alert(BOOKMARK_ERROR_MSG);
          break;
        }
      } catch(e) {}
      return false;
    }
    jQuery('.shareToSocialMedia').click(function(e) {
      for (var target = e.target; target; target = target.parentNode) {
        if (target === this) {
          target = null;
          break;
        } else if (target.nodeName.toLowerCase() == 'a') break;
      }
      if (target) switch(target.name.replace(/^#/,'')) {
        case 'facebook':  return clickFacebook(shareThis); break;
        case 'twitter':   return clickTwitter(shareThis); break;
        case 'email':     return clickEmail(shareThis,target); break;
        case 'print':     return clickPrint(shareThis); break;
        case 'favorites': return clickFaves(shareThis); break;
      }
      return true;
    }).find('a.email,a.print,a.facebook,a.twitter,a.favorites').css('visibility','visible');
  }

  function setup(type) {
    if (typeof setup[type] == 'function') (setup[type])();
  }

  setup.VehicleDetails = setupForVehicleDetails;

  setup(ContextManager.getPageName());

})(Cobalt.Core.JQueryFactory.getLatest());

