/*
 * Copyright (c) 2024 Ross Cunniff
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
/* Significant portions of this code were adapted from Hoverware, whose
 * GPL copyright is: */
/* (c) Copyright Hewlett-Packard Company 2001
 *
 * 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; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

using namespace oadl;

#include "libo3d.oah"

extern
    _intReadJPG,
    _intTextAttrs,
    _intTextHeight,
    _intTextAlign,
    _intTextOrient,
    _intTextExtrude,
    _intText3d;

o3d::Display disp(nil,nil) { o3dDefaultOptFlags = o3d::OPT_USE_DL }

proc main()
{
    var
        intDisp,
        draw,
        lightColor = [1.,1.,1.],
        lightDir = [1.,1.,0.],
        ambColor = [1.,1.,1.],
        front = {
            1.,0.,0.,   /* Color */
            0.,         /* Transp */
            1.,1.,1.,   /* SpecColor */
            0.1,        /* Shininess */
            1.0,        /* PrimSize */
            0xFFFFFFFFu, /* Visibility */
            o3d::SURF_TWOSIDED, /* Flags */
            0,          /* NumTex */
            nil, nil, nil, nil, nil, nil, nil, nil
        },
        back = {
            0.,0.,1.,   /* Color */
            0.,         /* Transp */
            1.,1.,1.,   /* SpecColor */
            0.1,        /* Shininess, */
            1.0,        /* PrimSize */
            0xFFFFFFFFu, /* Visibility */
            o3d::SURF_TWOSIDED, /* Flags */
            0,          /* Num Textures */
            nil, nil, nil, nil, nil, nil, nil, nil
        },
        side = {
            1.,0.,1.,   /* Color */
            0.,         /* Transp */
            1.,1.,1.,   /* SpecColor */
            0.1,        /* Shininess, */
            4.0,        /* PrimSize */
            0xFFFFFFFFu, /* Visibility */
            o3d::SURF_WIREFRAME, /* Flags */
            0,          /* Num Textures */
            nil, nil, nil, nil, nil, nil, nil, nil
        },
        cam = {
            true,       /* Perspective */
            true,       /* Mirror */
            0.,0.,-5.,  /* Pos */
            0.,0.,1.,   /* Dir */
            0.,1.,0.,   /* Up */
            0.,0.,      /* Jitter */
            0.,0.,      /* Skew */
            30.0, 1.0,  /* Field, aspect */
            1.,10.,     /* Planes */
            nil
        },
        Mat,
        ang = 0.0,
        texID,
        img,    /* For the texture */
        texOrient = {
            1.,1.,1.,    /* Scale */
            0.,0.,0.,    /* Rotate */
            0.,0.,0.     /* Pos */
        },
        i, wireframe = 0;

    // Copy attrib arrays since we need to modify them
    front = @front;
    back = @back;
    side = @side;

    if( wireframe ) {
        front[o3d::SURF_FLAGS] = o3d::SURF_TWOSIDED;
        back[o3d::SURF_FLAGS]  = o3d::SURF_TWOSIDED;
        side[o3d::SURF_FLAGS]  = o3d::SURF_WIREFRAME;
    }
    else {
        front[o3d::SURF_FLAGS] = o3d::SURF_BLEND;
        back[o3d::SURF_FLAGS] = 0;
        side[o3d::SURF_FLAGS] = 0;
    }

    disp.chooseVisual(o3d::VIS_DBUFF|o3d::VIS_DEPTH, 0);
    draw = disp.createWindow( "Test", 0, 0, 512, 512, 0 );
    disp.makeCurrent( draw );

    img = o3d::_intReadJPG("Texture/Earth.jpg");
    if (img) {
        texID = disp.createTexture(img,
                                o3d::TM_TRILINEAR, /* Filter */
                                o3d::TM_MODULATE, /* Apply */
                                o3d::TM_REPEAT,   /* Bound */
                                o3d::TM_EXPLICIT, /* Coord mode */
                                texOrient,      /* Orient */
                                0 );            /* InternalFormat */
        front[o3d::SURF_NUM_TEX] = 1;
        front[o3d::SURF_TEXTURE_IDS+0] = texID;
        back[o3d::SURF_NUM_TEX] = 1;
        back[o3d::SURF_TEXTURE_IDS+0] = texID;
        side[o3d::SURF_NUM_TEX] = 1;
        side[o3d::SURF_TEXTURE_IDS+0] = texID;
    }

    intDisp = disp._intGetHandle();

    o3d::_intTextAttrs( intDisp, front, side, back );
    o3d::_intTextHeight( intDisp, 1.0 );
    o3d::_intTextAlign( intDisp, o3d::TEXT_ALIGN_CENTER,
                            o3d::TEXT_ALIGN_CENTER,
                            o3d::TEXT_ALIGN_CENTER );
    o3d::_intTextOrient( intDisp, 0.0, 1.0, 0.0,  1.0, 1.0, 1.0 );
    o3d::_intTextExtrude( intDisp, 0.0, 0.0, 0.5 );

    disp.ambientLight( 0.2, ambColor );
    disp.enableLighting( true );

    Mat = new PackFloat(16);

    while( 1 ) {
        disp.setCamera( cam );
        disp.directionalLight( lightColor, lightDir );

        o3d::RotateY( Mat, ang );

        disp.pushMatrix( Mat );
        o3d::_intText3d( intDisp, 0.0, 0.0, 0.0, "Test" );
        disp.popMatrix();

        disp.update( o3d::UPDATE_ALL );
        ang += 0.5;
    }
}