///|/ Copyright (c) Prusa Research 2020 - 2023 Tomáš Mészáros @tamasmeszaros, Lukáš Matěna @lukasmatena
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#ifndef SLA_SUPPORTPOINT_HPP
#define SLA_SUPPORTPOINT_HPP

#include <libslic3r/Point.hpp>

namespace Slic3r::sla {

// An enum to keep track of where the current points on the ModelObject came from.
enum class PointsStatus {
    NoPoints,           // No points were generated so far.
    Generating,     // The autogeneration algorithm triggered, but not yet finished.
    AutoGenerated,  // Points were autogenerated (i.e. copied from the backend).
    UserModified    // User has done some edits.
};

// Reason of automatic support placement usage
enum class SupportPointType {
    manual_add,
    island, // no move, island should be grouped
    slope,
    //thin,
    //stability,
    //edge
};

/// <summary>
/// Stereolithography(SLA) support point
/// </summary>
struct SupportPoint
{
    // Position on model surface
    Vec3f pos = Vec3f::Zero(); // [in mm]

    // radius of the touching interface
    // Also define force it must keep
    float head_front_radius = 0.f; // [in mm]

    // type
    SupportPointType type{SupportPointType::manual_add};
    
    bool is_island() const { return type == SupportPointType::island; }
    template<class Archive> void serialize(Archive &ar){
        ar(pos, head_front_radius, type);
    }

    // unsaved changes + cache invalidation
    bool operator==(const SupportPoint &sp) const {
        float rdiff = std::abs(head_front_radius - sp.head_front_radius);
        return (pos == sp.pos) && rdiff < float(EPSILON) && type == sp.type;
    }

    bool operator!=(const SupportPoint &sp) const { return !(sp == (*this)); }

};
using SupportPoints = std::vector<SupportPoint>;

} // namespace Slic3r::sla

#endif // SUPPORTPOINT_HPP
