// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2025 lacklustr@protonmail.com https://github.com/eadf

use crate::common::macros::integrity_assert;
use crate::corner_table::triangle_index::TriangleIndex;

#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq, Ord, Hash, PartialOrd)]
pub(crate) struct CornerIndex(pub(crate) u32);

impl CornerIndex {
    pub const INVALID: CornerIndex = CornerIndex(u32::MAX);

    #[allow(dead_code)]
    /// returns all the corners of the triangle self belongs to
    #[inline(always)]
    pub(crate) fn triangle_corners(self) -> [CornerIndex; 3] {
        self.triangle().corners()
    }

    #[inline(always)]
    pub fn is_valid(self) -> bool {
        self.0 != Self::INVALID.0
    }

    #[inline(always)]
    pub fn triangle(self) -> TriangleIndex {
        integrity_assert!(self.is_valid());
        TriangleIndex(self.0 / 3)
    }

    #[inline(always)]
    /// Get both next and previous corners in the same counter-clockwise triangle
    pub(super) fn next_prev(self) -> (Self, Self) {
        let base = (self.0 / 3) * 3;
        (Self(base + (self.0 + 1) % 3), Self(base + (self.0 + 2) % 3))
    }

    #[inline(always)]
    /// Get the previous corner in the same counter-clockwise triangle
    pub(super) fn prev(self) -> Self {
        Self((self.0 / 3) * 3 + (self.0 + 2) % 3)
    }

    #[inline(always)]
    /// Get the next corner in the same counter-clockwise triangle
    pub(super) fn next(self) -> Self {
        Self((self.0 / 3) * 3 + (self.0 + 1) % 3)
    }

    #[inline(always)]
    pub(crate) const fn usize(self) -> usize {
        self.0 as usize
    }
}
