// File SimTriangle.h by az

#ifndef SIMTRIANGLE_H
#define SIMTRIANGLE_H

#include "globals.h"
#include "SimNode.h"

#include <Inventor/nodes/SoSeparator.h>

#include <set>
#include <map>

class SoCoordinate3;
struct TriangleSettings;

/**
 * @brief Class that is used to display a triangle in the viewer widget.
 *
 * The triangle defines its own state and coloring according to its vertex nodes.
 * It does not hold simulation critical logic or information itself.
 */
class SimTriangle : public SoSeparator
{
private:
    /** We don't want anybody to use this constructor */
    SimTriangle();

    int m_triangleId;
    SoMaterial* m_material;
    SoCoordinate3* m_triangleCoordinates;

    std::set<SimNode*> m_vertexNodes;

public:
    SimTriangle(int id, SimNode* vertexA, SimNode* vertexB, SimNode* vertexC);
    SimTriangle(TriangleSettings &settings);
    int id();
    void addVertexNode(SimNode* vertexNode);
    void removeVertexNode(SimNode* vertexNode);
    void rescale(double factor);
    void setTransparency(float transparency);
    void updateColor();
    void resetColor();
    void getTriangleSettings(TriangleSettings& settings);
    std::set<SimNode*>* getVertexNodes();
};

/**
 * @brief Functor class for stl algorithms to define the transparency of a triangle.
 */
class SetTriangleTransparency
{
    float transparency;
public:
    explicit SetTriangleTransparency(float t) : transparency(t) {}
    void operator() (std::pair<int,SimTriangle*> triangle_pair) {
        triangle_pair.second->setTransparency(transparency);
    }
};

/**
 * @brief Functor class for stl algorithms to define the color of a triangle.
 */
class UpdateTriangleColor
{
public:
    explicit UpdateTriangleColor() {}
    void operator() (std::pair<int,SimTriangle*> triangle_pair) {
        triangle_pair.second->updateColor();
    }
};

/**
 * @brief Functor class for stl algorithms to reset the color of a triangle.
 */
class ResetTriangleColor
{
public:
    explicit ResetTriangleColor() {}
    void operator() (std::pair<int,SimTriangle*> triangle_pair) {
        triangle_pair.second->resetColor();
    }
};

/**
 * @brief Functor class for stl algorithms to rescale a triangle.
 */
class RescaleTriangle
{
    double factor;
public:
    explicit RescaleTriangle(double f) : factor(f) {}
    void operator() (std::pair<int,SimTriangle*> triangle_pair) {
        triangle_pair.second->rescale(factor);
    }
};

#endif //SIMTRIANGLE_H
