/* Copyright (c) 2001 IBK-Landquart-Switzerland. All rights reserved.
 *
 * Module      :  ZPtrlist.hpp
 * Application :  IBK Open Class Library
 * Purpose     :  Pointer list class as generic base class for any kind
 *                of list.
 *
 * Date        Description                                 Who
 * --------------------------------------------------------------------------
 * 2001.06.12  First implementation                        P.Koch, IBK
 *
 * OPEN SOURCE LICENSE
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to IBK at info@ibk-software.ch.
 */
#define ZC_BUILDING_ZBASE

#include <ZExcept.hpp>

ZExport0 ZPointerlist::ZPointerlist ():iCount (0), iSize (0), iList (0)
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::ZPointerlist()");
}                               // ZPointerlist

ZExport0 ZPointerlist::
ZPointerlist (const ZPointerlist & aPointerlist):iCount (0), iSize (0),
iList (0)
{
  ZFUNCTRACE_DEVELOP
    ("ZPointerlist::ZPointerlist(const ZPointerlist& aPointerist)");
  *this = aPointerlist;
}                               // ZPointerlist

ZExport0 ZPointerlist::~ZPointerlist ()
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::~ZPointerlist()");
  drop ();
  if (iList)
    delete[]iList;
}                               // ~ZPointerlist

ZExport (ZPointerlist &) ZPointerlist::operator= (const ZPointerlist & aList)
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::operator=(const ZPointerlist& aList)");
  drop ();
  *this += aList;
  return *this;
}                               // operator=

ZExport (ZPointerlist &) ZPointerlist::operator+= (const ZPointerlist & aList)
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::operator+=(const ZPointerlist& aList)");
  for (long i = 0; i < aList.count (); i++)
    addAsLast (copy (aList[i]));
  return *this;
}                               // operator+=

ZExport (void *) ZPointerlist::operator[](long aIndex) const
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::operator[](long aIndex) const");
  ZTRACE_DEVELOP ("aIndex " + ZString (aIndex));
  if (aIndex >= iCount || aIndex < 0)
    ZTHROWEXC ("Invalid index");
  return iList[aIndex];
}                               // operator[]

ZExport (ZPointerlist &) ZPointerlist::removeFromPos (long aIndex)
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::removeFromPos(long aIndex)");

  if (aIndex >= iCount || aIndex < 0)
    ZTHROWEXC ("Invalid index");
  del (iList[aIndex]);
  for (long i = aIndex + 1; i < iCount; i++)
    iList[i - 1] = iList[i];
  iCount--;
  return *this;
}                               // ZPointerlist::removeFromPos

ZExport (ZPointerlist &) ZPointerlist::addAtPos (long aIndex, void *aPointer)
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::addAtPos(long aIndex, void* aPointer");

  if (aIndex > iCount || aIndex < 0)
    ZTHROWEXC ("Invalid index");

  if (iCount == iSize)
      {
        iSize = iSize ? iSize + iSize : 10;
        ZTRACE_DEVELOP ("iSize " + ZString (iSize));
        void **newList = new void *[iSize];
        long i = 0;
        while (i < aIndex)
            {
              newList[i] = iList[i];
              i++;
            }                   // while
        newList[i++] = aPointer;
        while (i <= iCount)
            {
              newList[i] = iList[i - 1];
              i++;
            }                   // while
        if (iList)
          delete[]iList;
        iList = newList;
      }
  else
      {
        for (long i = iCount; i > aIndex; i--)
          iList[i] = iList[i - 1];
        iList[aIndex] = aPointer;
      }                         // if
  iCount++;
  return *this;
}                               // addAtPos

ZExport (ZPointerlist &) ZPointerlist::drop ()
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::drop()");
  for (long i = 0; i < iCount; i++)
    del (iList[i]);
  iCount = 0;
  return *this;
}                               // ZPointerlist::drop

ZExport (long) ZPointerlist::find (const void *aPointer) const
{
  ZFUNCTRACE_DEVELOP ("ZPointerlist::find(const void* aPointer) const");
  for (long i = 0; i < iCount; i++)
    if (equal (aPointer, iList[i]))
      return i;
  return -1;
}                               // ZPointerlist::find
