// Generated by CoffeeScript 1.10.0
(function() {
  var TYPES, fn, key, value, zero;

  TYPES = {
    VarChar: function(length) {
      return {
        type: TYPES.VarChar,
        length: length
      };
    },
    NVarChar: function(length) {
      return {
        type: TYPES.NVarChar,
        length: length
      };
    },
    Text: function() {
      return {
        type: TYPES.Text
      };
    },
    Int: function() {
      return {
        type: TYPES.Int
      };
    },
    BigInt: function() {
      return {
        type: TYPES.BigInt
      };
    },
    TinyInt: function() {
      return {
        type: TYPES.TinyInt
      };
    },
    SmallInt: function() {
      return {
        type: TYPES.SmallInt
      };
    },
    Bit: function() {
      return {
        type: TYPES.Bit
      };
    },
    Float: function() {
      return {
        type: TYPES.Float
      };
    },
    Numeric: function(precision, scale) {
      return {
        type: TYPES.Numeric,
        precision: precision,
        scale: scale
      };
    },
    Decimal: function(precision, scale) {
      return {
        type: TYPES.Decimal,
        precision: precision,
        scale: scale
      };
    },
    Real: function() {
      return {
        type: TYPES.Real
      };
    },
    Date: function() {
      return {
        type: TYPES.Date
      };
    },
    DateTime: function() {
      return {
        type: TYPES.DateTime
      };
    },
    DateTime2: function(scale) {
      return {
        type: TYPES.DateTime2,
        scale: scale
      };
    },
    DateTimeOffset: function(scale) {
      return {
        type: TYPES.DateTimeOffset,
        scale: scale
      };
    },
    SmallDateTime: function() {
      return {
        type: TYPES.SmallDateTime
      };
    },
    Time: function(scale) {
      return {
        type: TYPES.Time,
        scale: scale
      };
    },
    UniqueIdentifier: function() {
      return {
        type: TYPES.UniqueIdentifier
      };
    },
    SmallMoney: function() {
      return {
        type: TYPES.SmallMoney
      };
    },
    Money: function() {
      return {
        type: TYPES.Money
      };
    },
    Binary: function(length) {
      return {
        type: TYPES.Binary,
        length: length
      };
    },
    VarBinary: function(length) {
      return {
        type: TYPES.VarBinary,
        length: length
      };
    },
    Image: function() {
      return {
        type: TYPES.Image
      };
    },
    Xml: function() {
      return {
        type: TYPES.Xml
      };
    },
    Char: function(length) {
      return {
        type: TYPES.Char,
        length: length
      };
    },
    NChar: function(length) {
      return {
        type: TYPES.NChar,
        length: length
      };
    },
    NText: function() {
      return {
        type: TYPES.NText
      };
    },
    TVP: function(tvpType) {
      return {
        type: TYPES.TVP,
        tvpType: tvpType
      };
    },
    UDT: function() {
      return {
        type: TYPES.UDT
      };
    },
    Geography: function() {
      return {
        type: TYPES.Geography
      };
    },
    Geometry: function() {
      return {
        type: TYPES.Geometry
      };
    },
    Variant: function() {
      return {
        type: TYPES.Variant
      };
    }
  };

  module.exports.TYPES = TYPES;

  module.exports.DECLARATIONS = {};

  fn = function(key, value) {
    return value.inspect = function() {
      return "[sql." + key + "]";
    };
  };
  for (key in TYPES) {
    value = TYPES[key];
    value.declaration = key.toLowerCase();
    module.exports.DECLARATIONS[value.declaration] = value;
    fn(key, value);
  }

  module.exports.declare = function(type, options) {
    var ref, ref1, ref2, ref3, ref4, ref5;
    switch (type) {
      case TYPES.VarChar:
      case TYPES.NVarChar:
      case TYPES.VarBinary:
        return type.declaration + " (" + (options.length > 8000 ? 'MAX' : (ref = options.length) != null ? ref : 'MAX') + ")";
      case TYPES.NVarChar:
        return type.declaration + " (" + (options.length > 4000 ? 'MAX' : (ref1 = options.length) != null ? ref1 : 'MAX') + ")";
      case TYPES.Char:
      case TYPES.NChar:
      case TYPES.Binary:
        return type.declaration + " (" + ((ref2 = options.length) != null ? ref2 : 1) + ")";
      case TYPES.Decimal:
      case TYPES.Numeric:
        return type.declaration + " (" + ((ref3 = options.precision) != null ? ref3 : 18) + ", " + ((ref4 = options.scale) != null ? ref4 : 0) + ")";
      case TYPES.Time:
      case TYPES.DateTime2:
      case TYPES.DateTimeOffset:
        return type.declaration + " (" + ((ref5 = options.scale) != null ? ref5 : 7) + ")";
      case TYPES.TVP:
        return options.tvpType + " readonly";
      default:
        return type.declaration;
    }
  };

  module.exports.cast = function(value, type, options) {
    var ns, ref, scale;
    if (value == null) {
      return null;
    }
    switch (typeof value) {
      case 'string':
        return "N'" + (value.replace(/'/g, '\'\'')) + "'";
      case 'number':
        return value;
      case 'boolean':
        if (value) {
          return 1;
        } else {
          return 0;
        }
      case 'object':
        if (value instanceof Date) {
          ns = value.getUTCMilliseconds() / 1000;
          if (value.nanosecondDelta != null) {
            ns += value.nanosecondDelta;
          }
          scale = (ref = options.scale) != null ? ref : 7;
          if (scale > 0) {
            ns = String(ns).substr(1, scale + 1);
          } else {
            ns = "";
          }
          return "N'" + (value.getUTCFullYear()) + "-" + (zero(value.getUTCMonth() + 1)) + "-" + (zero(value.getUTCDate())) + " " + (zero(value.getUTCHours())) + ":" + (zero(value.getUTCMinutes())) + ":" + (zero(value.getUTCSeconds())) + ns + "'";
        } else if (Buffer.isBuffer(value)) {
          return "0x" + (value.toString('hex'));
        } else {
          return null;
        }
        break;
      default:
        return null;
    }
  };

  zero = function(value, length) {
    var i, j, ref;
    if (length == null) {
      length = 2;
    }
    value = String(value);
    if (value.length < length) {
      for (i = j = 1, ref = length - value.length; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {
        value = "0" + value;
      }
    }
    return value;
  };

}).call(this);
