//#####################################################################
// Copyright 2002-2006, Robert Bridson, Ronald Fedkiw, Geoffrey Irving, Sergey Koltakov, Neil Molino, Eftychios Sifakis, Jerry Talton.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class SEGMENT_MESH
//#####################################################################
#ifndef __SEGMENT_MESH__
#define __SEGMENT_MESH__

#include <Core/Meshes/SIMPLEX_MESH_BASE.h>
#include <Core/Vectors/VECTOR.h>
namespace PhysBAM{

template<>
class SIMPLEX_MESH<1>:public SIMPLEX_MESH_BASE<1>
{
public:
    typedef VECTOR<int,2> ELEMENT_TYPE;
    typedef SIMPLEX_MESH_BASE<1> BASE;
    using BASE::number_nodes;using BASE::elements;using BASE::neighbor_nodes;using BASE::incident_elements;
    using BASE::Simplex;using BASE::Node_In_Simplex;using BASE::Replace_Node_In_Simplex;using BASE::Add_Connectivity;

    ARRAY<ARRAY<int> >* connected_segments;  // a list of connected segment components, in no particular order
    ARRAY<ARRAY<int> >* ordered_loop_nodes;  // an ordered list of adjacent nodes for each connected component that is a simple loop (useful for boundaries)
    
    POINT_SIMPLEX_MESH* boundary_mesh;

    SIMPLEX_MESH();
    SIMPLEX_MESH(const int number_nodes_input,const ARRAY<VECTOR<int,2> >& segment_list);
    SIMPLEX_MESH(const SIMPLEX_MESH& segment_mesh);
    ~SIMPLEX_MESH();
    
    int Get_Opposite_Endpoint(const int segment,const int node)
    {assert(Node_In_Segment(node,segment));if(elements(segment)(0) == node) return elements(segment)(1);else return elements(segment)(0);}

    int Segment(const int node1,const int node2) const
    {return Simplex(VECTOR<int,2>(node1,node2));}

    bool Node_In_Segment(const int node,const int segment) const
    {return Node_In_Simplex(node,segment);}

    bool Segments_Adjacent(const int segment1,const int segment2) const
    {int i,j;elements(segment1).Get(i,j);return Node_In_Segment(i,segment2) || Node_In_Segment(j,segment2);}

    void Replace_Node_In_Segment(const int segment,const int old_node,const int new_node)
    {Replace_Node_In_Simplex(segment,old_node,new_node);}

    SIMPLEX_MESH& Get_Segment_Mesh()
    {return *this;}

//#####################################################################
    void Delete_Auxiliary_Structures() override;
    void Refresh_Auxiliary_Structures() override;
    void Initialize_Ordered_Components();
    void Initialize_Straight_Mesh(const int number_of_points,bool loop=false,int start_offset=0);
    void Initialize_Boundary_Mesh();
    bool Assert_Consistent() const override;
//#####################################################################
};
}
#endif
