var SocialMedia;

(function () {
  var $ = typeof SocialMedia !== 'undefined' ? SocialMedia : (SocialMedia = {
    host:         function ()               {return 'adserver.socialmedia.com'},
    json_request: function (url)            {return jQuery.getJSON ('http://' + $.host () + '/api/v1/' + url)},

    log:          function (message, level) {return $.json_request ('services/logging/' + (level || 'info') + '?message=' + escape (message) + '&callback=?')},

    animate:      function () {
      var queue = Array.prototype.slice.call (arguments);
      var next  = function () {queue.length && run.apply (this, /^(\w+)\((\w+)\)$/i.exec (queue.shift ()).slice (1))};
      var run   = function (command, id) {
        if (/delay\d+/i.test (command)) return setTimeout (next, Number (command.substring (5)));
        command == 'hide' && (command = 'softHide');
        command == 'show' && (command = 'softShow');
        $.ad (id).container[command] (next);
      };
      next ();
    },

    ad: (function (adState) {return function (adId) {return adState[adId] || (adState[adId] = {})}}) ({})});

  $.log.warn  = function (s) {return $.log (s, 'warning')};
  $.log.info  = function (s) {return $.log (s, 'info')};
  $.log.error = function (s) {return $.log (s, 'error')};

  var lastScriptElement = (function (scriptElements) {return scriptElements[scriptElements.length - 1]}) (document.getElementsByTagName ('script'));
  var scriptParams      = (function () {
    var query  = lastScriptElement.src.replace (/^[^?]*\?/, '');
    var pairs  = query && query.split(/[;&]/);
    var result = {};

    for (var i = 0, l = pairs.length; i < l; ++i) {var parsed = pairs[i].split ('=');
                                                   parsed && parsed.length == 2 && (result[unescape(parsed[0])] = unescape (parsed[1]))}
    return result;
  }) ();

  if (scriptParams.adId) {
    typeof jQuery === 'undefined' && document.writeln('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></' + 'script>');

    var jQueryInterval = setInterval (function () {if (typeof jQuery !== 'undefined') {
                                                     clearInterval (jQueryInterval);
                                                     onDependenciesLoaded (jQuery.noConflict ());
                                                   }}, 10);

    var onDependenciesLoaded = function (jQuery) {
      var ad = $.ad (scriptParams.adId);

      jQuery.socialMediaInitialized || (jQuery.socialMediaInitialized = !! jQuery.extend (jQuery.fn, {
        overlayIn:  function (callback) {
          this.css ({zIndex: 1 << 30}).ad.overlay.width (window.innerWidth).height (window.innerHeight).css ({display: 'block', opacity: 0}).animate ({opacity: 0.5});
          callback && callback ()},

        overlayOut: function (callback) {this.ad.overlay.animate ({opacity: 0}, callback)},

        slideDown:  function (callback) {this.animate ({height: this.ad.height}, function () {jQuery.browser.safari && this.hide ().append ('<div></div>').show ();
                                                                                              callback && callback ()})},
        slideUp:    function (callback) {this.animate ({height: 1},              callback)},

        softHide:   function (callback) {this.        css ({left: -(1 << 20)});                                     callback && callback ()},
        softShow:   function (callback) {this.show ().css ({left: 'auto', height: (this.ad.height || 250) + 'px'}); callback && callback ()}}));

      ad.id = scriptParams.adId;

      ad.data || (ad.data = {});
      jQuery.extend (ad.data, scriptParams);
      jQuery.extend (ad, {container: jQuery.extend (jQuery (document.createElement ('div')).attr ('id', 'socialmedia-ad-' + ad.id).css ({position: 'relative'}), {ad: ad}),
                          overlay:   jQuery ('<div id="socialmedia-overlay-' + ad.id + '"></div>').css (
                                       {left: 0, top: 0, zIndex: 1 << 20, width: '100%', height: '100%', background: 'black', position: 'fixed', display: 'none'})});

      var formParents = jQuery (lastScriptElement.parentNode).parents ('form');
      jQuery (formParents.length ? formParents[formParents.length - 1].parentNode : lastScriptElement.parentNode).append (ad.overlay).append (ad.container);

      ad.data.visible === undefined || ad.data.visible == 'false' && ad.container.hide ();

      var defaultAdContainerHeight = ad.container.height ();
      var adLoaded                 = false;
      
      setTimeout (function () {if (! adLoaded) {
                                 var backupDir = 'http://static.socialmedia.com/ads/' + ad.id + '/backup/';
                                 $.log.warn ('Retrieving backup for ad ' + ad.id);

                                 ad.container.empty().append('<a href="http://www.socialmedia.com?ad.id=' + ad.id + '"><img src="' + backupDir + 'image.png"/></a>');
                                 jQuery.getJSON (backupDir + 'metaLoader.js?callback=?', function (data, textStatus) {
                                   data && data.clickthroughUrl && ad.container.find('a').attr('href', data.clickthroughUrl)});
                               }}, 2000);
      
      var notLoadedCount = 0;
      var loadedChecker  = setInterval (function() {! adLoaded && notLoadedCount < 120 ? ++notLoadedCount && $.log.warn ('Primary ad ' + ad.id + ' NOT loaded after ' + notLoadedCount + ' seconds')
                                                                                       : clearInterval (loadedChecker)}, 1000);
      var timeOfAdLoadRequest = + new Date ();

      setTimeout (function () {
        jQuery.getJSON ('http://' + $.host () + '/api/v1/ads/' + ad.id + '?callback=?',
          function (data, textStatus) {if (adLoaded = !! (data && data.adCode)) {
                                         $.log.warn ('Primary ad ' + ad.id + ' successfully loaded after ' + Math.round ((+ new Date () - timeOfAdLoadRequest) / 1000.0) + ' seconds');

                                         ad.container.empty ().append (data.adCode);

                                         var heightFinder = setInterval (function () {
                                           if (ad.container.height () != defaultAdContainerHeight) {
                                             ad.height = ad.container.height ();
                                             ad.container.css ('left').charAt (0) == '-' && ad.container.css ({left: 'auto', height: '1px'});

                                             clearInterval (heightFinder);
                                           }}, 50);
                                       }})}, 200);
    };
  }
}) ();
