/////////////////////////////////////////////////////////////
//                                                         //
// Copyright (c) 2007-2017 by The University of Queensland //
// Centre for Geoscience Computing                         //
// http://earth.uq.edu.au/centre-geoscience-computing      //
//                                                         //
// Primary Business: Brisbane, Queensland, Australia       //
// Licensed under the Open Software License version 3.0    //
// http://www.apache.org/licenses/LICENSE-2.0              //
//                                                         //
/////////////////////////////////////////////////////////////

#include "Shape.h"
#include <stdlib.h>
#include <cmath>

using std::cos;
using std::sin;

Shape::Shape() {
  this->pitch=0;
  this->yaw=0;
  this->roll=0;
  this->randomOrientation = 0;
}

Shape::~Shape() {

}

/**
 * Tell the shape to be randomly orientated.  This will make every object
 * have a random orientation
 * \param i 1 for using random orientation, 0 to disable
 */
void Shape::makeOrientationRandom(int i) {
  this->randomOrientation = i;
}

/**
 * Returns 1 if the shape is to be randomly orientated
 * \returns 1 if shape is to be randomly orientated
 */
int Shape::useRandomOrientation() {
  return this->randomOrientation;
}


/**
 * Sets a random orientation.  Note that this will be run before every
 * insert if the appropriate function is called.
 */
void Shape::setRandomOrientation() {
  setRandomPitch();
  setRandomYaw();
  setRandomRoll();
}

/** 
 * Set a random pitch to the object
 */
void Shape::setRandomPitch() {
  this->pitch = (rand() % 180) - 90;
}

/** 
 * Set a random yaw to the object
 */
void Shape::setRandomYaw() {
  this->yaw = (rand() % 360) - 180;
}

/**
 * Set a random roll to the object
 */
void Shape::setRandomRoll() {
  this->roll = (rand() % 360) - 180;
}

/**
 * Rotate a point around the x, y and z axies.  Rotation values are given
 * using setRoll functions etc.
 * \param point the point to rotate
 * \returns the rotated point
 */
Vector3 Shape::rotatePoint(Vector3 point) {
  double roll = this->roll *M_PI/180;
  double yaw = this->yaw *M_PI/180;
  double pitch = this->pitch *M_PI/180;
  /*
  double x = (cos(yaw)*cos(roll)+sin(yaw)*sin(pitch)*sin(roll))* point.x()
           + (-sin(yaw)*cos(pitch)) * point.y() 
           + (sin(yaw)*sin(pitch)*cos(roll)-cos(yaw)*sin(roll))* point.z();
  double y = (sin(yaw)*cos(roll)-cos(yaw)*sin(pitch)*sin(roll))* point.x()
           + (cos(yaw)*cos(pitch)) * point.y()
           + (-cos(yaw)*sin(pitch)*cos(roll)-sin(yaw)*sin(roll))*point.z();
  double z = (cos(pitch)*sin(roll))*point.x()
           + (sin(pitch)*point.y())
           + (cos(pitch)*cos(roll))*point.y();
  Vector3 newpoint(x,y,z);
  */
  Vector3 newpoint = point.rotate(Vector3(roll,yaw,pitch),Vector3(0,0,0));
  return newpoint;
}

int Shape::bias() { return this->bias_factor; }

void Shape::setBias(int i) {
  this->bias_factor = i;
}

void Shape::setPitch(double pitch) { this->pitch = pitch; }
double Shape::getPitch() { return this->pitch; }
void Shape::setYaw(double yaw) { this->yaw = yaw; }
double Shape::getYaw() { return this->yaw; }
void Shape::setRoll(double roll) { this->roll = roll; }
double Shape::getRoll() { return this->roll; }


void Shape::setBondTag(int tag) { bondTag = tag; }
int Shape::getBondTag() { return bondTag; }
void Shape::setParticleTag(int tag) { particleTag = tag; }
int Shape::getParticleTag() { return particleTag; }


