﻿class StringBuilder {
    
    public function __construct($ini = NULL) {
        $this->arr = [];
        $this->str = NULL;
        $this->len = 0;
        if($ini !== NULL) $this->Append($ini);
    }
    public function __toString() {
        if($this->arr !== NULL) {
            $this->str = implode("", $this->arr);
            $this->arr = null;
        }
        return $this->str;
    }
    public function Length() {
        return $this->len;
    }
    public function SetLength($value) {
        if($value < $this->len) {
            $this->str = mb_substr($this->__toString(), 0, $value);
            $this->len = $value;
        }
        return $this->len;
    }
    public function Append($val) {
        if($val === NULL) return $this;
        $s = strval($val);
        if($this->str !== null) {
            $this->arr = [];
            array_push($this->arr, $this->str);
            $this->str = NULL;
        }
        if($this->arr === NULL) $this->arr = [];
        array_push($this->arr, $s);
        $this->len += mb_strlen($s);
        return $this;
    }
    public function Insert($ind, $val) {
        if($ind >= $this->len) {
            $this->Append($val);
            return $this;
        }
        if($val === NULL) return $this;
        $s = strval($val);
        
        $ss = $this->__toString();
        $this->arr = [];
        if($ind == 0) {
            array_push($this->arr, $s);
            array_push($this->arr, $ss);
        }
        else {
            array_push($this->arr, mb_substr($ss, 0, $ind));
            array_push($this->arr, $s);
            array_push($this->arr, mb_substr($ss, $ind));
        }
        $this->str = NULL;
        $this->len += mb_strlen($s);
        return $this;
    }
    public function Remove($ind, $cou) {
        $ss = $this->__toString();
        $this->arr = [];
        if($ind > 0) array_push($this->arr, substr($ss, 0, $ind));
        if($ind + $cou < $this->len) array_push($this->arr, substr($ss, $ind + $cou));
        $this->len -= $cou;
        $this->str = NULL;
        return $this;
    }
    
    public function CharAt($ind) {
        $s = $this->__toString();
        if($ind < mb_strlen($s)) return mb_substr($s, $ind, 1);
        return NULL;
    }
    public function SetCharAt($ind, $char) {
        $ss = $this->__toString();
        $this->arr = [];
        if($ind == 0) {
            array_push($this->arr, $char);
            if(strlen($ss) > 1)
                array_push($this->arr, mb_substr($ss, 1));
        }
        else {
            array_push($this->arr, mb_substr($ss, 0, $ind));
            array_push($this->arr, $char);
            if($ind + 1 < strlen($ss))
                array_push($this->arr, mb_substr($ss, $ind + 1));
        }
        $this->str = NULL;
    }
    public function Replace($old, $new) {
        $str = $this->__toString();
        $this->str = str_replace($old, $new, $str);
        return $this;
    }
}
