const resName = GetParentResourceName();
// Utils
function maxTwoDecimals() {
	if(isNaN(this.value)) {
		return
	}
	let number = parseFloat(this.value);
	if(number) {
		this.value = number.toFixed(2);
	}
}
$(".max-two-decimals").change(maxTwoDecimals)
function componentToHex(c) {
	var hex = c.toString(16);
	return hex.length == 1 ? "0" + hex : hex;
  }
  
function rgbToHex(r, g, b) {
	return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function hexToRgb(hex) {
	var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
	return result ? {
	  r: parseInt(result[1], 16),
	  g: parseInt(result[2], 16),
	  b: parseInt(result[3], 16)
	} : null;
}
// Harvestable items
let harvestableItemsDatatable = $("#harvestable-items-container").DataTable( {
	"lengthMenu": [10, 15, 20],
	"createdRow": function ( row, data, index ) {
		$(row).addClass("clickable");
		$(row).click(function() {
			let harvestableItemId = parseInt(data[0]);
			editHarvestableItem(harvestableItemId);
		})
	},
} );
let harvestableItems = {};
function loadHarvestableItems() {
	$.post(`https://${resName}/getAllHarvestableItems`, {}, async function(rawHarvestableItems) {
		// Manually create the table to avoid incompatibilities due table indexing
		harvestableItems = {};
		for(const[k, itemData] of Object.entries(rawHarvestableItems)) {
			harvestableItems[itemData.id] = itemData;
		}
		harvestableItemsDatatable.clear();
		for(const[itemId, itemData] of Object.entries(harvestableItems)) {
			harvestableItemsDatatable.row.add([
				itemId,
				await getItemLabel(itemData.name),
				itemData.minQuantity,
				itemData.maxQuantity,
				itemData.coords.x,
				itemData.coords.y,
				itemData.coords.z,
			])
		}
		harvestableItemsDatatable.draw()
	})
}
// Harvestable items creation
$("#new-harvestable-item-btn").click(function() {
	let harvestableModal = $("#harvestable-item-modal");
	harvestableModal.data("action", "create");
	harvestableModal.find("input").val("");
	$("#harvestable-scale-x").val(1.5);
	$("#harvestable-scale-y").val(1.5);
	$("#harvestable-scale-z").val(1.5);
	$("#harvestable-icon-type").val(1);
	$("#harvestable-min-quantity").val(1);
	$("#harvestable-max-quantity").val(1);
	$("#harvestable-harvest-time").val(5);
	// Converts from edit modal to create modal
	$("#delete-harvestable-item-btn").hide();
	$("#save-harvestable-item-btn").text( getLocalizedText("menu:create") );
	$("#harvestable-item-map-blip").change();
    harvestableModal.modal("show");
})
$("#harvestable-choose-item-btn").click(async function() {
	const itemName = await itemsDialog();
    $("#harvestable-item-name").val(itemName);
})
$("#harvestable-current-coords-btn").click(async function(event) {
	if(event.shiftKey) {
		const coordsInUI = {
			x: parseFloat( $("#harvestable-coords-x").val() ),
			y: parseFloat( $("#harvestable-coords-y").val() ),
			z: parseFloat( $("#harvestable-coords-z").val() )
		}
		teleportToCoords(coordsInUI);
		return;
	}
	let coords = await getCurrentCoords()
	
	$("#harvestable-coords-x").val(coords.x);
	$("#harvestable-coords-y").val(coords.y);
	$("#harvestable-coords-z").val(coords.z);
})
$("#harvestable-item-map-blip").change(function() {
	let enabled = $(this).prop("checked");
	$("#harvestable-item-map-blip-inputs").find("input").prop("disabled", !enabled);
})
$("#harvestable-form").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	
	let harvestableItem = {
		name: $("#harvestable-item-name").val(),
		iconType: parseInt( $("#harvestable-icon-type").val() ),
		coords: {
			x: parseFloat( $("#harvestable-coords-x").val() ),
			y: parseFloat( $("#harvestable-coords-y").val() ),
			z: parseFloat( $("#harvestable-coords-z").val() ),
		},
		scale: {
			x: parseFloat( $("#harvestable-scale-x").val() ),
			y: parseFloat( $("#harvestable-scale-y").val() ),
			z: parseFloat( $("#harvestable-scale-z").val() ),
		},
		bounce: $("#harvestable-bounce").prop("checked"),
		followCamera: $("#harvestable-follow-camera").prop("checked"),
		rotate: $("#harvestable-rotate").prop("checked"),
		color: hexToRgb(  $("#harvestable-color").val() ),
		opacity: parseInt( $("#harvestable-opacity").val() ),
		timeToHarvest: parseInt( $("#harvestable-harvest-time").val() ),
		minQuantity: parseInt( $("#harvestable-min-quantity").val() ),
		maxQuantity: parseInt( $("#harvestable-max-quantity").val() )
	}
	let isBlipEnabled = $("#harvestable-item-map-blip").prop("checked");
	if( isBlipEnabled ) {
		harvestableItem.blipName = $("#harvestable-item-blip-name").val();
		harvestableItem.blipSprite = parseInt( $("#harvestable-item-sprite-id").val() );
		harvestableItem.blipColor = parseInt( $("#harvestable-item-blip-color").val() );
		harvestableItem.blipScale = parseFloat( $("#harvestable-item-blip-scale").val() );
	}
	let harvestableItemModal = $("#harvestable-item-modal");
	let action = $(harvestableItemModal).data("action");
	let response = null;
	switch(action) {
		case "create": {
			response = await $.post(`https://${resName}/createNewHarvestableItem`, JSON.stringify(harvestableItem));
			break;
		}
		case "edit": {
			let itemId = harvestableItemModal.data("itemId");
			response = await $.post(`https://${resName}/updateHarvestableItem`, JSON.stringify({
				itemId: itemId,
				itemData: harvestableItem
			}));
			break;
		}
	}
	harvestableItemModal.modal("hide");
	loadHarvestableItems();
	showServerResponse(response);
}) 
// Harvestable items edit
function editHarvestableItem(harvestableItemId) {
	let itemData = harvestableItems[harvestableItemId];
	$("#harvestable-item-name").val(itemData.name);
	$("#harvestable-icon-type").val(itemData.iconType);
	$("#harvestable-coords-x").val(itemData.coords.x);
	$("#harvestable-coords-y").val(itemData.coords.y);
	$("#harvestable-coords-z").val(itemData.coords.z);
	$("#harvestable-scale-x").val(itemData.scale.x);
	$("#harvestable-scale-y").val(itemData.scale.y);
	$("#harvestable-scale-z").val(itemData.scale.z);
	$("#harvestable-bounce").prop("checked", itemData.bounce);
	$("#harvestable-follow-camera").prop("checked", itemData.followCamera);
	$("#harvestable-rotate").prop("checked", itemData.rotate);
	$("#harvestable-color").val( rgbToHex(itemData.color.r, itemData.color.g, itemData.color.b) );
	$("#harvestable-opacity").val(itemData.opacity);
	$("#harvestable-harvest-time").val(itemData.timeToHarvest);
	$("#harvestable-min-quantity").val(itemData.minQuantity);
	$("#harvestable-max-quantity").val(itemData.maxQuantity);
	let mapBlipCheckbox = $("#harvestable-item-map-blip");
	if(itemData.blipSprite) {
		$("#harvestable-item-blip-name").val(itemData.blipName);
		$("#harvestable-item-sprite-id").val(itemData.blipSprite);
		$("#harvestable-item-blip-color").val(itemData.blipColor);
		$("#harvestable-item-blip-scale").val(itemData.blipScale);
		mapBlipCheckbox.prop("checked", true);
	} else {
		mapBlipCheckbox.prop("checked", false);
	}
	mapBlipCheckbox.change();
	let harvestableModal = $("#harvestable-item-modal");
	harvestableModal.data("itemId", harvestableItemId);
	harvestableModal.data("action", "edit");
	$("#delete-harvestable-item-btn").show();
	$("#save-harvestable-item-btn").text( getLocalizedText("menu:save") );
	harvestableModal.modal("show");
}
// Harvestable item delete
$("#delete-harvestable-item-btn").click(async function() {
	if(!await confirmDeletion()) return;
	let itemId = $("#harvestable-item-modal").data("itemId");
	const response = await $.post(`https://${resName}/deleteHarvestableItem`, JSON.stringify({
		itemId: itemId
	}));
	$("#harvestable-item-modal").modal("hide");
	loadHarvestableItems();
	showServerResponse(response);
})
// Drugs Fields
let drugsFieldsDatatable = $("#fields-container").DataTable({
	"lengthMenu": [10, 15, 20],
	"createdRow": function ( row, data, index ) {
		$(row).addClass("clickable");
		$(row).click(function() {
			let fieldId = parseInt(data[0]);
			editDrugField(fieldId);
		})
	},
} );
let drugsFields = {};
function loadDrugsFields() {
	$.post(`https://${resName}/getAllDrugsFields`, {}, function(rawDrugsFields) {
		// Manually create the table to avoid incompatibilities due table indexing
		drugsFields = {};
		for(const[k, fieldData] of Object.entries(rawDrugsFields)) {
			drugsFields[fieldData.id] = fieldData;
		}
		drugsFieldsDatatable.clear();
		for(const[fieldId, fieldData] of Object.entries(drugsFields)) {
			drugsFieldsDatatable.row.add([
				fieldId,
				fieldData.label,
				fieldData.radius,
				fieldData.coords.x,
				fieldData.coords.y,
				fieldData.coords.z,
			])
		}
		drugsFieldsDatatable.draw()
	})
}
$("#new-field-btn").click(function() {
	let fieldModal = $("#field-modal");
	fieldModal.data("action", "create");
	fieldModal.find("input").val("");
	$("#field-map-blip").prop("checked", false).change();
	// Converts from edit modal to create modal
	$("#delete-field-btn").hide();
	$("#save-field-btn").text( getLocalizedText("menu:create") );
	$("#fields-items").empty();
	addItemToField();
    fieldModal.modal("show");
})
$("#field-current-coords-btn").click(async function(event) {
	if(event.shiftKey) {
		const coordsInUI = {
			x: parseFloat( $("#field-coords-x").val() ),
			y: parseFloat( $("#field-coords-y").val() ),
			z: parseFloat( $("#field-coords-z").val() )
		}
		teleportToCoords(coordsInUI);
		return;
	}
	let coords = await getCurrentCoords();
	$("#field-coords-x").val(coords.x);
	$("#field-coords-y").val(coords.y);
	$("#field-coords-z").val(coords.z);
});
$("#field-required-item-choose-btn").click(async function() {
	const itemName = await itemsDialog();
	$("#field-required-item-name").val(itemName);
})
$("#field-required-item-toggle").change(function() {
	let enabled = $(this).prop("checked");
	
	$("#field-required-item-choose-btn").prop("disabled", !enabled);
	$("#field-required-item-lose-on-use").prop("disabled", !enabled);
	$("#field-required-item-name").prop("disabled", !enabled).prop("required", enabled);
})
async function addItemToField(itemData = {}) {
	let itemDiv = $(`
		
		
			
			${getLocalizedText("menu:choose_item")} 
			
			 
	`);
	resultItemDiv.find(".choose-item-btn").click(async function() {
		const itemName = await itemsDialog();
		resultItemDiv.find(".result-item-name").val(itemName);
	})
	resultItemDiv.find(".remove-result-item-btn").click(function() {
		resultItemDiv.remove();
	})
	craftingRecipeContainer.append(resultItemDiv);
}
$("#crafting-recipe-add-result-item-btn").click(function() {
	addResultItemInCraftingRecipe();
})
function addIngredientInCraftingRecipe(ingredientName = "", ingredientMinQuantity = 1, ingredientMaxQuantity = 3, ingredientPerfectQuantity = 2, loseOnUse = true) {
	let ingredientsContainer = $("#crafting-recipe-ingredients-container");
	let ingredientDiv = $(`
		
		
			
			${getLocalizedText("menu:choose_item")} 
			
			 
	`);
	rewardItemDiv.find(".choose-item-btn").click(async function() {
		const itemName = await itemsDialog();
		rewardItemDiv.find(".reward-item-name").val(itemName);
	})
	rewardItemDiv.find(".remove-reward-item-btn").click(function() {
		rewardItemDiv.remove();
	})
	rewardsContainer.append(rewardItemDiv);
}
$("#crafting-recipe-add-reward-item-btn").click(function() {
	addRewardItemInCraftingRecipe();
})
// Laboratories
let laboratoriesDatatable = $("#laboratories-container").DataTable( {
	"lengthMenu": [10, 15, 20],
	"createdRow": function ( row, data, index ) {
		$(row).addClass("clickable");
		$(row).click(function() {
			let laboratoryId = parseInt(data[0]);
			editLaboratory(laboratoryId);
		})
	},
} );
let laboratories = {};
function loadLaboratories() {
	$.post(`https://${resName}/getAllLaboratories`, {}, function(rawLaboratories) {
		// Manually create the table to avoid incompatibilities due table indexing
		laboratories = {};
		for(const[k, laboratoryData] of Object.entries(rawLaboratories)) {
			laboratories[laboratoryData.id] = laboratoryData;
		}
		laboratoriesDatatable.clear();
		for(const[laboratoryId, laboratoryData] of Object.entries(laboratories)) {
			laboratoriesDatatable.row.add([
				laboratoryId,
				laboratoryData.name,
				laboratoryData.coords.x,
				laboratoryData.coords.y,
				laboratoryData.coords.z,
			])
		}
		laboratoriesDatatable.draw()
	})
}
// Create new laboratory
$("#new-laboratory-btn").click(function() {
	let laboratoryModal = $("#laboratory-modal");
	laboratoryModal.modal("show");
	laboratoryModal.data("action", "create");
	$("#laboratory-name").val("");
	$("#laboratory-coords-x").val("");
	$("#laboratory-coords-y").val("");
	$("#laboratory-coords-z").val("");
	$("#laboratory-scale-x").val("1.5");
	$("#laboratory-scale-y").val("1.5");
	$("#laboratory-scale-z").val("0.5");
	$("#laboratory-icon-type").val("1");
	$("#laboratory-opacity").val("100");
	$("#laboratory-map-blip").prop("checked", false).change();
	// Resets stuff related to allowed jobs (all allowed)
	setLaboratoryAllowedJobsText(false);
	$("#laboratory-allowed-jobs").data("jobs", false);
	// Resets stuff related to allowed recipes
	$("#laboratory-allowed-crafting-recipes").text(getLocalizedText("menu:no_crafting_recipe_allowed"));
	$("#laboratory-allowed-crafting-recipes").data("craftingRecipes", {});
	// Adapts the modal from edit mode to create mode
	$("#delete-laboratory-btn").hide();
	$("#laboratory-modal-confirm-btn").text(  getLocalizedText("menu:create") );
})
function setLaboratoryAllowedJobsText(jobs) {
	if(jobs === false) {
		$("#laboratory-allowed-jobs").text(getLocalizedText("menu:all_jobs_allowed"));
	} else if(Object.keys(jobs).length == 0) {
		$("#laboratory-allowed-jobs").text(getLocalizedText("menu:no_job_allowed"));
	} else {
		$("#laboratory-allowed-jobs").text(  Object.keys(jobs).join(", ") );
	}
}
$("#laboratory-choose-jobs").click(async function() {
	const oldJobs = $("#laboratory-allowed-jobs").data("jobs");
	const jobs = await jobsDialog(oldJobs);
		
	setLaboratoryAllowedJobsText(jobs);
	$("#laboratory-allowed-jobs").data("jobs", jobs)
})
// Dialog that shows all crafting recipes and returns the selected ones
function craftingRecipesDialog(cb) {
	let inputCraftingRecipesModal = $("#input-crafting-recipes-dialog-modal")
	inputCraftingRecipesModal.modal("show");
	$("#input-crafting-recipes-search").val("");
	$.post(`https://${resName}/getAllCraftingRecipes`, JSON.stringify({}), function (craftingRecipes) {
		let craftingRecipesListDiv = $("#crafting-recipes-list");
		craftingRecipesListDiv.empty();
		
		for(const[k, craftingRecipeData] of Object.entries(craftingRecipes)) {
			let craftingRecipeDiv = $(`
			
				
					${craftingRecipeData.name}
				 
			
		`);
		craftingRecipesListDiv.append(craftingRecipeDiv);
		}
		// Unbinds the button and rebinds it to callback the selected crafting recipes
		$("#input-crafting-recipes-confirm-btn").unbind().click(function() {
			let selectedCraftingRecipes = {};
			craftingRecipesListDiv.find("input:checked").each(function() {
				let recipeId = $(this).val();
				selectedCraftingRecipes[recipeId] = true;
			});
			inputCraftingRecipesModal.modal("hide");
			cb(selectedCraftingRecipes);
		})
	});
}
$("#input-crafting-recipe-search").on("keyup", function() {
	let text = $(this).val().toLowerCase();
	$("#crafting-recipes-list .form-check").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
    });
})
// Choose crafting recipes for laboratory
$("#laboratory-choose-recipes").click(function() {
	craftingRecipesDialog((selectedRecipes) => {
		if(Object.keys(selectedRecipes).length == 0) {
			$("#laboratory-allowed-crafting-recipes").text(getLocalizedText("menu:no_crafting_recipe_allowed"));
		} else {
			$("#laboratory-allowed-crafting-recipes").text(Object.keys(selectedRecipes).map(recipeId => craftingRecipes[recipeId].name).join(", "));
		}
		$("#laboratory-allowed-crafting-recipes").data("recipes", selectedRecipes);
	})
})
// Sets current coords for laboratory
$("#laboratory-current-coords-btn").click(async function(event) {
	if(event.shiftKey) {
		const coordsInUI = {
			x: parseFloat( $("#laboratory-coords-x").val() ),
			y: parseFloat( $("#laboratory-coords-y").val() ),
			z: parseFloat( $("#laboratory-coords-z").val() )
		}
		teleportToCoords(coordsInUI);
		return;
	}
	const coords = await getCurrentCoords();
	$("#laboratory-coords-x").val(coords.x);
	$("#laboratory-coords-y").val(coords.y);
	$("#laboratory-coords-z").val(coords.z);
})
// To edit an existing laboratory
function editLaboratory(laboratoryId) {
	let laboratoryModal = $("#laboratory-modal");
	laboratoryModal.data("laboratoryId", laboratoryId);
	laboratoryModal.data("action", "edit");
	let laboratoryData = laboratories[laboratoryId];
	$("#laboratory-name").val(laboratoryData.name);
	$("#laboratory-coords-x").val(laboratoryData.coords.x);
	$("#laboratory-coords-y").val(laboratoryData.coords.y);
	$("#laboratory-coords-z").val(laboratoryData.coords.z);
	$("#laboratory-scale-x").val(laboratoryData.scale.x);
	$("#laboratory-scale-y").val(laboratoryData.scale.y);
	$("#laboratory-scale-z").val(laboratoryData.scale.z);
	
	$("#laboratory-bounce").prop("checked", laboratoryData.bounce);
	$("#laboratory-follow-camera").prop("checked", laboratoryData.followCamera);
	$("#laboratory-rotate").prop("checked", laboratoryData.rotate);
	
	$("#laboratory-icon-type").val(laboratoryData.iconType);
	
	$("#laboratory-color").val( rgbToHex(laboratoryData.color.r, laboratoryData.color.g, laboratoryData.color.b) );
	$("#laboratory-opacity").val(laboratoryData.opacity);
	let mapBlipCheckbox = $("#laboratory-map-blip");
	if(laboratoryData.blipSprite) {
		$("#laboratory-blip-name").val(laboratoryData.blipName);
		$("#laboratory-sprite-id").val(laboratoryData.blipSprite);
		$("#laboratory-blip-color").val(laboratoryData.blipColor);
		$("#laboratory-blip-scale").val(laboratoryData.blipScale);
		mapBlipCheckbox.prop("checked", true);
	} else {
		mapBlipCheckbox.prop("checked", false);
	}
	mapBlipCheckbox.change();
	setLaboratoryAllowedJobsText(laboratoryData.allowedJobs);
	$("#laboratory-allowed-jobs").data("jobs", laboratoryData.allowedJobs);
	let sanitizedAllowedRecipes = {};
	Object.keys(laboratoryData.allowedRecipes).forEach(recipeId => {
		if(recipeId == 0) {
			recipeId = 1;
		}
		sanitizedAllowedRecipes[recipeId] = true;
	});
	$("#laboratory-allowed-crafting-recipes").text( Object.keys(sanitizedAllowedRecipes).map(recipeId => craftingRecipes[recipeId] ? craftingRecipes[recipeId].name : null).join(", ") );
	$("#laboratory-allowed-crafting-recipes").data("recipes", sanitizedAllowedRecipes);
	// Adatps the modal from create mode to edit mode
	$("#delete-laboratory-btn").show();
	$("#laboratory-modal-confirm-btn").text(  getLocalizedText("menu:save") );
	laboratoryModal.modal("show");
}
// To delete an existing laboratory
$("#delete-laboratory-btn").click(async function() {
	if(!await confirmDeletion()) return;
	let laboratoryId = $("#laboratory-modal").data("laboratoryId");
	if(laboratoryId == null) return;
	const response = await $.post(`https://${resName}/deleteLaboratory`, JSON.stringify({
		laboratoryId: laboratoryId
	}));
	showServerResponse(response);
	$("#laboratory-modal").modal("hide");
	loadLaboratories();
})
$("#laboratory-map-blip").change(function() {
	let enabled = $(this).prop("checked");
	$("#laboratory-map-blip-inputs").find("input").prop("disabled", !enabled);
})
// Gets the laboratory data from its modal
function getLaboratoryData() {
	let laboratoryData = {
		name: $("#laboratory-name").val(),
		coords: {
			x: parseFloat( $("#laboratory-coords-x").val() ),
			y: parseFloat( $("#laboratory-coords-y").val() ),
			z: parseFloat( $("#laboratory-coords-z").val() )
		},
		iconType: parseInt( $("#laboratory-icon-type").val() ),
		scale: {
			x: parseFloat( $("#laboratory-scale-x").val() ),
			y: parseFloat( $("#laboratory-scale-y").val() ),
			z: parseFloat( $("#laboratory-scale-z").val() ),
		},
		bounce: $("#laboratory-bounce").prop("checked"),
		followCamera: $("#laboratory-follow-camera").prop("checked"),
		rotate: $("#laboratory-rotate").prop("checked"),
		color: hexToRgb(  $("#laboratory-color").val() ),
		opacity: parseInt( $("#laboratory-opacity").val() ),
		allowedJobs: $("#laboratory-allowed-jobs").data("jobs"),
		allowedRecipes: $("#laboratory-allowed-crafting-recipes").data("recipes") || {}
	}
	let isBlipEnabled = $("#laboratory-map-blip").prop("checked");
	if( isBlipEnabled ) {
		laboratoryData.blipName = $("#laboratory-blip-name").val();
		laboratoryData.blipSprite = parseInt( $("#laboratory-sprite-id").val() );
		laboratoryData.blipColor = parseInt( $("#laboratory-blip-color").val() );
		laboratoryData.blipScale = parseFloat( $("#laboratory-blip-scale").val() );
	}
	return laboratoryData;
}
// Saves laboratory data
$("#laboratory-form").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	
	let laboratoryModal = $("#laboratory-modal");
	let laboratoryData = getLaboratoryData();
	let action = laboratoryModal.data("action");
	let response = null;
	switch(action) {
		case "create": {
			response = await $.post(`https://${resName}/createNewLaboratory`, JSON.stringify(laboratoryData))
			break;
		}
		case "edit": {
			let laboratoryId = laboratoryModal.data("laboratoryId");
			response = await $.post(`https://${resName}/updateLaboratory`, JSON.stringify({laboratoryId: laboratoryId, laboratoryData: laboratoryData}))
			break;
		}
	}
	showServerResponse(response);
	
	laboratoryModal.modal("hide");
	loadLaboratories();
})
function addRequiredItemInPocketCrafting(pocketCraftingDiv, itemName = "", itemQuantity = 1, loseOnUse = true) {
	let requiredItemsContainer = pocketCraftingDiv.find(".pocket-crafting-required-items");
	let requiredItemDiv = $(`
		
	`);
	requiredItemDiv.find(".choose-item-btn").click(async function() {
		const itemName = await itemsDialog();
		requiredItemDiv.find(".required-item-name").val(itemName);
	}).tooltip();
	requiredItemDiv.find(".remove-required-item-btn").click(function() {
		requiredItemDiv.remove();
	});
	requiredItemsContainer.append(requiredItemDiv);
}	
async function addPocketCrafting(itemName, pocketCraftingData, isNew = false) {
	const itemLabel = await getItemLabel(itemName) || "Unknown item - " + itemName;
	
	const div = $(`
		
			${getLocalizedText("menu:you_have_to_use")} '${itemLabel}'  ${getLocalizedText("menu:to_start_the_crafting")} (${itemName})  
			
			${getLocalizedText("menu:pocket_craftings:required_items")} 
			
			
			
			
				${getLocalizedText("menu:pocket_craftings:delete_pocket_crafting")} 
				${getLocalizedText("menu:pocket_craftings:add_required_item")} 
			
		 
		 - ${ getLocalizedText("menu:effects:may_need_restart") } `)
	}
	$("#pocket-craftings-list").append(div);
}
// Pocket sellings
$("#create-new-pocket-crafting-btn").click(async function() {
	const itemName = await itemsDialog(getLocalizedText("menu:choose_the_item_that_will_start_pocket_crafting_on_use"));
	if(!itemName) return;
	addPocketCrafting(itemName, null, true);
});
function getAllPocketCraftings() {
	const pocketCraftings = {};
	$("#pocket-craftings-list").find(".pocket-crafting").each(function() {
		const itemName = $(this).data("itemToUse");
		const pocketCrafting = {
			resultItem: {
				name: $(this).find(".result-item-name").val(),
				quantity: parseInt($(this).find(".item-quantity").val())
			},
			timeToCraft: parseInt($(this).find(".time-to-craft").val()),
			requiredItems: []
		};
		$(this).find(".required-item").each(function() {
			const requiredItem = {
				name: $(this).find(".required-item-name").val(),
				quantity: parseInt($(this).find(".required-item-quantity").val()),
				loseOnUse: $(this).find(".form-check-input").prop("checked")
			};
			pocketCrafting.requiredItems.push(requiredItem);
		});
		pocketCraftings[itemName] = pocketCrafting;
	});
	return pocketCraftings;
}
$("#pocket-craftings").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	let serverSettings = {
		pocketCraftings: getAllPocketCraftings(),
	}
	const response = await $.post(`https://${resName}/saveSettings`, JSON.stringify({
		clientSettings: {},
		serverSettings: serverSettings,
		sharedSettings: {}
	}));
	showServerResponse(response);
});
// Plane selling
$("#plane-selling-current-coords-btn").click(async function(event) {
	if(event.shiftKey) {
		const coordsInUI = {
			x: parseFloat( $("#plane-selling-coords-x").val() ),
			y: parseFloat( $("#plane-selling-coords-y").val() ),
			z: parseFloat( $("#plane-selling-coords-z").val() )
		}
		teleportToCoords(coordsInUI);
		return;
	}
	const coords = await getCurrentCoords();
	
	$("#plane-selling-coords-x").val(coords.x);
	$("#plane-selling-coords-y").val(coords.y);
	$("#plane-selling-coords-z").val(coords.z);
})
function togglePlaneWholeOcean() {
	let enabled = $("#plane-use-the-whole-ocean").prop("checked");
	$("#plane-selling-coords").find("input").prop("disabled", enabled);
}
$("#plane-use-the-whole-ocean").change(togglePlaneWholeOcean);
$("#plane-add-new-drug").click(function() {
	addAcceptableDrugToDiv("#plane-selling-acceptable-drugs");
})
// Enables/Disables all inputs for plane selling
function togglePlaneSelling() {
	let enable = $("#enable-plane-selling").prop("checked");
	$("#selling-plane").find("input, button").not("#enable-plane-selling").prop("disabled", !enable);
}
$("#enable-plane-selling").change(togglePlaneSelling);
// Boat selling
$("#boat-selling-current-coords-btn").click(async function(event) {
	if(event.shiftKey) {
		const coordsInUI = {
			x: parseFloat( $("#boat-selling-coords-x").val() ),
			y: parseFloat( $("#boat-selling-coords-y").val() ),
			z: parseFloat( $("#boat-selling-coords-z").val() )
		}
		teleportToCoords(coordsInUI);
		return;
	}
	const coords = await getCurrentCoords();
	$("#boat-selling-coords-x").val(coords.x);
	$("#boat-selling-coords-y").val(coords.y);
	$("#boat-selling-coords-z").val(coords.z);
});
function toggleBoatWholeOcean() {
	let enabled = $("#boat-use-the-whole-ocean").prop("checked");
	$("#boat-selling-coords").find("input").prop("disabled", enabled);
}
$("#boat-use-the-whole-ocean").change(toggleBoatWholeOcean);
$("#boat-add-new-drug").click(function() {
	addAcceptableDrugToDiv("#boat-selling-acceptable-drugs");
})
function toggleBoatSelling() {
	let enable = $("#enable-boat-selling").prop("checked");
	$("#selling-boat").find("input, button").not("#enable-boat-selling").prop("disabled", !enable);
}
$("#enable-boat-selling").change(toggleBoatSelling);
// NPC Selling
function toggleNpcSelling() {
	let enable = $("#enable-npc-selling").prop("checked");
	$("#selling-npc").find("input, button").not("#enable-npc-selling").prop("disabled", !enable);
}
$("#enable-npc-selling").change(toggleNpcSelling);
function addAcceptableDrugToDiv(drugsListDiv, drugName = "", minPrice = 500, maxPrice = 1000) {
	let drugDiv = $(`
		
	`)
	drugDiv.find(".choose-item-btn").click(async function() {
		const itemName = await itemsDialog();
		drugDiv.find(".drug-name").val(itemName);
	}).tooltip();
	drugDiv.find(".remove-btn").click(function() {
		drugDiv.remove();
	});
	$(drugsListDiv).append(drugDiv);
}
function fillAcceptableDrugsForDiv(drugsListDiv, drugs) {
	$(drugsListDiv).empty();
	if(drugs) {
		for(drug of drugs) {
			addAcceptableDrugToDiv(drugsListDiv, drug.name, drug.minPrice, drug.maxPrice);
		}
	}
}
function getAcceptableDrugFromDiv(drugsListDiv) {
	let drugs = [];
	$(drugsListDiv).find(".drug").each(function() {
		let drug = {
			name: $(this).find(".drug-name").val(),
			minPrice: parseInt( $(this).find(".drug-min-price").val() ),
			maxPrice: parseInt( $(this).find(".drug-max-price").val() ),
		}
		drugs.push(drug);
	})
	return drugs;
}
$("#npc-add-new-drug").click(function() {
	addAcceptableDrugToDiv("#npc-selling-acceptable-drugs");
})
$("#npc-selling-command-is-enabled").change(function() {
	const enabled = $(this).prop("checked");
	$("#npc-selling-command").prop("disabled", !enabled);
	$("#npc-selling-command-has-to-spawn-npc").prop("disabled", !enabled);
});
// Save selling
$("#selling").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	let clientSettings = {
		// Boat and plane selling
		heightToSell: parseInt( $("#minimum-plane-height").val() ),
		sellUseWholeOcean:  {
			plane: $("#plane-use-the-whole-ocean").prop("checked"),
			boat: $("#boat-use-the-whole-ocean").prop("checked")
		},
		sellArea: {
			plane: {
				coords: {
					x: parseFloat( $("#plane-selling-coords-x").val() ),
					y: parseFloat( $("#plane-selling-coords-y").val() ),
					z: parseFloat( $("#plane-selling-coords-z").val() )
				},
	
				radius: parseFloat( $("#plane-selling-coords-radius").val() )
			},
			boat: {
				coords: {
					x: parseFloat( $("#boat-selling-coords-x").val() ),
					y: parseFloat( $("#boat-selling-coords-y").val() ),
					z: parseFloat( $("#boat-selling-coords-z").val() )
				},
				radius: parseFloat( $("#boat-selling-coords-radius").val() )
			}
		},
		sellShowRadius: {
			plane: $("#plane-show-radius-while-selling").prop("checked"),
			boat: $("#boat-show-radius-while-selling").prop("checked")
		},
		// Narcos selling
		narcosModel: $("#narcos-model").val(),
		showNarcosBlip: $("#enable-narcos-blip").prop("checked"),
		narcosBlip: {
			name: $("#narcos-selling-blip-name").val(),
			color: parseInt( $("#narcos-selling-blip-color").val() ),
			scale: parseFloat( $("#narcos-selling-blip-scale").val() ),
			sprite: parseInt( $("#narcos-selling-blip-sprite").val() )
		},
		// Pushers selling
		pusherModel: $("#pushers-model").val(),
		showPushersBlips: $("#enable-pushers-blip").prop("checked"),
		pusherBlip: {
			name: $("#pushers-selling-blip-name").val(),
			color: parseInt( $("#pushers-selling-blip-color").val() ),
			scale: parseFloat( $("#pushers-selling-blip-scale").val() ),
			sprite: parseInt( $("#pushers-selling-blip-sprite").val() )
		}
	}
	let serverSettings = {
		rewards: {
			plane: getRewardDivData("#plane-selling-reward-div"),
			boat: getRewardDivData("#boat-selling-reward-div"),
			npc: getRewardDivData("#npc-selling-reward-div"),
			narcos: getRewardDivData("#narcos-selling-reward-div"),
			pushers: getRewardDivData("#pushers-selling-reward-div")
		},
		// Plane selling
		planeAcceptableDrugs: getAcceptableDrugFromDiv("#plane-selling-acceptable-drugs"),
		planeSellingMinimumPolice: parseInt( $("#plane-minimum-police").val() ),
		// Boat selling
		boatAcceptableDrugs: getAcceptableDrugFromDiv("#boat-selling-acceptable-drugs"),
		boatSellingMinimumPolice: parseInt( $("#boat-minimum-police").val() ),
		// NPC selling
		minNPCSellQuantity: parseInt( $("#npc-selling-min-quantity").val() ),
		maxNPCSellQuantity: parseInt( $("#npc-selling-max-quantity").val() ),
		sellToNPCChancesToAccept: parseInt( $("#npc-accept-chances").val() ),
		maxNPCsSellableDrugQuantity: parseInt( $("#npc-max-drug-quantity").val() ),
		npcAcceptableDrugs: getAcceptableDrugFromDiv("#npc-selling-acceptable-drugs"),
		npcSellingMinimumPolice: parseInt( $("#npc-minimum-police").val() ),
		npcAlertPoliceChances: parseInt( $("#npc-alert-police-chances").val() ),
		canNPCRobPlayer: $("#npc-can-rob-player").prop("checked"),
		canNPCAttackPlayer: $("#npc-can-attack-player").prop("checked"),
		// Narcos selling
		narcosBuyerLocations: getNarcosBuyerLocations(),
		narcosLocationChangeTime: parseInt( $("#narcos-location-change").val() ),
		narcosCallPoliceChances: parseInt( $("#narcos-police-alert-chances").val() ),
		narcosAcceptsOnlyOneBuyerPerLocation: $("#narcos-accepts-only-one-buyer-per-location").prop("checked"),
		
		narcosNeededDrugs: getNarcosDrugs(),
		narcosSellingMinimumPolice: parseInt( $("#narcos-minimum-police").val() ),
		// Pushers selling
		pushersCallPoliceChances: parseInt( $("#pushers-alert-police-chances").val() ),
		pushers: getPushers(),
		pushersSellingMinimumPolice: parseInt( $("#pushers-minimum-police").val() ),
	}
	let sharedSettings = {
		enableAirplaneSell: $("#enable-plane-selling").prop("checked"),
		enableBoatSell: $("#enable-boat-selling").prop("checked"),
		timeToSellInPlane: parseInt( $("#time-to-sell-in-plane").val() ),
		timeToSellInBoat: parseInt( $("#time-to-sell-in-boat").val() ),
		alarmPoliceInPlane: $("#enable-plane-police-alert").prop("checked"),
		alarmPoliceInBoat: $("#enable-boat-police-alert").prop("checked"),
		// NPC selling
		npcSecondsToSell: parseInt( $("#npc-seconds-to-sell").val() ),
		// Pushers selling
		arePushersEnabled: $("#enable-pushers-selling").prop("checked"),
		// Narcos selling
		enableNarcosSelling: $("#enable-narcos-selling").prop("checked"),
		enableNPCSell: $("#enable-npc-selling").prop("checked"),
	}
	const response = await $.post(`https://${resName}/saveSettings`, JSON.stringify({
		clientSettings: clientSettings,
		serverSettings: serverSettings,
		sharedSettings: sharedSettings
	}));
	showServerResponse(response);
})
// Narcos selling
function toggleNarcosSelling() {
	let narcosSelling = $("#enable-narcos-selling").prop("checked");
	
	$("#selling-narcos").find("input, button").not("#enable-narcos-selling").prop("disabled", !narcosSelling);
}
$("#enable-narcos-selling").change(toggleNarcosSelling);
function toggleNarcosBlip() {
	let narcosBlip = $("#enable-narcos-blip").prop("checked");
	$("#narcos-selling-blip-name").prop("disabled", !narcosBlip);
	$("#narcos-selling-blip-color").prop("disabled", !narcosBlip);
	$("#narcos-selling-blip-scale").prop("disabled", !narcosBlip);
	$("#narcos-selling-blip-sprite").prop("disabled", !narcosBlip);
}
$("#enable-narcos-blip").change(toggleNarcosBlip);
function addNarcosSpawnLocation(coords = {}, heading = 0.0) {
	let newSpawnDiv = $(`
		
			
			${ getLocalizedText("menu:current_coords_heading") } 
		 
	`)
	newSpawnDiv.find(".max-two-decimals").on("change", maxTwoDecimals);
	newSpawnDiv.find(".current-coords-btn").click(async function(event) {
		if(event.shiftKey) {
			const coordsInUI = {
				x: parseFloat( newSpawnDiv.find(".coord-x").val() ),
				y: parseFloat( newSpawnDiv.find(".coord-y").val() ),
				z: parseFloat( newSpawnDiv.find(".coord-z").val() )
			}
	
			teleportToCoords(coordsInUI, parseFloat(newSpawnDiv.find(".heading").val()));
			return;
		}
	
		const data = await getCurrentCoordsAndHeading();
	
		newSpawnDiv.find(".coord-x").val(data.coords.x);
		newSpawnDiv.find(".coord-y").val(data.coords.y);
		newSpawnDiv.find(".coord-z").val(data.coords.z);
		newSpawnDiv.find(".heading").val(data.heading);
	});
	newSpawnDiv.find(".remove-btn").click(function() {
		newSpawnDiv.remove();
	});
	$("#narcos-spawn-locations").append(newSpawnDiv);
}
$("#narcos-add-spawn-btn").click(function() {
	addNarcosSpawnLocation();
})
function getNarcosBuyerLocations() {
	let buyerLocations = [];
	$("#narcos-spawn-locations").find(".spawn-location").each(function() {
		let spawnDiv = $(this);
		let coords = {
			x: parseFloat( spawnDiv.find(".coord-x").val() ),
			y: parseFloat( spawnDiv.find(".coord-y").val() ),
			z: parseFloat( spawnDiv.find(".coord-z").val() )
		};
		let heading = parseFloat( spawnDiv.find(".heading").val() );
		buyerLocations.push({
			coords: coords,
			heading: heading
		});
	})
	return buyerLocations;
}
function addNarcosDrug(drugName = "", minQuantity = 1, maxQuantity = 2, minPrice = 500, maxPrice = 1000) {
	let drugDiv = $(`
		
	`)
	drugDiv.find(".choose-item-btn").click(async function() {
		const itemName = await itemsDialog();
		drugDiv.find(".drug-name").val(itemName);
	}).tooltip();
	drugDiv.find(".remove-btn").click(function() {
		drugDiv.remove();
	});
	$("#narcos-selling-acceptable-drugs").append(drugDiv);
}
$("#narcos-add-new-drug").click(function() {
	addNarcosDrug();
})
function getNarcosDrugs() {
	let drugs = [];
	$("#narcos-selling-acceptable-drugs").find(".drug").each(function() {
		let drug = {
			name: $(this).find(".drug-name").val(),
			minPrice: parseInt( $(this).find(".drug-min-price").val() ),
			maxPrice: parseInt( $(this).find(".drug-max-price").val() ),
			minQuantity: parseInt( $(this).find(".drug-min-quantity").val() ),
			maxQuantity: parseInt( $(this).find(".drug-max-quantity").val() )
		}
		drugs.push(drug);
	})
	return drugs;
}
// Pushers
function togglePushersSelling() {
	let enabled = $("#enable-pushers-selling").prop("checked");
	$("#selling-pushers").find("input, button").not("#enable-pushers-selling").prop("disabled", !enabled);
}
$("#enable-pushers-selling").change(togglePushersSelling);
function addPusherDrug(pusherDiv, drugData = {}) {
	let drugDiv = $(`
		
	`);
	drugDiv.find(".btn-close").click(function() {
		drugDiv.remove();
	});
	// Initialize tooltip so player knows what the field is for
	drugDiv.find(".drug-max-quantity").tooltip();
	drugDiv.find(".choose-item-btn").tooltip();
	drugDiv.find(".choose-item-btn").click(async function() {
		const itemName = await itemsDialog();
		drugDiv.find(".drug-name").val(itemName);
	})
	pusherDiv.find(".pusher-drugs-list").append(drugDiv);
}
function addPusher(pusherData = {}) {
	let pusherDiv = $(`
		
			
				${ getLocalizedText("menu:pushers:location") }
				
				${ getLocalizedText("menu:current_coords_heading") } 
			 
			
			${ getLocalizedText("menu:pushers:work_time") }
			${ getLocalizedText("menu:pushers:work_time:subtitle") } - 
			
			
				${ getLocalizedText("menu:pushers:acceptable_drugs") }
				
				
				
			 
			${ getLocalizedText("menu:remove") } 
		 
		
			${itemLabel} (${itemName}) 
			
				${ getLocalizedText("menu:effects:taking_method") }
				
				${ getLocalizedText("menu:effects:drunk_effects") }
				
				${ getLocalizedText("menu:effects:visual_color_effects") }
				
				${ getLocalizedText("menu:effects:perks") }
				
				${ getLocalizedText("menu:effects:cumulative_effect") }
				
				${ getLocalizedText("menu:effects:special_effect") }
				
				
					${ getLocalizedText("menu:effects:duration") } 
				
			 
			
				${ getLocalizedText("menu:effects:remove_this_effect") } 
			
		 
		 - ${ getLocalizedText("menu:effects:may_need_restart") } `)
	}
	itemEffectDiv.data("itemName", itemName);
	itemEffectDiv.find(".remove-effect-btn").click(function() {
		itemEffectDiv.remove();
	})
	$("#drugs-effects").append(itemEffectDiv);
}
function getEffectsDataFromDiv(effectDiv, itemName) {
	let effectData = {
		takingMethod: $(`input[name=drug-assume-type-${itemName}]:checked`).val(),
		effects: [],
		effectsDuration: parseInt( effectDiv.find(".effect-duration").val() ),
		cumulativeEffects: []
	};
	let visualColorEffect = $(`input[name=camera-color-effects-${itemName}]:checked`).val();
	if(visualColorEffect != "none") {
		effectData.effects.push(visualColorEffect)
	}
	const specialEffect = $(`input[name=drug-special-effect-${itemName}]:checked`).val();
	if(specialEffect != "none") {
		effectData.effects.push(specialEffect)
	}
	effectDiv.find(".cumulative-effect").each(function() {
		if (!$(this).find(".cumulative-effect-checkbox").prop("checked")) return;
		const type = $(this).data("cumulativeName");
		const action = $(this).find("input[type=radio]:checked").val() || "increase"; // In case people don't select any
		const amount = parseInt( $(this).find(".cumulative-effect-amount").val() );
		effectData.cumulativeEffects.push({type, action, amount});
	});
	effectDiv.find(".stackable-effect:checked").each(function() {
		effectData.effects.push( $(this).val() );
	});
	return effectData;
}
function getAllEffectsData() {
	let effectsData = {};
	$("#drugs-effects").find(".drug-effect").each(function() {
		let itemName = $(this).data("itemName");
		effectsData[itemName] = getEffectsDataFromDiv($(this), itemName);
	});
	return effectsData;
}
$("#create-new-item-effect-btn").click(async function() {
	const itemName = await itemsDialog();
	addItemEffect(itemName, {}, true);
});
// Saves the new effects
$("#effects").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	let serverSettings = {
		drugsEffects: getAllEffectsData(),
	}
	let clientSettings = {}
	let sharedSettings = {}
	const response = await $.post(`https://${resName}/saveSettings`, JSON.stringify({
		clientSettings: clientSettings,
		serverSettings: serverSettings,
		sharedSettings: sharedSettings
	}));
	showServerResponse(response);
});
/* AUCTIONS */
let auctionsDatatable = $("#auctions-container").DataTable( {
	"lengthMenu": [10, 15, 20],
	"columnDefs": [
        { 
            "targets": -1, // Ultima colonna
            "data": null,
			"className": "col-1",
            "defaultContent": `
			
				
			`
        }
    ],
	"createdRow": function ( row, data, index ) {
		$(row).addClass("clickable");
		$(row).click(function() {
			let auctionId = parseInt(data[0]);
			editAuction(auctionId);
		});
		$(row).find(".force-start-auction-btn").click(async function(event) {
			event.stopPropagation();
			const auctionId = parseInt(data[0]);
			$.post(`https://${resName}/forceStartAuction`, JSON.stringify({auctionId}));
		}).tooltip().prop("title", getLocalizedText("menu:start_now"));
	},
} );
let auctions = {};
async function loadAuctions() {
	const rawAuctions = await $.post(`https://${resName}/getAllAuctions`);
	// Manually create the table to avoid incompatibilities due table indexing
	auctions = {};
	for(const[k, auction] of Object.entries(rawAuctions)) {
		auctions[auction.id] = auction;
	}
	auctionsDatatable.clear();
	for(const[auctionId, auction] of Object.entries(auctions)) {
		auctionsDatatable.row.add([
			auctionId || "???",
			auction.label || "???",
		])
	}
	auctionsDatatable.draw()
}
function setAuctionConfig(auction) {
	const config = auction ? auction.config : {};
	$("#auction-label").val(auction?.label || "Default");
	$("#auction-min-players-online").val(config.minPlayersForAuction ?? 3);
	$("#auction-min-police-online").val(config.minPoliceOnline ?? 0);
	$("#auction-randomize-items").prop("checked", config.randomizeItems ?? false);
	$("#auction-multiplier").val(config.multiplier ?? 1);
	$("#auction-max-rounds").val(config.maxRounds ?? 3);
	$("#auction-alert-police-after-round").val(config.alertPoliceAfterRound ?? 2);
	$("#auction-time-between-rounds").val(config.timeBetweenRoundsSeconds ?? 30);
	$("#auction-warning-before-start").val(config.warningBeforeAuctionStartMinutes ?? 15);
	$("#auction-no-bid-timeout").val(config.noBidTimeoutSeconds ?? 30);
	$("#auction-min-bid-increment").val(config.minBidIncrement ?? 100);
	$("#auction-blip-btn").data("blipData", config.blipData ?? getDefaultBlipCustomization());
	if(config.accountToPayWith) {
		setRewardDivData("#auction-account-to-pay-with", config.accountToPayWith);
	}
	// Locations
	$("#auction-locations-list").empty();
	if(config.locations) {
		config.locations.forEach(location => {
			addAuctionLocation(location);
		});
	}
	// Items
	$("#auction-items-list").empty();
	if(config.objectsRewards) {
		config.objectsRewards.forEach(item => {
			addAuctionItem(item);
		});
	}
}
$("#new-auction-btn").click(function() {
	let auctionModal = $("#auction-modal");
	auctionModal.modal("show");
	auctionModal.data("action", "create");
	setAuctionConfig();
	
	// Adapts the modal from edit mode to create mode
	$("#delete-auction-btn").hide();
	$("#auction-modal-confirm-btn").text(  getLocalizedText("menu:create") );
})
function editAuction(auctionId) {
	let auction = auctions[auctionId];
	let auctionModal = $("#auction-modal");
	auctionModal.modal("show");
	auctionModal.data("action", "edit");
	auctionModal.data("auctionId", auctionId);
	setAuctionConfig(auction);
	// Adapts the modal from create mode to edit mode
	$("#delete-auction-btn").show();
	$("#auction-modal-confirm-btn").text( getLocalizedText("menu:save") );
}
function getAuctionSetup() {
	return {
		label: $("#auction-label").val(),
		config: {
			minPlayersForAuction: parseInt( $("#auction-min-players-online").val() ),
			minPoliceOnline: parseInt( $("#auction-min-police-online").val() ),
			blipData: $("#auction-blip-btn").data("blipData"),
			randomizeItems: $("#auction-randomize-items").prop("checked"),
			multiplier: parseFloat( $("#auction-multiplier").val() ),
			maxRounds: parseInt( $("#auction-max-rounds").val() ),
			alertPoliceAfterRound: parseInt( $("#auction-alert-police-after-round").val() ),
			accountToPayWith: getRewardDivData("#auction-account-to-pay-with"),
			timeBetweenRoundsSeconds: parseInt( $("#auction-time-between-rounds").val() ),
			warningBeforeAuctionStartMinutes: parseInt( $("#auction-warning-before-start").val() ),
			noBidTimeoutSeconds: parseInt( $("#auction-no-bid-timeout").val() ),
			minBidIncrement: parseInt( $("#auction-min-bid-increment").val() ),
			objectsRewards: getAuctionItems(),
			locations: getAuctionLocations()
		}
	}
}
$("#auction-form").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	
	let auction = getAuctionSetup();
	let modal = $("#auction-modal");
	let action = $(modal).data("action");
	let response = null;
	switch(action) {
		case "create": {
			response = await $.post(`https://${resName}/createNewAuction`, JSON.stringify(auction));
			break;
		}
		case "edit": {
			let auctionId = modal.data("auctionId");
			response = await $.post(`https://${resName}/updateAuction`, JSON.stringify({
				auctionId,
				auction
			}));
			break;
		}
	}
	modal.modal("hide");
	loadAuctions();
	showServerResponse(response);
});
$("#delete-auction-btn").click(async function() {
	if(!await confirmDeletion()) return;
	let auctionId = $("#auction-modal").data("auctionId");
	const response = await $.post(`https://${resName}/deleteAuction`, JSON.stringify({auctionId}));
	$("#auction-modal").modal("hide");
	loadAuctions();
	showServerResponse(response);
})
function addAuctionLocation(location = {}) {
	const div = $(`
		
		${getLocalizedText("menu:broker_ped")} 
		
	
		${getLocalizedText("menu:broker_vehicle")} 
		
	
		${getLocalizedText("menu:text")} 
		
	
		${getLocalizedText("menu:remove_location")} 
		
		 
	`);
		
	div.find(".remove-location-btn").click(function() {
		div.remove();
	});
	// Broker
	div.find(".broker-model").val(location.broker?.model || "s_m_m_highsec_01");
	div.find(".broker-coordinates-x").val(location.broker?.coordinates?.x || "");
	div.find(".broker-coordinates-y").val(location.broker?.coordinates?.y || "");
	div.find(".broker-coordinates-z").val(location.broker?.coordinates?.z || "");
	div.find(".broker-heading").val(location.broker?.heading || "");
	div.find(".choose-broker-coordinates-btn").click(async function() {
		const model = div.find(".broker-model").val();
		const data = await placeEntity(model, "ped");
		if(!data) return;
		div.find(".broker-coordinates-x").val(data.coords.x);
		div.find(".broker-coordinates-y").val(data.coords.y);
		div.find(".broker-coordinates-z").val(data.coords.z);
		div.find(".broker-heading").val(data.heading);
	});
	// Broker vehicle
	div.find(".vehicle-model").val(location.vehicle?.model || "burrito3");
	div.find(".vehicle-coordinates-x").val(location.vehicle?.coordinates?.x || "");
	div.find(".vehicle-coordinates-y").val(location.vehicle?.coordinates?.y || "");
	div.find(".vehicle-coordinates-z").val(location.vehicle?.coordinates?.z || "");
	div.find(".vehicle-heading").val(location.vehicle?.heading || "");
	div.find(".choose-vehicle-coordinates-btn").click(async function() {
		const model = div.find(".vehicle-model").val();
		const data = await placeEntity(model, "vehicle");
		if(!data) return;
		div.find(".vehicle-coordinates-x").val(data.coords.x);
		div.find(".vehicle-coordinates-y").val(data.coords.y);
		div.find(".vehicle-coordinates-z").val(data.coords.z);
		div.find(".vehicle-heading").val(data.heading);
	});
	
	// Text
	div.find(".text-coordinates-x").val(location.text?.coordinates?.x || "");
	div.find(".text-coordinates-y").val(location.text?.coordinates?.y || "");
	div.find(".text-coordinates-z").val(location.text?.coordinates?.z || "");
	div.find(".choose-text-coordinates-btn").click(async function() {
		const data = await placeEntity();
		if(!data) return;
		div.find(".text-coordinates-x").val(data.x);
		div.find(".text-coordinates-y").val(data.y);
		div.find(".text-coordinates-z").val(data.z);
	});
	$("#auction-locations-list").append(div);
}
$("#add-auction-location-btn").click(function() {
	addAuctionLocation();
})
function getAuctionLocations() {
	let locations = [];
	$("#auction-locations-list").find(".auction-location").each(function() {
		let location = {
			broker: {
				model: $(this).find(".broker-model").val(),
				coordinates: {
					x: parseFloat( $(this).find(".broker-coordinates-x").val() ),
					y: parseFloat( $(this).find(".broker-coordinates-y").val() ),
					z: parseFloat( $(this).find(".broker-coordinates-z").val() ),
				},
				heading: parseFloat( $(this).find(".broker-heading").val() ),
			},
			vehicle: {
				model: $(this).find(".vehicle-model").val(),
				coordinates: {
					x: parseFloat( $(this).find(".vehicle-coordinates-x").val() ),
					y: parseFloat( $(this).find(".vehicle-coordinates-y").val() ),
					z: parseFloat( $(this).find(".vehicle-coordinates-z").val() ),
				},
				heading: parseFloat( $(this).find(".vehicle-heading").val() ),
			},
			text: {
				coordinates: {
					x: parseFloat( $(this).find(".text-coordinates-x").val() ),
					y: parseFloat( $(this).find(".text-coordinates-y").val() ),
					z: parseFloat( $(this).find(".text-coordinates-z").val() ),
				}
			}
		}
		locations.push(location);
	});
	return locations;
}
function addAuctionItem(item={}) {
	const div = $(`
	
	
	`);
	const objectDiv = createDivForObjectChoose(item);
	div.find(".btn-close").after(objectDiv);
	div.find(".btn-close").click(function() {
		div.remove();
	});
	div.find("[data-bs-toggle=tooltip]").tooltip();
	div.find(".item-quantity").val(item.quantity || 10);
	div.find(".item-base-price").val(item.basePrice || 1000);
	setChoosenObject(objectDiv, item);
	$("#auction-items-list").append(div);
}
$("#add-auction-item-btn").click(function() {
	addAuctionItem();
});
function getAuctionItems() {
	let items = [];
	$("#auction-items-list").find(".auction-item").each(function() {
		const object = getChoosenObject($(this));
		let item = {
			quantity: parseInt( $(this).find(".item-quantity").val() ),
			basePrice: parseInt( $(this).find(".item-base-price").val() ),
			name: object.name,
			label: object.label,
			type: object.type,
		}
		items.push(item);
	});
	return items;
}
$("#auction-blip-btn").click(async function() {
	const oldBlipData = $(this).data("blipData");
	const blipData = await blipDialog(oldBlipData);
	$(this).data("blipData", blipData);
});
// [[ NEXUS ]]
const voteInstanceRater = raterJs({
	starSize: 35,
	element: document.querySelector("#vote-instance-rater"),
	rateCallback: async function rateCallback(rating, done) {
		const instanceId = $("#nexus-modal").data("instance").id;
		const success = await $.post(`https://${resName}/nexus/rateInstance`, JSON.stringify({rating, instanceId}));
		if(success) voteInstanceRater.setRating(rating);
		done();
	}
});
const averageInstanceVotes = raterJs({
	starSize: 20,
	readOnly: true,
	element: document.querySelector("#nexus-modal-instance-average-rating"),
});
$("#nexus-import-instance-btn").click(async function() {
	const instance = $("#nexus-modal").data("instance");
	const id = instance.id;
	const mappedItemsNames = await itemsMapperDialog(instance.requiredItemsNames);
	if(!mappedItemsNames) return;
	const response = await $.post(`https://${resName}/nexus/importInstance`, JSON.stringify({id, mappedItemsNames}));
	$("#nexus-modal").modal("hide");
	if(response === true) reloadAllData();
	showServerResponse(response);
});
let nexusDataTable = $("#nexus-table").DataTable({
	"lengthMenu": [5, 10, 15, 20],
	"pageLength": 10,
	"order": [[4, 'desc'], [5, 'desc']],
	"createdRow": function (row, data, index) {
		$(row).addClass("clickable");
		$(row).click(function () {
			const instance = $(this).data("instance");
			showInstance(instance);
			$("#nexus-modal").modal("show");
		});
	},
	"columnDefs": [{ "defaultContent": "???", "targets": "_all" }]
});
  
function showInstance(instance) {
	$("#nexus-modal").data("instance", instance);
	$("#nexus-modal-instance-listing-label").text(instance.label);
	$("#nexus-instance-content-type").text(instance.type);
	$("#nexus-instance-content-amount").text(instance.content.length);
	$("#nexus-modal-instance-description").text(instance.description || getLocalizedText("menu:nexus:no_description"));
	$("#nexus-modal-instance-author").text(instance.author);
	// Content names and labels
	$("#nexus-modal-instance-content").empty();
	instance.content.forEach(content => {
		$("#nexus-modal-instance-content").append(`
			${content.label || content.name} 
		`);
	});
	// Votes
	if(instance?.votes?.total > 0) {
		averageInstanceVotes.setRating(instance?.votes.averageRating);
	} else {
		averageInstanceVotes.setRating(0);
	}
	$("#nexus-modal-instance-total-votes").text(instance.votes?.total || 0);
	// This server vote
	voteInstanceRater.setRating(0);
}
$("#upload-to-nexus-btn").click(async function() {
	const type = await listDialog(getLocalizedText("menu:nexus:data_to_share"), getLocalizedText("menu:search"), [
		{value: "harvestable_item", label: getLocalizedText("menu:harvestable_item")},	
		{value: "drug_field", label: getLocalizedText("menu:drug_field")},
		{value: "crafting_recipe", label: getLocalizedText("menu:crafting_recipe")},
		{value: "laboratory", label: getLocalizedText("menu:laboratory")},
	]);
	if(!type) return;
	let dataToChooseFrom = [];
	// Depending on the type, we retrieve the possible data and create a multiSelectDialog
	switch(type) {
		case "harvestable_item":
			dataToChooseFrom = await $.post(`https://${resName}/getAllHarvestableItems`);
			break;
		case "drug_field":
			dataToChooseFrom = await $.post(`https://${resName}/getAllDrugsFields`);
			break;
		case "crafting_recipe":
			dataToChooseFrom = await $.post(`https://${resName}/getAllCraftingRecipes`);
			break;
		case "laboratory":
			dataToChooseFrom = await $.post(`https://${resName}/getAllLaboratories`);
			break;
	}
	if(!dataToChooseFrom) return;
	let elements = [];
	Object.values(dataToChooseFrom).forEach(data => {
		elements.push({
			value: data.id,
			label: data.id + " - " + (data.label || data.name)
		});
	})
	const selectedData = await multiSelectDialog(getLocalizedText("menu:nexus:data_to_share"), getLocalizedText("menu:search"), elements);
	if(!selectedData) return;
	$("#nexus-modal-upload").data("selectedData", selectedData);
	$("#nexus-modal-upload").data("dataType", type);
	$("#nexus-upload-label").val("");
	$("#nexus-upload-description").val("");
	$("#nexus-upload-accept-tos").prop("checked", false);
	
	$("#nexus-modal-upload").modal("show");
});
$("#nexus-upload-form").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	const dataToUpload = {
		type: $("#nexus-modal-upload").data("dataType"),
		ids: $("#nexus-modal-upload").data("selectedData"),
		label: $("#nexus-upload-label").val(),
		description: $("#nexus-upload-description").val(),
	}
	const result = await $.post(`https://${resName}/nexus/uploadData`, JSON.stringify(dataToUpload));
	if(result == true) {
		swal("Success", getLocalizedText("menu:nexus:upload_success"), "success");
		resetNexus();
	} else {
		swal("Error", result, "error");
	}
	$("#nexus-modal-upload").modal("hide");
});
$("#enter-in-nexus-btn").click(async function() {
	$("#nexus-login").find(".spinner-border").show();
	$("#enter-in-nexus-label").text("...");
	const sharedData = await $.get(`https://${resName}/nexus/getSharedData`);
	if(!sharedData) {
		swal("Error", getLocalizedText("menu:nexus:not_available"), "error");
		resetNexus();
		return;
	} 
	
	nexusDataTable.clear()
	Object.values(sharedData).forEach(instance => {
		const roundedAverageRating = instance?.votes?.averageRating ? Math.round(instance.votes.averageRating) : 0;
		const ratingStars = instance?.votes?.total ? "⭐".repeat(roundedAverageRating) : getLocalizedText("menu:nexus:not_rated");
		const limitedDescription = instance.description?.length > 30 ? instance.description.substring(0, 30) + "..." : instance.description;
		const amount = instance.content.length;
		const rawRow = nexusDataTable.row.add( [instance.label, limitedDescription, instance.type, amount, ratingStars, instance.votes?.total || 0, instance.author] );
		const rowDiv = $(rawRow.node());
		$(rowDiv).data("instance", instance);
	})
	nexusDataTable.draw();
	$("#nexus-login").hide();
	$("#nexus-container").show();
})
function resetNexus() {
	$("#nexus-login").show();
	$("#nexus-login").find(".spinner-border").hide();
	$("#enter-in-nexus-label").text("Enter in Nexus");
	$("#nexus-container").hide();
}
function reloadAllData() {
	resetNexus();
	loadHarvestableItems();
	loadDrugsFields();
	loadCraftingRecipes();
	loadLaboratories();
	loadAuctions();
}
// Open/Close menu
function openMenu(version, fullConfig) {
	$("#advanced-drugs-creator-version").text(version);
    $("#drugs_creator").show();
	reloadAllData();
	window.dispatchEvent(new Event('menuOpened'));
	loadSettings(fullConfig);
}
function closeMenu() {
    $("#drugs_creator").hide();
    $.post(`https://${resName}/close`, {})
}
$("#close-main-btn").click(closeMenu);
function playSound(name, speed = 1.0, volume = 1.0) {
    // Create an AudioContext
    var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    // Create the audio element
    var audio = new Audio(`./assets/audio/${name}.mp3`);
    audio.playbackRate = speed;
    // Create a media element source
    var source = audioCtx.createMediaElementSource(audio);
    // Create a gain node
    var gainNode = audioCtx.createGain();
    gainNode.gain.value = volume; // Set the volume
    // Connect the source to the gain node and the gain node to the destination
    source.connect(gainNode);
    gainNode.connect(audioCtx.destination);
    // Play the audio
    audio.play();
}
// Messages received by client
window.addEventListener('message', (event) => {
	let data = event.data;
	let action = data.action;
	if (action == 'openMenu') {
		openMenu(data.version, data.fullConfig);
	} else if (action == "playSound") {
		playSound(data.name, data.speed, data.volume);
	}
})