// Qt Viewer for libVRML97
//
// Copyright (C) 1999 by Kenneth Bentley <bentley@nuc.net>
//
// This software may be distributed under the terms of the Q
// Public License, version 1.0 or later. Please see the file LICENSE for 
// terms. 

// based on libVRML97 by Chris Morley. and gtkLookat, by Erik Andersen

// libVRML97 is Copyright (C) 1998,1999 Chris Morley (cmorley@vermontel.com)

// gtkLookat is Copyright (C) 1998 by Erik Andersen <andersee@debian.org> under
// the terms of the GNU Public License. Erik Anderson has granted permission to 
// license this derivative work under QPL.



/**
  * mainWgt is our TopLevel widget (in standalone mode) , it contains an OpenGL 
  * canvas (vGLWidget), and a viewer object (ViewerQt) which connects us to
  * libVRML97.
  *
**/

#include "mainwgt.h"

#include <qfont.h>
#include <qapp.h>
#include <qkeycode.h>
#include <qfile.h>
#include <qfiledlg.h>
#include <qpopmenu.h>
#include <qlabel.h>
#include <qmsgbox.h>

//libVRML97 includes
#include <OpenVRML/VrmlScene.h>//mdvh
#include <OpenVRML/GL/ViewerOpenGL.h> // vrml97 keyevents//mdvh


#include "ViewerQt.h"  // interface to libVRML97
#include "vGLWidget.h" // our openGL 'canvas' 

static void worldChangedCB( int reason )
{
    switch (reason)
    {
            case VrmlScene::DESTROY_WORLD:
                    //delete vrmlScene;
                    //fprintf(stderr, "worldChangedCB()\n");
                    GS.sig_destroy_world();
                    exit(0);
                    break;
    }
}

mainWgt::mainWgt(  QWidget *parent, const char *name )
        : QWidget( parent, name )
{
    setMinimumSize( 50, 50);

    connect( this, SIGNAL(key_quit() ), qApp, SLOT(quit() ) );

    connect( &GS, SIGNAL(destroy_scene() ), this, SLOT(SceneDestroy() ) );

    canvas = new vGLWidget( this, "canvas" );

    vrmlScene = new VrmlScene();
    vrmlScene->addWorldChangedCallback( worldChangedCB );
    worldChangedCB( VrmlScene::REPLACE_WORLD );

    viewer = new ViewerQt( this, vrmlScene, canvas );
    canvas->setViewerPtr( viewer ); // now they know each other

    // want status to handle LibVRML97 messages, and uistatus for local (GUI) stuff
    status = new QLabel( this, "status" );
    status->setFrameStyle( QFrame::Panel | QFrame::Sunken );
    status->setAlignment( AlignRight );
    status->setFont( QFont("times",10,QFont::Normal) );
    status->setFixedHeight( 20 );
    status->setText( "" );

    uistatus = new QLabel( this, "uistatus" );
    uistatus->setFrameStyle( QFrame::Panel | QFrame::Sunken );
    uistatus->setAlignment( AlignRight );
    uistatus->setFont( QFont("times",10,QFont::Normal) );
    uistatus->setFixedHeight( 20 );
    uistatus->setText( "" );
    viewer->timerUpdate();
}

mainWgt::~mainWgt()
{
    // being anal, since Qt deletes all parented widgets.
    // as such, delete order is important!
    delete vrmlScene; //vrmlScene may talk to theSystem during destruct, so delete it 1st.
                      //while there's still a label (status) to receive messages.
    delete canvas;
    delete viewer;
    delete status;
    delete uistatus;
}

void mainWgt::resizeEvent( QResizeEvent * )
{
    canvas->resize( width() , height() - 20);
    uistatus->setGeometry(0, height() - 20, width() / 2 , status->height() );
    status->setGeometry(width() /2 , height() - 20, width() / 2, status->height() );
}

void mainWgt::load()
{
    QString fn = QFileDialog::getOpenFileName();
    if ( !fn.isEmpty() )
        load( fn );
}


void mainWgt::load( const char *fileName )
{
     int slen = strlen(fileName);
     QApplication::setOverrideCursor(waitCursor);
     if (vrmlScene && fileName){
         char * msg = new char[slen + 30]; 
         msg[slen+29] = '\0';
         if (vrmlScene->load( fileName))
             sprintf(msg, "Ok, file \"%s\" was loaded!\n", fileName);
         else
             sprintf(msg, "Rats! Error loading file \"%s\"\n", fileName);
         uistatus->setText(msg);
         delete [] msg;
         viewer->timerUpdate();
     }
     QApplication::restoreOverrideCursor();
}

void mainWgt::save()
{
}

void mainWgt::print()
{
}

void mainWgt::closeDoc()
{
    close();                                    // will call closeEvent()
}

//void mainWgt::closeEvent( QCloseEvent * )
//{
//}

void mainWgt::keyPressEvent( QKeyEvent *event ) 
{
    ViewerOpenGL::EventInfo e;
    e.event = ViewerOpenGL::EVENT_KEY_DOWN;
    switch ( event->key() ) {
            case Key_Home:      e.what = ViewerOpenGL::KEY_HOME; 
                                uistatus->setText("resetting view");
                                break;
            case Key_Left:      e.what = ViewerOpenGL::KEY_LEFT; 
                                uistatus->setText("stepping left");
                                break;
            case Key_Up:        e.what = ViewerOpenGL::KEY_UP; 
                                uistatus->setText("stepping up");
                                break;
            case Key_Right:     e.what = ViewerOpenGL::KEY_RIGHT; 
                                uistatus->setText("stepping right");
                                break;
            case Key_Down:      e.what = ViewerOpenGL::KEY_DOWN; 
                                uistatus->setText("stepping down");
                                break;
            case Key_PageUp:    e.what = ViewerOpenGL::KEY_PAGE_UP; 
                                break;
            case Key_PageDown:  e.what = ViewerOpenGL::KEY_PAGE_DOWN; 
                                break;

      /* these are keys that libVRML97 handles as of 0.8.0. If that proves to
         be a moving target, we may relenquish all keys to libVRML97. But for
         now, we return unwanted keys lest other widgets want them;
       */
            case Key_Comma:     e.what = event->ascii() ; 
                                uistatus->setText("Look left");
                                break;
            case Key_A:         e.what = event->ascii() ; 
                                uistatus->setText("Look up");
                                break;
            case Key_Z:         e.what = event->ascii() ; 
                                uistatus->setText("Look down");
                                break;
            case Key_Period:    e.what = event->ascii() ; 
                                uistatus->setText("Look right");
                                break;
            case Key_B:         e.what = event->ascii() ; 
                                break;
            case Key_L:         e.what = event->ascii() ; 
                                break;
            case Key_T:         e.what = event->ascii() ; 
                                break;
            case Key_W:         e.what = event->ascii() ; 
                                break;
            case Key_R:         e.what = event->ascii() ; 
                                uistatus->setText("reset user navigation");
                                break;
            case Key_Slash:     e.what = event->ascii() ; 
                                break;
            case Key_Q:         e.what = event->ascii() ; 
                                uistatus->setText("aiiieeeeee...what to delete first?");
                                emit key_quit();
            case Key_O:
                                if ( event->state() & AltButton ) { /* open file--for stand-alone version */
                                    load();
                                }
                                break;
            default:
                                event->ignore();
                                return; // avoid handleInput() 
    }

    viewer->handleInput( &e );
}

void mainWgt::sys_mesg(const char *mesg)
{
     if (strlen(mesg) > 1 ) {
         if (status)
          status->setText(mesg);
     }
}

void mainWgt::SetStop( bool state)
{
    viewer->SetStop(state);
}

void mainWgt::SceneDestroy( )
{
    delete vrmlScene;
    vrmlScene = 0;
}

