-- CONSTRUCTOR

function Tracker.new(name)
	local self = {}
	setmetatable(self, Tracker)
	
	self.name = name
	self.totalVolume = 0
	self.parts = {}
	self.partToItem = {}
	self.items = {}
	self.whitelistParams = nil
	self.characters = {}
	self.baseParts = {}
	self.exitDetections = {}
	self.janitor = Janitor.new()

	if name == "player" then
		local function updatePlayerCharacters()
			local characters = {}
			for _, player in pairs(players:GetPlayers()) do
				local character = player.Character
				if character then
					characters[character] = true
				end
			end
			self.characters = characters
		end
		
		local function playerAdded(player)
			local function charAdded(character)
				local humanoid = character:WaitForChild("Humanoid", 3)
				if humanoid then
					updatePlayerCharacters()
					self:update()
					for _, valueInstance in pairs(humanoid:GetChildren()) do
						if valueInstance:IsA("NumberValue") then
							valueInstance.Changed:Connect(function()
								self:update()
							end)
						end
					end
				end
			end
			if player.Character then
				charAdded(player.Character)
			end
			player.CharacterAdded:Connect(charAdded)
			player.CharacterRemoving:Connect(function(removingCharacter)
				self.exitDetections[removingCharacter] = nil
			end)
		end
		
		players.PlayerAdded:Connect(playerAdded)
		for _, player in pairs(players:GetPlayers()) do
			playerAdded(player)
		end
		
		players.PlayerRemoving:Connect(function(player)
			updatePlayerCharacters()
			self:update()
		end)


	elseif name == "item" then
		local function updateItem(itemDetail, newValue)
			if itemDetail.isCharacter then
				self.characters[itemDetail.item] = newValue
			elseif itemDetail.isBasePart then
				self.baseParts[itemDetail.item] = newValue
			end
			self:update()
		end
		Tracker.itemAdded:Connect(function(itemDetail)
			updateItem(itemDetail, true)
		end)
		Tracker.itemRemoved:Connect(function(itemDetail)
			self.exitDetections[itemDetail.item] = nil
			updateItem(itemDetail, nil)
		end)
	end

	trackers[self] = true
	task.defer(self.update, self)
	return self
end


