#include "md2_file.h"
#include "md2_model.h"

#include <string>

#ifdef WIN32
#include <windows.h>
#endif

#include <GL/gl.h>

/*
ostream & md2_file::operator<<( ostream & os, const model_t & md ) {
        os << " :: magic:            " << md.magic << endl
           << " :: version:          " << md.version << endl
           << " :: skinWidth:        " << md.skinWidth << endl
           << " :: skinHeight:       " << md.skinHeight << endl
           << " :: frameSize:        " << md.frameSize << endl
           << " :: numSkins:         " << md.numSkins << endl
           << " :: numVertices:      " << md.numVertices << endl
           << " :: numTexCoords:     " << md.numTexCoords << endl
           << " :: numTriangles:     " << md.numTriangles << endl
           << " :: numGLCommands:    " << md.numGLCommands << endl
           << " :: numFrames:        " << md.numFrames << endl
           << " :: offsetSkins:      " << md.offsetSkins << endl
           << " :: offsetTexCoords:  " << md.offsetTexCoords << endl
           << " :: offsetTriangles:  " << md.offsetTriangles << endl
           << " :: offsetFrames:     " << md.offsetFrames << endl
           << " :: offsetGLCommands: " << md.offsetGLCommands << endl
           << " :: offsetEnd:        " << md.offsetEnd << endl;
        
        return os;
}
*/

void md2_file::loadFrames( istream & is, model_t & md, md2_frame_t * frames ) {
        is.seekg( md.offsetFrames );

        triangleVertex_t * tmp_verts = new triangleVertex_t[ md.numVertices ];
        
        for ( int i = 0; i < md.numFrames; ++i ) {
                frame_t frame;
                is.read( &frame, sizeof( frame_t ) );
                //                cout << " frame name=" << frame.name << endl;
                //                cout << " frame trans=" << frame.translate[0] << ", " << frame.translate[1] << ", " << frame.translate[2] << endl;

                strncpy( frames[i].name, frame.name, 16 );
                is.read( tmp_verts, sizeof( triangleVertex_t ) * md.numVertices );
                frames[i].trans[0] = frame.translate[0];
                frames[i].trans[1] = frame.translate[1];
                frames[i].trans[2] = frame.translate[2];
                
                float * ptr = frames[i].verts;
                
                for ( int j = 0; j < md.numVertices; ++j ) {
                        *(ptr++) = tmp_verts[j].vertex[0] * frame.scale[0] + frame.translate[0];
                        *(ptr++) = tmp_verts[j].vertex[1] * frame.scale[1] + frame.translate[1];
                        *(ptr++) = tmp_verts[j].vertex[2] * frame.scale[2] + frame.translate[2];
                }
        }

        delete[] tmp_verts;
}

int md2_file::loadGLCmds( istream & is, model_t & md, md2_gl_cmd_t ** gl_cmds ) {
        
        int * words = new int[ md.numGLCommands ];
        
        is.seekg( md.offsetGLCommands );
        is.read( words, md.numGLCommands * 4 );
        
        int num_cmds = 0;

        for ( int i = 0; i < md.numGLCommands; ++i ) {
                if ( words[i] == 0 )
                        break;
                
                ++num_cmds;
                //                cout << " has num verts " << words[i] << endl;
                
                i += abs( words[ i ] ) * 3;
        }

        *gl_cmds = new md2_gl_cmd_t[ num_cmds ];
        
        //        cout << " num_cmds: " << num_cmds << endl;

        int * ptr = words;
        
        for ( int i = 0; i < num_cmds; ++i ) {
                
                //                cout << " fixup command " << i << " type " << *ptr << endl;
                
                if ( *ptr > 0 ) {
                        (*gl_cmds)[i].gl_type = GL_TRIANGLE_STRIP;
                        (*gl_cmds)[i].num_verts = *ptr;
                }
                else {
                        (*gl_cmds)[i].gl_type = GL_TRIANGLE_FAN;
                        (*gl_cmds)[i].num_verts = -(*ptr);
                }
                

                (*gl_cmds)[i].texcoords = new float[ 2 * (*gl_cmds)[i].num_verts ];
                (*gl_cmds)[i].verts_i = new int[ (*gl_cmds)[i].num_verts ];

                float * tptr = (*gl_cmds)[i].texcoords;
                                        
                for ( int j = 0; j < (*gl_cmds)[i].num_verts; ++j ) {
                        
                        //                        cout << " s=" <<  *((float*)ptr+1)  << ", t=" << *((float*)ptr+2) << endl;

                        *(tptr++) = *((float*)++ptr);
                        *(tptr++) = 1 - *((float*)++ptr);
                        
                        (*gl_cmds)[i].verts_i[j] = *(++ptr);
                }
                
                ++ptr;
        }
        
        delete[] words;
        return num_cmds;
}
