/****************************************************************************
**
**  indeview_main.cpp    of the IndeView project, see http://www.indeview.org
**
**
**  The IndeView application is a stand-alone viewer to display presentations
**  created by IndeView creator modules like IndeViewExport.bas or kpr2iv.sh.
**  -------------------------------------------------------------------------
**  This enables you to show OpenOffice/StarOffice or KOffice presentations
**  on machines where the respective presentation program is not available.
**
**
**  Copyright (C) 2003..2004 Michael & Karl-Heinz Zimmer.
**  All rights reserved.
**
**  This file is distributed under the terms of the
**  GNU Lesser General Public License version 2.1 as published by the
**  Free Software Foundation and appearing in the file LICENSE included
**  in the packaging of this file.
**
**  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
**  THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
**  PURPOSE.
**
**  See http://www.indeview.org for further information.
**
**  Contact info@indeview.org if any conditions of this
**  licensing are not clear to you.
**
**
**  Please consider sending
**  a little picture postcard to   Michael & Karl-Heinz Zimmer
**                                 Butzengasse 15
**                                 54343 Föhren
**                                 Germany
**
**  Your feedback will be very much appreciated: we would be glad about
**  receiving a visual representation of where on earth you are living
**  using our little module.
**
*****************************************************************************/

#include <qapplication.h>
#include <qlayout.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qpainter.h>
#include <qcursor.h>
#include <qtimer.h>

#include "indeview_main.h"


// Make sure the following include file contains a
//      static const char * keyboardC32_xpm[] = {
//        ...
//      };
// and add a newline at the end of the file.
#include "keyboardC32.inc"


IndeViewMain::IndeViewMain( const QStringList& params,
                            IndeViewSlides* slides,
                            bool deleteSlidesWhenDone )
  :
    IndeViewWidget( slides, deleteSlidesWhenDone, 0, "IndeView",
                    Qt::WRepaintNoErase | Qt::WStyle_Customize | Qt::WStyle_Splash ),
    mParams( params ),
    mSlideSelectionPopup(0),
    mListBox(0),
    mOkButton(0),
    mHelpScreen(QPixmap()),
    mHelpScreenVisible(false),
    mIsInitialized(false)
{
  setFocusPolicy( QWidget::StrongFocus );
  for( unsigned int i=0; i<mParams.count(); ++i){
    if( mParams[i].upper() == "--DONT-SCALE" )
      setOptionDontScale( true );
    else if( mParams[i].upper() == "--DONT-STRETCH" )
      setOptionDontStretch( true );
  }
}

IndeViewMain::~IndeViewMain()
{
  if( mSlideSelectionPopup )
    delete mSlideSelectionPopup;
}

void IndeViewMain::initAll()
{
  QTimer::singleShot( 500, this, SLOT( slotInitialize() ) );
}

void IndeViewMain::slotInitialize()
{
  if( !curSlide() )
    close( true );

  // create and populate little popup window for slide selection
  if( !mSlideSelectionPopup ){
    mSlideSelectionPopup = new QVBox( this, 0,
      WType_TopLevel | WStyle_Customize | WType_Popup | WShowModal );
    mSlideSelectionPopup->setMargin( 20 );
    mListBox = new QListBox( mSlideSelectionPopup, "Select a slide:" );
    mListBox->insertStringList( slideNames() );

    QPushButton *mOkButton = new QPushButton( "OK", mSlideSelectionPopup );
    connect( mListBox, SIGNAL(selected( int )), this, SLOT(slotSlideSelected( int )) );
    connect( mOkButton, SIGNAL(clicked()), this, SLOT(slotSlideSelected()) );
    mSlideSelectionPopup->move( QPoint(0,0) );
    mSlideSelectionPopup->hide();
  }

  // set the slide area topmost
  setActiveWindow();
  move(0,0);
  resize(qApp->desktop()->size());
  mIsInitialized = true;
  update();
  raise();
};


void IndeViewMain::keyPressEvent( QKeyEvent *e )
{
  uint key = e->key();

  if( helpScreenVisible() ){
    hideHelpScreen();
  }else if( mSlideSelectionPopup && mSlideSelectionPopup->isVisible() ){
    if( key == Key_Escape || key == Key_Q )
      slotSlideSelected( 0 );
    else if( key == Key_Return || key == Key_Enter )
      slotSlideSelected();
  }else{
    bool bPageWasChanged;
    int realDelta;
    int realMoveX;
    int realMoveY;
    bool bWasZoom, bWasMove;
    if( key == Key_F1 )
      showHelpScreen();
    else if( key == Key_Escape || key == Key_Q || key == Key_X )
      close( true );
    else if( key == Key_Return || key == Key_Enter || key == Key_Space || key == Key_PageDown ){
      gotoNextSlide( bPageWasChanged );
      if( !bPageWasChanged )
        close();
    }else if( key == Key_Backspace || key == Key_PageUp )
      gotoPrevSlide( bPageWasChanged );
    else if( key == Key_Home )
      gotoFirstSlide( bPageWasChanged );
    else if( key == Key_End )
      gotoLastSlide( bPageWasChanged );
    else if( key == Key_Plus )
      changeZoom( 1, realDelta );
    else if( key == Key_Minus )
      changeZoom( -1, realDelta );
    else if( key == Key_Z ){
      if ( e->state() & ShiftButton )
        changeZoom( -1, realDelta );
      else
        changeZoom( 1, realDelta );
    }else if( key == Key_0 || key == Key_O )
      resetZoom( bWasZoom );
    else if( key == Key_Right || key == Key_6 )
      moveHoriVert( 32, 0, realMoveX, realMoveY );
    else if( key == Key_Left || key == Key_4 )
      moveHoriVert( -32, 0, realMoveX, realMoveY );
    else if( key == Key_Down || key == Key_2 )
      moveHoriVert( 0, 20, realMoveX, realMoveY );
    else if( key == Key_Up || key == Key_8 )
      moveHoriVert( 0, -20, realMoveX, realMoveY );
    else if( key == Key_7 )
      moveHoriVert( -32, -20, realMoveX, realMoveY );
    else if( key == Key_9 )
      moveHoriVert( 32, -20, realMoveX, realMoveY );
    else if( key == Key_1 )
      moveHoriVert( -32, 20, realMoveX, realMoveY );
    else if( key == Key_3 )
      moveHoriVert( 32, 20, realMoveX, realMoveY );
    else if( key == Key_5 )
      resetMove( bWasMove );
    else if( key == Key_L )
      getImageFromListbox();
    else{
      e->ignore();
      return;

    }
  }
  e->accept();
}

void IndeViewMain::mousePressEvent( QMouseEvent *e )
{
  bool bPageWasChanged;
  if( helpScreenVisible() ){
    hideHelpScreen();
    e->ignore();
    return;

  }else if ( e->button() == LeftButton ){
    if ( e->state() & ShiftButton )
      gotoLastSlide( bPageWasChanged );
    else{
      gotoNextSlide( bPageWasChanged );
      if( !bPageWasChanged )
        close();
    }
  }else if ( e->button() == RightButton ){
    if ( e->state() & ShiftButton )
      gotoFirstSlide( bPageWasChanged );
    else
      gotoPrevSlide( bPageWasChanged );
  }else if ( e->button() == MidButton ){
    getImageFromListbox();
  }else{
    e->ignore();
    return;

  }
  e->accept();
}

void IndeViewMain::slotSlideSelected( int index )
{
  mSlideSelectionPopup->hide();
  raise();
  setFocus();
  bool bPageWasChanged;
  if( 0 <= index )
    gotoSlide( index, bPageWasChanged );
}

void IndeViewMain::slotSlideSelected()
{
  if( mSlideSelectionPopup && mListBox )
    slotSlideSelected( mListBox->index( mListBox->selectedItem() ) );
}

void IndeViewMain::getImageFromListbox()
{
  mListBox->setCurrentItem( curSlideIdx() );
  mSlideSelectionPopup->show();
  mSlideSelectionPopup->raise();
  mListBox->setFocus();
}

void IndeViewMain::showHelpScreen()
{
  if( mHelpScreen.isNull() ){
    QApplication::setOverrideCursor(QCursor( Qt::WaitCursor ));
    mHelpScreen = keyboardC32_xpm;
    QApplication::restoreOverrideCursor();	// restore original cursor
  }
  mHelpScreenVisible = true;
  update();
}
void IndeViewMain::hideHelpScreen()
{
  mHelpScreenVisible = false;
  update();
}
bool IndeViewMain::helpScreenVisible()
{
  return mHelpScreenVisible;
}

void IndeViewMain::processPainterAfterDrawing( QPainter& painter )
{
  if( helpScreenVisible() )
    painter.drawPixmap( (width()  - mHelpScreen.width() ) / 2,
                        (height() - mHelpScreen.height()) / 2,
                        mHelpScreen );
}
