#pragma once
#ifndef TRIANGLE_H
#define TRIANGLE_H

#include <QDebug>
#include <QVector>
#include "vertex.h"

class Triangle {
    public:
        struct Edge {
            enum Name {
                uv,
                vw,
                wu
            };

            Name name;
            unsigned int a;
            unsigned int b;
            unsigned int c;
        };

        struct Neighbor {
            Triangle *triangle;
            Edge edge;
        };

        struct Neighbors {
            Neighbor uv;
            Neighbor vw;
            Neighbor wu;

            Triangle::Neighbor get_neighbor(Triangle::Edge::Name name) const;
        };

        Triangle();
        Triangle(const Triangle &other);
        Triangle(const QVector<Vertex> *vertex_buffer, unsigned int u, unsigned int v, unsigned int w);

        Vertex u() const;
        Vertex v() const;
        Vertex w() const;

        unsigned int u_idx() const;
        unsigned int v_idx() const;
        unsigned int w_idx() const;

        bool get_shared_edge(Triangle other, Edge &edge_a, Edge &edge_b) const;

        bool hasSharedEdge(Triangle other);

        Triangle &operator=(const Triangle &other);

        // == and < both ignore the vertex buffer, they only compare indices.
        // They are implemented so that Triangle can be used as the key of a QMap.
        bool operator==(const Triangle &other) const;
        bool operator!=(const Triangle &other) const;
        bool operator<(const Triangle &other) const;

        bool next_ctrclockwise(Edge first, Edge next) const;
        bool next_clockwise(Edge first, Edge next) const;

    private:
        const QVector<Vertex> *vertex_buffer_;
        unsigned int u_;
        unsigned int v_;
        unsigned int w_;

        void rotate_indices();
        bool get_shared_edge_(const Triangle &other, Edge &edge_a, Edge &edge_b) const;
};

Triangle::Edge::Name rotate_edge_name(Triangle::Edge::Name edge);
void ibToTriangles(QVector<Vertex> *vb, QVector<unsigned int> &ib, QVector<Triangle> &triangles);
void trianglesToIB(const QVector<Triangle> &triangles, QVector<unsigned int> &ib);

QDebug operator<<(QDebug d, const Triangle &triangle);

#endif
