/**********************************************************************
 *
 *    FILE:            HeightField.cpp
 *
 *    DESCRIPTION:    Read/Write osg::HeightField in binary format to disk.
 *
 *    CREATED BY:        Auto generated by iveGenerator
 *                    and later modified by Rune Schmidt Jensen.
 *
 *    HISTORY:        Created 27.3.2003
 *
 *    Copyright 2003 VR-C
 **********************************************************************/

#include "Exception.h"
#include "Shape.h"
#include "Object.h"

#include <osg/Endian>

using namespace ive;


////////////////////////////////////////////////////////////////////////////////
//
//  Sphere
//
void Sphere::write(DataOutputStream* out)
{
    // Write CullFace's identification.
    out->writeInt(IVESPHERE);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj)
    {
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("Sphere::write(): Could not cast this osg::Sphere to an osg::Object.");

    // Write Sphere's properties.
    out->writeVec3(getCenter());
    out->writeFloat(getRadius());
}

void Sphere::read(DataInputStream* in)
{
    // Peek on Sphere's identification.
    int id = in->peekInt();
    if(id == IVESPHERE)
    {
        // Read Sphere's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj)
        {
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("Sphere::read(): Could not cast this osg::Sphere to an osg::Object.");

        // Read Sphere's properties
        setCenter(in->readVec3());
        setRadius(in->readFloat());

    }
    else
    {
        throw Exception("Sphere::read(): Expected Sphere identification.");
    }
}


////////////////////////////////////////////////////////////////////////////////
//
//  Box
//
void Box::write(DataOutputStream* out)
{
    // Write CullFace's identification.
    out->writeInt(IVEBOX);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj)
    {
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("Box::write(): Could not cast this osg::Box to an osg::Object.");

    // Write Box's properties.
    out->writeVec3(getCenter());
    out->writeVec3(getHalfLengths());
    out->writeQuat(getRotation());
}

void Box::read(DataInputStream* in)
{
    // Peek on Box's identification.
    int id = in->peekInt();
    if(id == IVEBOX)
    {
        // Read Box's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj)
        {
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("Box::read(): Could not cast this osg::Box to an osg::Object.");

        // Read Box's properties
        setCenter(in->readVec3());
        setHalfLengths(in->readVec3());
        setRotation(in->readQuat());

    }
    else
    {
        throw Exception("Box::read(): Expected Box identification.");
    }
}


////////////////////////////////////////////////////////////////////////////////
//
//  Cone
//
void Cone::write(DataOutputStream* out)
{
    // Write CullFace's identification.
    out->writeInt(IVECONE);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj)
    {
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("Cone::write(): Could not cast this osg::Cone to an osg::Object.");

    // Write Cone's properties.
    out->writeVec3(getCenter());
    out->writeFloat(getRadius());
    out->writeFloat(getHeight());
    out->writeQuat(getRotation());
}

void Cone::read(DataInputStream* in)
{
    // Peek on Cone's identification.
    int id = in->peekInt();
    if(id == IVECONE)
    {
        // Read Cone's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj)
        {
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("Cone::read(): Could not cast this osg::Cone to an osg::Object.");

        // Read Cone's properties
        setCenter(in->readVec3());
        setRadius(in->readFloat());
        setHeight(in->readFloat());
        setRotation(in->readQuat());

    }
    else
    {
        throw Exception("Cone::read(): Expected Cone identification.");
    }
}


////////////////////////////////////////////////////////////////////////////////
//
//  Cylinder
//
void Cylinder::write(DataOutputStream* out)
{
    // Write CullFace's identification.
    out->writeInt(IVECYLINDER);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj)
    {
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("Cylinder::write(): Could not cast this osg::Cylinder to an osg::Object.");

    // Write Cylinder's properties.
    out->writeVec3(getCenter());
    out->writeFloat(getRadius());
    out->writeFloat(getHeight());
    out->writeQuat(getRotation());
}

void Cylinder::read(DataInputStream* in)
{
    // Peek on Cylinder's identification.
    int id = in->peekInt();
    if(id == IVECYLINDER)
    {
        // Read Cylinder's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj)
        {
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("Cylinder::read(): Could not cast this osg::Cylinder to an osg::Object.");

        // Read Cylinder's properties
        setCenter(in->readVec3());
        setRadius(in->readFloat());
        setHeight(in->readFloat());
        setRotation(in->readQuat());

    }
    else
    {
        throw Exception("Cylinder::read(): Expected Cylinder identification.");
    }
}


////////////////////////////////////////////////////////////////////////////////
//
//  Capsule
//
void Capsule::write(DataOutputStream* out)
{
    // Write CullFace's identification.
    out->writeInt(IVECAPSULE);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj)
    {
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("Capsule::write(): Could not cast this osg::Capsule to an osg::Object.");

    // Write Capsule's properties.
    out->writeVec3(getCenter());
    out->writeFloat(getRadius());
    out->writeFloat(getHeight());
    out->writeQuat(getRotation());
}

void Capsule::read(DataInputStream* in)
{
    // Peek on Capsule's identification.
    int id = in->peekInt();
    if(id == IVECAPSULE)
    {
        // Read Capsule's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj)
        {
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("Capsule::read(): Could not cast this osg::Capsule to an osg::Object.");

        // Read Capsule's properties
        setCenter(in->readVec3());
        setRadius(in->readFloat());
        setHeight(in->readFloat());
        setRotation(in->readQuat());

    }
    else
    {
        throw Exception("Capsule::read(): Expected Capsule identification.");
    }
}


////////////////////////////////////////////////////////////////////////////////
//
//  HeightField
//
void HeightField::write(DataOutputStream* out)
{
    // Write CullFace's identification.
    out->writeInt(IVEHEIGHTFIELD);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj)
    {
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("HeightField::write(): Could not cast this osg::HeightField to an osg::Object.");

    // Write HeightField's properties.
    out->writeUInt(getNumColumns());
    out->writeUInt(getNumRows());
    out->writeVec3(getOrigin());
    out->writeFloat(getXInterval());
    out->writeFloat(getYInterval());
    out->writeQuat(getRotation());
    out->writeFloat(getSkirtHeight());
    out->writeUInt(getBorderWidth());
    
    unsigned int size = getHeightList().size();
    out->writeUInt(size);
    for(unsigned int i = 0; i < size; i++)
    {
        out->writeFloat((getHeightList())[i]);
    }

    
    
    
}

void HeightField::read(DataInputStream* in)
{
    // Peek on HeightField's identification.
    int id = in->peekInt();
    if(id == IVEHEIGHTFIELD)
    {
        // Read HeightField's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj)
        {
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("HeightField::read(): Could not cast this osg::HeightField to an osg::Object.");

        // Read HeightField's properties
        //setColor(in->readVec4());
        unsigned int col = in->readUInt();
        unsigned int row = in->readUInt();        
        allocate(col,row);

        setOrigin(in->readVec3());
        setXInterval(in->readFloat());
        setYInterval(in->readFloat());
        setRotation(in->readQuat());
        
        setSkirtHeight(in->readFloat());
        setBorderWidth(in->readUInt());
    
        unsigned int size = in->readUInt();
        in->_istream->read((char*)&(getHeightList()[0]), FLOATSIZE*size);
        if (in->_istream->rdstate() & in->_istream->failbit)
            throw Exception("HeightField::read(): Failed to read height array.");
        if (in->_byteswap) {
           float *ptr = (float*)&(getHeightList()[0]) ;
           for (unsigned int i = 0 ; i < size ; i++ ) {
              osg::swapBytes((char *)&(ptr[i]),FLOATSIZE) ;
           }
        }

    }
    else
    {
        throw Exception("HeightField::read(): Expected HeightField identification.");
    }
}

