--
-- VariableColoredParts
-- Specialization for changeing the color of parts
--
-- @author  Stefan Maurus	
-- @date  05/03/2015

-- Copyright © Stefan Maurus, www.stefanmaurus.de

VariableColoredParts = {};

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

function VariableColoredParts:load(xmlFile)	
	self.setCurrentColor = SpecializationUtil.callSpecializationsFunction("setCurrentColor");

	self.open = SpecializationUtil.callSpecializationsFunction("open");
	self.close = SpecializationUtil.callSpecializationsFunction("close");
	self.letsGoButtonCallback = SpecializationUtil.callSpecializationsFunction("letsGoButtonCallback");
	self.selectColor = SpecializationUtil.callSpecializationsFunction("selectColor");
	self.buyCurrentSelected = SpecializationUtil.callSpecializationsFunction("buyCurrentSelected");

	self.scrollBarRCallback = SpecializationUtil.callSpecializationsFunction("scrollBarRCallback");
	self.scrollBarGCallback = SpecializationUtil.callSpecializationsFunction("scrollBarGCallback");
	self.scrollBarBCallback = SpecializationUtil.callSpecializationsFunction("scrollBarBCallback");

	self.changeNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.variableColoredParts#changeNode"));
	if self.changeNode ~= nil then
		self.nearestDistanceToPerson = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.variableColoredParts#nearestDistanceToPerson"), 3);
		self.onlyAvailableAtDealer = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.variableColoredParts#onlyAvailableAtDealer"), true);
		self.colorScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.variableColoredParts#colorScale"), 0.8);
		
		local i = 0;
		self.variableColors = {};
		while true do
			local key = string.format("vehicle.variableColoredParts.color(%d)", i);
			if not hasXMLProperty(xmlFile, key) then
				break;
			end;
			
			local price = Utils.getNoNil(getXMLFloat(xmlFile, key.."#price"), 1000);	
			local i18n_name = getXMLString(xmlFile, key.."#i18n_name");
			local r = Utils.getNoNil(getXMLFloat(xmlFile, key.."#r"), 0)/255;		
			local g = Utils.getNoNil(getXMLFloat(xmlFile, key.."#g"), 0)/255;	
			local b = Utils.getNoNil(getXMLFloat(xmlFile, key.."#b"), 0)/255;	
			local custom = Utils.getNoNil(getXMLBool(xmlFile, key.."#custom"), false);
			local default = Utils.getNoNil(getXMLBool(xmlFile, key.."#default"), false);
				
			table.insert(self.variableColors, {node=node,price=price,i18n_name=i18n_name,r=r,g=g,b=b, custom=custom, default=default});
			i = i + 1;
		end;

		i = 0;
		self.variableParts = {};
		while true do
			local key = string.format("vehicle.variableColoredParts.part(%d)", i);
			if not hasXMLProperty(xmlFile, key) then
				break;
			end;
			
			local index = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));	
			local shaderParameter = getXMLString(xmlFile, key.."#shaderParameter");
			
			table.insert(self.variableParts, {index=index,shaderParameter=shaderParameter});
			i = i + 1;
		end;
		
		local hasDefault = false;
		for i = 1, table.getn(self.variableColors) do
			if self.variableColors[i].default then
				self.currentColorR = 0;
				self.currentColorG = 0;
				self.currentColorB = 0;				
				self:setCurrentColor(self.variableColors[i].r, self.variableColors[i].g, self.variableColors[i].b);
				hasDefault = true;
			end;
		end;
		if not hasDefault then
			print("Default color is missing in "..self.configFileName);
		end;
		
		self.currentSelected = 1;
		
		self.colorPicker = {};
		local width, height = getNormalizedScreenValues(512, 512);
		self.colorPicker.xPos = 0.5-width*0.5;
		self.colorPicker.yPos = 0.5-height*0.5;
	
		self.gui = RafftnixGUI:new(nil, true, true);
		
		self.colorPicker.backgroundImage = self.gui:createImage(self.gui.baseElement, self.colorPicker.xPos, self.colorPicker.yPos, width, height, "sources/HUD/colorPicker.dds");
		self.colorPicker.headerText = self.gui:createText(self.colorPicker.backgroundImage, 0, 0, width, height+height*0.1, g_i18n:getText("COLORPICKER_HEADER"), 0.02, {1,1,1,1});
		self.colorPicker.headerText:setTextFocus("middle","top");
		
		self.colorPicker.letsGoButton = self.gui:createButton(self.colorPicker.backgroundImage,width*0.8, 0, width*0.2, 0.015, g_i18n:getText("COLORPICKER_CLOSE"), 0.015, {1,1,1,1}, self.letsGoButtonCallback, self);
		self.colorPicker.letsGoButton:setTextFocus("right","bottom");
		
		local width, _ = getNormalizedScreenValues(226, 0);
		self.colorPicker.list = self.gui:createList(self.gui.baseElement, self.colorPicker.xPos, self.colorPicker.yPos, width, height, height/10, 10, self.selectColor, self, 1)
		
		for i=1, table.getn(self.variableColors) do
			local item = self.variableColors[i];
			local container = self.gui:createElement(self.colorPicker.list, 0, 0, width, height/10);
			container.nameText = self.gui:createText(container, 0.004, 0.02, 0, 0, g_i18n:getText(item.i18n_name), 0.015, 1);
		end;
		
		self.colorPicker.list.elements[self.currentSelected].nameText:setTextColor({234/255, 199/255, 123/255, 1});		
		
		local widthCI, height = getNormalizedScreenValues(285, 354);
		local xPos, _ = getNormalizedScreenValues(226, 0);
		self.colorPicker.currentInfo = self.gui:createElement(self.colorPicker.backgroundImage, xPos, 0, widthCI, height);
		
		local textStartX, textStartY = getNormalizedScreenValues(8, 316);
		local _, textSize = getNormalizedScreenValues(0, 16);
		self.colorPicker.currentInfoName = self.gui:createText(self.colorPicker.currentInfo, textStartX, textStartY, 0, 0, g_i18n:getText("COLORPICKER_INFO_NAME").." \n"..g_i18n:getText(self.variableColors[self.currentSelected].i18n_name), textSize, {1,1,1,1});	
		self.colorPicker.currentInfoPrize = self.gui:createText(self.colorPicker.currentInfo, textStartX, textStartY-textSize*4, 0, 0, g_i18n:getText("COLORPICKER_INFO_PRIZE").." "..self.variableColors[self.currentSelected].price.."€", textSize, {1,1,1,1});
		self.colorPicker.currentInfoCCode = self.gui:createText(self.colorPicker.currentInfo, textStartX, textStartY-textSize*6, 0, 0, string.format(g_i18n:getText("COLORPICKER_INFO_CCODE"), self.variableColors[self.currentSelected].r, self.variableColors[self.currentSelected].g, self.variableColors[self.currentSelected].b) , textSize, {1,1,1,1});

		local posX, posY = getNormalizedScreenValues(169, 222);
		local width, height = getNormalizedScreenValues(98, 110);		
		self.colorPicker.currentInfoColor = self.gui:createImage(self.colorPicker.currentInfo, posX, posY, width, height, "sources/HUD/white_non.dds");
		setOverlayColor(self.colorPicker.currentInfoColor.overlayId, self.variableColors[self.currentSelected].r, self.variableColors[self.currentSelected].g, self.variableColors[self.currentSelected].b, 1);
	
		local width, posY = getNormalizedScreenValues(225, 60);
		self.colorPicker.CurrentInfoBuy = self.gui:createButton(self.colorPicker.currentInfo, 0, posY, widthCI, posY/2, g_i18n:getText("COLORPICKER_BUY"), 0.015, {1,1,1,1}, self.buyCurrentSelected, self);
		self.colorPicker.CurrentInfoBuy:setTextFocus("middle","center");
		
		local posX, posY = getNormalizedScreenValues(245, 393);
		local width, height = getNormalizedScreenValues(251, 16);	
		local needleWidth, heightDif = getNormalizedScreenValues(5, 37);	
				
		self.colorPicker.scrollBarRE = self.gui:createElement(self.colorPicker.backgroundImage, posX, posY+heightDif+heightDif, width, height);		
		self.colorPicker.scrollBarR = self.gui:createScrollBar(self.colorPicker.scrollBarRE, 0, 0, width, height, needleWidth, width, self.scrollBarRCallback, self, "sources/HUD/needle.dds")
		self.colorPicker.scrollBarGE = self.gui:createElement(self.colorPicker.backgroundImage, posX, posY+heightDif, width, height);		
		self.colorPicker.scrollBarG = self.gui:createScrollBar(self.colorPicker.scrollBarGE, 0, 0, width, height, needleWidth, width, self.scrollBarGCallback, self, "sources/HUD/needle.dds")
		self.colorPicker.scrollBarBE = self.gui:createElement(self.colorPicker.backgroundImage, posX, posY, width, height);		
		self.colorPicker.scrollBarB = self.gui:createScrollBar(self.colorPicker.scrollBarBE, 0, 0, width, height, needleWidth, width, self.scrollBarBCallback, self, "sources/HUD/needle.dds")

		for i = 1, table.getn(self.variableColors) do
			if self.variableColors[i].custom then
				self.colorPicker.scrollBarR:setValue(self.variableColors[i].r);
				self.colorPicker.scrollBarG:setValue(self.variableColors[i].g);
				self.colorPicker.scrollBarB:setValue(self.variableColors[i].b);	
			end;
		end;
	end;
end;

function VariableColoredParts:delete()
end;

function VariableColoredParts:readStream(streamId, connection)
	if self.changeNode ~= nil then
		self:setCurrentColor(streamReadFloat32(streamId), streamReadFloat32(streamId), streamReadFloat32(streamId), true);
	end;
end;

function VariableColoredParts:writeStream(streamId, connection) 
	if self.changeNode ~= nil then
		streamWriteFloat32(streamId, self.currentColorR); 
		streamWriteFloat32(streamId, self.currentColorG); 
		streamWriteFloat32(streamId, self.currentColorB); 
	end;
end;

function VariableColoredParts:setCurrentColor(r, g, b, noEventSend)
	self.currentColorR = r;
	self.currentColorG = g;
	self.currentColorB = b;	
	
	local colorScaleR = self.currentColorR*self.colorScale;
	local colorScaleG = self.currentColorG*self.colorScale;
	local colorScaleB = self.currentColorB*self.colorScale;
	
	for i = 1, table.getn(self.variableParts) do
		setShaderParameter(self.variableParts[i].index, self.variableParts[i].shaderParameter, colorScaleR, colorScaleG, colorScaleB, 0, false);
	end;
	
	SetCurrentColorEvent.sendEvent(self, r, g, b, noEventSend);
end;

function VariableColoredParts:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if self.changeNode ~= nil then
		local r, g, b = Utils.getVectorFromString(getXMLString(xmlFile, key.."#currentColor"));
		if r ~= nil and g ~= nil and b ~= nil then
			self:setCurrentColor(r, g, b);	
		end;
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;
 
function VariableColoredParts:getSaveAttributesAndNodes(nodeIdent)
	if self.changeNode ~= nil then
		return 'currentColor="' .. self.currentColorR.. ' ' .. self.currentColorG.. ' ' .. self.currentColorB.. '" ';
	else
		return '';	
	end;
end;

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

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

function VariableColoredParts:update(dt)
	if self.changeNode ~= nil then
		if g_currentMission.controlPlayer then
			local nearestDistance1 = self.nearestDistanceToPerson;	
			local nearestDistance2 = 100;
			local x1,y1,z1 = getWorldTranslation(self.changeNode);
			if g_currentMission.player ~= nil then
				local x2,y2,z2 = getWorldTranslation(g_currentMission.player.rootNode);		
				local distance1 = Utils.vector3Length(x1-x2,y1-y2,z1-z2);	
				local distance2 = Utils.vector3Length(g_currentMission.storeSpawnPlaces[1].startX-x2,g_currentMission.storeSpawnPlaces[1].startY-y2,g_currentMission.storeSpawnPlaces[1].startZ-z2);	
				if not self.onlyAvailableAtDealer then
					distance2 = nearestDistance2;
				end;
				if distance1 <= nearestDistance1 and distance2 <= nearestDistance2 then
					g_currentMission:addHelpButtonText(g_i18n:getText("COLORPICKER_OPENMENU"), InputBinding.IMPLEMENT_EXTRA);	
					if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
						self:open();
					end;

				elseif distance1 <= nearestDistance1 and distance2 > nearestDistance2 then
					g_currentMission:addExtraPrintText(g_i18n:getText("COLORPICKER_HELP_1"));
					g_currentMission:addExtraPrintText(g_i18n:getText("COLORPICKER_HELP_2"));
				end;
			end;
		end;
	end;
end;

function VariableColoredParts:updateTick(dt)
end;

function VariableColoredParts:draw()
end;

function VariableColoredParts:open()
	self.gui:open();
end;

function VariableColoredParts:close()
	self.gui:close();
end;

function VariableColoredParts:selectColor(index)
	self.currentSelected = index;
	for i = 1, table.getn(self.colorPicker.list.elements) do
		if i == index then
			self.colorPicker.list.elements[index].nameText:setTextColor({234/255, 199/255, 123/255, 1});
		else
			self.colorPicker.list.elements[i].nameText:setTextColor({1, 1, 1, 1});
		end;
	end;

	self.colorPicker.currentInfoName:setText(g_i18n:getText("COLORPICKER_INFO_NAME").." \n"..g_i18n:getText(self.variableColors[self.currentSelected].i18n_name));	
	self.colorPicker.currentInfoPrize:setText(g_i18n:getText("COLORPICKER_INFO_PRIZE").." "..self.variableColors[self.currentSelected].price.."€");
	self.colorPicker.currentInfoCCode:setText(string.format(g_i18n:getText("COLORPICKER_INFO_CCODE"), self.variableColors[self.currentSelected].r*255, self.variableColors[self.currentSelected].g*255, self.variableColors[self.currentSelected].b*255));
	setOverlayColor(self.colorPicker.currentInfoColor.overlayId, self.variableColors[self.currentSelected].r, self.variableColors[self.currentSelected].g, self.variableColors[self.currentSelected].b, 1);
end;

function VariableColoredParts:buyCurrentSelected()
	self:setCurrentColor(self.variableColors[self.currentSelected].r, self.variableColors[self.currentSelected].g, self.variableColors[self.currentSelected].b);
end;

function VariableColoredParts:letsGoButtonCallback()
	self:close();
end;

function VariableColoredParts:scrollBarRCallback(value)
	for i = 1, table.getn(self.variableColors) do
		if self.variableColors[i].custom then
			self.variableColors[i].r = value;	
		end;
	end;
	self:selectColor(self.currentSelected);
end;

function VariableColoredParts:scrollBarGCallback(value)
	for i = 1, table.getn(self.variableColors) do
		if self.variableColors[i].custom then
			self.variableColors[i].g = value;	
		end;
	end;
	self:selectColor(self.currentSelected);	
end;

function VariableColoredParts:scrollBarBCallback(value)
	for i = 1, table.getn(self.variableColors) do
		if self.variableColors[i].custom then
			self.variableColors[i].b = value;	
		end;
	end;
	self:selectColor(self.currentSelected);	
end;

SetCurrentColorEvent = {};
SetCurrentColorEvent_mt = Class(SetCurrentColorEvent, Event);

InitEventClass(SetCurrentColorEvent, "SetCurrentColorEvent");

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

function SetCurrentColorEvent:new(vehicle, r, g, b)
    local self = SetCurrentColorEvent:emptyNew()
    self.vehicle = vehicle;
	self.r = r;
	self.g = g;
	self.b = b;	
    return self;
end;

function SetCurrentColorEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.r = streamReadFloat32(streamId);
	self.g = streamReadFloat32(streamId);
	self.b = streamReadFloat32(streamId);	
	if self.vehicle ~= nil then
		self.vehicle:setCurrentColor(self.r, self.g, self.b, true);
	end;
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetCurrentColorEvent:new(self.vehicle, self.r, self.g, self.b), nil, connection, self.vehicle);
    end;
end;

function SetCurrentColorEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteFloat32(streamId, self.r);
	streamWriteFloat32(streamId, self.g);
	streamWriteFloat32(streamId, self.b);	
end;

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