/** * ATM Interface * Handles banking transactions with PIN authentication */ // ============================================================================ // STATE // ============================================================================ let enteredPin = ''; let currentView = 'welcomeView'; let previousView = 'welcomeView'; // ============================================================================ // VIEW MANAGEMENT // ============================================================================ function showView(viewId) { // Hide all views document.querySelectorAll('.atm-view').forEach(view => { view.style.display = 'none'; }); // Show selected view const view = document.getElementById(viewId); if (view) { view.style.display = 'flex'; previousView = currentView; currentView = viewId; // Update balance displays when showing certain views if (viewId === 'menuView' || viewId === 'balanceView' || viewId === 'depositView') { updateBalances(); } } } // ============================================================================ // PIN AUTHENTICATION // ============================================================================ function generateKeypad() { const keypad = document.getElementById('keypad'); if (!keypad) return; // Define keypad layout const keys = [ { value: '1', label: '1', type: 'number' }, { value: '2', label: '2', type: 'number' }, { value: '3', label: '3', type: 'number' }, { value: '4', label: '4', type: 'number' }, { value: '5', label: '5', type: 'number' }, { value: '6', label: '6', type: 'number' }, { value: '7', label: '7', type: 'number' }, { value: '8', label: '8', type: 'number' }, { value: '9', label: '9', type: 'number' }, { value: 'clear', label: 'Clear', type: 'action', class: 'key-clear' }, { value: '0', label: '0', type: 'number' }, { value: 'enter', label: 'Enter', type: 'action', class: 'key-enter' } ]; // Clear existing keypad keypad.innerHTML = ''; // Generate buttons keys.forEach(key => { const button = document.createElement('button'); button.className = `key-btn${key.class ? ' ' + key.class : ''}`; button.textContent = key.label; // Add click handler if (key.type === 'number') { button.onclick = () => enterPin(key.value); } else if (key.value === 'clear') { button.onclick = () => clearPin(); } else if (key.value === 'enter') { button.onclick = () => submitPin(); } keypad.appendChild(button); }); } function enterPin(digit) { if (enteredPin.length < 4) { enteredPin += digit; updatePinDisplay(); } } function clearPin() { enteredPin = ''; updatePinDisplay(); } function updatePinDisplay() { const dots = document.querySelectorAll('.pin-dot'); dots.forEach((dot, index) => { if (index < enteredPin.length) { dot.classList.add('filled'); } else { dot.classList.remove('filled'); } }); } function submitPin() { if (enteredPin.length !== 4) { showError('Please enter a 4-digit PIN'); return; } // In a real implementation, this would validate with the server const currentState = store.getState(); if (enteredPin === currentState.pin) { enteredPin = ''; updatePinDisplay(); showView('menuView'); } else { showError('Incorrect PIN'); clearPin(); } } // ============================================================================ // BALANCE MANAGEMENT // ============================================================================ function updateBalances() { const currentState = store.getState(); // Update all balance displays const cashElements = ['cashBalance', 'cashBalanceDetail', 'availableCash']; const bankElements = ['bankBalance', 'bankBalanceDetail']; cashElements.forEach(id => { const el = document.getElementById(id); if (el) el.textContent = `$${currentState.accounts.cash.toLocaleString()}`; }); bankElements.forEach(id => { const el = document.getElementById(id); if (el) el.textContent = `$${currentState.accounts.bank.toLocaleString()}`; }); const totalEl = document.getElementById('totalBalance'); if (totalEl) { const total = currentState.accounts.cash + currentState.accounts.bank; totalEl.textContent = `$${total.toLocaleString()}`; } } // ============================================================================ // WITHDRAW OPERATIONS // ============================================================================ function withdrawAmount(amount) { const currentState = store.getState(); if (amount > currentState.accounts.bank) { showError('Insufficient funds'); return; } store.dispatch(withdraw(amount)); sendEvent('atm::withdraw', { amount: amount }); showSuccess(`Withdrew $${amount.toLocaleString()}`); } function withdrawCustom() { const input = document.getElementById('withdrawInput'); const amount = parseFloat(input.value); if (!amount || amount <= 0) { showError('Please enter a valid amount'); return; } const currentState = store.getState(); if (amount > currentState.accounts.bank) { showError('Insufficient funds'); return; } store.dispatch(withdraw(amount)); sendEvent('atm::withdraw', { amount: amount }); input.value = ''; showSuccess(`Withdrew $${amount.toLocaleString()}`); } // ============================================================================ // DEPOSIT OPERATIONS // ============================================================================ /** * Deposits specified amount into bank account * @deprecated Use store actions instead */ function depositAmount() { const input = document.getElementById('depositInput'); const amount = parseFloat(input.value); if (!amount || amount <= 0) { showError('Please enter a valid amount'); return; } const currentState = store.getState(); if (amount > currentState.accounts.cash) { showError('Insufficient cash'); return; } store.dispatch(deposit(amount)); sendEvent('atm::deposit', { amount: amount }); input.value = ''; showSuccess(`Deposited $${amount.toLocaleString()}`); } /** * Deposits all available cash into bank account * @deprecated Use store actions instead */ function depositAll() { const currentState = store.getState(); if (currentState.accounts.cash <= 0) { showError('No cash to deposit'); return; } const amount = currentState.accounts.cash; store.dispatch(deposit(amount)); sendEvent('atm::deposit', { amount: amount }); showSuccess(`Deposited $${amount.toLocaleString()}`); } // ============================================================================ // TRANSFER OPERATIONS // ============================================================================ /** * Transfers specified amount from bank account to player account * @deprecated Use store actions instead */ function transferFunds() { const playerIdInput = document.getElementById('transferPlayerId'); const amountInput = document.getElementById('transferAmount'); const playerId = playerIdInput.value.trim(); const amount = parseFloat(amountInput.value); if (!playerId) { showError('Please enter a player ID'); return; } if (!amount || amount <= 0) { showError('Please enter a valid amount'); return; } const currentState = store.getState(); if (amount > currentState.accounts.bank) { showError('Insufficient funds'); return; } store.dispatch(transfer('bank', amount, 'player')); sendEvent('atm::transfer', { playerId: playerId, amount: amount }); playerIdInput.value = ''; amountInput.value = ''; showSuccess(`Transferred $${amount.toLocaleString()} to Player ${playerId}`); } // ============================================================================ // RESULT SCREENS // ============================================================================ function showSuccess(message) { document.getElementById('successMessage').textContent = message; showView('successView'); updateBalances(); } function showError(message) { document.getElementById('errorMessage').textContent = message; showView('errorView'); } function goBackFromError() { // If error happened during PIN entry, go back to PIN view // Otherwise go back to menu view if (previousView === 'pinView') { showView('pinView'); } else { showView('menuView'); } } // ============================================================================ // ATM CONTROL // ============================================================================ function exitATM() { enteredPin = ''; updatePinDisplay(); sendEvent('atm::close', {}); showView('welcomeView'); } // ============================================================================ // ARMA 3 INTEGRATION // ============================================================================ /** * Sends an event to Arma 3 * @param {string} event - Event name * @param {Object} data - Event data */ function sendEvent(event, data) { if (typeof A3API !== 'undefined') { A3API.SendAlert(JSON.stringify({ event: event, data: data })); } else { console.log('Event:', event, 'Data:', data); } } // ============================================================================ // INITIALIZATION // ============================================================================ function initATM() { // Subscribe to store updates if (typeof store !== 'undefined') { store.subscribe(() => { updateBalances(); }); } // Generate keypad generateKeypad(); // Show welcome screen showView('welcomeView'); // Update initial balances updateBalances(); console.log('[ATM] Interface initialized'); } // Auto-initialize if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initATM); } else { initATM(); } // ============================================================================ // GLOBAL EXPORTS // ============================================================================ window.showView = showView; window.generateKeypad = generateKeypad; window.enterPin = enterPin; window.clearPin = clearPin; window.submitPin = submitPin; window.withdrawAmount = withdrawAmount; window.withdrawCustom = withdrawCustom; window.depositAmount = depositAmount; window.depositAll = depositAll; window.transferFunds = transferFunds; window.goBackFromError = goBackFromError; window.exitATM = exitATM;