/**
 * List容器
 */
export class List<T> {

    private _items: T[];

    constructor(array?: T[]) {
        if (array)
            this._items = array;
        else
            this._items = [];
    }

    /**
     * 数量(属性)
     */
    public get Count() { return this._items.length; }


    /**
     * 添加
     * @param item Item
     */
    public Add(item: T): void {
        this._items.push(item);
    }


    /**
     * 移除
     * @param item Item
     * @returns 是否移除成功
     */
    public Remove(item: T): boolean {
        for (var i = 0, j = this._items.length; i < j; i++) {
            if (this._items[i] === item) {
                this._items.splice(i, 1);
                return true;
            }
        }
        return false;
    }

    /**
     * 从索引处移除
     * @param index 索引
     * @returns 是否移除成功
     */
    public RemoveAt(index: number): boolean {
        if (index < 0 || index >= this._items.length) {
            return false;
        }
        this._items.splice(index, 1);
        return true;
    }

    /**
     * 包含
     * @param item Item
     * @returns True: 包含; False: 未包含
     */
    public Contains(item: T): boolean {
        for (var i = 0, j = this._items.length; i < j; i++) {
            if (this._items[i] === item) {
                return true;
            }
        }
        return false;
    }


    /**
     * 排序
     * @param comparer 比较器
     */
    public Sort(comparer?: (a: T, b: T) => number): void {
        this._items.sort(comparer);
    }


    /**
     * 获取下标(不存在返回-1)
     * @param item Item
     * @returns 下标
     */
    public IndexOf(item: T): number {
        for (var i = 0, j = this._items.length; i < j; i++) {
            if (this._items[i] === item) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 索引器
     * @param index 索引
     * @returns Item
     */
    public GetItem(index: number): T {
        return this._items[index];
    }


    /**
     * 迭代器
     * @param callback 回调
     */
    public Foreach(callback: (item: T, index: number) => void, thisArg?: any): void {
        if (callback) {
            this._items.forEach((value: T, index: number, _: T[]) => {
                callback.call(thisArg, value, index);
            });
        }
    }

    /**
     * 过滤
     * @param predicate 
     * @returns 过滤后新的List<T>
     */
    public Filter(predicate: (value: T, index: number, array: T[]) => unknown): List<T> {
        return new List<T>(this._items.filter(predicate))
    }


    /**
     * 清理
     */
    public Clear() {
        this._items = [];
    }
}