/*
 * SFMatrix4f.cpp
 *
 * Copyright (C) 1999 Stephen F. White
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include "stdafx.h"
#include "DuneApp.h"

#include "swt.h"
#include "SFMatrix4f.h"
#include "SFFloat.h"

MyString    
SFMatrix4f::getString(int index, int stride) const
{
    MyString ret = "";
    char buffer[256];
    mysnprintf(buffer, 255, "%g", _value[stride]);
    ret += buffer;
    return ret;
}

bool
SFMatrix4f::equals(const FieldValue *value) const
{
    if (value->getType() == SFMATRIX4F) {
        SFMatrix4f *v = (SFMatrix4f *) value;
        for (int i = 0; i < 16; i++)
            if (v->getValue()[i] != _value[i])
                return false;
        return true;
    } else {
        return false;
    }
}

void
SFMatrix4f::clamp(const FieldValue *min, const FieldValue *max)
{
    if (min) {
        float fmin = ((SFFloat *) min)->getValue();
        for (int i = 0; i < 16; i++) {
            if (_value[i] < fmin) _value[i] = fmin;
        }
    }

    if (max) {
        float fmax = ((SFFloat *) max)->getValue();
        for (int i = 0; i < 16; i++) {
            if (_value[i] > fmax) _value[i] = fmax;
        }
    }
}

bool        
SFMatrix4f::readLine(int index, char *line)
{
    if (sscanf(line, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", 
               _value + 0, _value + 1, _value + 2, _value + 3, 
               _value + 4, _value + 5, _value + 6, _value + 7, 
               _value + 8, _value + 9, _value + 10, _value + 11, 
               _value + 12, _value + 13, _value + 14, _value + 15 
              ) != 16)
        return false;
    return true;
}

int 
SFMatrix4f::writeData(int f, int i) const
{
    return mywritef(f, "%g %g %g %g  %g %g %g %g  %g %g %g %g  %g %g %g %g", 
                       _value[0], _value[1], _value[2], _value[3], 
                       _value[4], _value[5], _value[6], _value[7], 
                       _value[8], _value[9], _value[10], _value[11],
                       _value[12], _value[13], _value[14], _value[15]);
}

int 
SFMatrix4f::write(int f, int indent) const
{
    RET_ONERROR( mywritef(f, "%g %g %g %g\n  %g %g %g %g\n  %g %g %g %g\n  %g %g %g %g\n", 
                       _value[0], _value[1], _value[2], _value[3], 
                       _value[4], _value[5], _value[6], _value[7], 
                       _value[8], _value[9], _value[10], _value[11],
                       _value[12], _value[13], _value[14], _value[15]) )
    TheApp->incSelectionLinenumber();
    TheApp->incSelectionLinenumber();
    TheApp->incSelectionLinenumber();
    return 0;
}

int
SFMatrix4f::writeC(int filedes, const char* variableName, int languageFlag) const
{
    RET_ONERROR( mywritestr(filedes, "m_") )
    RET_ONERROR( mywritestr(filedes, variableName) )
    RET_ONERROR( mywritestr(filedes, "[") )
    if (!(languageFlag & JAVA_SOURCE))
        RET_ONERROR( mywritestr(filedes, "16") )
    RET_ONERROR( mywritestr(filedes, "] = { ") )
    RET_ONERROR( mywritef(filedes, "%gf, %gf, %gf, %gf,",
                          _value[0], _value[1], _value[2], _value[3]) )
    RET_ONERROR( mywritef(filedes, "%gf, %gf, %gf, %gf,",
                          _value[4], _value[5], _value[6], _value[7]) )
    RET_ONERROR( mywritef(filedes, "%gf, %gf, %gf  %gf,", 
                          _value[8], _value[9], _value[10], _value[11]) )
    RET_ONERROR( mywritef(filedes, "%gf, %gf, %gf %gf,\n", 
                          _value[12], _value[13], _value[14], _value[15]) )
    RET_ONERROR( mywritestr(filedes, " };\n") )
    return 0;
}

int
SFMatrix4f::writeAc3d(int filedes, int indent) const
{
    // not needed yet
    return 0;
}

MyString
SFMatrix4f::getEcmaScriptComment(MyString name, int flags) const
{
    const char *indent = ((FieldValue *)this)->getEcmaScriptIndent(flags);
    MyString ret;
    ret = "not implemented yet";
    return ret;
}

FieldValue *
SFMatrix4f::getRandom(Scene *scene, int nodeType)
{
    int size = 16;
    float *array = new float[size];
    for (int i = 0; i < size; i++)
        array[i] = FLOAT_RAND();
    return new SFMatrix4f(array);
}

