--
-- mountableStrawChopper
-- specialization for mountable straw chopper
--
-- author:	Burner
-- date: 	21.06.2013
--

mountableStrawChopper = {};

function mountableStrawChopper.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Combine, specializations);
end;

function mountableStrawChopper:load(xmlFile)
	self.mountChopper = SpecializationUtil.callSpecializationsFunction("mountChopper");
	self.activateChopper = SpecializationUtil.callSpecializationsFunction("activateChopper");

	self.chopper = {};
	local chopperNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopper#chopperNode"));
	if chopperNode ~= nil then
		self.chopper.node = chopperNode;
		setVisibility(chopperNode, false);
		
		local strawTilt = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopper#strawTiltNode"));
		if strawTilt ~= nil then
			self.chopper.strawTilt = strawTilt;
			setVisibility(strawTilt, true);
		end;
		
		local chopperAnimation = getXMLString(xmlFile, "vehicle.chopper#activationAnimation");
		if chopperAnimation ~= nil then
			self.chopper.chopperAnimation = chopperAnimation;
		end;
		
		self.chopper.activatedFromOutside = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.chopper#activatedFromOutside"), false);
		
		self.chopper.optionsNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopper#optionsNode")), self.chopper.node);
		
		self.chopperActive = false;
		self.chopperMounted = false;
	end;
end;

function mountableStrawChopper:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'chopperMounted="'.. tostring(self.chopperMounted) ..'" chopperActivated="'.. tostring(self.chopperActive) ..'"';
	return attributes, nil;
end;

function mountableStrawChopper:delete()
end;

function mountableStrawChopper:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		local chopperMounted = Utils.getNoNil(getXMLBool(xmlFile, key.."#chopperMounted"), false);
		local chopperActivated = Utils.getNoNil(getXMLBool(xmlFile, key.."#chopperActivated"), false);
		self:mountChopper(chopperMounted);
		self:activateChopper(chopperActivated);
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function mountableStrawChopper:mouseEvent(posX, posY, isDown, isUp, button)
end;

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

function mountableStrawChopper:readStream(streamId, connection)
	self:activateChopper(streamReadBool(streamId), true);
	self:mountChopper(streamReadBool(streamId), true);
end;

function mountableStrawChopper:writeStream(streamId, connection)
	streamWriteBool(streamId, self.chopperActive);
	streamWriteBool(streamId, self.chopperMounted);
end;

function mountableStrawChopper:update(dt)
	if self.isClient then
		if g_currentMission.player ~= nil then
			local nearestDistance = 2;
			local vx, vy, vz = getWorldTranslation(g_currentMission.player.rootNode);
			local px, py, pz = getWorldTranslation(self.chopper.optionsNode); 
			local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);	
			if distance < nearestDistance then
				if InputBinding.hasEvent(InputBinding.mountableStrawChopper_ChopperMount) then
					self:mountChopper(not self.chopperMounted);
				end;
				if self.chopperMounted then
					if self.chopper.activatedFromOutside then
						if InputBinding.hasEvent(InputBinding.mountableStrawChopper_ActivateChopper) then
							self:activateChopper(not self.chopperActive);
						end;
						if self.chopperActive then
							g_currentMission:addHelpButtonText(g_i18n:getText("mountableStrawChopper_DeactivateChopper"), InputBinding.mountableStrawChopper_ActivateChopper);
						else
							g_currentMission:addHelpButtonText(g_i18n:getText("mountableStrawChopper_ActivateChopper"), InputBinding.mountableStrawChopper_ActivateChopper);
						end;
					end;
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("mountableStrawChopper_ChopperUnmount")), InputBinding.mountableStrawChopper_ChopperMount);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("mountableStrawChopper_ChopperMount")), InputBinding.mountableStrawChopper_ChopperMount);
				end;
			end;
		end;
	end;
	
	if self:getIsActiveForInput(false) and self.chopperMounted and not self.chopper.activatedFromOutside then
		if InputBinding.hasEvent(InputBinding.mountableStrawChopper_ActivateChopper) then
			self:activateChopper(not self.chopperActive);
		end;
	end;

	if self.chopperActive then
		self.strawEmitState = false;
		self.strawEnableTime = nil;
		self.chopperActivated = true;
									
		if self.lastArea > 0 then
			if self.chopperActivated then
				if self.chopperEnableTime == nil then
					self.chopperEnableTime = self.time + self.chopperToggleTime;
				else
					self.chopperDisableTime = nil;
				end;
				disableChopperEmit = false;
			end;
			
			if self.chopperEnableTime ~= nil and self.chopperEnableTime <= self.time then
				self:setChopperPSEnabled(true, false, false);
				self:setStrawPSEnabled(false, false, false);
			end;
		end;	
	else
		if self.chopperMounted and self.lastArea > 0 then
			if self.chopperActivated == true and self.chopperActive == false then
				self:activateChopper(true);
			end;
		end;
    end;
end;

function mountableStrawChopper:updateTick(dt)   
end;

function mountableStrawChopper:draw()
	if self.chopperMounted and not self.chopper.activatedFromOutside then
		if self.chopperActive then
			g_currentMission:addHelpButtonText(g_i18n:getText("mountableStrawChopper_DeactivateChopper"), InputBinding.mountableStrawChopper_ActivateChopper);
		else
			g_currentMission:addHelpButtonText(g_i18n:getText("mountableStrawChopper_ActivateChopper"), InputBinding.mountableStrawChopper_ActivateChopper);
		end;
	end;
end;

function mountableStrawChopper:onEnter()
end;

function mountableStrawChopper:onLeave()
end;

function mountableStrawChopper:activateChopper(isActive, noEventSend)
	if isActive ~= self.chopperActive then
		ActivateChopperEvent.sendEvent(self, isActive, noEventSend);
		self.chopperActive = isActive;
		if isActive then
			if self.chopper.chopperAnimation ~= nil and self.playAnimation ~= nil then
				self:playAnimation(self.chopper.chopperAnimation, -1, nil, true);
			end;
		else
			if self.chopper.chopperAnimation ~= nil and self.playAnimation ~= nil then
				self:playAnimation(self.chopper.chopperAnimation, 1, nil, true);
			end;
		end;
	end;
end;

function mountableStrawChopper:mountChopper(chopperMounted, noEventSend)
	MountChopperEvent.sendEvent(self, chopperMounted, noEventSend);
	self.chopperMounted = chopperMounted;
	if self.chopper.strawTilt ~= nil then
		setVisibility(self.chopper.strawTilt, not chopperMounted);
	end;
	if self.chopper.node ~= nil then
		setVisibility(self.chopper.node, chopperMounted);
	end;
	if chopperMounted == false then
		self:activateChopper(false);
	end;
end;

function mountableStrawChopper:onLeave()
	self:setChopperPSEnabled(false, false, false);
	self:setStrawPSEnabled(false, false, false);
end;

MountChopperEvent = {};
MountChopperEvent_mt = Class(MountChopperEvent, Event);

InitEventClass(MountChopperEvent, "MountChopperEvent");

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

function MountChopperEvent:new(vehicle, chopperMountState)
    local self = MountChopperEvent:emptyNew()
    self.vehicle = vehicle;
	self.chopperMountState = chopperMountState;
    return self;
end;

function MountChopperEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.chopperMountState = streamReadBool(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function MountChopperEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.chopperMountState);
end;

function MountChopperEvent:run(connection)   
	self.vehicle:mountChopper(self.chopperMountState, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(MountChopperEvent:new(self.vehicle, self.chopperMountState), nil, connection, self.vehicle);
    end;
end;

function MountChopperEvent.sendEvent(vehicle, chopperMountState, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(MountChopperEvent:new(vehicle, chopperMountState), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(MountChopperEvent:new(vehicle, chopperMountState));
		end;
	end;
end;

ActivateChopperEvent = {};
ActivateChopperEvent_mt = Class(ActivateChopperEvent, Event);

InitEventClass(ActivateChopperEvent, "ActivateChopperEvent");

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

function ActivateChopperEvent:new(vehicle, chopperState)
    local self = ActivateChopperEvent:emptyNew()
    self.vehicle = vehicle;
	self.chopperState = chopperState;
    return self;
end;

function ActivateChopperEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.chopperState = streamReadBool(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function ActivateChopperEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.chopperState);
end;

function ActivateChopperEvent:run(connection)   
	self.vehicle:activateChopper(self.chopperState, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(ActivateChopperEvent:new(self.vehicle, self.chopperState), nil, connection, self.vehicle);
    end;
end;

function ActivateChopperEvent.sendEvent(vehicle, chopperState, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(ActivateChopperEvent:new(vehicle, chopperState), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(ActivateChopperEvent:new(vehicle, chopperState));
		end;
	end;
end;