
(function(){
  // applegate.datatable ======================================================

  YAHOO.namespace("applegate.dwr");

  var global = YAHOO.applegate.global,
    dwr = YAHOO.applegate.dwr,
    lang = YAHOO.lang;

  // DwrDataSource ============================================================

  /**
   * DwrDataSource class.
   * Use to back YAHOO DataTable widgets with data from a Dwr Object.
   * @param method ServiceBean.methodName - note no
   * @param args
   */
  dwr.DwrDataSource = function(method, args, cfg){

    dwr.DwrDataSource.superclass.constructor.call(this,[], {});

    this._dwrCfg = lang.merge({
      // insert defaults here
      displayField:null,
      transformer:function(v){return v;},
      appendRequest:false,
      mergeRequest:false
    },cfg || {}); // no defaults yet

    // forces the parseArrayData to be called in handleResponse
    //    this.responseType = YAHOO.util.DataSource.TYPE_JSARRAY ;
    this._dwrMethod = method ;
    this._dwrArgs = args;
    this.responseSchema = this._dwrCfg.fields ? {fields:this._dwrCfg.fields} : {};
    this.responseType = this.TYPE_DWR;

    this.createEvent("dwrArgumentsChangedEvent");
  };
  //noinspection JSUnusedLocalSymbols
  YAHOO.lang.extend(dwr.DwrDataSource, YAHOO.util.DataSourceBase, {

    /**
     * Custom DataType to force the DataSourceBase class to fall through to
     * it's default response handling code in parseData.
     */
    TYPE_DWR: 999,

    /* override  makeConnection in YAHOO.util.DataSource */
    makeConnection : function( oRequest , oCallback , oCaller ) {
      YAHOO.log("DwrDataSource.makeConnection request:" + oRequest + " oCallback:" + oCallback + " oCaller:" + oCaller,"debug", "global-dwr.js");
      // from the super.makeConnection()
      this.fireEvent("requestEvent", {request:oRequest,callback:oCallback,caller:oCaller});
      var tId = YAHOO.util.DataSource._nTransactionId++;

      var args ;
      if( this._dwrCfg.mergeRequest !== true){
        // copy the args... and add the last parameter as the dwr options block
        var args = global.copyArray(this._dwrArgs);
        if (this._dwrCfg.appendRequest){
          if( lang.isString(oRequest))
            args.push(decodeURIComponent(oRequest));
          else
            args.push(oRequest);
        }
      }else{
        // start with a array with a single empty object at element 0
        args = [{}];
        // merge the parameters... will only work if the parameters are objects
        global.forEach(this._dwrArgs,function(a){
          args[0] = lang.merge(args[0], a);
        });
        // merge the oRequest on top
        args[0] = lang.merge(args[0], oRequest);
      }
      var oSelf = this;
      args.push({
        callback:function(response){
          global.forEach(response, function(v) {
//            oSelf.updateDisplayValue(v);
            return oSelf._dwrCfg.transformer(v);
          });
          oSelf.handleResponse(oRequest, response, oCallback, oCaller, tId);
        }
      });
      // run the request, for a description of apply():
      // see http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function/apply)
      this._dwrMethod.apply(this, args);
    },

    /**
     * Changes the underlying dataSource argument(s)
     */
    setDwrArguments : function(){
      this._dwrArgs = global.copyArray(arguments) ;
      this.fireEvent("dwrArgumentsChangedEvent", {source:this,arguments:this._dwrArgs});
      return this;
    },

    updateDisplayValue : function(item){
      // YUI AutoComplete expects the displayValue to be in position[0]
      var dv = this.formatDisplayValue(item);
      if( dv ){
        item[0] = dv ;
      }
    },

    formatDisplayValue : function(item){
      return item[this._dwrCfg['displayField']];
    },

    /**
     * Overridden method that parses the response into a response object.
     * Since the Dwr responses are well formed arrays of fields, we can simply
     * return the oFullResponse as the results.
     *
     * @method parseData
     * @param oRequest {Object} Request object.
     * @param oFullResponse {Object} The full Array from the live database.
     * @return {Object} Parsed response object with the following properties:<br>
     *     - results (Array) Array of parsed data results<br>
     *     - error (Boolean) True if there was an error
     */
    parseData : function(oRequest, oFullResponse){
      if( lang.isArray(oFullResponse) )
        return {results:global.toArray(oFullResponse)};
      if( lang.isArray(oFullResponse.list) ){
        var meta = {};
        global.forEach(oFullResponse, function(v,k){ if (k !== "list"){ meta[k] = v } });
        return {
          results:global.toArray(oFullResponse.list),
          meta: meta
        };
      }
      // empty
      return {results:[]};
    }
  });

  // ~DwrDataSource ===========================================================

})();