#include "Zeichnung3D.h"

using namespace Framework;

// Inhalt der Zeichnung3D Klasse

// Konstruktor
Zeichnung3D::Zeichnung3D()
    : ReferenceCounter()
{
    welt = welt.identity();
    pos = Vec3<float>(0, 0, 0);
    angle = Vec3<float>(0, 0, 0);
    rend = 0;
    alpha = 0;
    radius = 0;
    size = 1.f;
}

Zeichnung3D::~Zeichnung3D() {}

// Setzt die Position der Zeichnung in der Welt
//  p: Die Position
void Zeichnung3D::setPosition(const Vec3<float>& p)
{
    pos = p;
    rend = 1;
}

// Setzt die Position der Zeichnung in der Welt
//  x: Die x Position
//  y: Die y Position
//  z: Die z Position
void Zeichnung3D::setPosition(float x, float y, float z)
{
    pos.x = x;
    pos.y = y;
    pos.z = z;
    rend = 1;
}

// Setzt die Position der Zeichnung in der Welt
//  x: Die x Position
void Zeichnung3D::setX(float x)
{
    pos.x = x;
    rend = 1;
}

// Setzt die Position der Zeichnung in der Welt
//  y: Die y Position
void Zeichnung3D::setY(float y)
{
    pos.y = y;
    rend = 1;
}

// Setzt die Position der Zeichnung in der Welt
//  z: Die z Position
void Zeichnung3D::setZ(float z)
{
    pos.z = z;
    rend = 1;
}

// Setzt die Drehung der Zeichnung in der Welt
//  d: Die drehung um die x, y und z achse
void Zeichnung3D::setDrehung(const Vec3<float>& d)
{
    angle = d;
    rend = 1;
}

// Setzt die Drehung der Zeichnung in der Welt
//  xWinkel: Die drehung um die x achse
//  yWinkel: Die drehung um die y achse
//  zWinkel: Die drehung um die z achse
void Zeichnung3D::setDrehung(float xWinkel, float yWinkel, float zWinkel)
{
    angle.x = xWinkel;
    angle.y = yWinkel;
    angle.z = zWinkel;
    rend = 1;
}

// Setzt die Drehung der Zeichnung in der Welt
//  winkel: Die drehung um die x achse
void Zeichnung3D::setDrehungX(float winkel)
{
    angle.x = winkel;
    rend = 1;
}

// Setzt die Drehung der Zeichnung in der Welt
//  winkel: Die drehung um die y achse
void Zeichnung3D::setDrehungY(float winkel)
{
    angle.y = winkel;
    rend = 1;
}

// Setzt die Drehung der Zeichnung in der Welt
//  winkel: Die drehung um die z achse
void Zeichnung3D::setDrehungZ(float winkel)
{
    angle.z = winkel;
    rend = 1;
}

// Legt fest, ob das Objekt teilweise oder ganz transparente stellen enth�lt
//  a: true, wenn teilweise oder ganz transparente stellen vorhanden sind
void Zeichnung3D::setAlpha(bool a)
{
    alpha = a;
    rend = 1;
}

//! Setzt die skallierung
void Zeichnung3D::setSize(float size)
{
    this->size = size;
    rend = 1;
}

// Errechnet die Matrizen aller Knochen des Skeletts der Zeichnung
//  viewProj: Die miteinander multiplizierten Kameramatrizen
//  matBuffer: Ein Array mit Matrizen, der gef�llt werden soll
//  return: Die Anzahl der Matrizen, die die Zeichnung ben�tigt
int Zeichnung3D::errechneMatrizen(
    const Mat4<float>& viewProj, Mat4<float>* matBuffer)
{
    matBuffer[0] = viewProj * welt;
    return 1;
}

// Verarbeitet ein Mausereignis
//  me: Das Mausereignis, das verarbeitet werden soll
void Zeichnung3D::doMausEreignis(MausEreignis3D& me) {}

// Verarbeitet ein Tastaturereignis
//  te: das Tastaturereignis, das verarbeitet werden soll
void Zeichnung3D::doTastaturEreignis(TastaturEreignis& te) {}

// Verarbeitet die vergangene Zeit
//  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion
//  vergangen ist return: true, wenn sich das Objekt ver�ndert hat, false
//  sonnst.
bool Zeichnung3D::tick(double tickval)
{
    if (rend)
    {
        welt = welt.translation(pos) * welt.rotationZ(angle.z)
             * welt.rotationX(angle.x) * welt.rotationY(angle.y)
             * welt.scaling(size);
        rend = 0;
        return 1;
    }
    return 0;
}

// Gibt zur�ck, ob das Objekt teilweise oder ganz transparente stellen enth�lt
bool Zeichnung3D::hatAlpha() const
{
    return alpha;
}

// Gibt den radius einer Kugel zur�ck, die das gesammte Model umschlie�t
float Zeichnung3D::getRadius() const
{
    return radius;
}

// Gibt einen Punkt zur�ck, der die Position der Zeichnung in der Welt darstellt
const Vec3<float>& Zeichnung3D::getPos() const
{
    return pos;
}

// Gibt die X Position der Zeichnung in der Welt zur�ck
float Zeichnung3D::getX() const
{
    return pos.x;
}

// Gibt die Y Position der Zeichnung in der Welt zur�ck
float Zeichnung3D::getY() const
{
    return pos.y;
}

// Gibt die Z Position der Zeichnung in der Welt zur�ck
float Zeichnung3D::getZ() const
{
    return pos.z;
}

// Gibt einen Vektor zur�ck, der die drehung der Zeichnung in der Welt
// darstellt. x ist die Drehung um die X Achse im Bogenma� usw
const Vec3<float>& Zeichnung3D::getDrehung() const
{
    return angle;
}

// Gibt die Drehung um die X Achse im Bogenma� zur�ck
float Zeichnung3D::getXDrehung() const
{
    return angle.x;
}

// Gibt die Drehung um die Y Achse im Bogenma� zur�ck
float Zeichnung3D::getYDrehung() const
{
    return angle.y;
}

// Gibt die Drehung um die Z Achse im Bogenma� zur�ck
float Zeichnung3D::getZDrehung() const
{
    return angle.z;
}

// Gibt die Matrix zur�ck, die die Zeichnung in den Welt Raum �bersetzt
const Mat4<float>& Zeichnung3D::getMatrix() const
{
    return welt;
}

//! Berechnet w�r einen Punkt in lokalen Zeichnungs Koordinaten den Punkt in
//! Weltkoordinaten durch anwendung von Drehung, Skallierung und Verschiebung
Vec3<float> Zeichnung3D::applyWorldTransformation(
    const Vec3<float>& modelPos) const
{
    return welt * modelPos;
}