<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Drop Chance Calculator</title>
    <style>
        .white-label {
            color: white; /* Change 'blue' to any color you want */
        }
        .red-label {
            color: red;
        }
.button {
  display: inline-block;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: bold;
  text-transform: uppercase;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s;
  margin: 7px
}

/* Styles for the Add button */
.add-button {
  background-color: #4CAF50; /* Green */
  color: white;
}

.add-button:hover {
  background-color: #45a049; /* Darker green */
}

/* Styles for the Remove button */
.remove-button {
  background-color: #f44336; /* Red */
  color: white;
  margin-left: 0px;
}

.remove-button:hover {
  background-color: #d32f2f; /* Darker red */
}

/* Styles for the Zoom In button */
.zoom-in-button {
  background-color: #2196F3; /* Blue */
  color: white;
  margin-left: 0px;
}

.zoom-in-button:hover {
  background-color: #1976D2; /* Darker blue */
}

/* Styles for the Zoom Out button */
.zoom-out-button {
  background-color: #FFC107; /* Yellow */
  color: white;
  margin-left: 0px;
}

.zoom-out-button:hover {
  background-color: #FFA000; /* Darker yellow */
}
.binomial-n {
  padding: 6px;
  border-radius: 5px;
  border-width: 3px;
  font-size: 16px;
  background-color: #999;
  color: white;
  margin: 7px;
  width: 100px;
}

/* Style for read-only input field */
.binomial-p {
  padding: 6px;
  background-color: #282727; /* Light gray background */
  font-size: 16px;
  color: rgb(235, 233, 233); /* Dark gray text color */
  margin: 7px;
  border-width: 3px;
  width: 100px;
}
.custom-select {
  padding: 10px 30px 10px 15px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 5px;
  background-color: #b9cdf0;
  color: #555;
  position: relative;
}

/* Style for custom dropdown arrow */
.custom-select::after {
  content: '\25BC'; /* Unicode character for dropdown arrow */
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
}

/* Style for select element when hovered */
.custom-select:hover {
  border-color: #999; /* Light gray border color */
}

/* Style for dropdown options */
.custom-select option {
  padding: 10px;
  font-size: 16px;
  background-color: #fff;
  color: #555;
}
.container {
        display: flex;
}
.left-div {
    width: 90%;
    padding: 20px;
}
.right-div {
     width: 250px;
    padding: 20px;
}
.toggle-button {
    background-color:white;
}

  /* Style for the toggle button when hovered */
.toggle-button:hover {
    background-color: #c33243; /* Darker green */
}

  /* Style for the toggle button when pressed */
.toggle-button:active {
    background-color: #9f1132; /* Dark green */
}

    </style>
    <!-- Include Chart.js -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js" integrity="sha512-UXumZrZNiOwnTcZSHLOfcTs0aos2MzBWHXOHOuB0J/R44QB0dwY5JgfbvljXcklVf65Gc4El6RjZ+lnwd2az2g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/2.0.1/chartjs-plugin-zoom.min.js" integrity="sha512-wUYbRPLV5zs6IqvWd88HIqZU/b8TBx+I8LEioQ/UC0t5EMCLApqhIAnUg7EsAzdbhhdgW07TqYDdH3QEXRcPOQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
    <div id="graph-container">
        <div>
            <label class='white-label custom' for="killCount">Kill Count:</label>
            <input class='binomial-n custom' style='border-color: rgb(230, 25, 75)' type="number" id="killCount" value="0"> <!-- Default value is 100 -->
            <label class='white-label custom' for="dropRate">Drop Rate:</label>
            <input class='binomial-n custom' style='border-color: rgb(230, 25, 75)' type="number" id="dropRate" value="1000"> <!-- Default value is 0.3 -->
            <button class='button remove-button' id="resetPage">Reset Sheet</button>
            <button class='button zoom-in-button' id="zoomIn">Zoom In</button>
            <button class='button zoom-out-button' id="zoomOut">Zoom Out</button>
            <button class='button remove-button' id="resetZoom">Reset Zoom</button>
        </div>
    </div>
    <div>
        <button class='button add-button' onclick="addBinomialLine()">Add Pet</button>
        <select class='custom-select' id="preset-values">
            <option value="2500">Abyssal Orphan</option>
            <option value="4000">Abyssal Protector</option>
            <option value="3000">Baby Mole</option>
            <option value="2500">Baron</option>
            <option value="1000">Bloodhound</option>
            <option value="3000">Butch</option>
            <option value="1500">Callisto Cub - Callisto</option>
            <option value="2800">Callisto Cub - Artio</option>
            <option value="500">Chompy Chick</option>
            <option value="3000">Hellpuppy</option>
            <option value="6500">Herbi</option>
            <option value="400">Huberte</option>
            <option value="3000">Ikkle Hydra</option>
            <option value="100">Jal-nib-rek - Off Task</option>
            <option value="75">Jal-nib-rek - On Task</option>
            <option value="3000">Kalphite Princess</option>
            <option value="400">Lil'Creator</option>
            <option value="650">Lil'Zik - Normal</option>
            <option value="500">Lil'Zik - HMT</option>
            <option value="2500">Lil'Viathan</option>
            <option value="1400">Little Nightmare - Phosani</option>
            <option value="3000">Moxi</option>
            <option value="2500">Muphin</option>
            <option value="500">Nexling</option>
            <option value="3000">Nid</option>
            <option value="1500">Nid - Destroy</option>
            <option value="3000">Noon</option>
            <option value="53">Olmlet</option>
            <option value="300">Pet Chaos Elemental</option>
            <option value="5000">Pet Dagannoth Prime</option>
            <option value="5000">Pet Dagannoth Supreme</option>
            <option value="5000">Pet Dark Core</option>
            <option value="5000">Pet General Graardor</option>
            <option value="5000">Pet K'ril Tsutsaroth</option>
            <option value="3000">Pet Kraken</option>
            <option value="5000">Pet Kree'arra</option>
            <option value="1000">Pet Penance Queen</option>
            <option value="3000">Pet Smoke Devil</option>
            <option value="4000">Pet Snakeling</option>
            <option value="5000">Pet Zilyana</option>
            <option value="5000">Phoenix</option>
            <option value="3000">Prince Black Dragon</option>
            <option value="1000">Quetzin</option>
            <option value="2016">Scorpia's Offspring</option>
            <option value="3000">Scurry</option>
            <option value="65">Skotos</option>
            <option value="200">Smol Heredit</option>
            <option value="2250">Smolcano</option>
            <option value="3000">Sraracha</option>
            <option value="8000">Tiny Tempor</option>
            <option value="200">Tzrek-Jad - Off Task</option>
            <option value="100">Tzrek-Jad - On Task</option>
            <option value="1500">Veneatis Spiderling Venenatis</option>
            <option value="2800">Veneatis Spiderling Spindel</option>
            <option value="1500">Vet'ion Jr. Vet'ion</option>
            <option value="2800">Vet'ion Jr. Calvar'ion</option>
            <option value="3000">Vorki</option>
            <option value="2000">Wisp</option>
            <option value="2000">Youngllef - Normal</option>
            <option value="800">Youngllef - Corrupted</option> 
        </select>
        <button class='button toggle-button' onclick="toggleCustom()">Toggle Custom</button>
    </div>
    <div>
        <label id="alertLabel" class="red-label"></label>
    </div>
    <div class="container">
        <div class="left-div">
            <canvas id="myChart"></canvas>
        </div>
        <div id="chance" class="right-div">
            <label class='white-label custom' for="totalChance">Total Chance at 0 kill count (custom):</label>
            <input class='binomial-p custom' style='border-color: rgb(230, 25, 75)' type="text" id="totalChance" readonly>
        </div>
    </div>

    <script id="startScript">
        var resPage = document.getElementById("resetPage");
        resPage.onclick = function() {
            // Get all buttons in the DOM
            var buttons = document.querySelectorAll('button');
            myChart.resetZoom();

            // Iterate through each button
            buttons.forEach(function(button) {
            // Check if the button has the specific label
                if (button.textContent.trim() === 'Remove') { // Replace 'Your Label' with the specific label
                    // Execute the button's onclick event
                    button.click();
                }
            });

        };
        var zoomIn = document.getElementById("zoomIn");
        zoomIn.onclick = function() {
                myChart.zoom(1.1);
            };
        var zoomOut = document.getElementById("zoomOut");
        zoomOut.onclick = function() {
                myChart.zoom(0.9);
            };
        var resZoom = document.getElementById("resetZoom");
        resZoom.onclick = function() {
                myChart.resetZoom();
            };

        var lineColors = ['rgb(230, 25, 75)', 'rgb(60, 180, 75)', 'rgb(255, 225, 25)', 'rgb(0, 130, 200)', 'rgb(245, 130, 48)', 'rgb(145, 30, 180)', 'rgb(70, 240, 240)', 'rgb(240, 50, 230)', 'rgb(210, 245, 60)', 'rgb(250, 190, 212)', 'rgb(0, 128, 128)', 'rgb(220, 190, 255)', 'rgb(170, 110, 40)', 'rgb(255, 250, 200)', 'rgb(128, 0, 0)', 'rgb(170, 255, 195)', 'rgb(128, 128, 0)', 'rgb(255, 215, 180)', 'rgb(0, 0, 128)', 'rgb(128, 128, 128)', 'rgb(255, 255, 255)', 'rgb(0, 0, 0)s'];
        
        
        var binomialLineContainers = []; // Array to store additional binomial lines
        var chanceFields = [];

        function updateTotals() {
            var dropRate = document.getElementById('dropRate').value; // Probability of success
            var killCount = parseInt(document.getElementById('killCount').value); // Number of trials
            var totalField = document.getElementById('totalChance');
            totalField.value = ((1-binomialProbability(0, killCount, 1/dropRate)) * 100).toFixed(2) + '%';
            var totalText = totalField.previousElementSibling.textContent;
            totalText = totalText.substring(totalText.indexOf(' kill'));
            totalField.previousElementSibling.textContent = 'Total Chance at ' + killCount + totalText;
            for (var i = 0; i < chanceFields.length; i++) {
                var container = binomialLineContainers[i];
                var binomialN = parseInt(container.querySelector('.binomial-n').value);
                var binomialP = parseFloat(container.querySelector('.binomial-p').value);
                if(isNaN(binomialN) || isNaN(binomialP) || binomialN > 1000000 || binomialN < 0)
                {
                    document.getElementById('alertLabel').textContent = 'Please enter valid input to update the graph';
                    invalidInput = true;
                    return;
                } else {
                    document.getElementById('alertLabel').textContent = '';
                }
                var chanceField = chanceFields[i];
                chanceField.value = ((1-binomialProbability(0, binomialN, 1/binomialP)) * 100).toFixed(2) + '%';
                var text = chanceField.previousElementSibling.textContent;
                text = text.substring(text.indexOf(' kill'));
                chanceField.previousElementSibling.textContent = 'Total Chance at ' + binomialN + text;
            }
            updateChart();
        }

        function updateChart() {
            var dropRate = document.getElementById('dropRate').value; // Probability of success
            var killCount = parseInt(document.getElementById('killCount').value); // Number of trials
            if(isNaN(killCount) || isNaN(dropRate) || killCount > 1000000 || dropRate > 1000000 || killCount < 0 || dropRate < 0)
            {
                document.getElementById('alertLabel').textContent = 'Please enter valid input to update the graph';
                return;
            } else {
                document.getElementById('alertLabel').textContent = '';
            }
            var maxKC = Math.max(killCount, dropRate*3);
            for (var i = 0; i < binomialLineContainers.length; i++) {
                var container = binomialLineContainers[i];
                var binomialN = parseInt(container.querySelector('.binomial-n').value);
                var binomialP = parseFloat(container.querySelector('.binomial-p').value);
                container.querySelector('.binomial-p').style.borderColor = lineColors[i+1];
                container.querySelector('.binomial-n').style.borderColor = lineColors[i+1];
                maxKC = Math.max(maxKC, binomialN, binomialP*3);
            }


            var xValues = [];
            var interval = maxKC / 20;
            interval = parseInt(interval);
            if (interval == 0) {
                interval = 1;
            }
            for (var i = 0; i <= maxKC; i++) {
                if (i % interval == 0) {
                  xValues.push(i);
                }
            }

            // Add additional binomial lines
            var invalidInput = false;
            for (var i = 0; i < binomialLineContainers.length; i++) {
                var extraDatasets = [{
                    label: 'Binomial Distribution',
                    data: [],
                    borderWidth: 2
                }];
                var container = binomialLineContainers[i];
                var binomialN = parseInt(container.querySelector('.binomial-n').value);
                var binomialP = parseFloat(container.querySelector('.binomial-p').value);
                if(isNaN(binomialN) || isNaN(binomialP) || binomialN > 1000000 || binomialN < 0)
                {
                    document.getElementById('alertLabel').textContent = 'Please enter valid input to update the graph';
                    invalidInput = true;
                    return;
                } else {
                    document.getElementById('alertLabel').textContent = '';
                }
                
                var chanceField = chanceFields[i];
                chanceField.value = ((1-binomialProbability(0, binomialN, 1/binomialP)) * 100).toFixed(2) + '%';
                chanceField.style.borderColor = lineColors[i+1];
                var data = [];
                for (var k = 0; k <= maxKC; k=k+interval) {
                    data.push({x: k, y: (1-(binomialProbability(0, k, 1/binomialP)))*100});
                }
                var regex = /\((.*?)\)/g;
                var matches = regex.exec(chanceField.previousElementSibling.textContent)[1];
                extraDatasets.push({
                    label: matches,
                    data: data,
                    borderColor: lineColors[i+1], // Different color for additional lines
                    borderWidth: 2
                });
                myChart.data.datasets[i+1] = extraDatasets[1];
                myChart.update();
                addPoint(binomialN, ((1-binomialProbability(0, binomialN, 1/binomialP)) * 100), i+1);
                maxKC = Math.max(maxKC, binomialN, binomialP*2);
            }
            console.log(invalidInput);
            if (!invalidInput) {
                var probabilities = [];
                for (var x = 0; x <= maxKC; x=x+interval) {
                    probabilities.push({x: x, y: (1-(binomialProbability(0, x, 1/dropRate)))*100});
                }
                console.log('here');
                myChart.data.datasets[0].data = probabilities; // Convert to percentage
                myChart.data.labels = xValues;
                myChart.update();
                document.getElementById('totalChance').value = ((1-binomialProbability(0, killCount, 1/dropRate)) * 100).toFixed(2) + '%';
                addPoint(killCount, ((1-binomialProbability(0, killCount, 1/dropRate)) * 100), 0);
            }
        }

        // Binomial probability function
        function binomialProbability(k, n, p) {
            return binomialCoefficient(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k);
        }

        // Binomial coefficient function (n choose k)
        function binomialCoefficient(n, k) {
            if (k === 0 || k === n) {
                return 1;
            } else {
                var numerator = 1;
                var denominator = 1;
                for (var i = 1; i <= k; i++) {
                    numerator *= (n - i + 1);
                    denominator *= i;
                }
                return numerator / denominator;
            }
        }

        // Data for the graph
        var data = {
            labels: Array.from({ length: 101 }, (_, i) => i), // X-axis labels from 0 to 100
            datasets: [{
                label: 'Custom',
                data: Array.from({ length: 101 }, () => 0), // Initialize with zeros
                fill: false,
                borderColor: lineColors[0],
                pointBackgroundColor: 'white',
                pointRadius: 3,
                borderWidth: 2,
                tension: 0.1 // Controls the curve of the line
            }]
        };

        // Configuration options
        var options = {
            plugins: {
                zoom: {
                    limits: {
                        x: {min: 0},
                        y: {min: 0, max: 100}
                    },
                    pan: {
                        enabled: true,
                        mode:'xy'
                    },
                    zoom: {
                        wheel: {
                        enabled: true
                    },
                        mode:'xy'
                    }
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    min: 0,
                    max: 100,
                    ticks: {
                        callback: function(value) {
                            return value.toFixed(1) + '%';
                        }
                    },
                    grid: {
                        color: (context) => {
                            if (context.tick.$context.tick.value === 0) {
                                return 'rgba(255,255,255,1)';
                            } else {
                                return 'rgba(128,128,128,.5)';
                            }
                        }
                    }
                },
                x: {
                    type: 'linear',
                    grid: {
                        color: (context) => {
                            if (context.tick.$context.tick.value === 0) {
                                return 'rgba(255,255,255,1)';
                            } else {
                                return 'rgba(128,128,128,.5)';
                            }
                        }
                    }
                }
            }
        };

        // Get canvas element
        var canvas = document.getElementById('myChart');

        // Set canvas size to fit the screen
        canvas.width = window.innerWidth * 0.8; // 80% of window width
        canvas.height = window.innerHeight * 0.6; // 60% of window height

        // Create the chart
        var ctx = canvas.getContext('2d');
        var myChart = new Chart(ctx, {
            type: 'line',
            data: data,
            options: options
        });

        // Add event listener to input fields to update the chart
        document.getElementById('dropRate').addEventListener('input', updateChart);
        document.getElementById('killCount').addEventListener('input', updateTotals);
        var presetOps = document.getElementById('preset-values');
        

        function addBinomialLine() {
            console.log(document.getElementById('alertLabel').textContent.length);
        if (document.getElementById('alertLabel').textContent.length >= 44) {
            document.getElementById('alertLabel').textContent = 'Please fix the input before adding another pet';
            return;
        }
        var bossName = presetOps.options[presetOps.selectedIndex].label;
        if (document.getElementsByClassName(bossName.split(' ').join('')).length > 0) {
            document.getElementById('alertLabel').textContent = 'You cannot add the same pet twice';
            return;
        }
        var container = document.getElementById('graph-container');
        var newContainer = document.createElement('div');
        var newNLabel = document.createElement('label');
        newContainer.classList.add(bossName.split(' ').join(''));
        newNLabel.classList.add(bossName.split(' ').join(''));
        newNLabel.classList.add('white-label');
        newNLabel.textContent = 'Kill Count: ';
        var newNInput = document.createElement('input');
        newNInput.type = 'number';
        newNInput.value = '0';
        newNInput.min = '0';
        newNInput.max ='999999';
        newNInput.classList.add('binomial-n');
        newNInput.classList.add(bossName.split(' ').join(''));
        newNInput.addEventListener('input', updateTotals);
        newNInput.style.borderColor = lineColors[binomialLineContainers.length+1];
        var newPLabel = document.createElement('label');
        
        newPLabel.textContent = 'Drop Rate ('+bossName+'): ';
        newPLabel.classList.add('white-label');
        var newPInput = document.createElement('input');
        newPInput.type = 'number';
        newPInput.value = presetOps.value;
        newPInput.min = '1';
        newPInput.classList.add('binomial-p');
        newPInput.classList.add(bossName.split(' ').join(''));
        newPInput.addEventListener('input', updateChart);
        newPInput.readOnly = true;
        newPInput.style.borderColor = lineColors[binomialLineContainers.length+1];
        var removeButton = document.createElement('button');
        removeButton.textContent = 'Remove - ' + bossName;
        removeButton.classList.add('remove-button');
        removeButton.classList.add('button');
        removeButton.onclick = function () {
            var elements = document.getElementsByClassName(bossName.split(' ').join(''));
            var elementsArray = Array.from(elements);
            var parent = document.getElementById('graph-container');
            var children = parent.children;
            var index = 0;
            for (var x = 0; x < children.length; x++) {
                if (children[x] === newContainer) {
                    index = x;
                }
            }
            elementsArray.forEach(function(element) {
                element.parentNode.removeChild(element);
            });
            myChart.data.datasets.splice(index,1);
            binomialLineContainers.splice(index-1,1);
            chanceFields.splice(index-1,1);
            updateChart();
        }
        newContainer.appendChild(document.createElement('br'));
        newContainer.appendChild(newNLabel);
        newContainer.appendChild(newNInput);
        newContainer.appendChild(newPLabel);
        newContainer.appendChild(newPInput);
        newContainer.appendChild(removeButton);
        container.appendChild(newContainer);
        binomialLineContainers.push(newContainer); // Store the new binomial line container
        var newChanceField = document.createElement('input');
        var newChanceLable = document.createElement('label');
        var chanceContainer = document.getElementById('chance');
        newChanceLable.textContent = 'Total Chance at '+newNInput.value+' kill count ('+bossName+'): ';
        newChanceField.type = 'text';
        newChanceField.readOnly = true;
        newChanceField.classList.add(bossName.split(' ').join(''));
        newChanceField.classList.add('binomial-p');
        newChanceLable.classList.add(bossName.split(' ').join(''));
        newChanceLable.classList.add('white-label');
        var breakObj = document.createElement('br');
        breakObj.classList.add(bossName.split(' ').join(''));
        chanceContainer.appendChild(breakObj);
        breakObj = document.createElement('br');
        breakObj.classList.add(bossName.split(' ').join(''));
        chanceContainer.appendChild(breakObj);
        chanceContainer.appendChild(newChanceLable);
        chanceContainer.appendChild(newChanceField);
        chanceFields.push(newChanceField);
        updateChart(); // Update the graph with the new binomial line
    }

    function addPoint(xValue, yValue, dataset) {
        if (!isNaN(xValue) && !isNaN(yValue)) {
            let index = 0;
            while (index < myChart.data.datasets[dataset].data.length && myChart.data.datasets[dataset].data[index].x < xValue) {
                index++;
            }
            myChart.data.labels.splice(index, 0, xValue);
            myChart.data.datasets[dataset].data.splice(index, 0, {x: xValue, y: yValue});

            var colorArray = new Array(myChart.data.datasets[dataset].data.length).fill('white');
            colorArray.splice(index, 0, 'orange');
            myChart.data.datasets[dataset].pointBackgroundColor = colorArray; // Change point color
            
            var radiusArray = new Array(myChart.data.datasets[dataset].data.length).fill(3);
            radiusArray.splice(index, 0, 10);
            myChart.data.datasets[dataset].pointRadius = radiusArray; // Increase point radius
            
            myChart.update();
        }
    }
    function toggleCustom() {
        var elements = document.querySelectorAll('.custom');
        console.log(myChart);
        elements.forEach(function(element) {
            if (element.style.display === 'none') {
                myChart.data.datasets[0].hidden = false;
                element.style.display = 'inline-block';
            } else {
                element.style.display = 'none';
                myChart.data.datasets[0].hidden = true;
            }
        });
        myChart.update();
    }
    // Initially update the chart
    updateChart();
    </script>
</body>
</html>
