/****************************************************************************
** Form implementation generated from reading ui file 'uidialogconvert.ui'
**
**   Created : Tue Oct 14 09:13:25 2006
**        by : Varol Okan, using XEmacs
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
****************************************************************************/

#include <qcheckbox.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qgroupbox.h>
#include <qpainter.h>
#include <qlayout.h>
#include <qslider.h>
#include <qlabel.h>
#include <qrect.h>

#include "global.h" // for TRANSPAREN_COLOR
#include "selectionobject.h"
#include "buttonobject.h"
#include "imageobject.h"
#include "movieobject.h"
#include "menuobject.h"
#include "textobject.h"

#include "dialogalign.h"

DialogAlign::DialogAlign ( MenuPreview *pMenuPreview )
    : uiDialogAlign ( NULL )
{
  m_pMenuPreview       = pMenuPreview;
  m_pSelectionObject   = NULL;
  m_pPreview           = NULL;
  m_iTimerID           =   -1;
  m_iTimerObjectSizeID =   -1;
  m_fZoom              =  1.0;

  // m_pFramePreview
  connect ( m_pCheckWidth,        SIGNAL ( toggled   ( bool ) ), this, SLOT ( slotRefresh     ( bool ) ) );
  connect ( m_pCheckHeight,       SIGNAL ( toggled   ( bool ) ), this, SLOT ( slotRefresh     ( bool ) ) );
  connect ( m_pComboAlign,        SIGNAL ( activated  ( int ) ), this, SLOT ( slotAlign       ( int  ) ) );
  connect ( m_pComboAlignPos,     SIGNAL ( activated  ( int ) ), this, SLOT ( slotAlignPos    ( int  ) ) );
  connect ( m_pComboDistance,     SIGNAL ( activated  ( int ) ), this, SLOT ( slotDistance    ( int  ) ) );
  connect ( m_pSliderHorizontally,SIGNAL (valueChanged( int ) ), this, SLOT ( slotSliderAlign ( int  ) ) );
  connect ( m_pSliderVertically,  SIGNAL (valueChanged( int ) ), this, SLOT ( slotSliderAlign ( int  ) ) );
  connect ( m_pEditWidth,         SIGNAL (textChanged(const QString&) ), this, SLOT( slotRefresh(const QString&) ) );
  connect ( m_pEditHeight,        SIGNAL (textChanged(const QString&) ), this, SLOT( slotRefresh(const QString&) ) );

  QGridLayout *pLayout;
  uint iFlags = 0;

#if (QT_VERSION > 0x0301FF)
	iFlags = Qt::WNoAutoErase;
#else
	iFlags = Qt::WPaintClever;
#endif

  m_pSliderHorizontally->setMaxValue ( 1000 );
  m_pSliderVertically  ->setMaxValue ( 1000 );
  m_pSliderHorizontally->hide ( );
  m_pSliderVertically  ->hide ( );

  pLayout       = new QGridLayout ( m_pFramePreview, 1, 1, 2, 2, "pLayout" );
  m_pPreview    = new QLabel      ( m_pFramePreview, "pPreview",  iFlags   );
  //m_pPreview->resize      (  720, 480  );
  pLayout->addWidget      ( m_pPreview, 0, 0 );
}

DialogAlign::~DialogAlign ( )
{
  uint t;
  for ( t=0; t<m_listOfObjects.count ( ); t++ )
    delete m_listOfObjects.at ( t );
  m_listOfObjects.clear ( );
}

void DialogAlign::initMe ( SelectionObject *pSelectionObject, QPixmap *pBackground )
{
  int         t;
  QRect       theRect;
  MenuObject *pObject;
  MenuObject *pFirstObject = NULL;
  ButtonObject tempButton, *pButton;
  TextObject   tempText; // ,   *pText;
  m_pSelectionObject = pSelectionObject;

  if ( m_pSelectionObject ) {
    pFirstObject = pSelectionObject->getObject ( 0 );

    if ( m_pSelectionObject->getCount ( ) < 3 ) {
      m_pComboDistance->hide ( );
      m_pGroupDistance->setTitle ( "" );
    }

    for ( t=0; t<m_pSelectionObject->getCount   ( ); t++ ) {
      pObject  = m_pSelectionObject->getObject ( t );
      if ( ! pObject )
        continue;
      // for this dialog we do not need the buttonObjects ...
      if ( pObject->objectType ( ) == tempButton.objectType ( ) ) {
        pButton = (ButtonObject *)pObject;
        pObject = pButton->getNormal ( 0 );
        if ( ! pObject )
               pObject = m_pSelectionObject->getObject ( t );
      }
      pObject = pObject->clone ( );
/* Okay, I removed text because it did not scale along.
      if ( pObject->objectType ( ) == tempText.objectType ( ) ) {
        QString qsEmpty;
        pText = (TextObject *)pObject;
        pText->setText ( qsEmpty );
        if ( pText->getBackgroundColor ( ) == QColor ( TRANSPARENT_COLOR ) )
             pText->setBackgroundColor ( QColor ( 200, 200, 200 ) );
      }
*/
      m_listOfObjects.append ( pObject );
    }
  }

  if ( pBackground )
    m_backgroundImage  = pBackground->convertToImage ( ); 

  // Let us take care of the background ...
  refreshBackgroundPixmap ( );

  // Now let us set some values ...
  if ( pFirstObject ) {
    theRect = pFirstObject->rect ( );
    m_pEditAlign->setText  ( QString ( "%1" ).arg ( theRect.top    ( ) ) );
    m_pEditWidth->setText  ( QString ( "%1" ).arg ( theRect.width  ( ) ) );
    m_pEditHeight->setText ( QString ( "%1" ).arg ( theRect.height ( ) ) );
  }
}

void DialogAlign::slotSliderAlign ( int iSliderPosition )
{
  // iPosition [0 .. 1000]
  int t, iValue, iSelection, iOffset, iPosition;
  int iLeft, iRight, iWidth, iHeight;
  double fValue = (double)iSliderPosition / 1000.0;
  MenuObject *pObject;

  iSelection = m_pComboAlign   ->currentItem ( );
  iPosition  = m_pComboAlignPos->currentItem ( );

  // restore the original positions
  iValue = 0;

  if ( iSelection == 0 )
    refreshBackgroundPixmap ( );
  else if ( iSelection == 1 ) { // Horizontal
    iValue = (int)( fValue * m_backgroundPixmap.height ( ) );
    for ( t=0; t<(int)m_listOfObjects.count ( ); t++ ) {
      pObject = m_listOfObjects.at ( t );
      if ( pObject ) {
        iHeight = pObject->rect ( ).height ( );
        iOffset = (int)( (float)iHeight * ( pObject->modifiers ( )->fScaleY - 1.0 ) / 2.0 );
        iRight  = iOffset - (int)( (float)iPosition * ( (float)iHeight / 2.0 + (float)iOffset ) );
        pObject->rect( ).setTop    ( iValue + iRight );
        pObject->rect( ).setHeight ( iHeight );
      }
    }
    iValue = (int) ( fValue * m_backgroundImage.height  ( ) );
    m_pEditAlign->setText ( QString ( "%1" ).arg ( iValue ) );
  }
  else {
    iValue = (int)( fValue * m_backgroundPixmap.width  ( ) );
    for ( t=0; t<(int)m_listOfObjects.count ( ); t++ ) {
      pObject = m_listOfObjects.at ( t );
      if ( pObject ) {
        iWidth     = pObject->rect( ).width ( );
        iOffset = (int)( (float)iWidth * ( pObject->modifiers ( )->fScaleX - 1.0 ) / 2.0 );
        iLeft   = iOffset - (int)( (float)iPosition * ( (float)iWidth / 2.0 + (float)iOffset ) );
        pObject->rect( ).setLeft  ( iValue + iLeft );
        pObject->rect( ).setWidth ( iWidth );
      }
    }
    iValue = (int) ( fValue * m_backgroundImage.width  ( ) );
    m_pEditAlign->setText ( QString ( "%1" ).arg ( iValue) );
  }

  refresh ( true );
}

void DialogAlign::slotAlign ( int iSelection )
{
  // Handle the combo box input ...
  bool bEnable = true;
  bool bEnableHorizontally = true;
  QRect theRect;
  float fValue;
  MenuObject *pObject = m_pSelectionObject->getObject ( 0 );
  if ( pObject )
    theRect = pObject->rect ( );

  if ( iSelection == 0 )        // None
    bEnable = false;
  else if ( iSelection == 1 )  { // Horizontally
    m_pComboAlignPos->clear ( );
    m_pComboAlignPos->insertItem ( tr ( "Top"    ) );
    m_pComboAlignPos->insertItem ( tr ( "Center" ) );
    m_pComboAlignPos->insertItem ( tr ( "Bottom" ) );
    bEnableHorizontally = true;
  }
  else  {                        // Vertically 
    m_pComboAlignPos->clear ( );
    m_pComboAlignPos->insertItem ( tr ( "Left"   ) );
    m_pComboAlignPos->insertItem ( tr ( "Middle" ) );
    m_pComboAlignPos->insertItem ( tr ( "Right"  ) );
    bEnableHorizontally = false;
  }

  if (  bEnableHorizontally && bEnable ) {
    m_pSliderHorizontally->show ( );
    fValue = (float)theRect.width ( ) / m_backgroundImage.width ( );
    m_pSliderHorizontally->setValue ( (int)( fValue * 1000 ) );
    m_pEditAlign->setText ( tr ( "%1" ).arg ( theRect.left ( ) ) );
  }
  else
    m_pSliderHorizontally->hide ( );

  if ( !bEnableHorizontally && bEnable ) {
    m_pSliderVertically->show ( );
    fValue = (float)theRect.height ( ) / m_backgroundImage.height ( );
    m_pSliderVertically->setValue ( (int)( fValue * 1000 ) );
    m_pEditAlign->setText ( tr ( "%1" ).arg ( theRect.top ( ) ) );
  }
  else
    m_pSliderVertically->hide ( );

  m_pEditAlign->setEnabled     ( bEnable );
  m_pComboAlignPos->setEnabled ( bEnable );
  m_pComboDistance->setEnabled ( bEnable );
  //  m_pLabelEquidistance->setEnabled ( bEnable );
  resetObjectPos ( );

  refresh ( true );
}

void DialogAlign::slotAlignPos ( int )
{
  int iPos = 0;
  if ( m_pComboAlign->currentItem ( ) == 1 )
    iPos = m_pSliderHorizontally->value  ( );
  else
    iPos = m_pSliderVertically->value    ( );
  slotSliderAlign ( iPos );
  //refresh ( true );
}

void DialogAlign::slotDistance ( int iPosition )
{
  // this function is called from m_pComboDistance.
  if ( iPosition == 0 )
    return;

  alignDistance ( m_listOfObjects );
}

void DialogAlign::alignDistance ( QPtrList<MenuObject> &listOfObjects )
{
  int iDistance = m_pComboDistance->currentItem ( );
  int iAlign    = m_pComboAlign   ->currentItem ( );
  if ( iDistance == 1 )  {
    if ( iAlign == 1 )
      alignHorizontalCenter ( listOfObjects );
    else if ( iAlign == 2 )
      alignVerticalCenter   ( listOfObjects );
  }
  else if ( iDistance == 2 ) {
    if ( iAlign == 1 )
      alignHorizontalSpace ( listOfObjects );
    else if ( iAlign == 2 )
      alignVerticalSpace   ( listOfObjects );
  }
}

void DialogAlign::alignHorizontalCenter ( QPtrList<MenuObject> &theList )
{
  float fDelta;
  QRect theRect;
  MenuObject *pObject,*pObjectMin = NULL;
  int iAvailableWidth, iMin, iMax, iDeltaMin, iDeltaMax;
  int t, iWidth, iCounter, iMinStart, iCurrentMin;
  QPtrList<MenuObject> listOfObjects = theList;

  iMax = iDeltaMax = -5000;
  iMin = iDeltaMin = +5000;
  for ( t=0; t<(int)theList.count ( ); t++ ) {
    pObject = theList.at ( t );
    if ( pObject ) {
      theRect = pObject->rect ( );
      if ( iMin   > theRect.left ( ) ) {
	iMin      = theRect.left ( );
	iDeltaMin = (int)( theRect.width ( ) / 2.0 ); 
	pObjectMin= pObject;
      }
      if ( iMax   < theRect.right ( ) ) {
	iMax      = theRect.right ( );
	iDeltaMax = (int)( theRect.width ( ) / 2.0 ); 
      }
    }
  }
  if ( ! pObjectMin )
    return;

  iMinStart = iMin + iDeltaMin;
  iCounter  = 1;
  listOfObjects.remove ( pObjectMin );
  iAvailableWidth = iMax-iDeltaMax - iMinStart;

  fDelta = (float)iAvailableWidth / ( theList.count ( ) - 1 );
  if (fDelta < 0.0 )
    return;

  while ( listOfObjects.count ( ) > 1 ) { // Note, the first and the last object should not move
    iCurrentMin = 5000;
    pObjectMin  = NULL;
    for ( t=0; t<(int)listOfObjects.count ( ); t++ ) {
      pObject = listOfObjects.at ( t );
      if ( ! pObject )
	continue;

      iMin = pObject->rect ( ).left ( ) + (int)( pObject->rect ( ).width ( ) / 2.0 );
      if ( iMin < iCurrentMin ) {
	iCurrentMin = iMin;
	pObjectMin  = pObject;
      }	 
    }
    if ( pObjectMin ) {
      listOfObjects.remove ( pObjectMin );
      iWidth = pObjectMin->rect ( ).width ( );
      pObjectMin->rect ( ).setLeft  ( iMinStart + (int)( fDelta * iCounter++ ) - (int)( iWidth / 2.0 ) );
      pObjectMin->rect ( ).setWidth ( iWidth );
    }
  }

  refresh ( true );
}

void DialogAlign::alignVerticalCenter ( QPtrList<MenuObject> &theList )
{
  float fDelta;
  QRect theRect;
  MenuObject *pObject,*pObjectMin = NULL;
  int iAvailableHeight, iMin, iMax, iDeltaMin, iDeltaMax;
  int t, iHeight, iCounter, iMinStart, iCurrentMin;
  QPtrList<MenuObject> listOfObjects = theList;

  iMax = iDeltaMax = -5000;
  iMin = iDeltaMin = +5000;
  for ( t=0; t<(int)theList.count ( ); t++ ) {
    pObject = theList.at ( t );
    if ( pObject ) {
      theRect = pObject->rect ( );
      if ( iMin   > theRect.top ( ) ) {
	iMin      = theRect.top ( );
	iDeltaMin = (int)( theRect.height ( ) / 2.0 ); 
	pObjectMin= pObject;
      }
      if ( iMax   < theRect.bottom ( ) ) {
	iMax      = theRect.bottom ( );
	iDeltaMax = (int)( theRect.height ( ) / 2.0 ); 
      }
    }
  }
  if ( ! pObjectMin )
    return;

  iMinStart = iMin + iDeltaMin;
  iCounter  = 1;
  listOfObjects.remove ( pObjectMin );
  iAvailableHeight = iMax-iDeltaMax - iMinStart;

  fDelta = (float)iAvailableHeight / ( theList.count ( ) - 1 );
  if (fDelta < 0.0 )
    return;

  while ( listOfObjects.count ( ) > 1 ) { // Note, the first and the last object should not move
    iCurrentMin = 5000;
    pObjectMin  = NULL;
    for ( t=0; t<(int)listOfObjects.count ( ); t++ ) {
      pObject = listOfObjects.at ( t );
      if ( ! pObject )
	continue;

      iMin = pObject->rect ( ).top ( ) + (int)( pObject->rect ( ).height ( ) / 2.0 );
      if ( iMin < iCurrentMin ) {
	iCurrentMin = iMin;
	pObjectMin  = pObject;
      }	 
    }
    if ( pObjectMin ) {
      listOfObjects.remove ( pObjectMin );
      iHeight = pObjectMin->rect ( ).height ( );
      pObjectMin->rect ( ).setTop    ( iMinStart + (int)( fDelta * iCounter++ ) - (int)( iHeight / 2.0 ) );
      pObjectMin->rect ( ).setHeight ( iHeight );
    }
  }

  refresh ( true );
}

void DialogAlign::alignHorizontalSpace ( QPtrList<MenuObject> &theList )
{
  float fDelta;
  QRect theRect;
  MenuObject *pObject,*pObjectMin = NULL;
  int iAvailableWidth, iMin, iMax;
  int t, iWidth, iStart, iCurrentMin;
  QPtrList<MenuObject> listOfObjects = theList;

  iMax = -5000;
  iMin = +5000;
  iAvailableWidth = 0;
  for ( t=0; t<(int)theList.count ( ); t++ ) {
    pObject = theList.at ( t );
    if ( pObject ) {
      theRect = pObject->rect ( );
      iAvailableWidth += theRect.width ( );
      if ( iMin > theRect.left  ( ) ) {
	   iMin = theRect.left  ( );
	   pObjectMin= pObject;
      }
      if ( iMax < theRect.right ( ) )
	   iMax = theRect.right ( );
    }
  }
  if ( ! pObjectMin )
    return;

  listOfObjects.remove ( pObjectMin );
  iStart = pObjectMin->rect ( ).right ( );
  fDelta = (float)( iMax - iMin - iAvailableWidth ) / ( theList.count ( ) - 1 );
  if ( fDelta < 0.0 )
    return;

  while ( listOfObjects.count ( ) > 1 ) { // Note, the first and the last object should not move
    iCurrentMin = 5000;
    for ( t=0; t<(int)listOfObjects.count ( ); t++ ) {
      pObject = listOfObjects.at ( t );
      if ( ! pObject )
	continue;

      iMin = pObject->rect ( ).left ( ) + (int)( pObject->rect ( ).width ( ) / 2.0 );
      if ( iMin < iCurrentMin ) {
	iCurrentMin = iMin;
	pObjectMin  = pObject;
      }
    }
    if ( pObjectMin ) {
      listOfObjects.remove ( pObjectMin );
      iWidth = pObjectMin->rect ( ).width  ( );
      pObjectMin->rect ( ).setLeft  ( iStart + (int)fDelta );
      pObjectMin->rect ( ).setWidth ( iWidth );
      iStart = pObjectMin->rect ( ).right  ( );
    }
  }

  refresh ( true );
}

void DialogAlign::alignVerticalSpace ( QPtrList<MenuObject> &theList )
{
  float fDelta;
  QRect theRect;
  MenuObject *pObject,*pObjectMin = NULL;
  int iAvailableHeight, iMin, iMax;
  int t, iHeight, iStart, iCurrentMin;
  QPtrList<MenuObject> listOfObjects = theList;

  iMax = -5000;
  iMin = +5000;
  iAvailableHeight = 0;
  for ( t=0; t<(int)theList.count ( ); t++ ) {
    pObject = theList.at ( t );
    if ( pObject ) {
      theRect = pObject->rect ( );
      iAvailableHeight += theRect.height ( );
      if ( iMin > theRect.top  ( ) ) {
	   iMin = theRect.top  ( );
	   pObjectMin= pObject;
      }
      if ( iMax < theRect.bottom ( ) )
	   iMax = theRect.bottom ( );
    }
  }
  if ( ! pObjectMin )
    return;

  listOfObjects.remove ( pObjectMin );
  iStart = pObjectMin->rect ( ).bottom ( );
  fDelta = (float)( iMax - iMin - iAvailableHeight ) / ( theList.count ( ) - 1 );
  if ( fDelta < 0.0 )
    return;

  while ( listOfObjects.count ( ) > 1 ) { // Note, the first and the last object should not move
    iCurrentMin = 5000;
    for ( t=0; t<(int)listOfObjects.count ( ); t++ ) {
      pObject = listOfObjects.at ( t );
      if ( ! pObject )
	continue;

      iMin = pObject->rect ( ).top ( ) + (int)( pObject->rect ( ).height ( ) / 2.0 );
      if ( iMin < iCurrentMin ) {
	iCurrentMin = iMin;
	pObjectMin  = pObject;
      }
    }
    if ( pObjectMin ) {
      listOfObjects.remove ( pObjectMin );
      iHeight = pObjectMin->rect ( ).height ( );
      pObjectMin->rect ( ).setTop    ( iStart + (int)fDelta );
      pObjectMin->rect ( ).setHeight ( iHeight );
      iStart = pObjectMin->rect ( ).bottom  ( );
    }
  }

  refresh ( true );
}

void DialogAlign::slotRefresh ( const QString & )
{
  // called from m_pEditWidth + m_pEditHeight
  slotRefresh ( true );
}

void DialogAlign::slotRefresh ( bool )
{
  // called from the check boxes
  if ( m_iTimerObjectSizeID != -1 )
    killTimer ( m_iTimerObjectSizeID );
  m_iTimerObjectSizeID = startTimer ( 500 );
}

void DialogAlign::slotRefresh ( )
{
  // called from the check boxes
  // if none of those two are active, then simply return.
  if ( ! m_pCheckWidth->isChecked ( ) && ! m_pCheckHeight->isChecked ( ) )
    return;
  
  bool  bOk;
  QRect theRect, newRect;
  int   t, iWidth, iHeight;
  MenuObject *pObject, *pOrigObject;
  ImageObject tempImage;
  MovieObject tempMovie;

  iWidth = m_pEditWidth->text ( ).toInt ( &bOk );
  if ( !bOk || ! m_pCheckWidth->isChecked  ( ) )
    iWidth = -1;

  iHeight = m_pEditHeight->text ( ).toInt  ( &bOk );
  if ( !bOk || ! m_pCheckHeight->isChecked ( ) )
    iHeight = -1;

  if ( ( iWidth < 1 ) && ( iHeight < 1 ) )
    return;

  for ( t=0; t<(int)m_listOfObjects.count ( ); t++ ) {
    pObject     = m_listOfObjects.at ( t );
    pOrigObject = m_pSelectionObject->getObject ( t );
    if ( ! pObject || ! pOrigObject )
      continue;

    theRect = pOrigObject->rect ( );
    if ( iWidth  > 0 )
      theRect.setWidth  ( iWidth  );
    if ( iHeight > 0 )
      theRect.setHeight ( iHeight );

    newRect = QRect ( (int)( m_fZoom * theRect.left   ( ) ),
		      (int)( m_fZoom * theRect.top    ( ) ),
		      (int)( m_fZoom * theRect.width  ( ) ),
		      (int)( m_fZoom * theRect.height ( ) ) );
    pObject->setRect ( newRect );
    resetZoom ( pObject );
    if ( ( pObject->objectType ( ) == tempImage.objectType ( ) ) ||
	 ( pObject->objectType ( ) == tempMovie.objectType ( ) )  ) {
      ImageObject *pImage = (ImageObject *)pObject;
      pImage->updatePixmap ( );
    }
    pObject->updateShadow  ( );
  }

  refresh ( true );
}

void DialogAlign::refreshBackgroundPixmap ( )
{
  // This function will use m_backgroundImage and re-create 
  // the scaled m_backgroundPixmap.
  int t;
  MenuObject *pObject;
  QRect  theRect, newRect;
  QImage backgroundImage;
  ImageObject tempImage;
  MovieObject tempMovie;
  TextObject  tempText;
  backgroundImage = m_backgroundImage.smoothScale ( m_pFramePreview->size ( ), QImage::ScaleMin);
  m_backgroundPixmap.convertFromImage ( backgroundImage );

  double fOldZoom = m_fZoom;
  m_fZoom = (double)m_backgroundPixmap.width ( ) / m_backgroundImage.width ( );

  // Now the selection object and the list of tempobjects should
  // always stay in synch, thus we can set the rects here ...
  for ( t=0; t<(int)m_listOfObjects.count ( ); t++ ) {
    pObject = m_pSelectionObject->getObject ( t );
    if ( ! pObject )
      continue;
    theRect = pObject->rect ( );
    newRect = QRect ( (int)( m_fZoom * theRect.left   ( ) ), 
		      (int)( m_fZoom * theRect.top    ( ) ), 
		      (int)( m_fZoom * theRect.width  ( ) ), 
		      (int)( m_fZoom * theRect.height ( ) ) );

    pObject = m_listOfObjects.at ( t );
    if ( ! pObject )
      continue;
    pObject->setRect ( newRect );
    pObject->updateShadow ( );

    if ( ( pObject->objectType ( ) == tempImage.objectType ( ) ) ||
         ( pObject->objectType ( ) == tempMovie.objectType ( ) )  ) {
      ImageObject *pImage = (ImageObject *)pObject;
      pImage->updatePixmap ( );
    }
    else if ( pObject->objectType ( ) == tempText.objectType ( ) )  {
      pObject->modifiers ( )->fScaleX *= m_fZoom / fOldZoom;
      pObject->modifiers ( )->fScaleY *= m_fZoom / fOldZoom;
    }
  }

  if ( m_pPreview )
       m_pPreview->setFixedSize ( m_backgroundPixmap.size ( ) );
}

void DialogAlign::resizeEvent ( QResizeEvent *pEvent )
{
  QDialog::resizeEvent ( pEvent );

  if ( m_iTimerID != -1 )
    killTimer ( m_iTimerID );
  m_iTimerID = startTimer ( 200 );
}

void DialogAlign::timerEvent ( QTimerEvent *pTimerEvent ) 
{
  //  printf ( "timerID<%d> vs <%d>",  pTimerEvent->timerId (), m_iTimerID );
  if ( pTimerEvent->timerId () == m_iTimerID ) {
    killTimer ( m_iTimerID );
    m_iTimerID = -1;
    refreshBackgroundPixmap ( );
    refresh ( true );
  }
  else if ( pTimerEvent->timerId () == m_iTimerObjectSizeID ) {
    killTimer ( m_iTimerObjectSizeID );
    m_iTimerObjectSizeID = -1;
    slotRefresh ( );
  }
  else 
    QDialog::timerEvent ( pTimerEvent );
}

void DialogAlign::resetObjectPos ( )
{
  uint t;
  QRect theRect, newRect;
  MenuObject *pObject, *pOrigObject;
  //double m_fZoom = (double)m_backgroundPixmap.width ( ) / m_backgroundImage.width ( );
  for ( t=0; t<m_listOfObjects.count ( ); t++ ) {
    pObject     = m_listOfObjects.at ( t );
    pOrigObject = m_pSelectionObject->getObject ( t );
    if ( pObject && pOrigObject ) {
      theRect = pOrigObject->rect ( );
      newRect = QRect ( (int)( m_fZoom * theRect.left   ( ) ), 
			(int)( m_fZoom * theRect.top    ( ) ), 
			(int)( m_fZoom * theRect.width  ( ) ), 
			(int)( m_fZoom * theRect.height ( ) ) );
      pObject->setRect( newRect );
    }
  }
}

void DialogAlign::refresh ( bool bRefresh )
{
  bool bEnable = false;
  if ( m_pCheckWidth->isChecked ( ) )
    bEnable = true;
  m_pEditWidth->setEnabled ( bEnable );

  bEnable = false;
  if ( m_pCheckHeight->isChecked ( ) )
    bEnable = true;
  m_pEditHeight->setEnabled ( bEnable );

  if ( m_pPreview ) {
    uint t;
    MenuObject *pObject;
    QPixmap thePixmap = m_backgroundPixmap;
    QPainter thePainter ( &thePixmap );
    drawLine ( &thePainter );

    for ( t=0; t<m_listOfObjects.count ( ); t++ ) {
      pObject = m_listOfObjects.at ( t );
      if ( pObject )
           pObject->drawContents ( &thePainter );
    }
    m_pPreview->setPaletteBackgroundPixmap ( thePixmap );
  }
  if ( m_pPreview && bRefresh )
       m_pPreview->repaint ( true );

}

void DialogAlign::drawLine ( QPainter *pPainter )
{
  int iSelection, iAlign, iPreviewWidth, iPreviewHeight;
  bool bOk;

  iSelection = m_pComboAlign->currentItem ( );
  iAlign     = m_pEditAlign->text ( ).toInt ( &bOk );

  // check if selection is None.
  if ( ( iSelection == 0 ) || ( ! bOk ) )
    return;

  pPainter->setPen ( QColor ( 220, 20, 20 ) );
  iPreviewHeight = m_pPreview->height ( );
  iPreviewWidth  = m_pPreview->width  ( );
  // the next check is for Horizontally
  if ( iSelection == 1 ) {
    double fHeight = (double)iPreviewHeight / m_backgroundImage.height ( );
    pPainter->drawLine ( 0, (int)(fHeight * iAlign), iPreviewWidth, (int)(fHeight * iAlign) );
  }
  else if ( iSelection == 2 ) {
    double fWidth = (double)iPreviewWidth / m_backgroundImage.width ( );
    pPainter->drawLine ( (int)(fWidth * iAlign), 0, (int)(fWidth * iAlign), iPreviewWidth );
  }
}

void DialogAlign::accept ( )
{
  MenuObject *pObject;
  QString qsWidth, qsHeight, qsTop, qsLeft;
  int     t, iWidth, iHeight, iTop, iLeft, iOffset;
  int     iCurrentWidth, iCurrentHeight, iPosition;
  bool    bOk, bWidthHeight=false;
  QRect   theRect;

  iWidth = iHeight = iTop = iLeft = -1;

  if ( m_pCheckWidth->isChecked  ( ) ) {
    qsWidth = m_pEditWidth->text ( );
    iWidth  = qsWidth.toInt ( &bOk );
    bWidthHeight = bOk;
    if ( ! bOk )
      iWidth = -1;
  }
  if ( m_pCheckHeight->isChecked   ( ) ) {
    qsHeight = m_pEditHeight->text ( );
    iHeight  = qsHeight.toInt ( &bOk );
    if ( ! bWidthHeight )
      bWidthHeight = bOk;
    if ( ! bOk )
      iHeight = -1;
  }
  if ( m_pComboAlign->currentItem ( ) == 1 ) {
    qsTop = m_pEditAlign->text ( );
    iTop  = qsTop.toInt ( &bOk );
    if ( ! bOk )
      iTop = -1;
  }
  else if ( m_pComboAlign->currentItem ( ) == 2 ) {
    qsLeft = m_pEditAlign->text ( );
    iLeft  = qsLeft.toInt ( &bOk );
    if ( ! bOk )
      iLeft = -1;
  }

  iPosition = m_pComboAlignPos->currentItem ( );

  // And finally we set the new rect for the objects ...
  for ( t=0; t<m_pSelectionObject->getCount  ( ); t++ ) {
    pObject  = m_pSelectionObject->getObject( t );
    if ( pObject ) {
      theRect = pObject->rect ( );
      iCurrentWidth  = theRect.width  ( );
      iCurrentHeight = theRect.height ( );
      if ( iWidth  > -1 )
	iCurrentWidth  = iWidth;
      if ( iHeight > -1 )
	iCurrentHeight = iHeight;

      if ( iTop > -1 ) {
	iOffset  = (int)( (float)iCurrentHeight * ( pObject->modifiers ( )->fScaleY - 1.0 ) / 2.0 );
	iOffset -= (int)( (float)iPosition * ( (float)iCurrentHeight / 2.0 + (float)iOffset ) );
	theRect.setTop  ( iTop + iOffset );
	//	theRect.setTop  ( iTop  - (int)( (float)iPosition * iCurrentHeight / 2.0 ) );
      }
      if ( iLeft > -1 ) {
	iOffset  = (int)( (float)iCurrentWidth * ( pObject->modifiers ( )->fScaleX - 1.0 ) / 2.0 );
	iOffset -= (int)( (float)iPosition * ( (float)iCurrentWidth / 2.0 + (float)iOffset ) );
	theRect.setLeft ( iLeft + iOffset );
	//	theRect.setLeft ( iLeft - (int)( (float)iPosition * iCurrentWidth  / 2.0 ) );
      }
      theRect.setWidth  ( iCurrentWidth  );
      theRect.setHeight ( iCurrentHeight );
      pObject->setRect  ( theRect );
      // we also reset the zoom / scale if the width / height has been set.
      if ( bWidthHeight )
	resetZoom ( pObject );
    }
  }

  // The second step is to align the distance between the objects ...
  QPtrList<MenuObject> listOfObjects;
  for ( t=0; t<m_pSelectionObject->getCount ( ); t++ ) {
    pObject  = m_pSelectionObject->getObject( t );
    if ( pObject )
      listOfObjects.append ( pObject );
  }

  alignDistance ( listOfObjects );

  // finally re-draw all objects to fit current pos/size
  for ( t=0; t<m_pSelectionObject->getCount  ( ); t++ ) {
    pObject  = m_pSelectionObject->getObject( t );
	if ( pObject )  {
         pObject->updateShadow ( );
         pObject->mouseReleaseEvent ( NULL );
	}
  }

  QDialog::accept ( );
}

void DialogAlign::resetZoom ( MenuObject *pObject )
{
  if ( ! pObject )
    return;
  // use for m_listOfObjects and m_selectionObject calls
  uint t;
  MovieObject  tempMovie;
  ImageObject  tempImage;
  ButtonObject tempButton;

  //printf ( "%s::%s::%d <%s>\n", __FILE__, __FUNCTION__, __LINE__, pObject->objectType ( ).ascii ( ) );
  pObject->modifiers ( )->fZoom = 1.0;
  pObject->modifiers ( )->fScaleX = 1.0;
  pObject->modifiers ( )->fScaleY = 1.0;
  if ( ( pObject->objectType ( ) == tempImage.objectType ( ) ) ||
       ( pObject->objectType ( ) == tempMovie.objectType ( ) )  ) {
    ImageObject *pImage = (ImageObject *)pObject;
    //printf ( "%s::%s::%d <%s>\n", __FILE__, __FUNCTION__, __LINE__, pObject->objectType ( ).ascii ( ) );
    pImage->manipulator  ( ).fScaleX = 1.0;
    pImage->manipulator  ( ).fScaleY = 1.0;
    //	  pImage->updatePixmap ( );
  }
  else if ( pObject->objectType () == tempButton.objectType ( ) ) {
    ButtonObject *pButton = (ButtonObject *)pObject;
    for ( t=0; t<pButton->getNormalCount ( ); t++ )
      resetZoom ( pButton->getNormal ( (int)t ) );
    for ( t=0; t<pButton->getSelectedCount ( ); t++ )
      resetZoom ( pButton->getSelected ( (int)t ) );
    for ( t=0; t<pButton->getHighlightedCount ( ); t++ )
      resetZoom ( pButton->getHighlighted ( (int)t ) );
  }
}


