/**
* UI Handlers Module
*
* This module manages user interactions and UI state.
* Implements:
* 1. Drag and Drop system
* 2. Event handling
* 3. UI state management
* 4. Input validation
*
* @module uiHandlers
*/
/**
* Initializes drag and drop functionality for tower placement
* Implements HTML5 Drag and Drop API
*
* @param {HTMLCanvasElement} canvas - Game canvas element
* @param {Object} gameState - Current game state
* @returns {Object} Drag handlers and state information
*/
function initializeDragAndDrop(canvas, gameState) {
let draggedTowerType = null;
let hoverCell = null;
const dragHandlers = {
/**
* Handles start of tower drag operation
* Sets up drag data and visual feedback
*/
onDragStart: (e) => {
draggedTowerType = e.target.dataset.towerType;
e.dataTransfer.setData('text/plain', '');
},
/**
* Handles end of drag operation
* Cleans up drag state
*/
onDragEnd: () => {
draggedTowerType = null;
hoverCell = null;
},
/**
* Handles drag over canvas
* Updates hover position and preview
*/
onDragOver: (e) => {
e.preventDefault();
const rect = canvas.getBoundingClientRect();
const x = Math.floor((e.clientX - rect.left) / (canvas.width / 20));
const y = Math.floor((e.clientY - rect.top) / (canvas.height / 20));
hoverCell = (x >= 0 && x < 20 && y >= 0 && y < 20) ? { x, y } : null;
},
/**
* Handles tower placement on drop
* Validates placement and updates game state
*/
onDrop: (e) => {
e.preventDefault();
if (!draggedTowerType || !hoverCell) return;
placeTower(gameState, draggedTowerType, hoverCell);
draggedTowerType = null;
hoverCell = null;
}
};
return {
dragHandlers,
getHoverInfo: () => ({ draggedTowerType, hoverCell })
};
}
/**
* Places a tower in the game grid
* Implements tower placement validation and state updates
*
* @param {Object} gameState - Current game state
* @param {string} towerType - Type of tower to place
* @param {Object} position - Grid position for placement
*/
function placeTower(gameState, towerType, position) {
const tower = TowerTypes[towerType];
if (
gameState.grid[position.y][position.x] === 'empty' &&
gameState.currency >= tower.cost
) {
gameState.grid[position.y][position.x] = 'tower';
gameState.towers.push(createTower(towerType, { ...position }));
gameState.currency -= tower.cost;
}
}