var iLikeFC = new Object();

//----------------------------------------------------------------------------
//
// iLikeFC.FCGadget class
//
// Wraps basic OpenSocial-context retrieval
//
//----------------------------------------------------------------------------

iLikeFC.FCGadget = Class.create();
iLikeFC.FCGadget.prototype = {
    
  initialize : function(bootstrapCB) {
    this.params = gadgets.util.getUrlParameters();

    // Retrieve basic info from the container
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPeopleRequest(new opensocial.IdSpec({'userId' : 'OWNER', 'groupId' : 'ADMINS'})), 'admins');
    req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
    
    var completionFunc = function(dataResponse) {
      var adminsObj = dataResponse.get('admins').getData();
      var viewerObj = dataResponse.get('viewer').getData();

      this.adminIds = [];
      this.viewerId = null;
      
      if (adminsObj) {
        adminsObj.each(function(person) {
          this.adminIds.push(person.getId());
        }.bind(this));
      }

      if (viewerObj) {
        this.viewerId = viewerObj.getId();  
      }

      if (bootstrapCB) {
        bootstrapCB();
      }
    }
    
    req.send(completionFunc.bind(this));
  },

  /* Mix OS state into a URL hit we are about to make */
  buildQueryParameters: function() {
    return {
      site_id: this.params['communityId'],
      admin_ids: this.adminIds.join(','),
      viewer_id: this.viewerId,
      view: gadgets.views.getCurrentView().getName()
    };
  }
};

/* Initialize with a callback to be invoked when we're all set up */
var initializeGadget = function(cb) {
  gadgets.util.registerOnLoadHandler(function() {
    function patchExistingCode(cb) {
      var timer = setInterval(function() {
        if((typeof(theApp) != 'undefined') && (theApp != null)) {
          clearInterval(timer);

          // Wire the playlist / API code to OpenSocial
          theApp.adjustHeight = function() {
            gadgets.window.adjustHeight();
          }

          // All done
          cb();
        }
      }, 10);
    };

    patchExistingCode(function() {
      iLikeFC.theGadget = new iLikeFC.FCGadget(cb);
    });
  });
}

// Global singleton instance
iLikeFC.theGadget = null;

//----------------------------------------------------------------------------
//
// iLikeFC.FCGadget.Ajax class
//
// Logically part of our FCGadget (refers to its global singleton)
// Routes Ajax requests out through OpenSocial

//----------------------------------------------------------------------------
  
iLikeFC.FCGadget.Ajax = {
  
  FetchContent: function(url, cb, options) {
    q = iLikeFC.theGadget.buildQueryParameters();
    url += (url.indexOf("?") == -1) ? "?" : "&";
    url += $H(q).toQueryString();
    iLikeFC.FCGadget.Ajax._ilike_raw_fetch(url, cb, options);
  },
  
  _ilike_raw_fetch: function(url, cb, options) {

    // Break our URL in two
    var params = '';
    var arr = url.split('?');
    
    if (arr.length > 0) {
      params = arr[1];
    }
    
    url = arr[0];
    var p = {};

    p[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
    p[gadgets.io.RequestParameters.POST_DATA] = params;

    // Into the void...
    gadgets.io.makeRequest(url, cb, p);
  }
}

//----------------------------------------------------------------------------
//
// iLikeFC.FCGadget.Request
//
// Ajax.Request mixin / override to route to our gadget
//
//----------------------------------------------------------------------------

iLikeFC.FCGadget.Request = Class.create();

iLikeFC.FCGadget.Request.prototype = {
  initiateRequest: function(url, options, target) {
    this.options = {
      evalScripts: true,
      updateDataObjects: true,
      extractJSONData: true,
      adjustHeight: true,
      method:'get',
      maxRetry:2
    };
    Object.extend(this.options, options || {});

    this.retry = this.retry || 0;    
    this.url = url;
    this.target = target;

    // normalize the target to a hash
    if (typeof(this.target) == "string") {
      this.target = {success: this.target}
    }
    
    iLikeFC.FCGadget.Ajax.FetchContent(this.url, this.finishResponse.bind(this), this.options);
  },

  responseIsInvalid: function(response) {
    // Check to see whether a given response was valid,
    // or whether the proxy failed us and we need to
    // attempt a retry.
    //
    // This default check is naive -- it calls a blank
    // response ('') a failure.
    // 
    // TODO:
    // The OpenSocial specification really ought to
    // define the response object interface and to
    // provide us with HTTP response codes -- both
    // for within their proxy layer, and from our
    // server.
    //
    // Until that happens, however, we'll need to
    // add special cases (preferably by extending
    // this class in a synd-specifc file) to check
    // each container.
    //
    return (typeof(response) == 'undefined' ||
            response == null ||
            typeof(response.text) == 'undefined' ||
            response.text == null ||
            response.text.length == 0
           );
  },

  finishResponse: function(response) {
    if (typeof(response) == "string") {
        response = {text: response};
    }
      
    if (this.responseIsInvalid(response))
    {
        // We got back a bad response -- attempt to retry
        if (this.retry < this.options.maxRetry) {
            this.retry++;
        
            if (this.options['onRetry'])
                this.options['onRetry']({responseText:response.text});
        
            // Initiate the request again
            function tryAgain() {
                this.initiateRequest(this.url, this.options, this.target);
            }
            setTimeout(tryAgain.bind(this), 10);
        
        } else {

            // We are over our max number of retries -- error state,
            // then close out the request.
        
            if (this.options['onError'])   this.options['onError']({responseText:response.text});
            if (this.options['onFailure']) this.options['onFailure']({responseText:response.text});
            this.close();
        }
      
        return;
    }
      
    // We're OK -- run onFetch
    this.onFetch(response.text);
    
    // Now that we've finished our onFetch, attempt to do some general cleanup 
    this.close(response.text);
  },

  close: function(t) {
    if (typeof(t) == 'undefined')
      t = null;

    // Evaluate any scripts passed back to us.
    if (t && this.options['evalScripts']) {
        t.evalScripts();
    } 

    // Run our closing hook if it's been provided
    if (this.options['onClose']) this.options['onClose']();
    
    // Finally, adjust our height.
    if (this.options['adjustHeight'] != false) gadgets.window.adjustHeight;
  }
};

//----------------------------------------------------------------------------
//
// iLikeFC.Ajax.*
//
// Clones of the Prototype Ajax classes to route to our gadget
//
//----------------------------------------------------------------------------

iLikeFC.Ajax = new Object();

iLikeFC.Ajax.Request = Class.create();
iLikeFC.Ajax.Updater = Class.create();

Object.extend(iLikeFC.Ajax.Request.prototype, Ajax.Request.prototype);
Object.extend(iLikeFC.Ajax.Request.prototype, iLikeFC.FCGadget.Request.prototype);
Object.extend(iLikeFC.Ajax.Request.prototype,
  {
    initialize: function(url, options) {
      this.initiateRequest(url, options);
    },
    
    onFetch: function(responseText) {
      if (typeof(this.options["onSuccess"]) != 'undefined')
        this.options["onSuccess"]({responseText:responseText});      
    }
    
  });

Object.extend(iLikeFC.Ajax.Updater.prototype, Ajax.Updater.prototype);
Object.extend(iLikeFC.Ajax.Updater.prototype, iLikeFC.FCGadget.Request.prototype);
Object.extend(iLikeFC.Ajax.Updater.prototype,
  {
    initialize: function(target, url, options) {
      if (typeof(target)=="string") {
        target = {success: target};
      }
      this.initiateRequest(url, options, target);
    },

    onFetch: function(responseText) {
      responseText = typeof responseText == 'undefined' ? '' : responseText.toString();

      $(this.target['success']).innerHTML = responseText.stripScripts();

      if (typeof(this.options["onSuccess"]) != 'undefined')
        this.options["onSuccess"]({responseText:responseText});
    }
  });

//----------------------------------------------------------------------------
//
// CTR Tracking
//
// Forked from gadget_base.js; should be re-fused...
//
//----------------------------------------------------------------------------

function wellDefined(variable) {
  return (typeof(variable) != 'undefined' && variable != null);
}

function uncachedImageLoad(imageUrl, width, height) {
  // Assume a 1x1 pixel if not specified
  if (!wellDefined(width)) {
    width = 1;
  }

  if (!wellDefined(height)) {
    height = 1;
  }
  
  // Defeat caching
  var d = new Date();
  imageUrl += (imageUrl.indexOf('?') == -1) ? '?' : '&';
  cache_time = d.getTime();
  imageUrl += "nocache=" + cache_time;
  var i = new Image(width, height);
  i.src = imageUrl;
  i.onload = function() { tVoid(); };
}

/* meh, this seems to help some browsers */
function tVoid() { return false; }

// Build the URL of a 1x1 tracker image, redirected through the
// tracker server.
function getKeywordImageUrl(keyword) {
    // TODO: Sense development mode reliabily
    var in_dev_mode = false;

    // Distinguish testing hits
    if (in_dev_mode) {
        keyword = 'D' + keyword;
    }

    base_url = 'http://c.ilike.com/conv_click.php?u=http%3A%2F%2Fs0.ilike.com%2Fimages%2Fpixel.gif&h=0072ac51ee3ddc6b3c8951c640ebb916&i=';

    // REVIEW: hardcoded production appID for FriendConnect
    var appId = '254';

    return base_url + keyword + ',' + appId;
}

//----------------------------------------------------------------------------
//
// CTR Tracking, not from gadget_base.js
//
//----------------------------------------------------------------------------

function countCtrKeyword(keyword) {
  uncachedImageLoad(getKeywordImageUrl(keyword));
}
