#ifndef COSY_MStarList
#define COSY_MStarList

#include <TClonesArray.h>

#include "MStar.h"

class MStarListIter;

class MStarList : public TObject
{
private:
    TClonesArray fStars;

public:
    MStarList() : fStars("MStar", 1000) {}

    void AddAt(Int_t idx, Double_t meanx, Double_t meany, Double_t mag)
    {
        new (fStars[idx]) MStar(meanx, meany, mag);
    }
    void Add(Double_t meanx, Double_t meany, Double_t mag=0)
    {
        AddAt(fStars.GetLast()+1, meanx, meany, mag);
    }
    MStar *operator[](Int_t i) { return (MStar*)fStars[i]; }

    void Reset()
    {
        fStars.Delete();
    }

    void Delete(Option_t *o="") { }
    void Delete(Int_t i)        { delete fStars.RemoveAt(i); }
    void Delete(MStar *obj)     { delete fStars.Remove(obj); }

    Int_t GetMax() const { return fStars.GetLast()+1; }
    Int_t GetRealEntries() const { return fStars.GetEntries(); }

    void RemoveTwins(Double_t radius);

    void Sort() { fStars.Sort(); }

    void Expand(int n) { fStars.Expand(n); }
};

class MStarListIter
{
private:
    MStarList *fList;

    Int_t      fNumPos;     // actual position in list

    Bool_t     fAll;        // iterate over all stars

    MStar      fReference;  // iterate only over stars not more than
    Float_t    fRadius;     // fRadius away from the reference

public:
    MStarListIter(MStarList *list) : fList(list), fNumPos(0),  fAll(kTRUE) {}
    MStarListIter(MStarList *list, const MStar &s, Float_t r) : fList(list), fNumPos(0), fAll(kFALSE), fReference(s), fRadius(r) {}

    MStar *Next()
    {
        const Double_t r2 = fRadius*fRadius;

        for (int i=fNumPos; i<fList->GetMax(); i++)
        {
            MStar *p = (*fList)[i];

            if (!p)
                continue;

            if (!fAll)
            {
                Double_t dx = p->GetX()-fReference.GetX();
                Double_t dy = p->GetY()-fReference.GetY();

                if (dx*dx + dy*dy > r2)
                    continue;
            }

            fNumPos = i+1;
            return p;
        }
        return NULL;
    }

    MStar *operator()() { return Next(); }

    void Reset() { fNumPos=0; }
};

#endif
