<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>🧮 Interactive Soroban Gallery - Demo</title>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src="https://unpkg.com/react-spring@9.7.0/dist/react-spring.umd.js"></script>
    <script src="https://unpkg.com/@use-gesture/react@10.3.0/dist/index.umd.js"></script>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        }

        #loading {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background: #f5f5f5;
            font-size: 1.2rem;
            color: #666;
        }

        #root {
            min-height: 100vh;
        }
    </style>
</head>
<body>
    <div id="loading">🧮 Loading Interactive Soroban Gallery...</div>
    <div id="root"></div>

    <script type="text/babel">
        const { useState, useCallback, useMemo, useEffect } = React;
        const { useSpring, animated, config } = window.ReactSpring;
        const { useDrag } = window.ReactUseGesture;

        // AbacusReact component implementation
        function useAbacusDimensions(columns, scaleFactor = 1) {
            return useMemo(() => {
                const baseBeadSize = 12 * scaleFactor;
                const baseRodSpacing = 25 * scaleFactor;
                const baseMargin = 20 * scaleFactor;
                const heavenEarthGap = 30 * scaleFactor;
                const barThickness = 2 * scaleFactor;

                const width = (columns * baseRodSpacing) + (2 * baseMargin);
                const height = (baseBeadSize * 6) + heavenEarthGap + barThickness + (2 * baseMargin);

                return { width, height, rodSpacing: baseRodSpacing, beadSize: baseBeadSize };
            }, [columns, scaleFactor]);
        }

        function useAbacusState(initialValue = 0) {
            const [value, setValue] = useState(initialValue);

            const getColumnValue = useCallback((columnIndex, totalColumns) => {
                const digits = value.toString().padStart(totalColumns, '0').split('').map(Number);
                return digits[columnIndex] || 0;
            }, [value]);

            const toggleBead = useCallback((bead, totalColumns) => {
                const currentColumnValue = getColumnValue(bead.columnIndex, totalColumns);
                let newColumnValue;

                if (bead.type === 'heaven') {
                    newColumnValue = bead.active ? currentColumnValue - 5 : currentColumnValue + 5;
                } else {
                    if (bead.active) {
                        newColumnValue = Math.min(currentColumnValue, bead.position);
                    } else {
                        newColumnValue = Math.max(currentColumnValue, bead.position + 1);
                    }
                }

                const digits = value.toString().padStart(totalColumns, '0').split('').map(Number);
                digits[bead.columnIndex] = Math.max(0, Math.min(9, newColumnValue));
                const newTotal = parseInt(digits.join(''), 10);
                setValue(newTotal);
            }, [value, getColumnValue]);

            return { value, setValue, toggleBead };
        }

        const COLOR_PALETTES = {
            default: ['#2E86AB', '#A23B72', '#F18F01', '#6A994E', '#BC4B51'],
            colorblind: ['#0173B2', '#DE8F05', '#CC78BC', '#029E73', '#D55E00'],
            mnemonic: ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd'],
            grayscale: ['#000000', '#404040', '#808080', '#b0b0b0', '#d0d0d0'],
            nature: ['#4E79A7', '#F28E2C', '#E15759', '#76B7B2', '#59A14F']
        };

        function getBeadColor(bead, totalColumns, colorScheme, colorPalette) {
            const inactiveColor = '#d3d3d3';
            if (!bead.active) return inactiveColor;

            switch (colorScheme) {
                case 'place-value': {
                    const placeIndex = totalColumns - bead.columnIndex - 1;
                    const colors = COLOR_PALETTES[colorPalette] || COLOR_PALETTES.default;
                    return colors[placeIndex % colors.length];
                }
                case 'alternating':
                    return bead.columnIndex % 2 === 0 ? '#1E88E5' : '#43A047';
                case 'heaven-earth':
                    return bead.type === 'heaven' ? '#E53E3E' : '#3182CE';
                default:
                    return '#000000';
            }
        }

        function calculateBeadStates(value, columns) {
            const digits = value.toString().padStart(columns, '0').split('').map(Number);

            return digits.map((digit, columnIndex) => {
                const beads = [];

                const heavenActive = digit >= 5;
                beads.push({
                    type: 'heaven',
                    value: 5,
                    active: heavenActive,
                    position: 0,
                    columnIndex
                });

                const earthValue = digit % 5;
                for (let i = 0; i < 4; i++) {
                    beads.push({
                        type: 'earth',
                        value: 1,
                        active: i < earthValue,
                        position: i,
                        columnIndex
                    });
                }

                return beads;
            });
        }

        const Bead = ({ bead, x, y, size, shape, color, animated, draggable, onClick }) => {
            const [{ x: springX, y: springY }, api] = useSpring(() => ({ x, y }));

            const bind = useDrag(({ movement: [mx, my], down }) => {
                if (!draggable) return;
                if (down) {
                    api.start({ x: x + mx, y: y + my, immediate: true });
                } else {
                    api.start({ x, y });
                }
            }, { enabled: draggable });

            useEffect(() => {
                if (animated) {
                    api.start({ x, y, config: config.gentle });
                } else {
                    api.set({ x, y });
                }
            }, [x, y, animated, api]);

            const renderShape = () => {
                const halfSize = size / 2;
                switch (shape) {
                    case 'diamond':
                        return React.createElement('polygon', {
                            points: `${size * 0.7},0 ${size * 1.4},${halfSize} ${size * 0.7},${size} 0,${halfSize}`,
                            fill: color,
                            stroke: '#000',
                            strokeWidth: '0.5'
                        });
                    case 'square':
                        return React.createElement('rect', {
                            width: size,
                            height: size,
                            fill: color,
                            stroke: '#000',
                            strokeWidth: '0.5',
                            rx: '1'
                        });
                    case 'circle':
                    default:
                        return React.createElement('circle', {
                            cx: halfSize,
                            cy: halfSize,
                            r: halfSize,
                            fill: color,
                            stroke: '#000',
                            strokeWidth: '0.5'
                        });
                }
            };

            const AnimatedG = animated.g;

            return React.createElement(AnimatedG, {
                transform: animated ? undefined : `translate(${x - size/2}, ${y - size/2})`,
                style: animated ? {
                    transform: springX.to((x, y) => `translate(${x - size/2}px, ${y - size/2}px)`)
                } : undefined,
                ...bind(),
                onClick,
                style: { cursor: draggable ? 'grab' : onClick ? 'pointer' : 'default' }
            }, renderShape());
        };

        const AbacusReact = ({
            value = 0,
            columns = 'auto',
            showEmptyColumns = false,
            hideInactiveBeads = false,
            beadShape = 'diamond',
            colorScheme = 'monochrome',
            colorPalette = 'default',
            scaleFactor = 1,
            animated = true,
            draggable = false,
            onClick,
            onValueChange
        }) => {
            const { value: currentValue, toggleBead } = useAbacusState(value);

            const effectiveColumns = useMemo(() => {
                if (columns === 'auto') {
                    return Math.max(1, currentValue.toString().length);
                }
                return columns;
            }, [columns, currentValue]);

            const dimensions = useAbacusDimensions(effectiveColumns, scaleFactor);
            const beadStates = useMemo(
                () => calculateBeadStates(currentValue, effectiveColumns),
                [currentValue, effectiveColumns]
            );

            const margin = 20 * scaleFactor;
            const heavenEarthGap = 30 * scaleFactor;
            const barY = margin + dimensions.beadSize * 1.5 + heavenEarthGap / 2;
            const beadSpacing = 4 * scaleFactor;

            const handleBeadClick = useCallback((bead) => {
                onClick?.(bead);
                toggleBead(bead, effectiveColumns);
                onValueChange?.(currentValue);
            }, [onClick, toggleBead, currentValue, effectiveColumns, onValueChange]);

            const rods = [];
            for (let colIndex = 0; colIndex < effectiveColumns; colIndex++) {
                const x = margin + (colIndex * dimensions.rodSpacing);
                rods.push(React.createElement('line', {
                    key: `rod-${colIndex}`,
                    x1: x,
                    y1: margin,
                    x2: x,
                    y2: dimensions.height - margin,
                    stroke: '#8B4513',
                    strokeWidth: 3 * scaleFactor
                }));
            }

            const bar = React.createElement('rect', {
                x: margin - 10 * scaleFactor,
                y: barY,
                width: dimensions.width - 2 * margin + 20 * scaleFactor,
                height: 2 * scaleFactor,
                fill: '#8B4513'
            });

            const beads = [];
            beadStates.forEach((columnBeads, colIndex) => {
                columnBeads.forEach((bead, beadIndex) => {
                    if (hideInactiveBeads && !bead.active) return;

                    const x = margin + (colIndex * dimensions.rodSpacing);
                    let y;

                    if (bead.type === 'heaven') {
                        y = margin + dimensions.beadSize / 2;
                    } else {
                        const earthStartY = barY + (2 * scaleFactor) + dimensions.beadSize / 2 + beadSpacing;
                        y = earthStartY + (bead.position * (dimensions.beadSize + beadSpacing));
                    }

                    const color = getBeadColor(bead, effectiveColumns, colorScheme, colorPalette);

                    beads.push(React.createElement(Bead, {
                        key: `bead-${colIndex}-${bead.type}-${beadIndex}`,
                        bead,
                        x,
                        y,
                        size: dimensions.beadSize,
                        shape: beadShape,
                        color,
                        animated,
                        draggable,
                        onClick: () => handleBeadClick(bead)
                    }));
                });
            });

            return React.createElement('svg', {
                width: dimensions.width,
                height: dimensions.height,
                viewBox: `0 0 ${dimensions.width} ${dimensions.height}`,
                style: { overflow: 'visible' }
            }, ...rods, bar, ...beads);
        };

        // Gallery Examples (simplified version)
        const GALLERY_EXAMPLES = [
            {
                id: 'basic-5',
                title: 'Basic Number 5',
                subtitle: 'Simple representation of 5',
                value: 5,
                config: { columns: 1, beadShape: 'diamond', colorScheme: 'monochrome', scaleFactor: 1, animated: true, draggable: true }
            },
            {
                id: 'colorful-123',
                title: 'Colorful 123',
                subtitle: 'Multi-column with place value colors',
                value: 123,
                config: { columns: 3, beadShape: 'diamond', colorScheme: 'place-value', colorPalette: 'default', scaleFactor: 1, animated: true, draggable: true }
            },
            {
                id: 'circles-42',
                title: 'Circle Beads - 42',
                subtitle: 'Different bead shape demonstration',
                value: 42,
                config: { columns: 2, beadShape: 'circle', colorScheme: 'place-value', colorPalette: 'default', scaleFactor: 1.2, animated: true, draggable: true }
            },
            {
                id: 'compact-999',
                title: 'Compact 999',
                subtitle: 'Square beads with alternating colors',
                value: 999,
                config: { columns: 3, beadShape: 'square', colorScheme: 'alternating', scaleFactor: 0.8, animated: true, draggable: true }
            }
        ];

        const InteractiveAbacusCard = ({ example }) => {
            const [currentValue, setCurrentValue] = useState(example.value);
            const [clickCount, setClickCount] = useState(0);

            const dimensions = useAbacusDimensions(example.config.columns, example.config.scaleFactor || 1);

            const handleValueChange = useCallback((newValue) => {
                setCurrentValue(newValue);
            }, []);

            const handleBeadClick = useCallback((bead) => {
                setClickCount(prev => prev + 1);
            }, []);

            const resetValue = useCallback(() => {
                setCurrentValue(example.value);
                setClickCount(0);
            }, [example.value]);

            return React.createElement('div', {
                style: {
                    background: 'white',
                    borderRadius: '12px',
                    boxShadow: '0 4px 15px rgba(0,0,0,0.1)',
                    overflow: 'hidden',
                    transition: 'all 0.3s ease',
                    margin: '20px'
                }
            },
                React.createElement('div', {
                    style: {
                        padding: '20px',
                        borderBottom: '1px solid #eee',
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'flex-start'
                    }
                },
                    React.createElement('div', null,
                        React.createElement('h3', { style: { margin: '0 0 5px 0', color: '#2c3e50', fontSize: '1.3rem' } }, example.title),
                        React.createElement('p', { style: { margin: 0, color: '#666', fontSize: '0.9rem' } }, example.subtitle)
                    ),
                    React.createElement('div', {
                        style: { display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: '5px' }
                    },
                        React.createElement('div', { style: { fontSize: '0.85rem', color: '#666' } }, `Value: ${currentValue}`),
                        React.createElement('div', { style: { fontSize: '0.85rem', color: '#666' } }, `Clicks: ${clickCount}`),
                        React.createElement('button', {
                            onClick: resetValue,
                            style: {
                                background: '#3498db',
                                color: 'white',
                                border: 'none',
                                borderRadius: '4px',
                                padding: '5px 10px',
                                cursor: 'pointer',
                                fontSize: '1.2rem'
                            }
                        }, '↻')
                    )
                ),
                React.createElement('div', {
                    style: {
                        padding: '30px',
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        minHeight: '200px',
                        background: '#fafafa'
                    }
                },
                    React.createElement('div', {
                        style: {
                            width: `${dimensions.width}px`,
                            height: `${dimensions.height}px`,
                            border: '2px solid rgba(0,0,0,0.1)',
                            borderRadius: '8px',
                            background: 'white',
                            padding: '10px'
                        }
                    },
                        React.createElement(AbacusReact, {
                            value: currentValue,
                            ...example.config,
                            onClick: handleBeadClick,
                            onValueChange: handleValueChange
                        })
                    )
                )
            );
        };

        const InteractiveGallery = () => {
            const [totalClicks, setTotalClicks] = useState(0);

            return React.createElement('div', {
                style: {
                    fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
                    lineHeight: 1.6,
                    color: '#333',
                    background: '#f5f5f5',
                    padding: '20px',
                    minHeight: '100vh'
                }
            },
                React.createElement('div', {
                    style: {
                        maxWidth: '1400px',
                        margin: '0 auto'
                    }
                },
                    React.createElement('div', {
                        style: {
                            textAlign: 'center',
                            marginBottom: '40px',
                            padding: '40px 20px',
                            background: 'white',
                            borderRadius: '12px',
                            boxShadow: '0 2px 10px rgba(0,0,0,0.1)'
                        }
                    },
                        React.createElement('h1', {
                            style: {
                                fontSize: '2.5rem',
                                marginBottom: '10px',
                                color: '#2c3e50'
                            }
                        }, '🧮 Interactive Soroban Gallery'),
                        React.createElement('p', {
                            style: {
                                fontSize: '1.1rem',
                                color: '#666',
                                marginBottom: '20px'
                            }
                        }, 'Click and drag the beads to explore how a Japanese abacus works!')
                    ),
                    React.createElement('div', {
                        style: {
                            background: '#e8f4fd',
                            border: '1px solid #bee5eb',
                            borderRadius: '8px',
                            padding: '20px',
                            marginBottom: '20px',
                            textAlign: 'center'
                        }
                    },
                        React.createElement('h3', {
                            style: {
                                color: '#0c5460',
                                marginBottom: '10px'
                            }
                        }, '🎯 How to Interact'),
                        React.createElement('p', {
                            style: {
                                color: '#0c5460',
                                margin: 0
                            }
                        }, 'Click beads to toggle their positions • Drag beads for tactile feedback • Reset button restores original values')
                    ),
                    React.createElement('div', {
                        style: {
                            display: 'grid',
                            gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))',
                            gap: '0px'
                        }
                    },
                        ...GALLERY_EXAMPLES.map(example =>
                            React.createElement(InteractiveAbacusCard, {
                                key: example.id,
                                example
                            })
                        )
                    )
                )
            );
        };

        // Hide loading and render gallery
        document.getElementById('loading').style.display = 'none';
        ReactDOM.render(React.createElement(InteractiveGallery), document.getElementById('root'));
    </script>
</body>
</html>