/***************************************************************************
                           kdetvimage.cpp
                           --------------
    begin                : Sat Jun 12 2004
    copyright            : (C) 2004 by Dirk Ziegelmeier
    email                : dziegel@gmx.de
 ***************************************************************************/

/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <kdebug.h>
#include "kdetvimagepool.h"

KdetvImagePool::KdetvImagePool(unsigned int count, unsigned int size)
    : _first(NULL),
      _fillLevel(0),
      _minFillLevel(0),
      _images(NULL)
{
    if( count != 0 ) {
        setSize(count, size);
    }
}

KdetvImagePool::~KdetvImagePool()
{
    delete[] _images;
}

void* KdetvImagePool::getImageStorage()
{
    KdetvPooledImage* i = _first;
    _first = i->_next;
    _fillLevel--;
    if(_fillLevel < _minFillLevel) {
        _minFillLevel = _fillLevel;
    }
    Q_ASSERT(_fillLevel >= 0);
    Q_ASSERT(i != NULL);

    return i;
}

KdetvSharedImage* KdetvImagePool::getImage()
{
    KdetvPooledImage* i = new(this)KdetvPooledImage(this);
    if(_bufSize != 0) {
        i->setBuffer((unsigned char*)(i + sizeof(KdetvPooledImage)), _bufSize, false);
    }
    //    kdDebug() << "getImage: " << i << " Level: " << _fillLevel << " min: " << _minFillLevel << endl;
    return i;
}

void KdetvImagePool::putImage(KdetvPooledImage* img)
{
    img->_next = _first;
    _first = img;
    _fillLevel++;
    //    kdDebug() << "putImage: " << img << " Level: " << _fillLevel << endl;
}

void KdetvImagePool::setSize(unsigned int count, unsigned int bufsize)
{
    Q_ASSERT(_images == NULL);
    Q_ASSERT(count > 0);

    _images = new unsigned char[count * (sizeof(KdetvPooledImage) + bufsize)];
    _bufSize = bufsize;
    _first = reinterpret_cast<KdetvPooledImage*>(_images);
    _fillLevel = count;
    _minFillLevel = count;

    unsigned char* curImage = _images;
    KdetvPooledImage* img;
    for(unsigned int i=0; i<(count-1); i++) {
        img        = reinterpret_cast<KdetvPooledImage*>(curImage);
        img->_next = reinterpret_cast<KdetvPooledImage*>(curImage + sizeof(KdetvPooledImage) + bufsize);
        curImage += sizeof(KdetvPooledImage) + bufsize;
    }

    img = reinterpret_cast<KdetvPooledImage*>(curImage);
    img->_next = NULL;
}
