--[[
The Casual Game Addict
]]


AddNewStoreCategory = {}

function AddNewStoreCategory.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(Lights, specializations)
end

function AddNewStoreCategory.registerEventListeners(vehicleType)
	SpecializationUtil.registerEventListener(vehicleType, "onLoad", AddNewStoreCategory)
	SpecializationUtil.registerEventListener(vehicleType, "onDelete", AddNewStoreCategory)
	SpecializationUtil.registerEventListener(vehicleType, "onUpdate", AddNewStoreCategory)
	SpecializationUtil.registerEventListener(vehicleType, "onLeaveVehicle", AddNewStoreCategory)
	SpecializationUtil.registerEventListener(vehicleType, "onStartMotor", AddNewStoreCategory)
	SpecializationUtil.registerEventListener(vehicleType, "onStopMotor", AddNewStoreCategory)
	SpecializationUtil.registerEventListener(vehicleType, "onPostDetach", AddNewStoreCategory)
	SpecializationUtil.registerEventListener(vehicleType, "onBeaconLightsVisibilityChanged", AddNewStoreCategory)
end

function AddNewStoreCategory.registerFunctions(vehicleType)
	SpecializationUtil.registerFunction(vehicleType, "loadAddNewStoreCategoryLight", AddNewStoreCategory.loadAddNewStoreCategoryLight)
	SpecializationUtil.registerFunction(vehicleType, "setRunningLightsState", AddNewStoreCategory.setRunningLightsState)
end

function AddNewStoreCategory:onLoad(savegame)
	self.spec_AddNewStoreCategory = {}
	local spec = self.spec_AddNewStoreCategory
	
	
	local strobeLightsKey = "vehicle.AddNewStoreCategory.strobeLights"
	if self.xmlFile:hasProperty(strobeLightsKey) then

		spec.strobeLights = {}
		spec.strobeLights.strobes = {}

		spec.strobeLights.active = false
		spec.strobeLights.reset = false

		spec.strobeLights.realBeaconLights = g_gameSettings:getValue("realBeaconLights")
		spec.strobeLights.realLights = 0
		spec.strobeLights.maxRealLights = 20

		
		local disableRealLightWarning = Utils.getNoNil(self.xmlFile:getBool(strobeLightsKey .. "#disableRealLightWarning"), false)

		local loadedXmlFiles = {}

		local i = 0
		while true do
			local key = string.format("%s.strobeLight(%d)", strobeLightsKey, i)

			if not self.xmlFile:hasProperty(key) then
				break
			end

			local strobe = {}
			local strobeLightLoaded = false

			local strobeXmlFilename = self.xmlFile:getString(key .. "#filename")
			if strobeXmlFilename ~= nil then
				strobeXmlFilename = Utils.getFilename(strobeXmlFilename, self.baseDirectory)

				local strobeXmlFile = nil
				if loadedXmlFiles[strobeXmlFilename] ~= nil then
					strobeXmlFile = loadedXmlFiles[strobeXmlFilename]
				else
					strobeXmlFile = loadXMLFile("strobeLightXML", strobeXmlFilename)
					if strobeXmlFile ~= nil and strobeXmlFile ~= 0 then
						loadedXmlFiles[strobeXmlFilename] = strobeXmlFile
					end
				end

				if strobeXmlFile ~= nil then
					strobeLightLoaded = self:loadAddNewStoreCategoryLight(strobe, self.xmlFile, key, strobeXmlFile, true)
					if strobe.realLightNode ~= nil then
						spec.strobeLights.realLights = spec.strobeLights.realLights + 1
					end
					
				end
			else
				strobeLightLoaded = self:loadAddNewStoreCategoryLight(strobe, self.xmlFile, key, nil, true)
			end

			if strobeLightLoaded then
				table.insert(spec.strobeLights.strobes, strobe)
			end

			i = i + 1
		end

		if not disableRealLightWarning and spec.strobeLights.realLights > spec.strobeLights.maxRealLights then
			g_logManager:warning("[AddNewStoreCategory] - More than 20 'real' strobe lights have been found in '%s' this may cause performance issues on some computers.")
		end

		for filename, file in pairs (loadedXmlFiles) do
			delete(file)
		end

		if next(spec.strobeLights.strobes) == nil then
			spec.strobeLights = nil
		end
	end

	
	local soundsKey = "vehicle.AddNewStoreCategory.beaconSound"
	if self.xmlFile:hasProperty(soundsKey) then
		local beaconSoundSample = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.AddNewStoreCategory", "beaconSound", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self)
		if beaconSoundSample ~= nil then
			spec.beaconSound = {}
			spec.beaconSound.sample = beaconSoundSample
			spec.beaconSound.isActive = false

		end
	end

	
	local fillWarningKey = "vehicle.AddNewStoreCategory.combineFillWarning"
	local percent = self.xmlFile:getFloat(fillWarningKey .. "#percent")
	if percent ~= nil then
		if self.spec_combine ~= nil and self.spec_fillUnit ~= nil then
			spec.combineFillWarning = {}
			spec.combineFillWarning.isEnabled = true	
			spec.combineFillWarning.percent = percent
			spec.combineFillWarning.beaconsSetActive = false
			spec.combineFillWarning.isActive = false
			spec.combineFillWarning.turnOnBeacons = Utils.getNoNil(self.xmlFile:getBool(fillWarningKey .. "#turnOnBeacons"), false)
			spec.combineFillWarning.playSound = Utils.getNoNil(self.xmlFile:getBool(fillWarningKey .. "#playWarningSound"), false)

			if spec.combineFillWarning.playSound then
				spec.combineFillWarning.soundLoops = Utils.getNoNil(self.xmlFile:getInt(fillWarningKey .. "#warningSoundLoops"), 3) 
				spec.combineFillWarning.is3DSound = Utils.getNoNil(self.xmlFile:getBool(fillWarningKey .. "#is3DSound"), false) 
				local inCabAlarmSample = nil
				if self.xmlFile:hasProperty(fillWarningKey .. ".alarmSound") then
					inCabAlarmSample = g_soundManager:loadSampleFromXML(self.xmlFile, fillWarningKey, "alarmSound", self.baseDirectory, self.components, spec.combineFillWarning.soundLoops, AudioGroup.VEHICLE, self.i3dMappings, self)
				else
					
					local memXml = '<vehicle> <AddNewStoreCategory> <combineFillWarning> <alarmSound template="ROLLBELT_ALARM" linkNode="0>" /> </combineFillWarning> </AddNewStoreCategory> </vehicle>'
					local memXmlFile = loadXMLFileFromMemory("alarmSoundFake", memXml)
					inCabAlarmSample = g_soundManager:loadSampleFromXML(memXmlFile, fillWarningKey, "alarmSound", self.baseDirectory, self.components, spec.combineFillWarning.soundLoops, AudioGroup.VEHICLE, self.i3dMappings, self)
					delete(memXmlFile)
				end

				spec.combineFillWarning.sample = inCabAlarmSample
				spec.combineFillWarning.samplePlaying = false
			end
		else
			g_logManager:xmlWarning(self.configFileName, "Combine Fill Warning is only for use on vehicles using the 'fillUnit' and 'combine' specialisations.")
		end
	end

	
	local runningLightsKey = "vehicle.AddNewStoreCategory.runningLights"
	if self.xmlFile:hasProperty(runningLightsKey) then
		spec.runningLights = {}
		spec.runningLights.lights = {}
		spec.runningLights.active = false

		spec.runningLights.realLights = 0
		spec.runningLights.maxRealLights = 20 

	
		local disableRealLightWarning = Utils.getNoNil(self.xmlFile:getBool(runningLightsKey .. "#disableRealLightWarning"), false)

		local loadedXmlFiles = {}

		local i = 0
		while true do
			local key = string.format("%s.runningLight(%d)", runningLightsKey, i)

			if not self.xmlFile:hasProperty(key) then
				break
			end

			local runLight = {}
			local runningLightsLoaded = false

			local lightXmlFilename = self.xmlFile:getString(key .. "#filename")
			if lightXmlFilename ~= nil then
				lightXmlFilename = Utils.getFilename(lightXmlFilename, self.baseDirectory)

				local lightXmlFile = nil
				if loadedXmlFiles[lightXmlFilename] ~= nil then
					lightXmlFile = loadedXmlFiles[lightXmlFilename]
				else
					lightXmlFile = loadXMLFile("runLightXML", lightXmlFilename)
					if lightXmlFile ~= nil and lightXmlFile ~= 0 then
						loadedXmlFiles[lightXmlFilename] = lightXmlFile
					end
				end

				if lightXmlFile ~= nil then
					runningLightsLoaded = self:loadAddNewStoreCategoryLight(runLight, self.xmlFile, key, lightXmlFile, false)
					if runLight.realLightNode ~= nil then
						spec.runningLights.realLights = spec.runningLights.realLights + 1
					end
				
				end
			else
				runningLightsLoaded = self:loadAddNewStoreCategoryLight(runLight, self.xmlFile, key, nil, false)
			end

			if runningLightsLoaded then
				table.insert(spec.runningLights.lights, runLight)
			end

			i = i + 1
		end

		if not disableRealLightWarning and spec.runningLights.realLights > spec.runningLights.maxRealLights then
			g_logManager:warning("[AddNewStoreCategory] - More than 20 'real' running lights have been found, this may cause performance issues on some computers.")
		end

		for filename, file in pairs (loadedXmlFiles) do
			delete(file)
		end

		if next(spec.runningLights.lights) == nil then
			spec.runningLights = nil
		end
	end
end

function AddNewStoreCategory:onDelete()
	local spec = self.spec_AddNewStoreCategory

	if spec.strobeLights ~= nil then
		for _, strobeLight in pairs(spec.strobeLights.strobes) do
			if strobeLight.filename ~= nil then
				g_i3DManager:releaseSharedI3DFile(strobeLight.filename, self.baseDirectory, true)
			end
		end
	end

	if spec.beaconSound ~= nil then
		g_soundManager:deleteSample(spec.beaconSound.sample)
	end

	if spec.combineFillWarning ~= nil and spec.combineFillWarning.sample ~= nil then
		g_soundManager:deleteSample(spec.combineFillWarning.sample)
	end
end

function AddNewStoreCategory:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
	local spec = self.spec_AddNewStoreCategory

	if spec.strobeLights ~= nil then
		if spec.strobeLights.active then

			spec.strobeLights.reset = true
			for _, st in ipairs(spec.strobeLights.strobes) do
				if st.t > st.ns then
					st.ls = not st.ls

					if spec.strobeLights.realBeaconLights and st.realLightNode ~= nil then
						setVisibility(st.realLightNode, st.ls)
					end

					if st.lightNode ~= nil then
						setVisibility(st.lightNode, st.ls)
					end

					if st.lightShaderNode ~= nil then
						local value = 1 * st.intensity
						if not st.ls then
							value = 0
						end
						setShaderParameter(st.lightShaderNode, "lightControl", value, st.shaderParameter[1], st.shaderParameter[2], st.shaderParameter[3], false)
					end

					st.t = 0
					if st.rnd then
						if st.ls then
							st.ns = math.random(st.rndnn,st.rndxn)
						else
							st.ns = math.random(st.rndnf,st.rndxf)
						end
					else
						st.ss = st.ss + 1
						if st.ss > table.getn(st.sq) then
							st.ss = 1
						end
						st.ns = st.sq[st.ss]
					end
				else
					st.t = st.t + dt
				end
			end
		else
			if spec.strobeLights.reset then
				for _, st in ipairs(spec.strobeLights.strobes) do
					if spec.strobeLights.realBeaconLights and st.realLightNode ~= nil then
						setVisibility(st.realLightNode, false)
					end

					if st.lightNode ~= nil then
						setVisibility(st.lightNode, false)
					end

					if st.lightShaderNode ~= nil then
						setShaderParameter(st.lightShaderNode, "lightControl", 0, st.shaderParameter[1], st.shaderParameter[2], st.shaderParameter[3], false)
					end
				end
				spec.strobeLights.reset = false
			end
		end
	end

	if spec.combineFillWarning ~= nil and spec.combineFillWarning.isEnabled and self:getIsActive() and not self.isHired then
		local percent = 100 * self:getFillUnitFillLevelPercentage(self.spec_combine.fillUnitIndex)
		if spec.combineFillWarning.isActive then
			if percent < spec.combineFillWarning.percent then
				if spec.combineFillWarning.beaconsSetActive and spec.combineFillWarning.turnOnBeacons then
					self:setBeaconLightsVisibility(false)
					spec.combineFillWarning.beaconsSetActive = false
				end
				spec.combineFillWarning.counter = spec.combineFillWarning.seconds
				spec.combineFillWarning.isActive = false

				if spec.combineFillWarning.playSound and spec.combineFillWarning.sample ~= nil and spec.combineFillWarning.samplePlaying then
					g_soundManager:stopSample(spec.combineFillWarning.sample)
					spec.combineFillWarning.samplePlaying = false
				end
			end
		else
			if percent >= spec.combineFillWarning.percent then
				if not self.spec_lights.beaconLightsActive and spec.combineFillWarning.turnOnBeacons then
					self:setBeaconLightsVisibility(true)
					spec.combineFillWarning.beaconsSetActive = true
				end
				spec.combineFillWarning.counter = 0
				spec.combineFillWarning.isActive = true

				if spec.combineFillWarning.playSound and spec.combineFillWarning.sample ~= nil and not spec.combineFillWarning.samplePlaying then
					if self.spec_enterable.isEntered or spec.combineFillWarning.is3DSound then
						g_soundManager:playSample(spec.combineFillWarning.sample)
						spec.combineFillWarning.samplePlaying = true
					end
				end
			end
		end
	end
	
	if spec.runningLights ~= nil and self.spec_attachable ~= nil then
		local rootVehicle = self:getRootVehicle()		
		if rootVehicle ~= nil and rootVehicle.getIsMotorStarted ~= nil then
			local isMotorStarted = rootVehicle:getIsMotorStarted()
			if isMotorStarted ~= spec.runningLights.active then
				self:setRunningLightsState(isMotorStarted)
			end
		else
			if spec.runningLights.active then
				self:setRunningLightsState(false)
			end
		end
	end
end

function AddNewStoreCategory:setRunningLightsState(isActive)
	local spec = self.spec_AddNewStoreCategory

	if spec.runningLights.lights ~= nil then
		spec.runningLights.active = isActive

		for _, runLight in ipairs(spec.runningLights.lights) do
			if runLight.realLightNode ~= nil and self:getUseHighProfile() then
				setVisibility(runLight.realLightNode, isActive)
			end

			if runLight.lightNode ~= nil then
				setVisibility(runLight.lightNode, isActive)
			end

			if runLight.lightShaderNode ~= nil then
				local intensity = 0
				if isActive then
					intensity = runLight.intensity
				end

				setShaderParameter(runLight.lightShaderNode, "lightControl", intensity, runLight.shaderParameter[1], runLight.shaderParameter[2], runLight.shaderParameter[3], false)
			end
		end
	end
end

function AddNewStoreCategory:onPostDetach()
	local spec = self.spec_AddNewStoreCategory
	if spec.runningLights ~= nil then
		self:setRunningLightsState(false)
	end
end

function AddNewStoreCategory:onLeaveVehicle()
	local spec = self.spec_AddNewStoreCategory
	if spec.combineFillWarning ~= nil and spec.combineFillWarning.isEnabled then
		if spec.combineFillWarning.samplePlaying and not spec.combineFillWarning.is3DSound then
			g_soundManager:stopSample(spec.combineFillWarning.sample)
			spec.combineFillWarning.samplePlaying = false
		end
	end
end

function AddNewStoreCategory:onStartMotor()
	if self.spec_AddNewStoreCategory.runningLights ~= nil then
		self:setRunningLightsState(true)
	end
end

function AddNewStoreCategory:onStopMotor()
	if self.spec_AddNewStoreCategory.runningLights ~= nil then
		self:setRunningLightsState(false)
	end
end

function AddNewStoreCategory:onBeaconLightsVisibilityChanged(visibility)
	local spec = self.spec_AddNewStoreCategory

	if spec.strobeLights ~= nil then
		spec.strobeLights.realBeaconLights = g_gameSettings:getValue("realBeaconLights")
		spec.strobeLights.active = visibility
	end

	if spec.beaconSound ~= nil then
		spec.beaconSound.isActive = visibility

		if spec.beaconSound.isActive then
			g_soundManager:playSample(spec.beaconSound.sample)
		else
			g_soundManager:stopSample(spec.beaconSound.sample)
		end
	end
end

function AddNewStoreCategory:loadAddNewStoreCategoryLight(light, xmlFile, key, lightXmlFile, isStrobeLight)
	local spec = self.spec_AddNewStoreCategory

	if light ~= nil then
		if isStrobeLight then
			light.ns = 0
			light.t = 1
			light.a = false

			local sequence = xmlFile:getString(key .. "#sequence")
			if sequence ~= nil then
				light.rnd = false
				light.sq = {string.getVector(sequence)}
				light.inv = Utils.getNoNil(xmlFile:getBool(key .. "#invert"), false)
				light.ls = light.inv
				light.ss = 1
			else
				light.rnd = true
				light.ls = false
				light.rndnn = Utils.getNoNil(xmlFile:getInt(key .. "#minOn"), 100)
				light.rndxn = Utils.getNoNil(xmlFile:getInt(key .. "#maxOn"), 100)
				light.rndnf = Utils.getNoNil(xmlFile:getInt(key .. "#minOff"), 100)
				light.rndxf = Utils.getNoNil(xmlFile:getInt(key .. "#maxOff"), 400)
				math.randomseed(getTime())
				math.random()
			end
		end


		if lightXmlFile ~= nil then
		
			light.useRealLight = Utils.getNoNil(xmlFile:getBool(key .. "#useRealLight"), false)

			local node = I3DUtil.indexToObject(self.components, xmlFile:getString(key .. "#linkNode"), self.i3dMappings)
			if node ~= nil then
				local sharedKey = "AddNewStoreCategoryShared.runningLight"
				if isStrobeLight then
					sharedKey = "AddNewStoreCategoryShared.strobeLight"
				end

				local i3dFilename = getXMLString(lightXmlFile, sharedKey .. ".filename")
				if i3dFilename ~= nil then
					local i3dNode = g_i3DManager:loadSharedI3DFile(i3dFilename, self.baseDirectory, false, false, false)
					if i3dNode ~= nil and i3dNode ~= 0 then
						local rootNode = I3DUtil.indexToObject(i3dNode, lightXmlFile:getString(sharedKey .. ".rootNode#node"))

					
						local lightNode = I3DUtil.indexToObject(i3dNode, lightXmlFile:getString(sharedKey .. ".light#node"))

					
						local lightShaderNode = I3DUtil.indexToObject(i3dNode, lightXmlFile:getString(sharedKey .. ".light#shaderNode"))

						if rootNode ~= nil and (lightNode ~= nil or lightShaderNode ~= nil) then
							link(node, rootNode)
							setTranslation(rootNode, 0,0,0)

							light.rootNode = rootNode
							light.filename = i3dFilename
							light.intensity = Utils.getNoNil(lightXmlFile:getFloat(sharedKey .. ".light#intensity"), 100)

							if lightNode ~= nil then
								light.lightNode = lightNode
								setVisibility(lightNode, false)
							end

							if lightShaderNode ~= nil then
								light.lightShaderNode = lightShaderNode
								local _, y, z, w = getShaderParameter(lightShaderNode, "lightControl")
								light.shaderParameter = {y, z, w}
								setShaderParameter(lightShaderNode, "lightControl", 0, y, z, w, false)
							end

							
							local xmlRealLightNode = I3DUtil.indexToObject(i3dNode, lightXmlFile:getString(sharedKey .. ".realLight#node"))
							if xmlRealLightNode ~= nil then
								light.defaultColor = {getLightColor(xmlRealLightNode)}
								setVisibility(xmlRealLightNode, false)

								if light.useRealLight then
									light.realLightNode = xmlRealLightNode
								end
							end

							
							if light.realLightNode == nil then
								local realLightNode = I3DUtil.indexToObject(self.components, lightXmlFile:getString(key .. "#realLightNode"), self.i3dMappings)
								if realLightNode ~= nil then
									light.defaultColor = {getLightColor(realLightNode)}
									setVisibility(realLightNode, false)
									light.realLightNode = realLightNode
								end
							end

							return true
						end
						delete(i3dNode)
					end
				end
			else
				g_logManager:error("[AddNewStoreCategory] - No link node was found at %s in '%s'",  key, self.configFileName)
			end
		else
			
			local lightNode = I3DUtil.indexToObject(self.components, xmlFile:getString(key .. "#lightNode"), self.i3dMappings)

			
			local lightShaderNode = I3DUtil.indexToObject(self.components, xmlFile:getString(key .. "#lightShaderNode"), self.i3dMappings)

			if lightNode ~= nil or lightShaderNode ~= nil then
				light.intensity = Utils.getNoNil(xmlFile:getFloat(key .. "#shaderIntensity"), 100)

				if lightNode ~= nil then
					light.lightNode = lightNode
					setVisibility(lightNode, false)
				end

				if lightShaderNode ~= nil then
					light.lightShaderNode = lightShaderNode
					local _, y, z, w = getShaderParameter(lightShaderNode, "lightControl")
					light.shaderParameter = {y, z, w}
					setShaderParameter(lightShaderNode, "lightControl", 0, y, z, w, false)
				end

				
				local realLightNode = I3DUtil.indexToObject(self.components, xmlFile:getString(key .. "#realLightNode"), self.i3dMappings)
				if realLightNode ~= nil then
					light.defaultColor = {getLightColor(realLightNode)}
					setVisibility(realLightNode, false)
					light.realLightNode = realLightNode
				end
			end

			return true
		end
	end

	return false
end





