/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkTDStack_DEFINED
#define SkTDStack_DEFINED

#include "SkTypes.h"

template <typename T> class SkTDStack : SkNoncopyable {
public:
    SkTDStack() : fCount(0), fTotalCount(0)
    {
        fInitialRec.fNext = NULL;
        fRec = &fInitialRec;

    //  fCount = kSlotCount;
    }
    ~SkTDStack()
    {
        Rec* rec = fRec;
        while (rec != &fInitialRec)
        {
            Rec* next = rec->fNext;
            sk_free(rec);
            rec = next;
        }
    }

    int count() const { return fTotalCount; }

    T* push()
    {
        SkASSERT(fCount <= kSlotCount);
        if (fCount == kSlotCount)
        {
            Rec* rec = (Rec*)sk_malloc_throw(sizeof(Rec));
            rec->fNext = fRec;
            fRec = rec;
            fCount = 0;
        }
        ++fTotalCount;
        return &fRec->fSlots[fCount++];
    }
    void push(const T& elem) { *this->push() = elem; }
    const T& index(int idx) const
    {
        SkASSERT(fRec && fCount > idx);
        return fRec->fSlots[fCount - idx - 1];
    }   
    T& index(int idx)
    {
        SkASSERT(fRec && fCount > idx);
        return fRec->fSlots[fCount - idx - 1];
    }   
    const T& top() const
    {
        SkASSERT(fRec && fCount > 0);
        return fRec->fSlots[fCount - 1];
    }
    T& top()
    {
        SkASSERT(fRec && fCount > 0);
        return fRec->fSlots[fCount - 1];
    }
    void pop(T* elem)
    {
        if (elem)
            *elem = fRec->fSlots[fCount - 1];
        this->pop();
    }
    void pop()
    {
        SkASSERT(fCount > 0 && fRec);
        --fTotalCount;
        if (--fCount == 0)
        {
            if (fRec != &fInitialRec)
            {
                Rec* rec = fRec->fNext;
                sk_free(fRec);
                fCount = kSlotCount;
                fRec = rec;
            }
            else
                SkASSERT(fTotalCount == 0);
        }
    }

private:
    enum {
        kSlotCount  = 8
    };

    struct Rec;
    friend struct Rec;

    struct Rec {
        Rec* fNext;
        T    fSlots[kSlotCount];
    };
    Rec     fInitialRec;
    Rec*    fRec;
    int     fCount, fTotalCount;
};

#endif

