// Generated by CoffeeScript 1.7.1
var EventEmitter, Request, RequestError, TYPES,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

EventEmitter = require('events').EventEmitter;

TYPES = require('./data-type').typeByName;

RequestError = require('./errors').RequestError;

Request = (function(_super) {
  __extends(Request, _super);

  Request.prototype.error = null;

  Request.prototype.canceled = false;

  function Request(sqlTextOrProcedure, callback) {
    this.sqlTextOrProcedure = sqlTextOrProcedure;
    this.callback = callback;
    this.parameters = [];
    this.parametersByName = {};
    this.userCallback = this.callback;
    this.callback = function() {
      if (this.preparing) {
        this.emit('prepared');
        return this.preparing = false;
      } else {
        this.userCallback.apply(this, arguments);
        return this.emit('requestCompleted');
      }
    };
  }

  Request.prototype.addParameter = function(name, type, value, options) {
    var parameter;
    if (options == null) {
      options = {};
    }
    parameter = {
      type: type,
      name: name,
      value: value,
      output: options.output || (options.output = false),
      length: options.length,
      precision: options.precision,
      scale: options.scale
    };
    this.parameters.push(parameter);
    return this.parametersByName[name] = parameter;
  };

  Request.prototype.addOutputParameter = function(name, type, value, options) {
    if (options == null) {
      options = {};
    }
    options.output = true;
    return this.addParameter(name, type, value, options);
  };

  Request.prototype.makeParamsParameter = function(parameters) {
    var parameter, paramsParameter, _i, _len;
    paramsParameter = '';
    for (_i = 0, _len = parameters.length; _i < _len; _i++) {
      parameter = parameters[_i];
      if (paramsParameter.length > 0) {
        paramsParameter += ', ';
      }
      paramsParameter += "@" + parameter.name + " ";
      paramsParameter += parameter.type.declaration(parameter);
      if (parameter.output) {
        paramsParameter += ' OUTPUT';
      }
    }
    return paramsParameter;
  };

  Request.prototype.transformIntoExecuteSqlRpc = function() {
    var parameter, _i, _len, _ref;
    this.originalParameters = this.parameters;
    this.parameters = [];
    this.addParameter('statement', TYPES.NVarChar, this.sqlTextOrProcedure);
    if (this.originalParameters.length) {
      this.addParameter('params', TYPES.NVarChar, this.makeParamsParameter(this.originalParameters));
    }
    _ref = this.originalParameters;
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      parameter = _ref[_i];
      this.parameters.push(parameter);
    }
    return this.sqlTextOrProcedure = 'sp_executesql';
  };

  Request.prototype.transformIntoPrepareRpc = function() {
    this.originalParameters = this.parameters;
    this.parameters = [];
    this.addOutputParameter('handle', TYPES.Int);
    this.addParameter('params', TYPES.NVarChar, this.makeParamsParameter(this.originalParameters));
    this.addParameter('stmt', TYPES.NVarChar, this.sqlTextOrProcedure);
    this.sqlTextOrProcedure = 'sp_prepare';
    this.preparing = true;
    return this.on('returnValue', (function(_this) {
      return function(name, value, metadata) {
        if (name === 'handle') {
          return _this.handle = value;
        } else {
          return _this.error = RequestError("Tedious > Unexpected output parameter " + name + " from sp_prepare");
        }
      };
    })(this));
  };

  Request.prototype.transformIntoUnprepareRpc = function(parameters) {
    this.parameters = [];
    this.addParameter('handle', TYPES.Int, this.handle);
    return this.sqlTextOrProcedure = 'sp_unprepare';
  };

  Request.prototype.transformIntoExecuteRpc = function(parameters) {
    var parameter, _i, _len, _ref;
    this.parameters = [];
    this.addParameter('handle', TYPES.Int, this.handle);
    _ref = this.originalParameters;
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      parameter = _ref[_i];
      parameter.value = parameters[parameter.name];
      this.parameters.push(parameter);
    }
    return this.sqlTextOrProcedure = 'sp_execute';
  };

  return Request;

})(EventEmitter);

module.exports = Request;
