//#####################################################################
// Copyright 2003-2009, Eran Guendelman, 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_GRID
//##################################################################### 
#ifndef __QT_GRID__
#define __QT_GRID__

#include <Core/Data_Structures/HASHTABLE.h>
#include <Core/Grids/GRID.h>
#include "QT_COMPONENT.h"
#include "QT_OBJECT.h"
#include <list>
#include <memory>

namespace PhysBAM
{
template<int d> class QT_GRID_COMPONENT;
struct GRID_OPTIONS;

template<int d>
class QT_GRID:public QT_COMPONENT
{
public:
    typedef float T;typedef VECTOR<int,d> IV;
    typedef VECTOR<T,d> TV;
    typedef GRID<TV> TYPE;
    typedef std::list<QT_GRID_COMPONENT<TV::m>*> T_LIST;
    typedef typename T_LIST::iterator T_ITER;
    typedef GRID_OPTIONS OPT;

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

    T_LIST grid_objects;
    bool has_selected_cell=false;
    bool has_selected_node=false;
    IV selected_cell{IV()-1};
    IV selected_node{IV()-1};

    static const QT_COMPONENT_OPTION options[];
    static const int num_options;
    typedef QT_GRID SELF;
public:

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

    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;
    void Add_Object(QT_GRID_COMPONENT<TV::m>& obj);
    void Remove_Object(QT_GRID_COMPONENT<TV::m>& obj);
    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;
    const auto& Get_Object() const {return obj;}

    const GRID<TV>& Grid() const {return obj->Obj();}
};

}

#endif
