
var util = require("util");
var events = require("events");
var coder = require("../coder");

exports.TcpConn = TcpConn


function TcpConn( socket ) {
    events.EventEmitter.call(this);
    socket.setNoDelay(true);
    socket.on("data",this._OnData.bind(this));
    socket.on("end",function(){
    	socket.end();
    });
    var self = this;
    socket.on("error",function(err){
    	self._OnClose(err);
    });
    socket.on("close",function(){
    	self._OnClose();
    });
    this.coder_ = new coder.Coder(this._OnMessage.bind(this));
    this.bclosed_ = false;
    this.socket_ = socket;
}

util.inherits(TcpConn, events.EventEmitter);

TcpConn.prototype._OnData = function(buf){
	this.coder_.OnData(buf);
}
TcpConn.prototype._OnMessage = function(msg){
	this.emit("message",msg);
}
TcpConn.prototype.Send = function(msg){
	if(this.bclosed_){
		return false;
	}
	var buf_writer = new coder.BufferWriter(msg.Length());
	msg.Encode(buf_writer);
	this.socket_.write(buf_writer.GetBuffer());
	return true;
}
TcpConn.prototype._OnClose = function(err){
	this.Close();
	this.emit("close",err);
}
TcpConn.prototype.Close = function(){
	if(this.bclosed_){
		return;
	}
	this.bclosed_ = true;
	if(this.socket_){
		this.socket_.removeAllListeners();
		this.socket_.end();
		var self = this;
		function cb(){
			self.socket_.destroy();
			self.socket_.removeAllListeners();
		}
		this.socket_.on("error",cb);
		this.socket_.on("close",cb);
	}
}