/* This file is part of the source code for the following publication:
 * Assembling Self-Supporting Structures, Deuss et al., SIGGRAPH Asia 2014
 *
 * Copyright (C) 2014 Mario Deuss <mario.deuss@epfl.ch>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "AABB.h"
#include <cmath>

namespace SelfAssembly {


  AABB::AABB() {
    setEmpty();
  }

  AABB::~AABB() {
  }


  ////convenience routines
  const AABB::Point AABB::getCenter() const {
    return (max_ + min_)/static_cast<Scalar>(2);
  }

  AABB::Scalar AABB::getRadius() const {
    if(isEmpty()) {
      return -1;
    }
    else {
      return (max_ - min_).norm()/static_cast<Scalar>(2);
    }
  }

  ////getter Setter of empty flag
  // the bounding box is assumed to be empty, as soon as the min/max values go into an invalid state
  bool AABB::isEmpty() const {
    return (max_[0]<min_[0] || max_[1]<min_[1] || max_[2]<min_[2]);
  }

  void AABB::setEmpty() {
    min_ = Point(0,0,0);
    max_ = Point(-1,-1,-1);
  }

  ////growing functions
  void AABB::extend(const AABB& _aabb){
    if(isEmpty()) {
      set(_aabb.getMin(),_aabb.getMax());
    }
    else {
      const Point& min = _aabb.getMin();
      const Point& max = _aabb.getMax();
      for(int i=0; i<3; ++i) {
        if(min[i] < min_[i]) {
          min_[i] = min[i];
        }
        if(max[i] > max_[i]) {
          max_[i] = max[i];
        }
      }
    }
  }


  void AABB::extend(const Point& _point){
    if(isEmpty()) {
      set(_point,_point);
    }
    else {
      for(int i=0; i<3; ++i) {
        if(_point[i] < min_[i]) {
          min_[i] = _point[i];
        }
        else if(_point[i] > max_[i]) {
          max_[i] = _point[i];
        }
      }
    }
  }



}//namespaces
