
function onceBuild() {
    let container = document.createElement('div');
	container.id = 'container-once-contents';
    container.style.marginLeft = '25px';
    container.style.marginBottom = '15px';

	let savedColor = localStorage.getItem(container.id+'-containerIdbackgroundColor');
    if (savedColor) {
        container.style.backgroundColor = savedColor;
    }

    let colorChangerQuickSpin = quickSpin_colorChanger(container.id);
    container.append(colorChangerQuickSpin);
    
    let title = 'Once';
    let msg = 'This looks backwards through the numbers until every number appears once.';
    let patternTitle = createTitleWithHelp(title, msg);
    container.appendChild(patternTitle);

	var allSpins = [...numbers];
	var result = processSpins(allSpins);
	var onceCountAll = result.frequencies;
	var counter = result.counter;
    var allNumbers = [...wheel0];

	let countOnce = document.createElement('span');
	countOnce.innerHTML = `Spins ${counter}`;
	countOnce.id = 'count-once';
	
    container.appendChild(countOnce);

    // Create and append the first unsorted table
    const table = document.createElement('div');
    createFrequencyTable(allNumbers, onceCountAll, allSpins, table);
    container.appendChild(table);

    // Label for sorted table
    const labelSorted = document.createElement('h3');
    labelSorted.textContent = "Sorted";
    container.appendChild(labelSorted);

    // Create and append the sorted table
    const sortedTable = document.createElement('div');
    createSortedFrequencyTable(allNumbers, onceCountAll, allSpins, sortedTable);
    container.appendChild(sortedTable);

    return container;
}

function onceUpdateAll(){
    let spinLength = document.getElementById('once-inputbox');
    spinLength.value = numbers.length;
    onceUpdate();
}

function onceUpdate(){
    let spinLength = document.getElementById('once-inputbox').value;
    spinLength = ensureInputValue(spinLength,10);
    if(spinLength>numbers.length) {spinLength = numbers.length; }
    updateOnceTable(spinLength);
}

function updateOnceTable() {

    var container = document.getElementById('container-once-contents');
    container.innerHTML = '';

	let savedColor = localStorage.getItem(container.id+'-containerIdbackgroundColor');
    if (savedColor) {
        container.style.backgroundColor = savedColor;
    }

    let colorChangerQuickSpin = quickSpin_colorChanger(container.id);
    container.append(colorChangerQuickSpin);

	let title = 'Once';
    let msg = 'This looks backwards through the numbers until every number appears once.';
    let patternTitle = createTitleWithHelp(title, msg);
    container.appendChild(patternTitle);

	var allSpins = [...numbers];
	var result = processSpins(allSpins);
	var onceCountAll = result.frequencies;
	var counter = result.counter;
    var allNumbers = [...wheel0];

	let countOnce = document.createElement('span');
	countOnce.innerHTML = `Spins ${counter}`;
	countOnce.id = 'count-once';
	
    container.appendChild(countOnce);

    // Create and append the first unsorted table
    const table = document.createElement('div');
    createFrequencyTable(allNumbers, onceCountAll, allSpins, table);
    container.appendChild(table);


	const label = document.createElement('span');
	label.innerHTML = "<h3>Sorted</h3>";
	container.appendChild(label);

    // Create and append the sorted table
    const sortedTable = document.createElement('div');
    createSortedFrequencyTable(allNumbers, onceCountAll, allSpins, sortedTable);
    container.appendChild(sortedTable);
}

function createFrequencyTable(numbers, frequencies, allSpins, container) {
    const numberRow = document.createElement('div');
    const onceAllRow = document.createElement('div');
    setupRows(numberRow, onceAllRow);

    numbers.forEach(num => {
        let [numberCell, onceAllCell] = createCells(num, frequencies[num] || 0, allSpins);
        numberRow.appendChild(numberCell);
        onceAllRow.appendChild(onceAllCell);
    });

    container.appendChild(onceAllRow);
    container.appendChild(numberRow);
}

function createSortedFrequencyTable(numbers, frequencies, allSpins, container) {
    const numberRow = document.createElement('div');
    const onceAllRow = document.createElement('div');
    setupRows(numberRow, onceAllRow);

    // Sort numbers by frequency ascending
    numbers.sort((a, b) => (frequencies[a] || 0) - (frequencies[b] || 0));

    numbers.forEach(num => {
        let [numberCell, onceAllCell] = createCells(num, frequencies[num] || 0, allSpins);
        numberRow.appendChild(numberCell);
        onceAllRow.appendChild(onceAllCell);
    });

    container.appendChild(onceAllRow);
    container.appendChild(numberRow);
}

function setupRows(...rows) {
    rows.forEach(row => {
        row.style.display = 'flex';
    });
}

function createCells(num, frequency, allSpins) {
    const numberCell = document.createElement('div');
    const onceAllCell = document.createElement('div');

    numberCell.innerText = num;
    onceAllCell.innerText = frequency;

    [numberCell, onceAllCell].forEach(cell => {
        cell.style.width = '32px';
        cell.style.height = '25px';
        cell.style.display = 'flex';
        cell.style.justifyContent = 'center';
        cell.style.alignItems = 'center';
        cell.style.border = '1px solid black';
    });

    numberCell.style.color = 'white';
    onceAllCell.style.color = 'black';

    if (numRed.includes(num)) {
        numberCell.style.backgroundColor = 'rgb(221, 82, 82)';
    } else if (numBlack.includes(num)) {
        numberCell.style.backgroundColor = 'rgb(68, 60, 60)';
    } else if (num === 0) {
        numberCell.style.backgroundColor = 'rgb(146, 196, 150)';
    }

    if (num === allSpins[allSpins.length - 1]) {
        onceAllCell.style.backgroundColor = 'yellow';
    }

    return [numberCell, onceAllCell];
}

function updateOnceNewNumber()
{

    var container = document.getElementById('container-once-contents');
    if(container)
    {
		
        updateOnceTable();
    }
}

function onceBuildbackup() {
    let last37 = numbers.slice(-37);


	// Counting the once of each number in last37
	const onceCountAll = numbers.reduce((acc, num) => {
		acc[num] = (acc[num] || 0) + 1;
		return acc;
	}, {});

	// Counting the once of each number in last37
	const onceCount = last37.reduce((acc, num) => {
		acc[num] = (acc[num] || 0) + 1;
		return acc;
	}, {});

	// Array of numbers from 0 to 35
	let allNumbers = Array.from({length: 36}, (_, index) => index);

	// Sort these numbers by their once in last37, then by number if frequencies are equal
	allNumbers.sort((a, b) => {
		const freqA = onceCount[a] || 0;
		const freqB = onceCount[b] || 0;
		return freqB - freqA || a - b;
	});


    // Create container for the table
    const table = document.createElement('div');
    
    // Create rows for numbers and frequencies
    const numberRow = document.createElement('div');
	const onceAllRow = document.createElement('div');
    const onceRow = document.createElement('div');
    const lastSeenRow = document.createElement('div'); 
	const lastUpRow = document.createElement('div');
    
    onceAllRow.style.display = numberRow.style.display = onceRow.style.display = lastSeenRow.style.display =  lastUpRow.style.display ='flex';



	const helpCellfreqAll = document.createElement('div');
	helpCellfreqAll.style.display = 'flex';
	helpCellfreqAll.style.justifyContent = 'center';
	helpCellfreqAll.style.alignItems = 'center';
	helpCellfreqAll.style.border = '1px solid black';
	helpCellfreqAll.style.width = '32px';
	helpCellfreqAll.style.height = '25px';
	var msg = 'Shows the once of the numbers that came up.';
	var helpIcon = createHelpBox(msg);
	helpCellfreqAll.appendChild(helpIcon);
	onceAllRow.appendChild(helpCellfreqAll);


	const helpCellfreq = document.createElement('div');
	helpCellfreq.style.display = 'flex';
	helpCellfreq.style.justifyContent = 'center';
	helpCellfreq.style.alignItems = 'center';
	helpCellfreq.style.border = '1px solid black';
	helpCellfreq.style.width = '32px';
	helpCellfreq.style.height = '25px';
	var msg = 'Shows the once of the numbers that came up over the last 37 spins.';
	var helpIcon = createHelpBox(msg);
	helpCellfreq.appendChild(helpIcon);
	onceRow.appendChild(helpCellfreq);

	const helpCelllaw = document.createElement('div');
	helpCelllaw.style.display = 'flex';
	helpCelllaw.style.justifyContent = 'center';
	helpCelllaw.style.alignItems = 'center';
	helpCelllaw.style.border = '1px solid black';
	helpCelllaw.style.width = '32px';
	helpCelllaw.style.height = '25px';
	var msg = 'The Law of the Third says that in 37 spins,';
	msg += '\nabout 24 numbers will come up.';
	msg += '\n\n';
	msg += "This leaves about 1/3 of the number not coming up,";
	msg += '\n';
	msg += "and several repeat numbers.";
	msg += '\n';
	msg += '\n';
	msg += 'This chart shows the once of numbers over the last 37 spins.';
	msg += '\n';
	msg += '\n';
	msg += 'We leave it to the player to figure out how take advantage of it.';
	var patternTitle = createHelpBox(msg);
	helpCelllaw.appendChild(patternTitle);
	numberRow.appendChild(helpCelllaw);


	const helpCell = document.createElement('div');
	helpCell.style.display = 'flex';
	helpCell.style.justifyContent = 'center';
	helpCell.style.alignItems = 'center';
	helpCell.style.border = '1px solid black';
	helpCell.style.width = '32px';
	helpCell.style.height = '25px';
	var msg = 'Shows the last time the number appeared in 37 spins.\nA blank means the number has appeared in over 37 spins.';
	var helpIcon = createHelpBox(msg);
	helpCell.appendChild(helpIcon);
	lastSeenRow.appendChild(helpCell);
	

	const helpLastUp = document.createElement('div');
	helpLastUp.style.display = 'flex';
	helpLastUp.style.justifyContent = 'center';
	helpLastUp.style.alignItems = 'center';
	helpLastUp.style.border = '1px solid black';
	helpLastUp.style.width = '32px';
	helpLastUp.style.height = '25px';
	var msg = 'Shows the last time the number appeared.\nA blank means the number has never come up.';
	var helpIcon = createHelpBox(msg);
	helpLastUp.appendChild(helpIcon);
	lastUpRow.appendChild(helpLastUp);


    allNumbers.forEach(num => {
        const numberCell = document.createElement('div');
		const onceAllCell = document.createElement('div');
        const onceCell = document.createElement('div');
        const lastSeenCell = document.createElement('div'); 
		const lastUpAllCell = document.createElement('div'); 

        numberCell.innerText = num;
        onceCell.innerText = onceCount[num] || 0;
		onceAllCell.innerText = onceCountAll[num] || 0;
		

        // Calculate spins since last appearance
        const lastIndexOfNum = last37.lastIndexOf(num);
        lastSeenCell.innerText = lastIndexOfNum !== -1 ? (last37.length - 1) - lastIndexOfNum : '';

		// Calculate Last up all
		const lastUpAllIndex = numbers.lastIndexOf(num);
		lastUpAllCell.innerText = lastUpAllIndex !== -1 ? (numbers.length - 1) - lastUpAllIndex : '';

        // Base styles for cells
        [numberCell, onceAllCell, onceCell, lastSeenCell, lastUpAllCell].forEach(cell => {
            cell.style.width = '32px';
            cell.style.height = '25px';
            cell.style.display = 'flex';
            cell.style.justifyContent = 'center';
            cell.style.alignItems = 'center';
            cell.style.border = '1px solid black';
        });

        numberCell.style.color = 'white';
		onceAllCell.style.color = 'black';
        onceCell.style.color = 'blue';
        lastSeenCell.style.color = 'blue'; // Color for spins since last appearance
		lastUpAllCell.style.color = 'black';

        // Apply background color based on the number
        if (numRed.includes(num)) {
            numberCell.style.backgroundColor = 'rgb(221, 82, 82)'; // Red
        } else if (numBlack.includes(num)) {
            numberCell.style.backgroundColor = 'rgb(68, 60, 60)'; // Black
        } else if (num === 0) {
            numberCell.style.backgroundColor = 'rgb(146, 196, 150)'; // Assuming 0 has a unique color
        }
	
        // Append cells to their respective rows
        numberRow.appendChild(numberCell);
		onceAllRow.appendChild(onceAllCell);
        onceRow.appendChild(onceCell);
        lastSeenRow.appendChild(lastSeenCell);
		lastUpRow.appendChild(lastUpAllCell);
    });






    // Append rows to the table container
	table.appendChild(onceAllRow);
    table.appendChild(onceRow);
    table.appendChild(numberRow);
    table.appendChild(lastSeenRow); 
	table.appendChild(lastUpRow);

	return table;
}

function onceGapHighlights(onceAllCell) {
	// New array of the same length as onceAllCell, initialized with zeros
	const newArray = new Array(onceAllCell.length).fill(0);
	
	// Temporary array to track the indexes of current zero sequence
	let tempIndexes = [];
	
	// Function to update newArray based on tempIndexes
	function updateNewArray() {
	  tempIndexes.forEach(index => {
		newArray[index] = 5;
	  });
	}
	
	// Iterate through onceAllCell with wrapping for loop continuity
	for (let i = 0; i < onceAllCell.length * 2; i++) {
	  // Use modulo to wrap index appropriately
	  const index = i % onceAllCell.length;
	  
	  if (onceAllCell[index] === 0) {
		tempIndexes.push(index);
		
		// If we reach the end of onceAllCell or the next number is not zero, check sequence length
		if (i === onceAllCell.length * 2 - 1 || onceAllCell[(index + 1) % onceAllCell.length] !== 0) {
		  if (tempIndexes.length >= 5) {
			updateNewArray();
		  }
		  // Reset tempIndexes for the next sequence
		  tempIndexes = [];
		}
	  } else {
		// If the sequence of zeros ends and it's 5 or more, update newArray
		if (tempIndexes.length >= 5) {
		  updateNewArray();
		}
		// Reset tempIndexes since we encountered a non-zero number
		tempIndexes = [];
	  }
	}
  
	return newArray;
}

function reduceCounts(onceCountObj) {
	// Clone the object to avoid mutating the original object
	let counts = { ...onceCountObj };
  
	// Convert the object values to an array to check for a zero value
	while (Object.values(counts).every(count => count !== 0)) {

	  // Iterate over the object keys and reduce each count by 1 if it's greater than 0
	  for (const key in counts) {
		if (counts[key] > 0) {
		  counts[key] -= 1;
		}
	  }
	}
  
	return counts;
}

function processSpins(allSpins) {
	const frequencies = {};
  
	let reduceSpins = false;
	let counter = 0;
	// Step 1: Count Frequencies backward
	for (let i = allSpins.length - 1; i >= 0; i--) {
	  const spin = allSpins[i];
	  frequencies[spin] = (frequencies[spin] || 0) + 1;
	  counter += 1;
	  // Check if all numbers have appeared at least once
	  if (Object.keys(frequencies).length === 37) { // 37 for numbers 0-36
		reduceSpins = true;
		break; // Stop if every number has appeared at least once
	  }
	}
	
	// Step 3: Optionally convert frequencies object to an array of frequencies
	// This depends on how you want to use the frequencies.
	// The function currently returns an object with the numbers as keys and their frequencies as values.
	return { frequencies, counter }; 
}