#include "core/math/Box.hpp"

Core::Box::Box(const Vector3& min_, const Vector3& max_)
    : min(min_), max(max_) {
}

Core::Box::Box(const Vector3& size) : min(), max() {
    for(size_t i = 0; i < 3; i++) {
        if(size[i] < 0.0f) {
            min[i] = size[i];
        } else {
            max[i] = size[i];
        }
    }
}

Core::Box Core::Box::offset(const Vector3& offset) const {
    return Box(min + offset, max + offset);
}

bool Core::Box::collidesWith(const Box& other) const {
    return max[0] > other.min[0] && min[0] < other.max[0] &&
           max[1] > other.min[1] && min[1] < other.max[1] &&
           max[2] > other.min[2] && min[2] < other.max[2];
}

Core::Box Core::Box::expand(const Vector3& offset) const {
    Vector3 add(offset[0] > 0.0f ? offset[0] : 0.0f,
                offset[1] > 0.0f ? offset[1] : 0.0f,
                offset[2] > 0.0f ? offset[2] : 0.0f);
    Vector3 sub(offset[0] < 0.0f ? offset[0] : 0.0f,
                offset[1] < 0.0f ? offset[1] : 0.0f,
                offset[2] < 0.0f ? offset[2] : 0.0f);
    return Box(min + sub, max + add);
}

Core::Box Core::Box::grow(const Vector3& growth) const {
    Vector3 half = growth * 0.5f;
    Vector3 nMin = min - half;
    Vector3 nMax = max + half;
    for(size_t i = 0; i < 3; i++) {
        if(nMin[i] > nMax[i]) {
            nMin[i] = (min[i] + max[i]) * 0.5f;
            nMax[i] = nMin[i];
        }
    }
    return Box(nMin, nMax);
}

const Core::Vector3& Core::Box::getMin() const {
    return min;
}

const Core::Vector3& Core::Box::getMax() const {
    return max;
}