package cz.softdeluxe.jlib.collections

import cz.softdeluxe.jlib.random

/**
 * Created by balat on 25.03.2017.
 */

/**
 * vrátí view z kolekce od pozice itemFrom (inclusive) do itemTo (exclusive). Pokud itemTo je null tak do konce
 * Pokud se itemFrom v kolekce nenajde tak vrací prázdné pole
 */
fun <T> List<T>.subListFrom(itemFrom: T, itemTo: T? = null): List<T> {
    val fromIndex: Int = this.indexOf(itemFrom).takeIf { it >= 0 } ?: return emptyList()
    val toIndex: Int = if (itemTo == null || !this.contains(itemTo)) size else this.indexOf(itemTo)

    return subList(fromIndex, toIndex)
}


/**
 * vrátí view z kolekce od pozice itemFrom (exclusive) do itemTo (exclusive). Pokud itemTo je null tak do konce
 * Pokud se itemFrom v kolekce nenajde tak vrací prázdné pole
 */
fun <T> List<T>.subListAfter(itemFrom: T, itemTo: T? = null): List<T> {
    val subListFrom = subListFrom(itemFrom, itemTo)
    return if (isEmpty()) emptyList() else subListFrom.subList(1, subListFrom.size)
}

/**
 * vrátí view z kolekce do pozice itemTo (exclusive)
 * Pokud se itemTo v kolekce nenajde tak vrací prázdné pole
 */
fun <T> List<T>.subListBefore(itemTo: T): List<T> {
    val toIndex: Int = this.indexOf(itemTo).takeIf { it >= 0 } ?: return emptyList()

    return subList(0, toIndex)
}


/**
 * vrátí další prvek v kolekci
 */
fun <T> List<T>.next(item: T): T? {
    val index = indexOf(item).takeIf { it >= 0 } ?: return null
    return getOrNull(index + 1)
}

/**
 * vrátí předchozí prvek v kolekci
 */
fun <T> List<T>.previous(item: T): T? {
    val index = indexOf(item).takeIf { it >= 0 } ?: return null
    return getOrNull(index - 1)
}

/**
 * vrátí náhodný prvek
 */
fun <T> List<T>.random(): T? = takeIf { it.isNotEmpty() }?.get(random.nextInt(size))

fun <T> List<T>.random(size: Int): List<T> {
    val orig = this.toMutableList()
    val ret = mutableListOf<T>()

    for (i in 0 until size) {
        val rand = orig.random() ?: break
        orig -= rand
        ret += rand
    }

    return ret
}