#include <stdio.h>
#include "dms/QuadricObject.h"

namespace dms
{

QuadricObject::QuadricObject(void)
    {
    quadric_ = gluNewQuadric();
    radius_ = 1.0;
    topRadius_ = 1.0;
    innerRadius_ = 0.0;
    height_ = 1.0;
    startAngle_ = 0.0;
    sweep_ = 180.0;
    slices_ = stacks_ = 8;
    rings_ = 1;
    axis_ = DMS_Z;
    makeSphere();
    setUseNormals(GL_TRUE);
    setUseTexture(GL_FALSE);
    setDrawStyle(GLU_FILL);
    }


QuadricObject::~QuadricObject(void)
    {
    gluDeleteQuadric(quadric_);
    }


void QuadricObject::setUseNormals(GLboolean state)
    {
    useNormals_ = state;
    }


void QuadricObject::setUseTexture(GLboolean state)
    {
    useTexture_ = state;
    }


void QuadricObject::setDrawStyle(GLenum style)
    {
    drawStyle_ = style;
    }


void QuadricObject::makeSphere(GLdouble radius,GLint slices,GLint stacks)
    {
    quadricType_ = DMS_GLU_SPHERE;
    radius_ = radius;
    slices_ = slices;
    stacks_ = stacks;
    }


void QuadricObject::makeCylinder(GLdouble baseRadius, GLdouble topRadius,
                          GLdouble height, GLint slices, GLint stacks, int axis)
    {
    quadricType_ = DMS_GLU_CYLINDER;
    radius_ = baseRadius;
    topRadius_ = topRadius;
    height_ = height;
    slices_ = slices;
    stacks_ = stacks;
    axis_ = axis;
    }


void QuadricObject::makeCone(GLdouble baseRadius, GLdouble height,
                          GLint slices, GLint stacks,int axis)
    {
    makeCylinder(baseRadius, 0.0, height, slices, stacks, axis);
    }


void QuadricObject::makeDisk(GLdouble innerRadius, GLdouble outerRadius,
                          GLint slices, GLint rings,int axis)
    {
    quadricType_ = DMS_GLU_DISK;
    radius_ = outerRadius;
    innerRadius_ = innerRadius;
    slices_ = slices;
    rings_ = rings;
    axis_ = axis;
    }


void QuadricObject::makePartialDisk(GLdouble innerRadius, GLdouble outerRadius,
                          GLint slices, GLint rings,
                          GLdouble startAngle, GLdouble sweep,int axis)
    {
    quadricType_ = DMS_GLU_PARTIAL_DISK;
    radius_ = outerRadius;
    innerRadius_ = innerRadius;
    slices_ = slices;
    rings_ = rings;
    startAngle_ = startAngle;
    sweep_ = sweep;
    axis_ = axis;
    }


void QuadricObject::draw(void)
    {
    Object::draw();

    gluQuadricTexture(quadric_, useTexture_);
    gluQuadricNormals(quadric_, useNormals_);
    gluQuadricDrawStyle(quadric_, drawStyle_);
    
    if (quadricType_ == DMS_GLU_SPHERE)
        gluSphere(quadric_, radius_, slices_, stacks_);
    else
        {
        if (axis_ != DMS_Z)
            {
            glPushMatrix();
            if (axis_ == DMS_X)
                glRotatef(90.0, 0.0, 1.0, 0.0);
            else
                glRotatef(-90.0, 1.0, 0.0, 0.0);
            }
        if (quadricType_ == DMS_GLU_CYLINDER)
            gluCylinder(quadric_, radius_, topRadius_, height_, slices_, stacks_);
        else if (quadricType_ == DMS_GLU_DISK)
            gluDisk(quadric_, innerRadius_, radius_, slices_, rings_);
        else if (quadricType_ == DMS_GLU_PARTIAL_DISK)
            gluPartialDisk(quadric_, innerRadius_, radius_, slices_, rings_,
                           startAngle_, sweep_);
        if (axis_ != DMS_Z)
            glPopMatrix();
        }
    }

}
