// 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.




#include "ViewerQt.h"
#include "vGLWidget.h"
#include <qevent.h> // QMouseEvent 
#include <qcursor.h> // Qt cursor styles
#include <qapplication.h>
#include <qtextstream.h>
#include <qtimer.h>
#include <OpenVRML/System.h>//mdvh
#ifndef WIN32 //mdvh
include <qt_x11.h>   // wan't to use XSendEvent in wsPostRedraw, although this
                      // hurts portability to win32 :(
#endif
ViewerQt::ViewerQt(QObject *parent, VrmlScene *scene, vGLWidget *da_widg) : 
                QObject(parent),
                ViewerOpenGL(scene),
                d_timer(0),
                d_Stop(false),
                d_redrawNeeded(false),
                d_width(0),
                d_height(0),
                da_widget(da_widg)
{
}


ViewerQt::~ViewerQt()
{
}

void ViewerQt::handleInput( ViewerOpenGL::EventInfo *e )
{
    da_widget->makeCurrent();
    input( e );
}

void ViewerQt::handleRedraw()
{
    if ( da_widget->isValid() )
    {
        int width, height;
        width = da_widget->width();
        height = da_widget->height();

        da_widget->makeCurrent();
        if (width != d_width || height != d_height)
        {
            resize( width, height );
            d_height = height;
            d_width = width;
        }
        redraw();
    }

    d_redrawNeeded = false;
}

void ViewerQt::vMousePressEvent( QMouseEvent *evnt )
{
    ViewerOpenGL::EventInfo e;

    e.event = ViewerOpenGL::EVENT_MOUSE_CLICK;
    switch (evnt->button() )
    {
            case rodent_LEFT  : e.what = 0; break; 
            case rodent_RIGHT : e.what = 1; break; // is Right==1 or Mid==1 ?
            case rodent_MID   : e.what = 2; break;
            case rodent_NONE  : return;
            default: break;  // ignore shift,alt, ctrl modifiers

    }
    e.x = evnt->x();
    e.y = evnt->y();
    handleInput( &e );
}

void ViewerQt::vMouseReleaseEvent( QMouseEvent *evnt )
{
    ViewerOpenGL::EventInfo e;

    e.event = ViewerOpenGL::EVENT_MOUSE_RELEASE;
    switch (evnt->button() )
    {
            case rodent_LEFT  : e.what = 0; break; 
            case rodent_RIGHT : e.what = 1; break; // is Right==1 or Mid==1 ?
            case rodent_MID   : e.what = 2; break;
            case rodent_NONE  : return;
            default: break; // ignore shift,alt, ctrl modifiers

    }
    e.x = evnt->x();
    e.y = evnt->y();
    handleInput( &e );
}

void ViewerQt::vMouseMoveEvent( QMouseEvent *evnt )
{
    // may be a move or a drag
    ViewerOpenGL::EventInfo e;
    e.event = ViewerOpenGL::EVENT_MOUSE_DRAG;
    e.what = 0;
    if ( (evnt->state()) & rodent_LEFT  )
        e.what = 0;
    else if ( (evnt->state()) & rodent_RIGHT )
        e.what = 1;
    else if ( (evnt->state()) & rodent_MID )
        e.what = 2;
    else
        e.event = ViewerOpenGL::EVENT_MOUSE_MOVE;
    e.x = evnt->x();
    e.y = evnt->y();
    handleInput( &e);
}

void ViewerQt::wsPostRedraw()
{
#if 1//mdvh
   da_widget->update();
#else
      XEvent e;
      e.xexpose.type = Expose;
      e.xexpose.serial = 0;
      e.xexpose.send_event = False;
      e.xexpose.display = da_widget->x11Display(); 
      e.xexpose.window = da_widget->winId();
      e.xexpose.x = e.xexpose.y = 0;
      e.xexpose.width = 0;
      e.xexpose.height = 0;
      e.xexpose.count = 0;
      XSendEvent( e.xexpose.display, e.xexpose.window,
		  False, 0L, &e );
#endif
}


void ViewerQt::wsSetCursor( CursorStyle c )
{
    if (da_widget)
    {
#ifdef Qt2x 
        // cursors still need work. May need to define them if Qt doesn't have
        // appropriate ones.

        switch(c) {
                case CURSOR_INFO:
                        da_widget->setCursor(IbeamCursor);
                        break;
                case CURSOR_CYCLE:
                        da_widget->setCursor(SizeAllCursor);
                        break;
                case CURSOR_UP_DOWN:
                        da_widget->setCursor(SizeVerCursor);
                        break;
                case CURSOR_CROSSHAIR:
                        da_widget->setCursor(CrossCursor);
                        break;
                case CURSOR_INHERIT:
                        // what does VRML want here? 
                default:
                        da_widget->setCursor(ArrowCursor);
                        break;
        }
#else
        switch(c) {
                case CURSOR_INFO:
                        da_widget->setCursor(ibeamCursor);
                        break;
                case CURSOR_CYCLE:
                        da_widget->setCursor(sizeAllCursor);
                        break;
                case CURSOR_UP_DOWN:
                        da_widget->setCursor(sizeVerCursor);
                        break;
                case CURSOR_CROSSHAIR:
                        da_widget->setCursor(crossCursor);
                        break;
                case CURSOR_INHERIT:
                        // what does VRML want here? 
                default:
                        da_widget->setCursor(arrowCursor);
                        break;
        }
#endif
    }
}

void ViewerQt::wsSwapBuffers()
{
    if (! da_widget->doubleBuffer() ){
        warn("ERROR: double buffering disabled\n");
    }
    da_widget->swapBuffers();
}

int ViewerQt::warn(char * str)
{
    qDebug(str);
    return TRUE;
}

void ViewerQt::timerUpdate()
{
    d_timer = 0;
    update( 0.0 );	
}

void ViewerQt::SetStop( bool state)
{
    d_Stop=state;
    if (state==false)
        timerUpdate();
}

void ViewerQt::wsSetTimer( double t ) 
{
    if (! d_timer && ! d_Stop )
    {
        unsigned int ms = (unsigned int) (1000.0 * t);
        d_timer = startTimer( ms );
    }
}

void ViewerQt::timerEvent(QTimerEvent *event)
{
    killTimer( ((QTimerEvent *)event)->timerId() );
    timerUpdate();
}


