// Generated by CoffeeScript 1.7.1
var EventEmitter, MessageIO, Packet, TYPE, isPacketComplete, packetHeaderLength, packetLength,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  __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; };

require('./buffertools');

EventEmitter = require('events').EventEmitter;

isPacketComplete = require('./packet').isPacketComplete;

packetLength = require('./packet').packetLength;

packetHeaderLength = require('./packet').HEADER_LENGTH;

Packet = require('./packet').Packet;

TYPE = require('./packet').TYPE;

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

  function MessageIO(socket, _packetSize, debug) {
    this.socket = socket;
    this._packetSize = _packetSize;
    this.debug = debug;
    this.sendPacket = __bind(this.sendPacket, this);
    this.eventData = __bind(this.eventData, this);
    this.socket.addListener('data', this.eventData);
    this.packetDataSize = this._packetSize - packetHeaderLength;
    this.packetBuffer = new Buffer(0);
    this.payloadBuffer = new Buffer(0);
  }

  MessageIO.prototype.eventData = function(data) {
    var endOfMessage, length, packet, packetsData;
    if (this.packetBuffer.length > 0) {
      this.packetBuffer = Buffer.concat([this.packetBuffer, data]);
    } else {
      this.packetBuffer = data;
    }
    packetsData = [];
    endOfMessage = false;
    while (isPacketComplete(this.packetBuffer)) {
      length = packetLength(this.packetBuffer);
      packet = new Packet(this.packetBuffer.slice(0, length));
      this.logPacket('Received', packet);
      packetsData.push(packet.data());
      if (packet.isLast()) {
        endOfMessage = true;
      }
      this.packetBuffer = this.packetBuffer.slice(length);
    }
    if (packetsData.length > 0) {
      this.emit('data', Buffer.concat(packetsData));
      if (endOfMessage) {
        return this.emit('message');
      }
    }
  };

  MessageIO.prototype.packetSize = function(packetSize) {
    if (arguments.length > 0) {
      this.debug.log("Packet size changed from " + this._packetSize + " to " + packetSize);
      this._packetSize = packetSize;
      this.packetDataSize = this._packetSize - packetHeaderLength;
    }
    return this._packetSize;
  };

  MessageIO.prototype.tlsNegotiationStarting = function(securePair) {
    this.securePair = securePair;
    return this.tlsNegotiationInProgress = true;
  };

  MessageIO.prototype.encryptAllFutureTraffic = function() {
    this.socket.removeAllListeners('data');
    this.securePair.encrypted.removeAllListeners('data');
    this.socket.pipe(this.securePair.encrypted);
    this.securePair.encrypted.pipe(this.socket);
    this.securePair.cleartext.addListener('data', this.eventData);
    return this.tlsNegotiationInProgress = false;
  };

  MessageIO.prototype.sendMessage = function(packetType, data, resetConnection) {
    var numberOfPackets, packet, packetNumber, packetPayload, payloadEnd, payloadStart, _i, _ref, _results;
    if (data) {
      numberOfPackets = (Math.floor((data.length - 1) / this.packetDataSize)) + 1;
    } else {
      numberOfPackets = 1;
      data = new Buffer(0);
    }
    _results = [];
    for (packetNumber = _i = 0, _ref = numberOfPackets - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; packetNumber = 0 <= _ref ? ++_i : --_i) {
      payloadStart = packetNumber * this.packetDataSize;
      if (packetNumber < numberOfPackets - 1) {
        payloadEnd = payloadStart + this.packetDataSize;
      } else {
        payloadEnd = data.length;
      }
      packetPayload = data.slice(payloadStart, payloadEnd);
      packet = new Packet(packetType);
      packet.last(packetNumber === numberOfPackets - 1);
      packet.resetConnection(resetConnection);
      packet.packetId(packetNumber + 1);
      packet.addData(packetPayload);
      _results.push(this.sendPacket(packet, packetType));
    }
    return _results;
  };

  MessageIO.prototype.sendPacket = function(packet, packetType) {
    this.logPacket('Sent', packet);
    if (this.tlsNegotiationInProgress && packetType !== TYPE.PRELOGIN) {
      return this.securePair.cleartext.write(packet.buffer);
    } else {
      if (this.securePair && !this.tlsNegotiationInProgress) {
        return this.securePair.cleartext.write(packet.buffer);
      } else {
        return this.socket.write(packet.buffer);
      }
    }
  };

  MessageIO.prototype.logPacket = function(direction, packet) {
    this.debug.packet(direction, packet);
    return this.debug.data(packet);
  };

  return MessageIO;

})(EventEmitter);

module.exports = MessageIO;
