var child_process	= require( "child_process" );
var request			= require( "request" );
var EOF				= "\n\x1A";
var http			= require( "http" );

var lua = child_process.spawn( "lua.exe", [ "init.lua" ], {
	cwd: __dirname + "/lua"
} );

var cmdbuf = [ "> require 'autorun'" ];
var processing = false;

function QueueCommand( cmd ) {

	cmdbuf.push( cmd );

}

function ProcessCommand() {

	if ( processing )
		return;

	var cmd = cmdbuf.shift();

	if ( !cmd )
		return;

	processing = true;

	lua.stdin.write( cmd );
	lua.stdin.write( EOF );

}

setInterval( ProcessCommand, 10 );

function LuaQuote( str ) {

	return "\"" + str.replace( /.|\r|\n/gm, function( c ) {

		switch ( c ) {

			case "\"":
			case "\\":
			case "\n":
				return "\\" + c;

			case "\r":
				return "\\r";
			case "\0":
				return "\\0";

		}

		return c;

	} ) + "\"";
}

function QueueHook( event, args ) {

	var buf = [ "> hook.Call(", LuaQuote( event ) ];

	if ( args && args.length > 0 ) {


		for ( var i = 0; i < args.length; i++ ) {

			buf.push( "," );
			buf.push( LuaQuote( args[ i ] ) );

		}

	}

	buf.push( ")" );

	QueueCommand( buf.join( "" ) );

}

function Require( path ) {

	QueueCommand( "> require(" + LuaQuote( path ) + ")" );

}

setInterval( function() {

	QueueHook( "Tick" );

	QueueCommand( "> timer.Tick()" );

}, 1000 );


var buf = [];

bot.on( "Message", function( name, steamID, msg ) {

	QueueCommand( "SteamID = " + steamID );

	QueueHook( "Message", [ name, steamID, msg ] );

	QueueCommand( msg.replace( EOF, "\\n\\x1A" ) );

} );

bot.on( "UserConnected", function( name, steamID ) {
	QueueHook( "Connected", [ name, steamID ] );
} );


bot.on( "UserDisconnected", function( name, steamID ) {
	QueueHook( "Disconnected", [ name, steamID ] );
} );

lua.stdout.on( "data", function( data ) {

	//
	// Handle multiple packets in a single chunk, or less
	//

	data = data.toString();

	var datas = data.split( EOF );

	buf.push( datas[ 0 ] );

	// Loop through all of our datas, except the last (unfinished) one
	for ( var i = 0; i < datas.length - 1; i++ ) {

		// Reconstruct our string
		buf = buf.join( "" );

		// Filter out unwanted shit
		buf = buf.replace( "\0", "\\0" );
		buf = buf.replace( "\t", "    " );

		// Ignore empty packets
		if ( buf.trim().length > 0 )
			bot.sendMessage( buf );

		buf = [ datas[ i + 1 ] ];
	}

	// We've received our packet. Prepare the next command!
	if ( buf.length == 1 && buf[0].length == 0 )
		processing = false;

} );
@@ -134,21 +134,100 @@
 ttp%22 );%0A
-%0A
 var 
+lua%09%09%09%09= null;%0Avar cmdbuf%09%09%09= null;%0Avar processing%09%09= null;%0A%0Afunction Init() %7B%0A%09
 lua = ch
@@ -274,16 +274,17 @@
 a%22 %5D, %7B%0A
+%09
 %09cwd: __
@@ -304,18 +304,16 @@
 ua%22%0A
+%09
 %7D );%0A%0A
-var 
+%09
 cmdb
@@ -344,20 +344,17 @@
 un'%22 %5D;%0A
-var 
+%09
 processi
@@ -365,16 +365,19 @@
  false;%0A
+%7D%0A%0A
 %0Afunctio
@@ -2537,12 +2537,96 @@
 false;%0A%0A%7D );
+%0A%0Abot.registerCommand( %22restart%22, function() %7B%0A%0A%09lua.kill();%0A%09Init();%0A%0A%7D );%0A%0AInit();

Enable restart-ation of Lua