(function($){
  /** 
   * @class Poll
   * @constructor
   * Requests JSON data from the server at the given url at set interval.
   * @param {Object} settings Configuration object
   */   
  function Poll( settings ){  
    this.settings = 
      $.extend({        
        url:'/',            /* The url the to call. */        
        publish_to:'/poll', /* The subscriber channel to which data should be published. */       
        post_publish: null, /* A function that will be called after the poll publishes data. The published data will be passed as the first argument. */
        interval:10*1000     /* The interval at which the poller will make calls to the server. (ms) */
      }, settings); 
    
    instance = this;
  }
  
  Poll.prototype = {

    /**
     * Start polling.
     */        
    start: function(){
      this.timer = setInterval(
        $.proxy(this.fetch, this), 
        this.settings.interval
      );    
      
      /* Fetch immediately */
      this.fetch();
    },

    /**
     * Stop polling.
     */          
    stop: function(){
      this.timer && clearInterval(this.timer);    
    },

    /**
     * Retreives data from the server.
     * If the call is successfull, the data_received method is invoked
     */      
    fetch: function(){		
	  if (!this.xhr){
		  this.xhr = $.ajax({
			url: this.settings.url,
			cache:false,
			success: $.proxy(this.data_received, this),
			complete: $.proxy(this.fetch_complete, this)
		  });    
	  }
    },

    /**
     * The callback fired when a fetch is successful. Previous response data and new response data are published to the given subscriber channel.
     * @param {Object} data The response.
     */          
    data_received: function( data ){      
      $.publish(this.settings.publish_to, [this.data, data]);
      
      this.data = data;
      
	  this.xhr = null;

      this.settings.post_publish && 
        this.settings.post_publish.call(this, data);
    },

	fetch_complete: function(){

		this.xhr = null;

	}
    
  };
  
  /** 
   * Creates an instance of a Poll object.
   * TODO: Any reason we shouldn't simply expose the Poll object?
   */
  $.new_poll = function( settings ){    
    return new Poll( settings )
  };
  
})(jQuery);

