--
-- hydraulic
-- 
--
--
-- @author:		fruktor 
-- @version:	v0.1
-- @date:		18/02/10
-- @history:	v0.1 - inital implementation
--
-- Copyright (C) 
--

Hydraulic = {};

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

function Hydraulic:load(xmlFile)
	self.hydraulic = {};
	--### load the hydraulic system
	local i=0;
	self.hydraulic.cylinder = {};
	while true do
		local girl = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinder(%d)#girl",i)) );
		if girl == nil then
			break;
		end;
		local boy = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinder(%d)#boy",i)) );
		local ref = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinder(%d)#ref",i)) );
		local target = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinder(%d)#target",i)) );
		
		local entry = {};
		entry.girl = girl;
		entry.boy = boy;
		entry.ref = ref;
		entry.target = target;
		local x1, y1, z1 = getWorldTranslation(boy);
		local x2, y2, z2 = getWorldTranslation(ref);
		entry.length2 = Utils.vector3Length(x1-x2, y1-y2, z1-z2);
		
		i=i+1;
		table.insert(self.hydraulic.cylinder, entry);
	end;
	
	--
	i=0;
	self.hydraulic.cylinders = {};
	while true do
		local girl = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinders(%d)#girl",i)) );
		if girl == nil then
			break;
		end;
		local boys = {};
		local refs = {};
		local lengths = {};
		local j=1;
		while true do 
			local boy = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinders(%d)#boy%d",i,j)) );
			local ref = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinders(%d)#ref%d",i,j)) );
			if boy == nil or ref == nil then 
				break;
			end;
			table.insert(boys, boy);
			table.insert(refs, ref);
			local x1, y1, z1 = getWorldTranslation(boy);
			local x2, y2, z2 = getWorldTranslation(ref);			
			local length = Utils.vector3Length(x1-x2, y1-y2, z1-z2);
			table.insert(lengths, length);
			j=j+1;
		end;
		local targetString = getXMLString(xmlFile, string.format("vehicle.hydraulic.cylinders(%d)#target",i,j))
		local target;
		local targetIsTrailer = false;
		if string.match(targetString, "trailer") then
			targetIsTrailer = true;
		else
			target = Utils.indexToObject( self.components, targetString );
		end;
		
		local entry = {};
		entry.girl = girl;
		entry.boys = boys;
		entry.boysCnt = table.getn(boys);
		entry.refs = refs;
		entry.lengths = lengths; 
		entry.target = target;
		entry.targetIsTrailer = targetIsTrailer;
		
		i=i+1;
		table.insert(self.hydraulic.cylinders, entry);
	end;
	
end;	
	
function Hydraulic:delete()
end;

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

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

function Hydraulic:update(dt)
end;

function Hydraulic:updateTick(dt)
	--#### update hydraulics --------------------------------------------------
	if self.hydraulic.cylinder ~= nil then
		for i, cylinder in pairs(self.hydraulic.cylinder) do
			local ax, ay, az = getWorldTranslation(cylinder.girl);
			local bx, by, bz = getWorldTranslation(cylinder.target);
			local x, y, z = worldDirectionToLocal(getParent(cylinder.girl), bx-ax, by-ay, bz-az);
			
			local upX, upY, upZ = 0,1,0;
			if math.abs(y) > 0.99*Utils.vector3Length(x, y, z) then
				-- direction and up is parallel
				upY = 0;
				if y > 0 then
					upZ = 1;
				else
					upZ = -1;
				end;
			end;
			
			setDirection(cylinder.girl, x, y, z, upX, upY, upZ);
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(cylinder.boy, 0, 0, distance - cylinder.length2);			
		end;
	end;
	--
	if self.hydraulic.cylinders ~= nil then 
		for i, cylinders in pairs(self.hydraulic.cylinders) do
		
			if cylinders.targetIsTrailer == false or
				(cylinders.targetIsTrailer == true and cylinders.target ~= nil) 
				then
		
				local ax, ay, az = getWorldTranslation(cylinders.girl);
				local bx, by, bz = getWorldTranslation(cylinders.target);
				local x, y, z = worldDirectionToLocal(getParent(cylinders.girl), bx-ax, by-ay, bz-az);
				
				local upX, upY, upZ = 0,1,0;
				if math.abs(y) > 0.99*Utils.vector3Length(x, y, z) then
					-- direction and up is parallel
					upY = 0;
					if y > 0 then
						upZ = 1;
					else
						upZ = -1;
					end;
				end;
				
				setDirection(cylinders.girl, x, y, z, upX, upY, upZ);
				local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
				for i, j in pairs(cylinders.boys) do
					if i==1 then
						setTranslation(j, 0, 0, distance/cylinders.boysCnt - cylinders.lengths[i]);			
					else
						setTranslation(j, 0, 0, distance/cylinders.boysCnt);			
					end;
				end;
				
			end;
		end;	
	end;
end;

function Hydraulic:draw()	
end;

function Hydraulic:onAttach(attacherVehicle)
end;

function Hydraulic:onDetach()
end;

function Hydraulic:onLeave()
end;

function Hydraulic:onDeactivate()
end;

function Hydraulic:onDeactivateSounds()
end;

function Hydraulic:attachImplement(object, jointIndex)
	if object.object.varioMulde ~= nil then
		for i, cylinders in pairs(self.hydraulic.cylinders) do
			if cylinders.targetIsTrailer == true then
				cylinders.target = object.object.varioMulde.cylRef;
				break;
			end;
		end;
	end;
	--[[
	print(tostring(object).." "..tostring(jointIndex));
	for i,j in pairs(object) do
		print(tostring(i).." "..tostring(j));
	end;
	print("....");
	for i,j in pairs(object.object.varioMulde) do
		print(tostring(i).." "..tostring(j));
	end;
	print("....");	]]--
end;

function Hydraulic:detachImplement()
	for i, cylinders in pairs(self.hydraulic.cylinders) do
		if cylinders.targetIsTrailer == true then
			cylinders.target = nil;
			break;
		end;
	end;
end;