$.extend($s,{
  ajax:{
  
    init: function() {
      //alert("initialized ajax"); 
    },
    
    lastTransaction: 0,
    
    generateTransactionId: function() {
      return ++this.lastTransaction;
    },
    
    getGallery: function(callback) {      
      //fire off the async request
      var tx = this.generateTransactionId();
      var url = $s.urls.getGalleryUrl(tx);
      $s.scroller.addMessage(tx, "Loading gallery from " + url);
      this.doPost({
        id: tx,
        url: url,
        scrollerId: tx,
        onSuccess: callback,
        onError: function(errors){
          alert(errors);
        }
      });
    },

    getDrawing: function(drawingId, callback) {
      //fire off the async request
      var tx = this.generateTransactionId();
      $s.scroller.addMessage(tx, "Loading drawing");
      var url = $s.urls.getDrawingUrl(tx);
      this.doPost({
        id: tx,
        url: url,
        scrollerId: tx,
        params: {'id':drawingId},
        onSuccess: callback,
        onError: function(errors){
          alert(errors);
        }
      });
    },    

    saveDrawing: function(drawingId, data, callback) {
      //fire off the async request
      var tx = this.generateTransactionId();
      $s.scroller.addMessage(tx, "Saving drawing");
      var url = $s.urls.saveDrawingUrl(tx);
      this.doPost({
        id: tx,
        url: url,
        scrollerId: tx,
        params: {'id':drawingId,'data':data},
        onSuccess: callback,
        onError: function(errors){
          alert(errors);
        }
      });
    },
    
    saveDrawingJson: function(drawingId, json, callback) {
      //fire off the async request
      var tx = this.generateTransactionId();
      $s.scroller.addMessage(tx, "Saving drawing");
      var url = $s.urls.saveDrawingUrl(tx);
      this.doPost({
        id: tx,
        url: url,
        scrollerId: tx,
        params: {'id':drawingId,'json':json},
        onSuccess: callback,
        onError: function(errors){
          alert(errors);
        }
      });
    },
    
    getDownloads: function(callback) {
      //fire off the async request
      var tx = this.generateTransactionId();
      $s.scroller.addMessage(tx, "Loading downloads");
      var url = $s.urls.getDownloadsUrl(tx);
      this.doPost({
        id: tx,
        url: url,
        params: {},
        scrollerId: tx,
        onSuccess: callback,
        onError: function(errors){
          alert(errors);
        }
      });
    },
    
    getSettings: function(callback) {
      //fire off the async request
      var tx = this.generateTransactionId();
      $s.scroller.addMessage(tx, "Loading settings");
      var url = $s.urls.getSettingsUrl(tx);
      this.doPost({
        id: tx,
        url: url,
        scrollerId: tx,
        params: {},
        onSuccess: callback,
        onError: function(errors){
          alert(errors);
        }
      });
    },
    
    saveSettings: function(params, callback) {
      //fire off the async request
      var tx = this.generateTransactionId();
      $s.scroller.addMessage(tx, "Saving settings");
      var url = $s.urls.saveSettingsUrl(tx);
      this.doPost({
        id: tx,
        url: url,
        params: params,
        scrollerId: tx,
        onSuccess: callback,
        onError: function(errors){
          alert(errors);
        }
      });
    },
    
    doPost: function(params) {
      if(!params.hasOwnProperty('id')) {
        alert("doPost requires a transaction id");
        return;
      }
      
      if(!params.hasOwnProperty('onSuccess')){
        params.onSuccess = function(data){};
      }
    
      if(!params.hasOwnProperty('onError')){
        params.onError = function(errors){};
      }
      
      if(!params.hasOwnProperty('beforeSend')) {
        params.beforeSend = function(id){};
      }
      
      if(!params.hasOwnProperty('params')) {
        params.params = {};
      }
      
      if(!params.hasOwnProperty('callback')) {
        params.callback = function(){};
      }
      
      if(params.hasOwnProperty('scrollerId')) {
        var currentSuccess = params.onSuccess;
        var currentError = params.onError;
        params.onSuccess = function(data){$s.scroller.removeMessage(params.scrollerId);currentSuccess(data);};
        params.onError = function(errors){$s.scroller.removeMessage(params.scrollerId);currentError(errors);};
      }
      
      //force this to run asynchronously
      $s.scroller.addMessage("post", "requesting " + params.url, "okay");
      if(!$s.TESTING) {
        document.location.href = params.url;
	return;
      }
      setTimeout(function(){
        $.ajax({
          type: "POST",
          url: params.url,
          data: $s.urls.qs(params.params),
          beforeSend: function(){
            $s.comet.addCallback(params.id, function(data){
              var errors = $s.comet.getErrors(data);
              if(errors != null && errors.length > 0) {
                params.onError(errors);
              }else{
                params.onSuccess(data);
              }
            });
            params.beforeSend();
          },
          success: function(data){
            //alert(data);
            try{
              data = JSON.parse(data);
            }catch(err){
              alert(data);
            }
            if($s.TESTING) {
              $s.comet.addMessage(params.id, data.data);
            }
          },  
          error: function(request, status, error){
            if($s.TESTING) {
              alert("error calling " + params.url);
            }
          }
        });
        
      //run it 1 second from now
      },1);     
    }

  }
});
