(function($) {

  /**
  * Partner object 
  **/
  var Partner = function(anchor, options) {
    var obj = this;
    obj.anchor = $(anchor);
    obj.options = options;
    obj.iframe = obj.anchor.find('iframe');
    obj.status = obj.anchor.find('.status');
    obj.action = obj.anchor.find('.action');
    obj.currentstate = obj.anchor.find('.currentstate');
    obj.radio_opt = obj.anchor.find('input[name=opt_state]');
    
    /* loading lock (yes, this is atomic) */
    obj.mutex = false;

    /* Hide iframe  */
    obj.iframe.hide();

    /* Click handler toggle for actions */
    obj.action.click(function() {
      var status = obj.getStatus();
      if(status == "cookie" || status == "nocookie") {
        obj.optout();
      } else if(status == "optedout") {
        obj.optin();
      } else {
        obj.call_partner_service('status');
      }
    });

    obj.radio_opt.click(function() {
      var status = obj.getStatus();
      if(status == "cookie" || status == "nocookie") {
        window.activity(4,obj.anchor.attr("id").slice(8));
        obj.optout();
      } else if(status == "optedout") {
        window.activity(5,obj.anchor.attr("id").slice(8));
        obj.optin();
      } else {
        obj.call_partner_service('status');
      }

    });

    /* Opt-out directly */
    obj.optout = function() {
      obj.call_partner_service("optout");
    } 

    /* Opt-in directly */
    obj.optin = function() {
      obj.call_partner_service("optin");
    }

    /* Call partner and get status */
    obj.call_partner_service = function(action) {

      /* if we're already loading, bail */
      if(!obj.mutex) { 
        obj.mutex = true;
      } else {
        return;
      }
      
      /* reset frame */
      obj.resetFrame();

      /* reset visuals of the div */
      obj.anchor.removeClass("network-error");
      obj.anchor.removeClass("network-optout");
      obj.anchor.removeClass("nocookie");

      var src = options.srcStatus;

      if(action == "optout") {
        src = options.srcOptout;
        src += obj.getToken();
      } else if(action == "optin") {
        src =  options.srcOptin;
        src += obj.getToken();
      }

      /* display loading message */ 
      obj.status.text(localisedStrings["contact_server"]);
      obj.action.text("");
      obj.action.css("cursor", "default");
      obj.anchor.fadeTo("fast", 0.33);
      obj.currentstate.text("");
      obj.currentstate.removeClass();
      obj.currentstate.addClass("currentstate-loading");
   
      /* Make call to partner server */
      obj.iframe.attr('src', src);
    
      /* Set timeout for call to partner server */ 
      setTimeout(obj.confirmLoad, 10000);
    }

    /* Partner call load timeout */
    obj.confirmLoad = function() {
      try {
        current_state = obj.getStatus();
      } catch(err) {
        current_state = false;
      }

      if(!current_state) {
        obj.iframe.attr('src', ''); 
        obj.status.html(localisedStrings["unable_to_connect"]);
        obj.action.text(localisedStrings["try_to_connect"]);
        obj.anchor.addClass("network-error");
      } else {
        obj.status.html(obj.getMessage());
        obj.action.text(obj.getAction());
      }
      obj.anchor.fadeTo("fast", 1);
      obj.action.css("cursor", "pointer");
      if (current_state == "optedout") {

        //set radio button to out
        obj.anchor.find("form input:radio").filter("[value=out]").attr('checked', true);
        obj.anchor.find("form input:radio").filter("[value=in]").attr('checked', false);
        // hilite div
        obj.anchor.addClass("network-optout");

      } else if(current_state == "nocookie" || current_state == "cookie") {
        if (current_state == "nocookie") {
          obj.anchor.addClass("nocookie");
        };
        //set radio button to in
        obj.anchor.find("form input:radio").filter("[value=out]").attr('checked', false);
        obj.anchor.find("form input:radio").filter("[value=in]").attr('checked', true);

      } else {
        obj.iframe.attr('src', '');
        obj.status.html(localisedStrings["unable_to_connect"]);
        obj.action.text(localisedStrings["try_to_connect"]);
        obj.anchor.addClass("network-error");
      }
			obj.currentstate.text(current_state);
			obj.currentstate.removeClass();
			obj.currentstate.addClass("currentstate-loaded");
      /* release lock */
      obj.mutex = false;
    }
  
    /* Action accessor */
    obj.getAction = function() {
      return localisedStrings[obj.iframe.contents().find('#action').val()];
    }

    /* Message accessor */
    obj.getMessage = function() {
      return localisedStrings[obj.iframe.contents().find('#message').val()];
    }

    /* Token accessor */
    obj.getToken = function() {
      return obj.iframe.contents().find('#token').val();
    }
    
    /* Status accessor */
    obj.getStatus = function() {
      return obj.iframe.contents().find('#status').val();
    }
    
    obj.resetFrame = function() {
      obj.iframe.contents().find('#status').val('');
    }

  };

  /**
  * loadPartner
  * Creates a Partner object and associates it with the given 
  * partner div.
  * */
  $.fn.loadPartner = function() {
    return this.each(function() {
      var obj = $(this);

      /* Build options based on HTML */
      var srcStatus = obj.children('#srcStatus').attr('href');
      var srcOptin = obj.children('#srcOptin').attr('href');
      var srcOptout = obj.children('#srcOptout').attr('href');

      var options = { srcStatus : srcStatus,
                      srcOptin : srcOptin,
                      srcOptout : srcOptout };

      /* Create and call the partner for initial status/token */
      var partner = new Partner(this, options);
      partner.call_partner_service("none");

      /* store the partner object in div */
      obj.data('partner', partner);

    });
  }

  /**
  * optout
  * Optout of this partner div by looking up the 
  * related object and opting out of that.
  * */
  $.fn.optout = function() {
    return this.each(function() {
      var obj = $(this);
      var partner = obj.data('partner');
      partner.optout();
    });
  };

    /**
  * optin
  * Optin of this partner div by looking up the
  * related object and opting out of that.
  * */
  $.fn.optin = function() {
    return this.each(function() {
      var obj = $(this);
      var partner = obj.data('partner');
      partner.optin();
    });
  };

}) (jQuery);

