import { ComponentChildren } from "preact";
import { css, render_and_copy } from "./common.tsx";
// combine a shake with a fall
// fall should be more delayed than shake
// we want outliers (a few letters falling before than others)
// exponentials should do

const default_shaky_delay = (x: number) => 8 + 10 * x;
export type DelayFn = (_: number) => number;

// exporting these in case they turn out to be useful
export const Shaky = ({
    children,
    delay = 0,
}: {
    children: ComponentChildren;
    delay?: number;
}) => (
    <div
        style={{
            transform: css.transform(css.translate(css.px(-1), css.px(-1))),
            animation: `0.2s spin alternate-reverse linear ${delay}s infinite`,
            display: css.inline_block,
        }}
    >
        {children}
    </div>
);

const default_fall_delay = (x: number) => (3 * x) ** 4;
export const Fall = ({
    children,
    delay = 0,
}: {
    children: ComponentChildren;
    delay?: number;
}) => (
    <div
        style={{
            display: css.inline_block,
        }}
    >
        {children}
    </div>
);

const msg = `
i haven't seen this on other blogs, but some of the posts on mine seem to be kinda unstable?
if that makes sense?
like, sometimes i see them shake, and i swear i saw some letters fall

i know i'm a (convicted?) css criminal, so i'm thinking that this might just be the w3 gods punishing me.

so. yeah. if you see anything like that on any of my posts let me know
`.trim();

// should probably do it word wise so they don't break
export const Crumble = ({
    msg,
    shaky_delay_fn = default_shaky_delay,
    fall_delay_fn = default_fall_delay,
}: {
    msg: string;
    shaky_delay_fn?: DelayFn;
    fall_delay_fn?: DelayFn;
}) => (
    <div>
        {msg.split("").map(c => {
            if (/[^\s]/.test(c)) {
                const seed = Math.random();
                return (
                    <Fall delay={fall_delay_fn(seed)}>
                        <Shaky delay={shaky_delay_fn(seed)}>{c}</Shaky>
                    </Fall>
                );
            }
            if (c == "\n") return <br />;
            return c;
        })}
    </div>
);

render_and_copy(<Crumble msg={msg} />);
