
var util = require("util");
var events = require("events");
var net = require("net");
var tcp_conn = require("./tcp_conn");



const SATE_CLOSED = 0;
const SATE_CONNECTING = 1;
const SATE_CONNECTED = 2;


exports.TcpClient = TcpClient;

function TcpClient(){
	 events.EventEmitter.call(this);
	 this.tcp_conn_ = null;
	 this.msg_arr_ = [];
	 this.state_ = SATE_CLOSED;
	 this.socket_ = null;
}

util.inherits(TcpClient, events.EventEmitter);
TcpClient.prototype.Connect = function(ip,port){
	if( this.state_ == SATE_CLOSED ){
		this.state_ = SATE_CONNECTING;
		var socket = new net.Socket();
		var self = this;
		this.socket_ = socket;
		socket.on("error",function(err){
			self.Close();
			self.emit("openfail",err);
		})
		socket.on("connect",function(){
			socket.removeAllListeners();
			self.socket_ = null;
			self.tcp_conn_ = new tcp_conn.TcpConn(socket);
			self.state_ = SATE_CONNECTED;
			self._SendCache();
			self.emit("open");
			self.tcp_conn_.on("message",function(msg){
				self.emit("message",msg);
			})
			self.tcp_conn_.on("close",function(err){
				self.Close();
				self.emit("close",err);
			})
		})
		socket.connect(port,ip);
	}
}
TcpClient.prototype.Send = function(msg){
	if(this.state_ == SATE_CLOSED){
		return false;
	}
	if(this.tcp_conn_){
		return this.tcp_conn_.Send(msg);
	}else{
		this.msg_arr_.push(msg);
		return true;
	}
}
TcpClient.prototype._SendCache = function(){
	var arr = this.msg_arr_;
	this.msg_arr_ = [];
	for(var i=0;i<arr.length;i++){
		this.tcp_conn_.Send(arr[i]);
	}
}

TcpClient.prototype.Close = function(){
	if(this.state_ == SATE_CLOSED){
		return;
	}
	this.state_ = SATE_CLOSED;
	if(this.socket_){
		this.socket_.removeAllListeners();
		this.socket_.destroy();
		this.socket_ = null;
	}else if(this.tcp_conn_){
		this.tcp_conn_.Close();
		this.tcp_conn_.removeAllListeners();
		this.tcp_conn_ = null;
	}
}