#include "mstring.h"
#include "mdebug.h"

string_obj* string_new(char* str)
{
    string_obj* result;

    const int len = strlen(str);
    
    result = MALLOC(sizeof(string_obj));
    
    result->mMallocLen = len*2 + 1;
    result->mStr = MALLOC(sizeof(char)*result->mMallocLen);
    strcpy(result->mStr, str);
    
    result->mLen = len;

    return result;
}

void string_delete(string_obj* str)
{
    FREE(str->mStr);
    
    FREE(str);
}

int string_length(string_obj* obj)
{
    return obj->mLen;
}

char* string_c_str(string_obj* obj)
{
    return obj->mStr;
}

void string_insert(string_obj* obj, int pos, char* str)
{
    char* new_str;
    char* tmp_str;
    const int str_len = strlen(str);

    if(pos <= obj->mLen) {
        if(obj->mLen+str_len+1 > obj->mMallocLen) {
            obj->mMallocLen = (obj->mLen + str_len + 1) * 2;
            new_str = MALLOC(obj->mMallocLen);

            memcpy(new_str, obj->mStr, pos);
            memcpy(new_str + pos, str, str_len);
            strcpy(new_str + pos + str_len, obj->mStr + pos);

            FREE(obj->mStr);

            obj->mStr = new_str;
            obj->mLen = strlen(new_str);
        }
        else {
            tmp_str = MALLOC(obj->mMallocLen);

            memcpy(tmp_str, obj->mStr, pos);
            memcpy(tmp_str + pos, str, str_len);
            strcpy(tmp_str + pos + str_len, obj->mStr + pos);

            strcpy(obj->mStr, tmp_str);
    
            FREE(tmp_str);
    
            obj->mLen = strlen(obj->mStr);
        }
    }
}


void string_push_back(string_obj* self, char* key)
{
    string_insert(self, string_length(self), key);
}

void string_push_back2(string_obj* self, char key)
{
    char tmp[2];
    tmp[0] = key;
    tmp[1] = 0;

    string_insert(self, string_length(self), tmp);
}

void string_erase(string_obj* obj, int pos, int len)
{
//    strcpy(obj->mStr + pos, obj->mStr+pos+len);
    if(pos>=0 && pos<obj->mLen && pos+len <= obj->mLen) {
        memmove(obj->mStr + pos, obj->mStr+pos+len, obj->mLen-pos-len+1);

        obj->mLen-=len;
    }
}

void string_put(string_obj* self, char* str)
{
    const int len = strlen(str);
    if(len+1 < self->mMallocLen) {
        strcpy(self->mStr, str);
        self->mLen = strlen(str);
    }
    else {
        FREE(self->mStr);
        
        self->mMallocLen = len*2 + 1;
        self->mStr = MALLOC(sizeof(char)*self->mMallocLen);
        
        strcpy(self->mStr, str);
        self->mLen = strlen(str);
    }
}

void string_trunc(string_obj* self, int n)
{
    if(n < strlen(self->mStr)) {
        self->mStr[n] = 0;
        self->mLen = strlen(self->mStr);
    }
}
