#include "mvector.h"
#include "mdebug.h"

vector_obj* vector_new(int first_size)
{
   vector_obj* self = (vector_obj*)MALLOC(sizeof(vector_obj));

   self->mTable = (void**)MALLOC(sizeof(void*) * first_size);
   self->mTableSize = first_size;
   self->mCount = 0;

   return self;
}

void vector_delete(vector_obj* self)
{
   FREE(self->mTable);
   FREE(self);
}

void* vector_item(vector_obj* self, int index)
{
   return self->mTable[index];
}
   
int vector_size(vector_obj* self)
{
   return self->mCount;
}
   
void vector_exchange(vector_obj* self, int n, void* item)
{
   self->mTable[n] = item;
}

void vector_add(vector_obj* self, void* item)
{
   if(self->mCount == self->mTableSize) {
      self->mTableSize = self->mTableSize * 2;

      self->mTable = (void**)REALLOC(self->mTable
                                       , sizeof(void*)*self->mTableSize);
   }

   self->mTable[self->mCount] = item;
   self->mCount++;
}

void vector_insert(vector_obj* self, int n, void* item)
{
   if(self->mCount == self->mTableSize) {
      self->mTableSize = self->mTableSize * 2;

      self->mTable = (void**)REALLOC(self->mTable
                              , sizeof(void*)*self->mTableSize);
   }

   memmove(self->mTable +n +1, self->mTable +n
                           , sizeof(void*)*(self->mCount - n));
   
   self->mTable[n] = item;
   self->mCount++;
}

int vector_index(vector_obj* self, void* item)
{
    int i;
    for(i=0; i<self->mCount; i++) {
        if(self->mTable[i] == item) {
            return i;
        }
    }

    return -1;
}

void vector_erase(vector_obj* self, int n)
{
    if(n>=0 && n<self->mCount) {
        memmove(self->mTable + n, self->mTable + n + 1, sizeof(void*)*(self->mCount -n-1));

        self->mCount--;
    }
}

void vector_pop_back(vector_obj* self)
{
    vector_erase(self, self->mCount-1);
}

static quick_sort(vector_obj* self, int left, int right, sort_if fun)
{
   int i;
   int j;
   void* center_item;

	if(left < right) {
		center_item = self->mTable[(left+right) / 2];

		i = left;
		j = right;

		do { 
			while(self->mTable[i]!=center_item
                     && fun(self->mTable[i], center_item))
         {
				i++;
			}
         
			while(center_item!=self->mTable[j]
                     && fun(center_item, self->mTable[j]))
         {
				j--;
			}

			if(i <= j) {
				void* tmp = self->mTable[i];					// swap
				self->mTable[i] = self->mTable[j];
				self->mTable[j] = tmp;

				i++;
				j--;
			}
		} while(i <= j);

		quick_sort(self, left, j, fun);
		quick_sort(self, i, right, fun);
	}
}

void vector_sort(vector_obj* self, sort_if fun)
{
    quick_sort(self, 0, self->mCount-1, fun);
}

void vector_clear(vector_obj* self)
{
    self->mCount = 0;
}
