/**
 * Create a number within a given range from a given string.
 */
export function stringToNumber(
    str: string,
    minNum: number,
    maxNum: number
): number {
    let ret = 0;
    let range = maxNum - minNum + 1;

    for (var i = 0; i < str.length; i++) {
        ret += str.charCodeAt(i);
    }

    return (ret % range) + minNum;
}

/**
 * Return all URL query parameters
 */
export function getURLParams() {
    const re = /[?&]?([^=]+)=([^&]*)/g;
    const qs = document.location.search.split('+').join(' ');
    let params: Record<string, string> = {};
    let tokens;

    while ((tokens = re.exec(qs))) {
        params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
    }

    return params;
}

/**
 * Set a URL parameter without refreshing the page.
 */
export function setURLParam(paramName: string, paramValue: string) {
    let url = window.location.href;

    if (url.indexOf(paramName + '=') >= 0) {
        var prefix = url.substring(0, url.indexOf(paramName)),
            suffix = url.substring(url.indexOf(paramName));

        suffix = suffix.substring(suffix.indexOf('=') + 1);
        suffix =
            suffix.indexOf('&') >= 0
                ? suffix.substring(suffix.indexOf('&'))
                : '';

        url = prefix + paramName + '=' + paramValue + suffix;
    } else {
        if (url.indexOf('?') < 0) {
            url += '?' + paramName + '=' + paramValue;
        } else {
            url += '&' + paramName + '=' + paramValue;
        }
    }

    window.history.pushState(null, document.title, url);
}

/**
 * Remove URL parameter without refreshing the page.
 */
export function removeURLParam(paramName: string) {
    let url = window.location.href,
        urlparts = url.split('?');

    if (urlparts.length >= 2) {
        var prefix = paramName + '=',
            pars = urlparts[1].split(/[&;]/g);

        for (var i = pars.length - 1; i >= 0; i--) {
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {
                pars.splice(i, 1);
            }
        }

        url = urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');

        window.history.pushState(null, document.title, url);
    }
}

const adjectiveList = [
    'adorable',
    'adventurous',
    'aggressive',
    'agreeable',
    'alert',
    'alive',
    'amused',
    'angry',
    'annoyed',
    'annoying',
    'anxious',
    'arrogant',
    'ashamed',
    'attractive',
    'average',
    'awful',
    'bad',
    'beautiful',
    'better',
    'bewildered',
    'black',
    'bloody',
    'blue',
    'blue-eyed',
    'blushing',
    'bored',
    'brainy',
    'brave',
    'breakable',
    'bright',
    'busy',
    'calm',
    'careful',
    'cautious',
    'charming',
    'cheerful',
    'clean',
    'clear',
    'clever',
    'cloudy',
    'clumsy',
    'colorful',
    'combative',
    'comfortable',
    'concerned',
    'condemned',
    'confused',
    'cooperative',
    'courageous',
    'crazy',
    'creepy',
    'crowded',
    'cruel',
    'curious',
    'cute',
    'dangerous',
    'dark',
    'dead',
    'defeated',
    'defiant',
    'delightful',
    'depressed',
    'determined',
    'different',
    'difficult',
    'disgusted',
    'distinct',
    'disturbed',
    'dizzy',
    'doubtful',
    'drab',
    'dull',
    'eager',
    'easy',
    'elated',
    'elegant',
    'embarrassed',
    'enchanting',
    'encouraging',
    'energetic',
    'enthusiastic',
    'envious',
    'evil',
    'excited',
    'expensive',
    'exuberant',
    'fair',
    'faithful',
    'famous',
    'fancy',
    'fantastic',
    'fierce',
    'filthy',
    'fine',
    'foolish',
    'fragile',
    'frail',
    'frantic',
    'friendly',
    'frightened',
    'funny',
    'gentle',
    'gifted',
    'glamorous',
    'gleaming',
    'glorious',
    'good',
    'gorgeous',
    'graceful',
    'grieving',
    'grotesque',
    'grumpy',
    'handsome',
    'happy',
    'healthy',
    'helpful',
    'helpless',
    'hilarious',
    'homeless',
    'homely',
    'horrible',
    'hungry',
    'hurt',
    'ill',
    'important',
    'impossible',
    'inexpensive',
    'innocent',
    'inquisitive',
    'itchy',
    'jealous',
    'jittery',
    'jolly',
    'joyous',
    'kind',
    'lazy',
    'light',
    'lively',
    'lonely',
    'long',
    'lovely',
    'lucky',
    'magnificent',
    'misty',
    'modern',
    'motionless',
    'muddy',
    'mushy',
    'mysterious',
    'nasty',
    'naughty',
    'nervous',
    'nice',
    'nutty',
    'obedient',
    'obnoxious',
    'odd',
    'old-fashioned',
    'open',
    'outrageous',
    'outstanding',
    'panicky',
    'perfect',
    'plain',
    'pleasant',
    'poised',
    'poor',
    'powerful',
    'precious',
    'prickly',
    'proud',
    'putrid',
    'puzzled',
    'quaint',
    'real',
    'relieved',
    'repulsive',
    'rich',
    'scary',
    'selfish',
    'shiny',
    'shy',
    'silly',
    'sleepy',
    'smiling',
    'smoggy',
    'sore',
    'sparkling',
    'splendid',
    'spotless',
    'stormy',
    'strange',
    'stupid',
    'successful',
    'super',
    'talented',
    'tame',
    'tasty',
    'tender',
    'tense',
    'terrible',
    'thankful',
    'thoughtful',
    'thoughtless',
    'tired',
    'tough',
    'troubled',
    'ugliest',
    'ugly',
    'uninterested',
    'unsightly',
    'unusual',
    'upset',
    'uptight',
    'vast',
    'victorious',
    'vivacious',
    'wandering',
    'weary',
    'wicked',
    'wide-eyed',
    'wild',
    'witty',
    'worried',
    'worrisome',
    'wrong',
    'zany',
    'zealous'
];

const animalList = [
    'Aardvark',
    'Albatross',
    'Alligator',
    'Alpaca',
    'Anole',
    'Ant',
    'Anteater',
    'Antelope',
    'Ape',
    'Armadillo',
    'Baboon',
    'Badger',
    'Barracuda',
    'Bat',
    'Bear',
    'Beaver',
    'Bee',
    'Binturong',
    'Bird',
    'Bison',
    'Bluebird',
    'Boar',
    'Bobcat',
    'Budgerigar',
    'Buffalo',
    'Butterfly',
    'Camel',
    'Capybara',
    'Caracal',
    'Caribou',
    'Cassowary',
    'Cat',
    'Caterpillar',
    'Cattle',
    'Chamois',
    'Cheetah',
    'Chicken',
    'Chimpanzee',
    'Chinchilla',
    'Chough',
    'Coati',
    'Cobra',
    'Cockroach',
    'Cod',
    'Cormorant',
    'Cougar',
    'Coyote',
    'Crab',
    'Crane',
    'Cricket',
    'Crocodile',
    'Crow',
    'Cuckoo',
    'Curlew',
    'Deer',
    'Dhole',
    'Dingo',
    'Dinosaur',
    'Dog',
    'Dogfish',
    'Dolphin',
    'Donkey',
    'Dove',
    'Dragonfly',
    'Duck',
    'Dugong',
    'Dunlin',
    'Eagle',
    'Echidna',
    'Eel',
    'Eland',
    'Elephant',
    'Elk',
    'Emu',
    'Falcon',
    'Ferret',
    'Finch',
    'Fish',
    'Fisher',
    'Flamingo',
    'Fly',
    'Flycatcher',
    'Fox',
    'Frog',
    'Gaur',
    'Gazelle',
    'Gecko',
    'Genet',
    'Gerbil',
    'Giant',
    'Giraffe',
    'Gnat',
    'Gnu',
    'Goat',
    'Goldfinch',
    'Goosander',
    'Goose',
    'Gorilla',
    'Goshawk',
    'Grasshopper',
    'Grouse',
    'Guanaco',
    'Guinea',
    'Guinea',
    'Gull',
    'Hamster',
    'Hare',
    'Hawk',
    'Hedgehog',
    'Hermit',
    'Heron',
    'Herring',
    'Hippopotamus',
    'Hoatzin',
    'Hoopoe',
    'Hornet',
    'Horse',
    'Human',
    'Hummingbird',
    'Hyena',
    'Ibex',
    'Ibis',
    'Iguana',
    'Impala',
    'Jackal',
    'Jaguar',
    'Jay',
    'Jellyfish',
    'Jerboa',
    'Kangaroo',
    'Kingbird',
    'Kingfisher',
    'Kinkajou',
    'Kite',
    'Koala',
    'Kodkod',
    'Komodo',
    'Kookaburra',
    'Kouprey',
    'Kudu',
    'Langur',
    'Lapwing',
    'Lark',
    'Lechwe',
    'Lemur',
    'Leopard',
    'Lion',
    'Lizard',
    'Llama',
    'Lobster',
    'Locust',
    'Loris',
    'Louse',
    'Lynx',
    'Lyrebird',
    'Macaque',
    'Macaw',
    'Magpie',
    'Mallard',
    'Mammoth',
    'Manatee',
    'Mandrill',
    'Margay',
    'Marmoset',
    'Marmot',
    'Meerkat',
    'Mink',
    'Mole',
    'Mongoose',
    'Monkey',
    'Moose',
    'Mosquito',
    'Mouse',
    'Myna',
    'Narwhal',
    'Newt',
    'Nightingale',
    'Nilgai',
    'Ocelot',
    'Octopus',
    'Okapi',
    'Oncilla',
    'Opossum',
    'Orangutan',
    'Oryx',
    'Ostrich',
    'Otter',
    'Ox',
    'Owl',
    'Oyster',
    'Panther',
    'Parrot',
    'Panda',
    'Partridge',
    'Peafowl',
    'Penguin',
    'Pheasant',
    'Pig',
    'Pigeon',
    'Pika',
    'Polar bear',
    'Pony',
    'Porcupine',
    'Porpoise',
    'Prairie',
    'Pug',
    'Quail',
    'Quelea',
    'Quetzal',
    'Rabbit',
    'Raccoon',
    'Ram',
    'Rat',
    'Raven',
    'Red deer',
    'Red panda',
    'Reindeer',
    'Rhea',
    'Rhinoceros',
    'Rook',
    'Saki',
    'Salamander',
    'Salmon',
    'Sand dollar',
    'Sandpiper',
    'Sardine',
    'Sassaby',
    'Sea lion',
    'Seahorse',
    'Seal',
    'Serval',
    'Shark',
    'Sheep',
    'Shrew',
    'Shrike',
    'Siamang',
    'Skink',
    'Skipper',
    'Skunk',
    'Sloth',
    'Snail',
    'Snake  ',
    'Spider  ',
    'Spoonbill',
    'Squid',
    'Squirrel',
    'Starling',
    'Stilt',
    'Swan',
    'Tamarin',
    'Tapir',
    'Tarsier',
    'Termite',
    'Thrush',
    'Tiger',
    'Toad',
    'Topi',
    'Toucan',
    'Turaco',
    'Turkey',
    'Turtle',
    'Vicuña',
    'Vinegaroon',
    'Viper',
    'Vulture',
    'Wallaby',
    'Walrus',
    'Wasp',
    'Water buffalo',
    'Waxwing',
    'Weasel',
    'Whale',
    'Wobbegong',
    'Wolf',
    'Wolverine',
    'Wombat',
    'Woodpecker',
    'Worm',
    'Wren',
    'Yak',
    'Zebra'
];

/**
 * Generate a random funny name.
 */
export function generateRandomName(): string {
    let adjective =
        adjectiveList[Math.floor(Math.random() * adjectiveList.length)];
    let noun = animalList[Math.floor(Math.random() * animalList.length)];

    adjective = adjective.charAt(0).toUpperCase() + adjective.slice(1);

    return `${adjective}${noun}`;
}
