datablock StaticShapeData(LuaLogic_RobotShapeData) {
	shapeFile = $LuaLogic::Path @ "bricks/special/cube.dts";
};

datablock fxDTSBrickData(LogicGate_RobotController_Data) {
	brickFile = $LuaLogic::Path @ "bricks/blb/RobotController.blb";
	category = "Logic Bricks";
	subCategory = "Special";
	uiName = "Robot Controller";
	iconName = $LuaLogic::Path @ "icons/Robot Controller";
	hasPrint = 1;
	printAspectRatio = "Logic";
	orientationFix = 3;
	
	isLogic = true;
	isLogicGate = true;
	//isLogicInput = true;
	
	logicInit   = lualogic_readfile($LuaLogic::Path @ "bricks/special/robot-init.lua"  );
	logicUpdate = lualogic_readfile($LuaLogic::Path @ "bricks/special/robot-update.lua");
	logicInput  = lualogic_readfile($LuaLogic::Path @ "bricks/special/robot-input.lua" );
	
	logicUIName = "Robot Controller";
	logicUIDesc = "Creates and controls a mobile robot that can detect and place bricks";
	
	numLogicPorts = 22;
	
	logicPortType[0] = 1;
	logicPortPos[0] = "15 -3 0";
	logicPortDir[0] = 3;
	logicPortUIName[0] = "ColorIn0";
	
	logicPortType[1] = 1;
	logicPortPos[1] = "13 -3 0";
	logicPortDir[1] = 3;
	logicPortUIName[1] = "ColorIn1";
	
	logicPortType[2] = 1;
	logicPortPos[2] = "11 -3 0";
	logicPortDir[2] = 3;
	logicPortUIName[2] = "ColorIn2";
	
	logicPortType[3] = 1;
	logicPortPos[3] = "9 -3 0";
	logicPortDir[3] = 3;
	logicPortUIName[3] = "ColorIn3";
	
	logicPortType[4] = 1;
	logicPortPos[4] = "7 -3 0";
	logicPortDir[4] = 3;
	logicPortUIName[4] = "ColorIn4";
	
	logicPortType[5] = 1;
	logicPortPos[5] = "5 -3 0";
	logicPortDir[5] = 3;
	logicPortUIName[5] = "ColorIn5";
	
	logicPortType[6] = 1;
	logicPortPos[6] = "1 -3 0";
	logicPortDir[6] = 3;
	logicPortUIName[6] = "Destroy Brick";
	logicPortCauseUpdate[6] = true;
	
	logicPortType[7] = 1;
	logicPortPos[7] = "-1 -3 0";
	logicPortDir[7] = 3;
	logicPortUIName[7] = "Plant Brick";
	logicPortCauseUpdate[7] = true;
	
	logicPortType[8] = 1;
	logicPortPos[8] = "-5 -3 0";
	logicPortDir[8] = 3;
	logicPortUIName[8] = "Move Down";
	logicPortCauseUpdate[8] = true;
	
	logicPortType[9] = 1;
	logicPortPos[9] = "-7 -3 0";
	logicPortDir[9] = 3;
	logicPortUIName[9] = "Move Up";
	logicPortCauseUpdate[9] = true;
	
	logicPortType[10] = 1;
	logicPortPos[10] = "-9 -3 0";
	logicPortDir[10] = 3;
	logicPortUIName[10] = "Move Right";
	logicPortCauseUpdate[10] = true;
	
	logicPortType[11] = 1;
	logicPortPos[11] = "-11 -3 0";
	logicPortDir[11] = 3;
	logicPortUIName[11] = "Move Left";
	logicPortCauseUpdate[11] = true;
	
	logicPortType[12] = 1;
	logicPortPos[12] = "-13 -3 0";
	logicPortDir[12] = 3;
	logicPortUIName[12] = "Move Backward";
	logicPortCauseUpdate[12] = true;
	
	logicPortType[13] = 1;
	logicPortPos[13] = "-15 -3 0";
	logicPortDir[13] = 3;
	logicPortUIName[13] = "Move Forward";
	logicPortCauseUpdate[13] = true;
	
	logicPortType[14] = 0;
	logicPortPos[14] = "15 3 0";
	logicPortDir[14] = 1;
	logicPortUIName[14] = "ColorOut0";
	
	logicPortType[15] = 0;
	logicPortPos[15] = "13 3 0";
	logicPortDir[15] = 1;
	logicPortUIName[15] = "ColorOut1";
	
	logicPortType[16] = 0;
	logicPortPos[16] = "11 3 0";
	logicPortDir[16] = 1;
	logicPortUIName[16] = "ColorOut2";
	
	logicPortType[17] = 0;
	logicPortPos[17] = "9 3 0";
	logicPortDir[17] = 1;
	logicPortUIName[17] = "ColorOut3";
	
	logicPortType[18] = 0;
	logicPortPos[18] = "7 3 0";
	logicPortDir[18] = 1;
	logicPortUIName[18] = "ColorOut4";
	
	logicPortType[19] = 0;
	logicPortPos[19] = "5 3 0";
	logicPortDir[19] = 1;
	logicPortUIName[19] = "ColorOut5";
	
	logicPortType[20] = 0;
	logicPortPos[20] = "1 3 0";
	logicPortDir[20] = 1;
	logicPortUIName[20] = "Brick Detected";
	
	logicPortType[21] = 1;
	logicPortPos[21] = "-1 3 0";
	logicPortDir[21] = 1;
	logicPortUIName[21] = "Detect Brick";
	logicPortCauseUpdate[21] = true;
};

function LogicGate_RobotController_Data::LuaLogic_Callback(%this, %brick, %data) {
	%robot = %brick.luaLogicRobot;
	if(!isObject(%robot)) { talk("brick " @ %brick @ " has no robot!"); return; }
	%pos = %robot.getPosition();
	
	initContainerBoxSearch(%pos, "0.49 0.49 0.19", $TypeMasks::FxBrickAlwaysObjectType);
	%tbrick = containerSearchNext();
	
	%output = "";
	
	for(%i=0; %i<getFieldCount(%data); %i++) {
		%field = getField(%data, %i);
		%first = getWord(%field, 0);
		
		if(%first $= "D") { // remove / detect brick
			if(isObject(%tbrick)) {
				%field = "B" @ 1 SPC
					%tbrick.getColorId() SPC
					%tbrick.getColorFxID() SPC
					%tbrick.getShapeFxId() SPC
					%tbrick.isRaycasting() SPC
					%tbrick.isColliding() SPC
					%tbrick.isRendering();
				%output = %output @ %field @ "\t";
			} else {
				%output = %output @ "B 0 0 0 0 0 0 0\t";
			}
		} else if(%first $= "R") {
			if(isObject(%tbrick)) {
				%tbrick.schedule(0, delete);
			}
		} else if(%first $= "P") { // plant brick
			LogicRobot_CreateBrickGroup();
			
			if(!isObject(%tbrick)) {
				%nbrick = new fxDTSBrick() {
					datablock = brick1x1fData;
					position = %pos;
					colorId   = getWord(%field, 1);
					colorFxId = getWord(%field, 2);
					shapeFxId = getWord(%field, 3);
					isPlanted = 1;
				};
				%nbrick.setTransform(%pos SPC "0 0 1 0");
				
				%err = %nbrick.plant();
				if(%err != 0 && %err != 2 && %err != 3) {
					%nbrick.delete();
				} else {
					%nbrick.setRaycasting(getWord(%field, 4));
					%nbrick.setColliding (getWord(%field, 5));
					%nbrick.setRendering (getWord(%field, 6));
					
					BrickGroup_12345678.add(%nbrick);
					%nbrick.setTrusted(1);
				}
			}
		} else if(%first $= "M") { // move
			%pos = getWords(%field, 1, 3);
			%rot = getWord(%field, 4);
			%robot.setTransform(%pos SPC "0 0 1" SPC (%rot*$pi/2));
		} else {
			talk("invalid robot callback " @ %field);
		}
	}
	
	lualogic_sendinput(%brick, 1, trim(%output));
}

function LogicGate_RobotController_Data::getRelativeVector(%this, %obj, %vec) {
	%rot = %obj.angleID;
	%x = getWord(%vec, 0); %y = getWord(%vec, 1); %z = getWord(%vec, 2);
	%ax = %x;
	switch(%rot) {
		case 1: %x =  %y; %y = -%ax;
		case 2: %x = -%x; %y = -%y ;
		case 3: %x = -%y; %y =  %ax;
	}
	return %x SPC %y SPC %z;
}

function LogicRobot_CreateBrickGroup() {
	if(!isObject(BrickGroup_12345678)) {
		new SimGroup(BrickGroup_12345678) {
			bl_id = 12345678;
			name = "\c1Robot";
			QuotaObject = GlobalQuota;
		};
		mainBrickGroup.add(BrickGroup_12345678);
	}
}

function LogicGate_RobotController_Data::createRobot(%this, %obj) {
	if(isObject(%obj.luaLogicRobot)) return;
	
	%pos = %obj.getPosition();
	%rpos = vectorAdd(%pos, %this.getRelativeVector(%obj, "0.25 7.75 0"));
	%robot = new StaticShape() {
		datablock = LuaLogic_RobotShapeData;
		position = %rpos;
	};
	%robot.setScale("1 1 1");
	%robot.setNodeColor("ALL", "1 1 1 1");
	missionCleanup.add(%robot);
	
	%obj.luaLogicRobot = %robot;
}

function LogicGate_RobotController_Data::Logic_onRemove(%this, %obj) {
	if(isObject(%obj.luaLogicRobot))
		%obj.luaLogicRobot.delete();
}

function LogicGate_RobotController_Data::Logic_onPlant(%this, %obj) {
	if(!isObject(%obj.luaLogicRobot))
		%this.createRobot(%obj);
}

function LogicGate_RobotController_Data::Logic_onAdd(%this, %obj) {
	if(!isObject(%obj.luaLogicRobot)) %this.createRobot(%obj);
	
	lualogic_sendinput(%obj, 1, "P" @ %obj.luaLogicRobot.getPosition() SPC %obj.getAngleId());
}