--
-- BuyableAloeConsole
-- Specialization for buyable Aloe console
--
-- @author  Stefan Maurus	
-- @date  2015-02-28

-- Copyright © Stefan Maurus, www.stefanmaurus.de

BuyableAloeConsole = {};

function BuyableAloeConsole.prerequisitesPresent(specializations)
	return true;
end;

function BuyableAloeConsole:load(xmlFile)
	self.onAloeConsoleTrigger = BuyableAloeConsole.onAloeConsoleTrigger;	
	self.setConsoleAttributes = SpecializationUtil.callSpecializationsFunction("setConsoleAttributes"); 
	
	self.aloeConsole = {};
	self.aloeConsole.trigger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#trigger"));
	addTrigger(self.aloeConsole.trigger, "onAloeConsoleTrigger", self);
	self.aloeConsole.inRange = false;
	
	self.aloeConsole.inTrigger = {};
	self.aloeConsole.PlayerinTrigger = false;
	self.aloeConsole.nearestDistanceToView = 3; --m
	
	self.aloeConsole.detachNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#detachNode"));
	self.aloeConsole.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#index"));
	self.aloeConsole.indexDetached = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#indexDetached"));
	setVisibility(self.aloeConsole.index, false);
	setVisibility(self.aloeConsole.indexDetached, true);		
	self.aloeConsole.attacherJoint = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#attacherJoint"));
	self.aloeConsole.LCS = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#LCS"));
	setVisibility(self.aloeConsole.LCS, false);	

	self.aloeConsole.helpMesh = {};
	self.aloeConsole.helpMesh[1] = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#small"));
	self.aloeConsole.helpMesh[2] = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aloeConsole#big"));	
	for i, v in ipairs(self.aloeConsole.helpMesh) do
		setVisibility(v, false);	
	end;
	
	self.consoleAttachedTo = -1;
	self.consoleAttachedSelf = nil;
	
	self.consolePositionY = 1.3;
	self.consolePositionZ = 1;
	self.consolePositionR = 0;
	
	self.lcsPositionX = -0.5;
	self.lcsPositionY = 0.5;
	self.lcsPositionZ = -1.3;
	self.lcsPositionR = 0;	
	
	self.controlsHUD = {};
	local width, height = getNormalizedScreenValues(256, 256);
	self.controlsHUD.xPos = 1-width;
	self.controlsHUD.yPos = 0.4;
	self.controlsHUD.overlay_console = Overlay:new("controls_console", Utils.getFilename("sources/HUD/controls_console.dds", self.baseDirectory), self.controlsHUD.xPos, self.controlsHUD.yPos, width, height);
	self.controlsHUD.overlay_lcs = Overlay:new("controls_lcs", Utils.getFilename("sources/HUD/controls_lcs.dds", self.baseDirectory), self.controlsHUD.xPos, self.controlsHUD.yPos, width, height);
	self.controlsHUD.helpText = "";
	 
	local fw = width/3;
	local fh = height/3;
	
	self.controlButtons = {{x=self.controlsHUD.xPos,	y=self.controlsHUD.yPos,		x1=self.controlsHUD.xPos+fw,	y1=self.controlsHUD.yPos+fh},
						{x=self.controlsHUD.xPos+fw,	y=self.controlsHUD.yPos,		x1=self.controlsHUD.xPos+fw*2,	y1=self.controlsHUD.yPos+fh},
						{x=self.controlsHUD.xPos+fw*2,	y=self.controlsHUD.yPos,		x1=self.controlsHUD.xPos+fw*3,	y1=self.controlsHUD.yPos+fh},
						{x=self.controlsHUD.xPos,		y=self.controlsHUD.yPos+fh,		x1=self.controlsHUD.xPos+fw,	y1=self.controlsHUD.yPos+fh*2},
						{x=self.controlsHUD.xPos+fw,	y=self.controlsHUD.yPos+fh,		x1=self.controlsHUD.xPos+fw*2,	y1=self.controlsHUD.yPos+fh*2},
						{x=self.controlsHUD.xPos+fw*2,	y=self.controlsHUD.yPos+fh,		x1=self.controlsHUD.xPos+fw*3,	y1=self.controlsHUD.yPos+fh*2},
						{x=self.controlsHUD.xPos,		y=self.controlsHUD.yPos+fh*2,	x1=self.controlsHUD.xPos+fw,	y1=self.controlsHUD.yPos+fh*3},
						{x=self.controlsHUD.xPos+fw,	y=self.controlsHUD.yPos+fh*2,	x1=self.controlsHUD.xPos+fw*2,	y1=self.controlsHUD.yPos+fh*3},
						{x=self.controlsHUD.xPos+fw*2,	y=self.controlsHUD.yPos+fh*2,	x1=self.controlsHUD.xPos+fw*3,	y1=self.controlsHUD.yPos+fh*3}};
	
	self.consoleID = 0;
	for i = 1, table.getn(g_currentMission.vehicles) do
		if g_currentMission.vehicles[i].configFileName == self.configFileName then
			self.consoleID = g_currentMission.vehicles[i].consoleID + 1;
		end;
	end;
	
	self.attachConsoleAfterLoading = false;
end;

--function BuyableAloeConsole:preDelete()	
--end;

function BuyableAloeConsole:delete()
	removeTrigger(self.aloeConsole.trigger);

	if self.consoleAttachedSelf ~= nil then
		self.consoleAttachedSelf:detachConsole(true);
	end;
end;

function BuyableAloeConsole:mouseEvent(posX, posY, isDown, isUp, button)
	if self.consoleAttachedSelf ~= nil then
		for i = 1, table.getn(self.controlButtons) do
			if posX > self.controlButtons[i].x and posX < self.controlButtons[i].x1 and posY > self.controlButtons[i].y and posY < self.controlButtons[i].y1 then
				if not self.consoleAttachedSelf.consolePositionated and (i==4 or i==6 or i==7 or i==9) then
					self.controlsHUD.helpText = "";
				else
					self.controlsHUD.helpText = g_i18n:getText("CONSOLE_CONTROL_"..i);
				end;
			end;
		end;
	end;
end;

function BuyableAloeConsole:keyEvent(unicode, sym, modifier, isDown)
end;

function BuyableAloeConsole:readStream(streamId, connection)
	self:setConsoleAttributes(streamReadFloat32(streamId), streamReadFloat32(streamId), streamReadFloat32(streamId), streamReadFloat32(streamId), streamReadFloat32(streamId), streamReadFloat32(streamId), streamReadFloat32(streamId), true);

	self.consoleAttachedTo = streamReadInt32(streamId);
	if self.consoleAttachedTo > -1 then
		self.attachConsoleAfterLoading = true;
	end;
end;

function BuyableAloeConsole:writeStream(streamId, connection) 
	streamWriteFloat32(streamId, self.consolePositionY); 
	streamWriteFloat32(streamId, self.consolePositionZ); 
	streamWriteFloat32(streamId, self.consolePositionR); 
	streamWriteFloat32(streamId, self.lcsPositionX); 
	streamWriteFloat32(streamId, self.lcsPositionY);
	streamWriteFloat32(streamId, self.lcsPositionZ); 
	streamWriteFloat32(streamId, self.lcsPositionR); 
	streamWriteInt32(streamId, self.consoleAttachedTo); 		
end;

function BuyableAloeConsole:setConsoleAttributes(y, z, r, x1, y1, z1, n, noEventSend)
	if y ~= nil and z ~= nil and r~= nil then -- set console position
		self.consolePositionY = y;
		self.consolePositionZ = z;
		setTranslation(self.aloeConsole.index, 0, y, z);
		self.consolePositionR = r;
		setRotation(self.aloeConsole.index, 0, math.rad(r), 0)
	end;
	if x1 ~= nil and y1 ~= nil and z1 ~= nil and n ~= nil then -- set lcs position
		self.lcsPositionX = x1;
		self.lcsPositionY = y1;
		self.lcsPositionZ = z1;
		self.lcsPositionR = n;	
		setTranslation(self.aloeConsole.LCS, x1, y1, z1);
		setRotation(self.aloeConsole.LCS, 0, math.rad(n), 0);
		local vis = true;
		if self.consoleAttachedSelf ~= nil then
		 vis = self.consoleAttachedSelf.consoleInstalled;
		end;
		setVisibility(self.aloeConsole.LCS, vis);
	end;
	SetConsoleAttributesEvent.sendEvent(self, y, z, r, x1, y1, z1, n, noEventSend);	
end;

function BuyableAloeConsole:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	local y, z, r = Utils.getVectorFromString(getXMLString(xmlFile, key.."#consolePos"));

	if y ~= nil then
		self.consolePositionY = y;
		self.consolePositionZ = z;
		self.consolePositionR = r;
	end;
	
	local x, y, z, n = Utils.getVectorFromString(getXMLString(xmlFile, key.."#lcsPos"));

	if x ~= nil then
		self.lcsPositionX = x;
		self.lcsPositionY = y;
		self.lcsPositionZ = z;
		self.lcsPositionR = n;		
	end;

	if not resetVehicles then 
		self.consoleAttachedTo = Utils.getNoNil(getXMLFloat(xmlFile, key.."#attachedto"),-1);
		if self.consoleAttachedTo > -1 then
			self.attachConsoleAfterLoading = true;
		end;
	end;
	
	return BaseMission.VEHICLE_LOAD_OK;
end;

function BuyableAloeConsole:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'consoleID="'..self.consoleID..'" attachedto="'..self.consoleAttachedTo..'" consolePos="'..self.consolePositionY..' '..self.consolePositionZ..' '..self.consolePositionR..'" lcsPos="'..self.lcsPositionX..' '..self.lcsPositionY..' '..self.lcsPositionZ..' '..self.lcsPositionR..'"';
	return attributes, nil;
end;

function BuyableAloeConsole:update(dt)
	for i=1, table.getn(self.aloeConsole.inTrigger) do
		local tractor = self.aloeConsole.inTrigger[i];
		if tractor ~= nil and tractor.consoleID == nil and tractor.consoleInstalled then
			tractor.consoleID = self;
			tractor.consoleID2 = self.consoleID;
			tractor.readyToInstallConsole = false;
			tractor.readyToUninstallConsole = true;
			self.consoleAttachedTo = tractor.tractorID;
			self.consoleAttachedSelf = tractor;
		end;	
		
		if tractor:getIsActiveForInput(false) and tractor.consoleID == nil then
			local allowsAttaching = true;
			for i = 1, table.getn(tractor.attacherJoints) do
				if tractor.attacherJoints[i].jointType == Vehicle.jointTypeNameToInt["attachableFrontloader"] then
					allowsAttaching = false;
				end;
			end;
			
			if tractor.readyToInstallConsole and allowsAttaching then
				g_currentMission:addHelpButtonText(g_i18n:getText("CONSOLE_ATTACH"), InputBinding.IMPLEMENT_EXTRA2);
			end;
		end;
		
		if tractor:getIsActiveForInput(false) and tractor.consoleID == self then
			if tractor.consoleAttachMode then
				local loader = "-/-";
				if getVisibility(self.aloeConsole.helpMesh[1]) then
					loader = "Q56 & +4.1p";
				end;
				if getVisibility(self.aloeConsole.helpMesh[2]) then
					loader = "Q88 & +7.3p";
				end;	
				
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("SHOW_FRONTLOADER_DUMMYS"), loader), InputBinding.IMPLEMENT_EXTRA);
			end;
			
			if tractor.consoleAttachMode and not tractor.consolePositionated then
				g_currentMission:addExtraPrintText(g_i18n:getText("CONSOLE_POSITIONATE_CONSOLE"));
				g_currentMission:addHelpButtonText(g_i18n:getText("CONSOLE_ROTATE180"), InputBinding.CONSOLE_ROTATE180);
			elseif tractor.consoleAttachMode and tractor.consolePositionated then
				g_currentMission:addExtraPrintText(g_i18n:getText("CONSOLE_POSITIONATE_LCS"));
			end;
			
			if tractor.readyToUninstallConsole and not tractor.consoleAttachMode and tractor.consoleID ~= nil then
				local allowsDetaching = false;
				for i, v in ipairs(tractor.attacherJoints) do
					if v.jointType == Vehicle.jointTypeNameToInt["attachableFrontloader"] then
						if v.jointIndex == 0 then
							allowsDetaching = true;
						end;
					end;
				end;
				
				if not allowsDetaching then
					g_currentMission:addExtraPrintText(g_i18n:getText("CONSOLE_DETACHFRONTLOADER"));
				else 
					g_currentMission:addHelpButtonText(g_i18n:getText("CONSOLE_DETACH"), InputBinding.CONSOLE_DETACH);
				end;
			end;
			
			local currentAction = "";
			
			if tractor.consoleAttachMode and not tractor.consolePositionated then
				currentAction = g_i18n:getText("CONSOLE_POSITIONATE_CONSOLE");
			elseif tractor.consoleAttachMode and tractor.consolePositionated then
				currentAction = g_i18n:getText("CONSOLE_POSITIONATE_LCS");
			end;
			
			if tractor.consoleAttachMode then
				g_currentMission:addExtraPrintText(g_i18n:getText("CONSOLE_VISABLEMOUSE"));
				
				local headline = g_i18n:getText("CONSOLE_VISABLEMOUSE");
				local width = getTextWidth(0.02, headline);
				renderText(0.5-width/2, 0.85, 0.02, headline);
				
				local headline = g_i18n:getText("CONSOLE_POSITIONATE_MODE");
				local width = getTextWidth(0.03, headline);
				renderText(0.5-width/2, 0.9, 0.03, headline);
				
				local width = getTextWidth(0.02, currentAction);
				renderText(0.5-width/2, 0.81, 0.02, currentAction);	
			end;
		end;
	end;
end;

function BuyableAloeConsole:updateTick(dt)
	if self.attachConsoleAfterLoading then
		if self.consoleAttachedSelf == nil then
			for i, v in pairs(g_currentMission.vehicles) do
				if v.tractorID ~= nil then
					if v.tractorID == self.consoleAttachedTo then
						v:attachConsole(self, true);
					end;
				end;
			end;
		end;
		self.attachConsoleAfterLoading = false;
	end;
end;

function BuyableAloeConsole:draw()
end;

function BuyableAloeConsole:onAttach(attacherVehicle)	
end;

function BuyableAloeConsole:onDetach()
end

function BuyableAloeConsole:onAloeConsoleTrigger(triggerId, otherId, onEnter, onLeave, onStay)
	if onEnter or onLeave then
		local tractor = g_currentMission.nodeToVehicle[otherId];		
		if tractor ~= nil then
			if tractor.readyToInstallConsole ~= nil then
				if self.consoleAttachedTo == -1 or self.consoleAttachedTo == tractor.tractorID then
					if onEnter then
						local add = true;
						for i=1, table.getn(self.aloeConsole.inTrigger) do
							if self.aloeConsole.inTrigger[i] == tractor then
								add = false;
							end;
						end;
						if add then
							table.insert(self.aloeConsole.inTrigger, tractor);
							if tractor.consoleID == nil then
								tractor.readyToInstallConsole = true;
							elseif tractor.consoleID == self then
								tractor.readyToUninstallConsole = true;
							end;
						end;
					else
						for i=1, table.getn(self.aloeConsole.inTrigger) do
							if tractor == self.aloeConsole.inTrigger[i] then
								tractor.readyToInstallConsole = false;
								tractor.readyToUninstallConsole = false; 
								table.remove(self.aloeConsole.inTrigger, i);						
								break;
							end;
						end;
					end;
				end;
			end;
		end;
	end;
end;

SetConsoleAttributesEvent = {};
SetConsoleAttributesEvent_mt = Class(SetConsoleAttributesEvent, Event);

InitEventClass(SetConsoleAttributesEvent, "SetConsoleAttributesEvent");

function SetConsoleAttributesEvent:emptyNew()
    local self = Event:new(SetConsoleAttributesEvent_mt);
    self.className="SetConsoleAttributesEvent";
    return self;
end;

function SetConsoleAttributesEvent:new(vehicle, y, z, r, x1, y1, z1, n)
    local self = SetConsoleAttributesEvent:emptyNew()
    self.vehicle = vehicle;
	self.y = y;
	self.z = z;
	self.r = r;
	self.x1 = x1;
	self.y1 = y1;
	self.z1 = z1;	
	self.n = n;	
    return self;
end;

function SetConsoleAttributesEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.y = streamReadFloat32(streamId);
	self.z = streamReadFloat32(streamId);
	self.r = streamReadFloat32(streamId);
	self.x1 = streamReadFloat32(streamId);
	self.y1 = streamReadFloat32(streamId);
	self.z1 = streamReadFloat32(streamId);	
	self.n = streamReadFloat32(streamId);	
	
	if self.vehicle ~= nil then
		self.vehicle:setConsoleAttributes(self.y, self.z, self.r, self.x1, self.y1, self.z1, self.n, true);
	end;
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetConsoleAttributesEvent:new(self.vehicle, self.y, self.r, self.z, self.x1, self.y1, self.z1, self.n), nil, connection, self.vehicle);
    end;
end;

function SetConsoleAttributesEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteFloat32(streamId, self.y); 
	streamWriteFloat32(streamId, self.z); 
	streamWriteFloat32(streamId, self.r); 
	streamWriteFloat32(streamId, self.x1); 
	streamWriteFloat32(streamId, self.y1);
 	streamWriteFloat32(streamId, self.z1); 
 	streamWriteFloat32(streamId, self.n); 		
end;

function SetConsoleAttributesEvent.sendEvent(vehicle, y, z, r, x1, y1, z1, n, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetConsoleAttributesEvent:new(vehicle, y, z, r, x1, y1, z1, n), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetConsoleAttributesEvent:new(vehicle, y, z, r, x1, y1, z1, n));
		end;
	end;
end;