﻿class MyList 
{
    public function __construct() {
        $this->items = [];
        $this->count = 0;
    }   
    public static function CreateFrom($ini) {
        $arr = new MyList();
        if($ini !== NULL)
            $arr->AddRange($ini);
        return $arr;
    }
    public static function CreateArray($len, $ini = NULL) {
        $arr = new MyList();
        $arr->items = array_fill(0, $len, $ini);
        $arr->count = $len;
        return $arr;
    }
    public static function WrapArrayConst($arr) {
        $res = new MyList();
        $res->items = $arr;
        $res->count = count($arr);
        return $res;
    }
    public static function WrapArray(&$arr) {
        $res = new MyList();
        $res->items = $arr;
        $res->count = count($arr);
        return $res;
    }
    
    public $items;
    public $count;
    
    public function Add($item) {
        array_push($this->items, $item); 
        $this->count++;
    }
    public function Insert($pos, $item) {
        array_splice($this->items, $pos, 0, 1);
        $this->items[$pos] = $item;
        $this->count++;
    }
    public function AddRange($items) {
        if($items instanceof MyList) {
            if($items->count == 0) return;
            array_push($this->items, ...$items->items); $this->count += $items->count;
        }
        else foreach ($items as $item) Add($item);
    }
    public function InsertRange($pos, $items) {
        if($items instanceof MyList) {
            if($items->count == 0) return;
            array_splice($this->items, $pos, 0, $items->items);
            $this->count += $items->count;
        }
        else foreach ($items as $item) { Insert($pos, $item); $pos++; }
    }
    
    public function Remove($item) {
        $pos = $this->IndexOf($item);
        if($pos >= 0) { array_splice($this->items, $pos, 1); $this->count--; }
    }
    public function RemoveAt($pos) {
        if($pos >= 0) { array_splice($this->items, $pos, 1); $this->count--; }
    }
    public function RemoveRange($pos, $len) {
        array_splice($this->items, $pos, $len);
        $this->count -= $len;
    }
    public function Clear() {
        array_splice($this->items, 0, $this->count);
        $this->count = 0;
    }
    
    public function Reverse() {
        $this->items = array_reverse($this->items);
    }
    public function Sort() {
        sort($this->items);
    }
    public function Usort($comp) {
        usort($this->items, $comp);
    }
    public function UsortComp($comp) {
        usort($this->items, function($a, $b) use($comp) { return $comp->Compare($a, $b); });
    }
        
    public function IndexOf($item, $ind0 = 0) {
        for($i = $ind0; $i < $this->count; $i++)
            if($this->items[$i] === $item)
                return $i;
        return -1;
    }
    public function LastIndexOf($item, $ind0 = -1) {
        if($ind0 < 0) $ind0 = $this->count - 1;
        for($i = $ind0; $i >= 0; $i--)
            if($this->items[$i] === $item)
                return $i;
        return -1;
    }
    
    public function Contains($item) {
        return in_array($item, $this->items, TRUE);
    }
    
    public function ToArray() {
        return $this;
    }
       
    public function &GetSubarray($pos, $len) {
		if($len <= 0) $len = $this->count - $pos;
        if($pos == 0 && $len == $this->count) 
            return $this->items;
        $res = array_fill(0, $len, NULL);
        for($i = 0; $i < $len; $i++) $res[$i] = $this->items[$pos + $i];
        return $res;
    }
}
