// Generated by CoffeeScript 1.7.0
var ReqlAuthError, ReqlAvailabilityError, ReqlCompileError, ReqlDriverCompileError, ReqlDriverError, ReqlError, ReqlInternalError, ReqlNonExistenceError, ReqlOpFailedError, ReqlOpIndeterminateError, ReqlQueryLogicError, ReqlQueryPrinter, ReqlResourceLimitError, ReqlRuntimeError, ReqlServerCompileError, ReqlTimeoutError, ReqlUserError,
  __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; };

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

  function ReqlError(msg) {
    this.name = this.constructor.name;
    this.msg = msg;
    this.message = msg;
    if (Error.captureStackTrace != null) {
      Error.captureStackTrace(this, this);
    }
  }

  return ReqlError;

})(Error);

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

  function ReqlCompileError() {
    return ReqlCompileError.__super__.constructor.apply(this, arguments);
  }

  return ReqlCompileError;

})(ReqlError);

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

  function ReqlDriverCompileError() {
    return ReqlDriverCompileError.__super__.constructor.apply(this, arguments);
  }

  return ReqlDriverCompileError;

})(ReqlCompileError);

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

  function ReqlServerCompileError() {
    return ReqlServerCompileError.__super__.constructor.apply(this, arguments);
  }

  return ReqlServerCompileError;

})(ReqlCompileError);

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

  function ReqlDriverError() {
    return ReqlDriverError.__super__.constructor.apply(this, arguments);
  }

  return ReqlDriverError;

})(ReqlError);

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

  function ReqlAuthError() {
    return ReqlAuthError.__super__.constructor.apply(this, arguments);
  }

  return ReqlAuthError;

})(ReqlDriverError);

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

  function ReqlRuntimeError(msg, term, frames) {
    this.name = this.constructor.name;
    this.msg = msg;
    this.frames = frames.slice(0);
    if (term != null) {
      if (msg[msg.length - 1] === '.') {
        this.message = "" + (msg.slice(0, msg.length - 1)) + " in:\n" + (ReqlQueryPrinter.prototype.printQuery(term)) + "\n" + (ReqlQueryPrinter.prototype.printCarrots(term, frames));
      } else {
        this.message = "" + msg + " in:\n" + (ReqlQueryPrinter.prototype.printQuery(term)) + "\n" + (ReqlQueryPrinter.prototype.printCarrots(term, frames));
      }
    } else {
      this.message = "" + msg;
    }
    if (Error.captureStackTrace != null) {
      Error.captureStackTrace(this, this);
    }
  }

  return ReqlRuntimeError;

})(ReqlError);

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

  function ReqlQueryLogicError() {
    return ReqlQueryLogicError.__super__.constructor.apply(this, arguments);
  }

  return ReqlQueryLogicError;

})(ReqlRuntimeError);

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

  function ReqlNonExistenceError() {
    return ReqlNonExistenceError.__super__.constructor.apply(this, arguments);
  }

  return ReqlNonExistenceError;

})(ReqlQueryLogicError);

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

  function ReqlResourceLimitError() {
    return ReqlResourceLimitError.__super__.constructor.apply(this, arguments);
  }

  return ReqlResourceLimitError;

})(ReqlRuntimeError);

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

  function ReqlUserError() {
    return ReqlUserError.__super__.constructor.apply(this, arguments);
  }

  return ReqlUserError;

})(ReqlRuntimeError);

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

  function ReqlInternalError() {
    return ReqlInternalError.__super__.constructor.apply(this, arguments);
  }

  return ReqlInternalError;

})(ReqlRuntimeError);

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

  function ReqlTimeoutError() {
    return ReqlTimeoutError.__super__.constructor.apply(this, arguments);
  }

  return ReqlTimeoutError;

})(ReqlError);

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

  function ReqlAvailabilityError() {
    return ReqlAvailabilityError.__super__.constructor.apply(this, arguments);
  }

  return ReqlAvailabilityError;

})(ReqlRuntimeError);

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

  function ReqlOpFailedError() {
    return ReqlOpFailedError.__super__.constructor.apply(this, arguments);
  }

  return ReqlOpFailedError;

})(ReqlAvailabilityError);

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

  function ReqlOpIndeterminateError() {
    return ReqlOpIndeterminateError.__super__.constructor.apply(this, arguments);
  }

  return ReqlOpIndeterminateError;

})(ReqlAvailabilityError);

ReqlQueryPrinter = (function() {
  var carrotMarker, carrotify, composeCarrots, composeTerm, joinTree;

  function ReqlQueryPrinter() {}

  ReqlQueryPrinter.prototype.printQuery = function(term) {
    var tree;
    tree = composeTerm(term);
    return joinTree(tree);
  };

  composeTerm = function(term) {
    var arg, args, key, optargs, _ref;
    args = (function() {
      var _i, _len, _ref, _results;
      _ref = term.args;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        arg = _ref[_i];
        _results.push(composeTerm(arg));
      }
      return _results;
    })();
    optargs = {};
    _ref = term.optargs;
    for (key in _ref) {
      if (!__hasProp.call(_ref, key)) continue;
      arg = _ref[key];
      optargs[key] = composeTerm(arg);
    }
    return term.compose(args, optargs);
  };

  ReqlQueryPrinter.prototype.printCarrots = function(term, frames) {
    var tree;
    if (frames.length === 0) {
      tree = [carrotify(composeTerm(term))];
    } else {
      tree = composeCarrots(term, frames);
    }
    return (joinTree(tree)).replace(/[^\^]/g, ' ');
  };

  composeCarrots = function(term, frames) {
    var arg, args, frame, i, key, optargs, _ref;
    frame = frames.shift();
    args = (function() {
      var _i, _len, _ref, _results;
      _ref = term.args;
      _results = [];
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        arg = _ref[i];
        if (frame === i) {
          _results.push(composeCarrots(arg, frames));
        } else {
          _results.push(composeTerm(arg));
        }
      }
      return _results;
    })();
    optargs = {};
    _ref = term.optargs;
    for (key in _ref) {
      if (!__hasProp.call(_ref, key)) continue;
      arg = _ref[key];
      if (frame === key) {
        optargs[key] = composeCarrots(arg, frames);
      } else {
        optargs[key] = composeTerm(arg);
      }
    }
    if (frame != null) {
      return term.compose(args, optargs);
    } else {
      return carrotify(term.compose(args, optargs));
    }
  };

  carrotMarker = {};

  carrotify = function(tree) {
    return [carrotMarker, tree];
  };

  joinTree = function(tree) {
    var str, term, _i, _len;
    str = '';
    for (_i = 0, _len = tree.length; _i < _len; _i++) {
      term = tree[_i];
      if (Array.isArray(term)) {
        if (term.length === 2 && term[0] === carrotMarker) {
          str += (joinTree(term[1])).replace(/./g, '^');
        } else {
          str += joinTree(term);
        }
      } else {
        str += term;
      }
    }
    return str;
  };

  return ReqlQueryPrinter;

})();

module.exports = {
  ReqlError: ReqlError,
  ReqlCompileError: ReqlCompileError,
  RqlCompileError: ReqlCompileError,
  ReqlServerCompileError: ReqlServerCompileError,
  ReqlDriverCompileError: ReqlDriverCompileError,
  RqlClientError: ReqlDriverError,
  ReqlRuntimeError: ReqlRuntimeError,
  RqlRuntimeError: ReqlRuntimeError,
  RqlServerError: ReqlRuntimeError,
  ReqlQueryLogicError: ReqlQueryLogicError,
  ReqlNonExistenceError: ReqlNonExistenceError,
  ReqlResourceLimitError: ReqlResourceLimitError,
  ReqlUserError: ReqlUserError,
  ReqlInternalError: ReqlInternalError,
  ReqlTimeoutError: ReqlTimeoutError,
  ReqlAvailabilityError: ReqlAvailabilityError,
  ReqlOpFailedError: ReqlOpFailedError,
  ReqlOpIndeterminateError: ReqlOpIndeterminateError,
  ReqlDriverError: ReqlDriverError,
  RqlDriverError: ReqlDriverError,
  ReqlAuthError: ReqlAuthError,
  printQuery: ReqlQueryPrinter.prototype.printQuery
};
