//#####################################################################
// Copyright 2004-2009, Eran Guendelman, Frank Losasso, Andrew Selle.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class QT_PARTICLES
//#####################################################################
#ifndef __QT_PARTICLES__
#define __QT_PARTICLES__

#include <Core/Arrays/ARRAY.h>
#include <Core/Matrices/FRAME.h>
#include <Core/Symbolics/PARTICLE_ATTRIBUTE_PROGRAM.h>
#include "QT_COMPONENT.h"
#include <memory>

namespace PhysBAM
{
template<class TV> class PARTICLES;
template<class OBJ> class QT_OBJECT;
struct PARTICLES_OPTIONS;

template<class TV>
class QT_PARTICLES:public QT_COMPONENT
{
public:
    typedef typename TV::SCALAR T;
    typedef PARTICLES<TV> TYPE;

    typedef PARTICLES_OPTIONS OPT;
private:
    OPT opt,raw_opt[4];
    std::shared_ptr<QT_OBJECT<TYPE>> obj;

    int selected_particle=-1;
    static const QT_COMPONENT_OPTION options[];
    static const int num_options;
    typedef QT_PARTICLES SELF;
    PARTICLE_ATTRIBUTE_PROGRAM<TV>* pa=nullptr;
public:

    QT_PARTICLES(QT_WORLD& world,const std::string& name,const std::string& file);
    QT_PARTICLES(QT_WORLD& world,const std::string& name,const std::shared_ptr<QT_OBJECT<TYPE>>& obj);

    virtual ~QT_PARTICLES();

    void Render(QT_RENDER_UTILS& ru) override;
    void Read() override;
    void Invalidate(bool invalidate_common) override;
    RANGE<FV> Bounding_Box() override;
    void Set_Selection(ARRAY_VIEW<int> selection) override;
    void Clear_Selection() override;
    FV Selection_Point() override;
    void Make_Dialog(QT_WINDOW& window) override;
    void Read_Option(std::istream& in,int level) override;
    void Set_Draw(bool draw) override;
    bool Draw() const override;
    void Save_Settings(std::ostream& out) override;
    void Clear_Settings() override;

    std::pair<FRAME<FV>,bool> Get_Frame(const std::string& attr,int p);
    void Print_Particle(std::ostream& o,int p);
    void Set_Range_From_Data();
    void Apply_Program();
};
}

#endif
