/*********************************************************
** Copyright (c) 2005
** University of Washington
** Licensed under the terms set forth by University of
** Washington. If you did not sign such a license, you
** are using this software/code illegally and you do not
** have permission to use, modify, or redistribute
** this or any files in this software package.
**
** File: ClusterNodeVector.cpp
**
**********************************************************/
#include "ClusterNodeVector.h"

CClusterNodeVector::CClusterNodeVector(int size) : m_endIter(iterator(this, 0)) {
  m_pVec = NULL;
  m_cap = size;

  if(size > 0) {
    m_pVec = new CClusterNode*[size];
    if (NULL == m_pVec)
      throw bad_alloc();
  }

  m_endIndex = 0;

}

CClusterNodeVector::iterator CClusterNodeVector::begin() { 
  return iterator(this, 0); 
}

CClusterNodeVector::~CClusterNodeVector() {
  if (NULL != m_pVec)
    free(m_pVec);
}

void CClusterNodeVector::push_back(CClusterNode* obj)
{
  // If the vector is at capacity, increase capacity
  if(m_endIndex >= m_cap)
    throw invalid_index();

  // Add the new element
  m_pVec[m_endIndex] = obj;

  m_endIndex++;

  // Update the end iterator
  m_endIter.m_cur = m_endIndex;
}

void CClusterNodeVector::insert(iterator iter, iterator start, iterator finish)
{
  if (iter != m_endIter)
    throw invalid_index();

  for(iterator iter = start; iter != finish; iter++)
    {
	push_back(*iter);
    }
}

void CClusterNodeVector::insert(iterator before, CClusterNode* pNode)
{
  push_back(pNode);
}

void CClusterNodeVector::Reallocate(int newCap) {
  CClusterNode** newPtr = (CClusterNode**)realloc(m_pVec, sizeof(CClusterNode*)*newCap);
  if (NULL == newPtr)
    throw bad_alloc();
  
  m_cap = newCap;
  m_pVec = newPtr;
}

bool CClusterNodeVector_iterator::operator==(const CClusterNodeVector_iterator& i1)
{
  return i1.m_pVec == m_pVec && i1.m_cur == m_cur;
}

bool CClusterNodeVector_iterator::operator!=(const CClusterNodeVector_iterator& i1)
{
  return !this->operator==(i1);
}

void CClusterNodeVector_iterator::operator++(int)
{
  if (m_cur < m_pVec->m_endIndex)
    m_cur++;
}

CClusterNode* CClusterNodeVector_iterator::operator*()
{
  if(this->operator ==(m_pVec->end()))
    throw invalid_index();
  
  return m_pVec->m_pVec[m_cur];
}

inline bool operator==(CClusterNodeVector_iterator& i1, CClusterNodeVector_iterator& i2)
{
  return i1.operator==(i2);
}
