--[[
	Author: Martin Fabík
	version: 2.71
	Date: 5.8.2016 (10:27)
	free for non-comerecial use
	Do not change this file without my permission
	Author contact: mar.fabik@gmail.com
	
	How to install showFillLevel:
	1. Insert tag 
		<specialization name="showFillLevel" className="showFillLevel" filename="scripts/showFillLevel.lua"/>
	between <specializations> and </specializations>
	
	2. Insert tag
		<specialization name="showFillLevel" />
	into your vehicle type
	
	3. Now in mod.xml file you can use fillowing tag with several types 
	<fillLevelDetections>	
		<fillLevelDetection type="scaleDetection" startPercent="0" endPercent="100" minScale="1 5 1" maxScale="1 100 1" index="0>1|10|14"/>
		<fillLevelDetection type="transDetection" startPercent="0" endPercent="100" minTrans="0.091 3.25 4" maxTrans="0.091 3.65 4" index="0>1|10|15"/>
		<fillLevelDetection type="rotatDetection" startPercent="0" endPercent="100" minRotat="0 180 0" maxRotat="0 180 180" index="0>1|10|16"/>
		<fillLevelDetection type="visibility" startPercent="0" endPercent="50" index="0>1|10|17"/>
		<fillLevelDetection type="stepsDetection" startPercent="0" endPercent="100" steps="1">
			<step1 index="0>1|10|11|2|5|124"/>
		</fillLevelDetection>
		<fillLevelDetection type="displayNum" precision="0" index="0>6" displayType="1" color="-200 -200 -200"/>
	</fillLevelDetections>
	
	Description for global attributes
	attribute 'startPercent' - define when current type starts work. (In visibility type defined start of visibility)
	attribute 'endPercent'  - define when current type end work. (In visibility type defined start of hiding object)
	attribute 'index' - index of object
	attribute 'type' - defin type of animation/action
	!!! stepsDetection = you must define how much steps will be used,
	then script set visibility fo each element by fill percent (step1 is 0% stepMAX is 100%)
]]--

showFillLevel = {};

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

function showFillLevel:load(xmlFile)
	self.lcp = {};
	local i = 0;
	self.lcp.stepsDetection = {};
	self.lcp.scaleDetection = {};
	self.lcp.transDetection = {};
	self.lcp.rotatDetection = {};
	self.lcp.visibility = {};
	self.lcp.displayNum = {};
	self.lcp.animations = {};
	self.lcp.vehicleType = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.fillLevelDetections#vehicleType"), 0);
	while true do
		local key = string.format("vehicle.fillLevelDetections.fillLevelDetection(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		-- allowed types:
		--   stepsDetection
		--   scaleDetection
		--   transDetection
		--   rotatDetection
		--   visibility
		--   displayNum
		local typeDetector = getXMLString(xmlFile, key.."#type");
		if typeDetector ~= nil then
			if typeDetector == "stepsDetection" then
				local numSteps = getXMLInt(xmlFile, key.."#steps");
				local startPercent = getXMLFloat(xmlFile, key.."#startPercent");
				local endPercent = getXMLFloat(xmlFile, key.."#endPercent");
				if numSteps ~= nil and startPercent ~= nil and endPercent ~= nil then
					local oldGetn = table.getn(self.lcp.stepsDetection)+1;
					self.lcp.stepsDetection[oldGetn] = {};
					self.lcp.stepsDetection[oldGetn].detector = {};
					for k=1, numSteps do
						self.lcp.stepsDetection[oldGetn].detector[k] = Utils.indexToObject(self.components, getXMLString(xmlFile,string.format(key..".step%d#index",k)));
						setVisibility(self.lcp.stepsDetection[oldGetn].detector[k], false);
					end;
					self.lcp.stepsDetection[oldGetn].startPercent = startPercent;
					self.lcp.stepsDetection[oldGetn].endPercent = endPercent;
				end;
			end;
			if typeDetector == "scaleDetection" then
				local startPercent = getXMLFloat(xmlFile, key.."#startPercent");
				local endPercent = getXMLFloat(xmlFile, key.."#endPercent");
				local minScale = getXMLString(xmlFile, key.."#minScale");
				local maxScale = getXMLString(xmlFile, key.."#maxScale");
				if minScale ~= nil and startPercent ~= nil and endPercent ~= nil and maxScale ~= nil then
					local oldGetn = table.getn(self.lcp.scaleDetection)+1;
					self.lcp.scaleDetection[oldGetn] = {};
					self.lcp.scaleDetection[oldGetn].minScale = {};
					self.lcp.scaleDetection[oldGetn].minScale.x,self.lcp.scaleDetection[oldGetn].minScale.y,self.lcp.scaleDetection[oldGetn].minScale.z = Utils.getVectorFromString(minScale);
					self.lcp.scaleDetection[oldGetn].maxScale = {}; 
					self.lcp.scaleDetection[oldGetn].maxScale.x,self.lcp.scaleDetection[oldGetn].maxScale.y,self.lcp.scaleDetection[oldGetn].maxScale.z = Utils.getVectorFromString(maxScale);
					self.lcp.scaleDetection[oldGetn].startPercent = startPercent;
					self.lcp.scaleDetection[oldGetn].endPercent = endPercent;
					self.lcp.scaleDetection[oldGetn].index = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
					setScale(self.lcp.scaleDetection[oldGetn].index, unpack(self.lcp.scaleDetection[oldGetn].minScale));
				end;
			end;
			if typeDetector == "transDetection" then
				local startPercent = getXMLFloat(xmlFile, key.."#startPercent");
				local endPercent = getXMLFloat(xmlFile, key.."#endPercent");
				local minTrans = getXMLString(xmlFile, key.."#minTrans");
				local maxTrans = getXMLString(xmlFile, key.."#maxTrans");
				if minTrans ~= nil and startPercent ~= nil and endPercent ~= nil and maxTrans ~= nil then
					local oldGetn = table.getn(self.lcp.transDetection) +1 ;
					self.lcp.transDetection[oldGetn] = {};
					self.lcp.transDetection[oldGetn].minTrans = {};
					self.lcp.transDetection[oldGetn].minTrans.x,self.lcp.transDetection[oldGetn].minTrans.y,self.lcp.transDetection[oldGetn].minTrans.z = Utils.getVectorFromString(minTrans);
					self.lcp.transDetection[oldGetn].maxTrans = {}; 
					self.lcp.transDetection[oldGetn].maxTrans.x,self.lcp.transDetection[oldGetn].maxTrans.y,self.lcp.transDetection[oldGetn].maxTrans.z = Utils.getVectorFromString(maxTrans);
					self.lcp.transDetection[oldGetn].startPercent = startPercent;
					self.lcp.transDetection[oldGetn].endPercent = endPercent;
					self.lcp.transDetection[oldGetn].index = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
					setTranslation(self.lcp.transDetection[oldGetn].index, unpack(self.lcp.transDetection[oldGetn].minTrans));
				end;
			end;
			if typeDetector == "rotatDetection" then
				local startPercent = getXMLFloat(xmlFile, key.."#startPercent");
				local endPercent = getXMLFloat(xmlFile, key.."#endPercent");
				local minRotat = getXMLString(xmlFile, key.."#minRotat");
				local maxRotat = getXMLString(xmlFile, key.."#maxRotat");
				if minRotat ~= nil and startPercent ~= nil and endPercent ~= nil and maxRotat ~= nil then
					local oldGetn = table.getn(self.lcp.rotatDetection) +1;
					self.lcp.rotatDetection[oldGetn] = {};
					self.lcp.rotatDetection[oldGetn].minRotat = {};
					self.lcp.rotatDetection[oldGetn].minRotat.x,self.lcp.rotatDetection[oldGetn].minRotat.y,self.lcp.rotatDetection[oldGetn].minRotat.z = Utils.getVectorFromString(minRotat);
					self.lcp.rotatDetection[oldGetn].maxRotat = {}; 
					self.lcp.rotatDetection[oldGetn].maxRotat.x,self.lcp.rotatDetection[oldGetn].maxRotat.y,self.lcp.rotatDetection[oldGetn].maxRotat.z = Utils.getVectorFromString(maxRotat);
					self.lcp.rotatDetection[oldGetn].startPercent = startPercent;
					self.lcp.rotatDetection[oldGetn].endPercent = endPercent;
					self.lcp.rotatDetection[oldGetn].index = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
					setRotation(self.lcp.rotatDetection[oldGetn].index, unpack(self.lcp.rotatDetection[oldGetn].minRotat));
				end;
			end;
			if typeDetector == "visibility" then
				local startPercent = getXMLFloat(xmlFile, key.."#startPercent");
				local endPercent = getXMLFloat(xmlFile, key.."#endPercent");
				if startPercent ~= nil and endPercent ~= nil then
					local oldGetn = table.getn(self.lcp.visibility);
					self.lcp.visibility[oldGetn] = {};
					self.lcp.visibility[oldGetn].startPercent = startPercent;
					self.lcp.visibility[oldGetn].endPercent = endPercent;
					self.lcp.visibility[oldGetn].index = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
					setVisibility(self.lcp.visibility[oldGetn].index, false);
				end;
			end;
			if typeDetector == "displayNum" then
				local numbers = getXMLString(xmlFile, key.."#index");
				local precision = Utils.getNoNil(getXMLInt(xmlFile, key.."#precision"), 0);
				local displayType = getXMLInt(xmlFile, key.."#displayType");
				if numbers ~= nil and displayType ~= nil then
					local oldGetn = table.getn(self.lcp.displayNum) + 1;
					self.lcp.displayNum[oldGetn] = {};
					self.lcp.displayNum[oldGetn].index = Utils.indexToObject(self.components, numbers);
					self.lcp.displayNum[oldGetn].precision = precision;
					self.lcp.displayNum[oldGetn].dType = displayType;
					self.lcp.displayNum[oldGetn].numbers = {};
					local color = getXMLString(xmlFile, key.."#color");
					local numberColor = {};
					numberColor.x,numberColor.y,numberColor.z = Utils.getVectorFromString(color);
					local k = 0;
					while true do
						if k == getNumOfChildren(self.lcp.displayNum[oldGetn].index) then
							break;
						end;
						local number = getChildAt(self.lcp.displayNum[oldGetn].index, k);
						setShaderParameter(number, "numberColor", Utils.getNoNil(numberColor.x,0), Utils.getNoNil(numberColor.y,0), Utils.getNoNil(numberColor.z,0), 1, false);
						self.lcp.displayNum[oldGetn].numbers[k] = number;
						k = k + 1;
					end;
					setVisibility(self.lcp.displayNum[oldGetn].index, true);
				end;
			end;
			if typeDetector == "animation" then
				local animation = getXMLString(xmlFile, key.."#animation");
				local startPercent = Utils.getNoNil(getXMLFloat(xmlFile, key.."#startPercent"), 0);
				local endPercent = Utils.getNoNil(getXMLFloat(xmlFile, key.."#endPercent"), 100);
				if animation ~= nil then
					local oldGetn = table.getn(self.lcp.animations)+1;
					self.lcp.animations[oldGetn] = {};
					self.lcp.animations[oldGetn].startPercent = startPercent;
					self.lcp.animations[oldGetn].endPercent = endPercent;
					self.lcp.animations[oldGetn].animation = animation;
					self:setAnimationTime(self.lcp.animations[oldGetn].animation, 1, true);
				end;
			end;
		end;
		i = i + 1;
	end;
end;

function showFillLevel:delete()
end;

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

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

function showFillLevel:update(dt)
	local fill,capacity;
	if self.lcp.vehicleType == 0 then
		fill,capacity = self:getAttachedTrailersFillLevelAndCapacity();
	elseif self.lcp.vehicleType == 1 then
		fill = self.fillLevel;
		capacity = self.capacity;
	end;
	
	if fill ~= nil and capacity ~= nil then	
		local fillPercent = ((fill/capacity)*100);
		local cifer = 0;
		local cifer2 = 0;
		local cifer3 = 0;
		local pp = fill;
		while true do
			if pp/(10) >= 0.1 then
				cifer = cifer + 1;
				pp = pp/(10);
			else
				break;
			end;
		end;
		pp = fillPercent;
		while true do
			if pp/(10) >= 0.1 then
				cifer2 = cifer2 + 1;
				pp = pp/(10);
			else
				break;
			end;
		end;
		pp = capacity;
		while true do
			if pp/(10) >= 0.1 then
				cifer3 = cifer3 + 1;
				pp = pp/(10);
			else
				break;
			end;
		end;
		
		-- stepsDetection start
		for _,v in pairs(self.lcp.stepsDetection) do
			if v.startPercent <= fillPercent and v.endPercent >= fillPercent then
				local oneStep = (v.endPercent-v.startPercent)/table.getn(v.detector);
				for i=1, table.getn(v.detector) do
					if i*oneStep < (fillPercent-v.startPercent) then
						setVisibility(v.detector[i], true);
					else
						setVisibility(v.detector[i], false);
					end;
				end;
			end;
			if v.endPercent <= fillPercent then
				for i=1, table.getn(v.detector) do
					setVisibility(v.detector[i], true);
				end;
			end;
			if v.startPercent >= fillPercent then
				for i=1, table.getn(v.detector) do
					setVisibility(v.detector[i], false);
				end;
			end;
		end;
		-- stepsDetection end
		
		-- scaleDetection start 
		for k,v in pairs(self.lcp.scaleDetection) do
			if v.startPercent < fillPercent and v.endPercent > fillPercent then
				local prm = {};
				local pointPerPercent = 100/(v.endPercent-v.startPercent);
				prm.x = v.minScale.x + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxScale.x-v.minScale.x))/100;
				prm.y = v.minScale.y + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxScale.y-v.minScale.y))/100;
				prm.z = v.minScale.z + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxScale.z-v.minScale.z))/100;
				setScale(v.index, prm.x, prm.y, prm.z);
			end;
			if v.endPercent <= fillPercent then
				setScale(v.index, v.maxScale.x, v.maxScale.y, v.maxScale.z);
			end;
			if v.startPercent >= fillPercent then
				setScale(v.index, v.minScale.x, v.minScale.y, v.minScale.z);
			end;
		end;
		-- scaleDetection end
		
		-- transDetection start
		for _,v in pairs(self.lcp.transDetection) do
			if v.startPercent < fillPercent and v.endPercent > fillPercent then
				local prm = {};
				local pointPerPercent = 100/(v.endPercent-v.startPercent);
				prm.x = v.minTrans.x + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxTrans.x-v.minTrans.x))/100;
				prm.y = v.minTrans.y + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxTrans.y-v.minTrans.y))/100;
				prm.z = v.minTrans.z + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxTrans.z-v.minTrans.z))/100;
				setTranslation(v.index, prm.x, prm.y, prm.z);
			end;
			if v.endPercent <= fillPercent then
				setTranslation(v.index, v.maxTrans.x, v.maxTrans.y, v.maxTrans.z);
			end;
			if v.startPercent >= fillPercent then
				setTranslation(v.index, v.minTrans.x, v.minTrans.y, v.minTrans.z);
			end;
		end;
		-- transDetection end 
		
		-- rotatDetection start
		for _,v in pairs(self.lcp.rotatDetection) do
			if v.startPercent < fillPercent and v.endPercent > fillPercent then
				local prm = {};
				local pointPerPercent = 100/(v.endPercent-v.startPercent);
				prm.x = v.minRotat.x + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxRotat.x-v.minRotat.x))/100;
				prm.y = v.minRotat.y + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxRotat.y-v.minRotat.y))/100;
				prm.z = v.minRotat.z + (pointPerPercent*(fillPercent-v.startPercent)*(v.maxRotat.z-v.minRotat.z))/100;
				setRotation(v.index, math.rad(prm.x), math.rad(prm.y), math.rad(prm.z));
			end;
			if v.endPercent <= fillPercent then
				setRotation(v.index, math.rad(v.maxRotat.x), math.rad(v.maxRotat.y), math.rad(v.maxRotat.z));
			end;
			if v.startPercent >= fillPercent then
				setRotation(v.index, math.rad(v.minRotat.x), math.rad(v.minRotat.y), math.rad(v.minRotat.z));
			end;
			setVisibility(v.index, true);
		end;
		-- rotatDetection end 
		
		-- self.lcp.visibility start
		for _,v in pairs(self.lcp.visibility) do
			if v.startPercent <= fillPercent and v.endPercent >= fillPercent then
				setVisibility(v.index, true);
			else
				setVisibility(v.index, false);
			end;
		end;
		-- self.lcp.visibility end 
		
		-- self.lcp.displayNum start
		for _,v in pairs(self.lcp.displayNum) do
			local numberNumbers = table.getn(v.numbers);
			local i = 0;
			while true do
				if i > numberNumbers then
					break;
				end;
				local num;
				if v.dType == 0 then
					num = math.floor((fill%(10^(i-v.precision+1)))*(1/(10^(i-v.precision))));
					if (i-v.precision) >= cifer then 
						num = -1; 
					end;
				elseif v.dType == 1 then
					num = math.floor((fillPercent%(10^(i-v.precision+1)))*(1/(10^(i-v.precision))));
					if (i-v.precision) >= cifer2 then 
						num = -1; 
					end;
				elseif v.dType == 2 then
					num = math.floor((fill%(10^(i-v.precision+1)))*(1/(10^(i-v.precision))));
				elseif v.dType == 3 then
					num = math.floor((fillPercent%(10^(i-v.precision+1)))*(1/(10^(i-v.precision))));
				elseif v.dType == 4 then
					num = math.floor((capacity%(10^(i-v.precision+1)))*(1/(10^(i-v.precision))));
				elseif v.dType == 5 then
					num = math.floor((capacity%(10^(i-v.precision+1)))*(1/(10^(i-v.precision))));
					if (i-v.precision) >= cifer3 then 
						num = -1; 
					end;
				end;
				setShaderParameter(v.numbers[i], "number", num, 0, 0, 0, false);
				i = i + 1;
			end;
		end;
		-- self.lcp.displayNum end 
		
		-- self.lcp.animations start
		-- something magical happens here
		for _,v in pairs(self.lcp.animations) do
			if v.startPercent < fillPercent and v.endPercent > fillPercent then
				local pointPerPercent = 100/(v.endPercent-v.startPercent);
				local norm = Utils.round((pointPerPercent*(fillPercent-v.startPercent)/100), 3);
				self:setAnimationTime(v.animation, norm, true);
			end;
			if v.endPercent <= fillPercent then
				self:setAnimationTime(v.animation, 1, true);
			end;
			if v.startPercent >= fillPercent then
				self:setAnimationTime(v.animation, 0, true);
			end;
		end;
		-- self.lcp.animations end 
	end;
end;

function showFillLevel:draw()
end;

function showFillLevel:updateTick(dt)
end;

function showFillLevel:readStream(streamId, connection)
end;

function showFillLevel:writeStream(streamId, connection)
end;

function showFillLevel:detachImplement(implement)
end;