--
--	Drawbar 
--	uses an animation, defined in the .i3d of the mod
--	to lift/lower the drawbar
--
--	author:		fruktor
--	date:		09.06.2011
--	version:	0.1	- initial implementaion
--
--	Copyright (C) - www.eifok-team.de
--      _  __      _           _                       
--     (_)/ _|    | |         | |                      
--  ___ _| |_ ___ | | ________| |_ ___  __ _ _ __ ___  
-- / _ \ |  _/ _ \| |/ /______| __/ _ \/ _` | '_ ` _ \ 
--|  __/ | || (_) |   <       | ||  __/ (_| | | | | | |
-- \___|_|_| \___/|_|\_\       \__\___|\__,_|_| |_| |_|
--

Drawbar = {};

function Drawbar.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations);
end;

function Drawbar:load(xmlFile)

	self.updateTargetTime = SpecializationUtil.callSpecializationsFunction("updateTargetTime");

	self.drawbar = {};
	self.drawbar.index 		= Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.drawbar#index"));
	self.drawbar.charSet 	= getAnimCharacterSet(self.drawbar.index);
	self.drawbar.clip 		= getXMLString(xmlFile, "vehicle.drawbar#clip");
	self.drawbar.clipIdx 	= getAnimClipIndex(self.drawbar.charSet, self.drawbar.clip);	
	self.drawbar.speedScale = getXMLFloat(xmlFile, "vehicle.drawbar#speedScale");
	self.drawbar.duration 	= getAnimClipDuration(self.drawbar.charSet, self.drawbar.clipIdx);
	self.drawbar.curTime 	= getAnimTrackTime(self.drawbar.charSet, 0);
	self.drawbar.targetTime = 2500;
	self.jointmove = false;
end;

function Drawbar:delete()
end;

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

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

function Drawbar:readStream(streamId, connection)
	--self.drawbar.targetTime = streamReadFloat32(streamId);
	local curTime = streamReadFloat32(streamId);
	self.drawbar.targetTime = curTime;
	--self:updateTargetTime(curTime, true);
end;

function Drawbar:writeStream(streamId, connection)
	streamWriteFloat32(streamId, self.drawbar.targetTime);
end;

function Drawbar:update(dt)
	
	local curTime = getAnimTrackTime(self.drawbar.charSet, 0);
	self.drawbar.curTime = curTime;
	--print("self.drawbar.curTime="..self.drawbar.curTime);

	if self:getIsActiveForInput() then	
		local targetTime = nil;
		if InputBinding.isPressed(InputBinding.DRAWBAR_up) then
			targetTime = Utils.getMovedLimitedValues({self.drawbar.curTime}, {0}, {self.drawbar.duration}, 1, self.drawbar.duration, dt, false);
		elseif InputBinding.isPressed(InputBinding.DRAWBAR_down) then
			targetTime = Utils.getMovedLimitedValues({self.drawbar.curTime}, {0}, {self.drawbar.duration}, 1, self.drawbar.duration, dt, true);
		end;
		if targetTime ~= nil then
			self:updateTargetTime(targetTime[1]);
		end;
	end;
		
	self.jointmove = false;
	if math.abs(curTime - self.drawbar.targetTime) > 5 then
		if curTime < self.drawbar.targetTime then
			assignAnimTrackClip(self.drawbar.charSet, 0, self.drawbar.clipIdx, self.drawbar.clip); 
			setAnimTrackSpeedScale(self.drawbar.charSet, 0, self.drawbar.speedScale);
			enableAnimTrack(self.drawbar.charSet, 0);	
			self.jointmove = true;
		elseif curTime > self.drawbar.targetTime then
			assignAnimTrackClip(self.drawbar.charSet, 0, self.drawbar.clipIdx, self.drawbar.clip); 
			setAnimTrackSpeedScale(self.drawbar.charSet, 0, -self.drawbar.speedScale);
			enableAnimTrack(self.drawbar.charSet, 0);	
			self.jointmove = true;
		end;
	else
		--assignAnimTrackClip(self.drawbar.charSet, 0, self.drawbar.clipIdx, self.drawbar.clip); 
		setAnimTrackSpeedScale(self.drawbar.charSet, 0, 0);
		disableAnimTrack(self.drawbar.charSet, 0);		
		clearAnimTrackClip(self.drawbar.charSet, 0);
		self.jointmove = false;
	end;

	
	if self:getIsActive() then
	
		if self.isServer and self.jointmove == true then
		
		local attacherVehicle = self:getRootAttacherVehicle()
			if attacherVehicle ~= nil and self.jointmove then
				for k, implement in pairs(attacherVehicle.attachedImplements) do
					local jointDesc = attacherVehicle.attacherJoints[implement.jointDescIndex];
					if implement.object == self then
						setJointFrame(jointDesc.jointIndex, 1, self.attacherJoint.node);
					end;
				end;
			end;
			
		end;
		
	end;

end;

function Drawbar:updateTick(dt)
end;

function Drawbar:draw()	

	g_currentMission:addExtraPrintText( string.format(g_i18n:getText("DRAWBAR_up"), InputBinding.getKeyNamesOfDigitalAction(InputBinding.DRAWBAR_up) ) );
	g_currentMission:addExtraPrintText( string.format(g_i18n:getText("DRAWBAR_down"), InputBinding.getKeyNamesOfDigitalAction(InputBinding.DRAWBAR_down) ) );
end;

function Drawbar:updateTargetTime(targetTime, noEventSend)
	UpdateTargetTimeEvent.sendEvent(self, targetTime, noEventSend);
	
	self.drawbar.targetTime = targetTime;
end;


--
--
--
--
--
UpdateTargetTimeEvent = {};
UpdateTargetTimeEvent_mt = Class(UpdateTargetTimeEvent, Event);

InitEventClass(UpdateTargetTimeEvent, "UpdateTargetTimeEvent");

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

function UpdateTargetTimeEvent:new(object, value)
    local self = UpdateTargetTimeEvent:emptyNew()
    self.object = object;
	self.value = value;
    return self;
end;

function UpdateTargetTimeEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.object = networkGetObject(id);
	self.value = streamReadFloat32(streamId);
    self:run(connection);
end;

function UpdateTargetTimeEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
	streamWriteFloat32(streamId, self.value);
end;

function UpdateTargetTimeEvent:run(connection)
	self.object:updateTargetTime(self.value, true);
	if not connection:getIsServer() then
		g_server:broadcastEvent(UpdateTargetTimeEvent:new(self.object, self.value), nil, connection, self.object);
	end;
end;

function UpdateTargetTimeEvent.sendEvent(vehicle, value, noEventSend)

	if vehicle.drawbar.targetTime ~= value then
		if noEventSend == nil or noEventSend == false then
			if g_server ~= nil then
				g_server:broadcastEvent(UpdateTargetTimeEvent:new(vehicle, value), nil, nil, vehicle);
			else
				g_client:getServerConnection():sendEvent(UpdateTargetTimeEvent:new(vehicle, value));
			end;
		end;
	end;
end;