--
-- Liftaxis
-- specialization for a liftaxis
--
-- Author: Sven777b (ICQ:95176001)
-- on 05-19-2010
--
-- Please respekt the work of others
-- donīt modify this script without my permission
--
-- Requirements : 
-- 1: a seperate component on Vehicle which contains the axis and wheels
-- 2: a entry in vehicle xml like this: <liftaxis compJoint="1" upperPos="0 0.6 0" lowerPos="0 0 0" movetime="5"/>  
-- 3: entries in moddesc.xml for button and helptext - ID: LIFTACHSE

Liftaxis = {};

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

function Liftaxis:load(xmlFile)
    
    self.setLiftOn = SpecializationUtil.callSpecializationsFunction("setLiftOn");
    local lai = getXMLInt(xmlFile, "vehicle.liftaxis#compJoint");
    if(self.componentJoints[lai] ~= nil) then
      self.liftAxis = {};
      self.liftAxis.compJoint = self.componentJoints[lai];

      local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.liftaxis#upperPos"));
      self.liftAxis.PosUp = {};
      self.liftAxis.PosUp[1] = Utils.getNoNil(x, 0);
      self.liftAxis.PosUp[2] = Utils.getNoNil(y, 0.5);
      self.liftAxis.PosUp[3] = Utils.getNoNil(z, 0);

      local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.liftaxis#lowerPos"));
      self.liftAxis.PosDn = {};
      self.liftAxis.PosDn[1] = Utils.getNoNil(x, 0);
      self.liftAxis.PosDn[2] = Utils.getNoNil(y, 0);
      self.liftAxis.PosDn[3] = Utils.getNoNil(z, 0);
      
      self.liftAxis.mvtime = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.liftaxis#movetime"),5) * 1000;

      self.liftAxis.lifted = true;
      self.liftAxis.lift = true;
    end;
end;

function Liftaxis:delete()
end;

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

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

function Liftaxis:update(dt)
	if self.liftAxis then
		if self:getIsActiveForInput() then
			if InputBinding.hasEvent(InputBinding.LIFTACHSE) then
				self:setLiftOn(not self.liftAxis.lift)
			end;
		end;
		if self:getIsActive() then
			if self.liftAxis.lift ~= self.liftAxis.lifted then
				local x, y, z = getTranslation(self.liftAxis.compJoint.jointNode);
				local ctrans = {x,y,z};
				local ntrans = Utils.getMovedLimitedValues(ctrans, self.liftAxis.PosUp, self.liftAxis.PosDn, 3, self.liftAxis.mvtime, dt, not self.liftAxis.lift);
				setJointFrame(self.liftAxis.compJoint.jointIndex, 0, self.liftAxis.compJoint.jointNode);
				setTranslation(self.liftAxis.compJoint.jointNode,unpack(ntrans));
				local finalpos = true;
				for i=1, 3 do
					if math.abs(ntrans[i] - ctrans[i]) > 0.001 then
						finalpos = false;
					end;
				end;
				if finalpos then
					self.liftAxis.lifted = self.liftAxis.lift;
				end;
			end;
		end;
	end;
end;

function Liftaxis:draw()
	if self:getIsActiveForInput() and self.liftAxis then
		if self.liftAxis.lift then
			g_currentMission:addHelpButtonText(g_i18n:getText("LIFTACHSE2"), InputBinding.LIFTACHSE);
		else
			g_currentMission:addHelpButtonText(g_i18n:getText("LIFTACHSE1"), InputBinding.LIFTACHSE);
		end;
		
	end;
end;

function Liftaxis:onDetach()
end;

function Liftaxis:onAttach()
end;


function Liftaxis:readStream(streamId, connection)  
  self.liftAxis.lift = streamReadBool(streamId);
  self.liftAxis.lifted = streamReadBool(streamId);
end


function Liftaxis:writeStream(streamId, connection)
    streamWriteBool(streamId, self.liftAxis.lift);
    streamWriteBool(streamId, self.liftAxis.lifted);
end    



function Liftaxis:setLiftOn(turned_on, noEventSend)
  if noEventSend ~= true then
		LiftaxisEvent.sendEvent(self, turned_on);
	end;
	self.liftAxis.lift = turned_on
end

LiftaxisEvent = {};
LiftaxisEvent_mt = Class(LiftaxisEvent, Event);

InitEventClass(LiftaxisEvent, "LiftaxisEvent");

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

function LiftaxisEvent:new(vehicle, lift)
    self.vehicle = vehicle;
    self.lift = lift
    return self;
end;

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

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

function LiftaxisEvent:run(connection)  
    self.vehicle:setLiftOn(self.lift, true);
	if not connection:getIsServer() then  
		g_server:broadcastEvent(LiftaxisEvent:new(self.vehicle, self.lift), nil, connection, self.object);
	end;
end;

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