/*****************************************************************************
 ** Class SubtitlesGui
 **
 ** This is a sub-project to 'Q' DVD-Author to handle the subtitles - tab
 ** of the main application
 **
 **   Created : 
 **        by : Varol Okan
 ** Copyright : (c) Varol Okan
 **   License : GPL v 2.0
 **
 *****************************************************************************/

#include <qframe.h>
#include <qslider.h>
#include <qpainter.h>
#include <qlistbox.h>
#include <qtextedit.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qcolordialog.h>
#include <qfontdatabase.h>


#include "dialogfont.h"

DialogFont::DialogFont ( QWidget *p, const char * n, WFlags f )
  : uiDialogFont ( p, n, f )
{
}

DialogFont::~DialogFont ( )
{

}

void DialogFont::initMe ( QString qsText )
{
  m_iBackgroundTransparency = 255; // background is transparent
  m_iForegroundTransparency =   0; // foreground is opaque
 
  m_pEditTransparency->setText   ( "0.00" );
  m_pEditBGTransparency->setText ( "1.00" );

  // Next we init the font selection...
  QFontDatabase database;
  //  setTransparency (0.0);
  QStringList listFonts = database.families ( );
  m_pListFonts->insertStringList  ( listFonts );
  // Next we search for a good starting font ...
  uint t, iIndex;
  QString fontName;
  for (iIndex=0;iIndex<m_pListFonts->count();iIndex++)	{
    fontName = m_pListFonts->text(iIndex);
    if (fontName == QString ("Arial"))
      break;
    else if (fontName == QString ("Courier"))
      break;
    else if (fontName == QString ("Times New Roman"))
      break;
    else if (fontName == QString ("Times"))
      break;
    else if (fontName == QString ("Nimbus Sans L"))
      break;
    else if (fontName == QString ("Sans Serif"))
      break;
  }
  if ( iIndex < listFonts.count ( ) )
    fontName = m_pListFonts->text(iIndex);
  else
    fontName = m_pListFonts->text( 0 );

  QStringList listStyles = database.styles    ( fontName );
  m_pComboFontStyle->insertStringList         ( listStyles );
  QString styleName = m_pComboFontStyle->text ( 0 );
  m_pComboFontStyle->setCurrentItem           ( 0 );

  // Here we get the sizes of the font.
  QValueList<int> listSizes = database.pointSizes(fontName);
  if (listSizes.isEmpty())	{
    listSizes = database.smoothSizes(fontName, styleName);
    if (listSizes.isEmpty())	{
      listSizes = database.standardSizes();
    }
  }
  // So lets say we can set the fontFamily at least ...
  m_pListFonts->setCurrentItem(iIndex);
  // And here we take care of the FontSize ...
  iIndex = 0;
  for (t=0;t<listSizes.count();t++)	{
    m_pComboFontSizes->insertItem (QString ("%1").arg(listSizes[t]));
    if (listSizes[t] < 19)	// Lets get at least a nice big raedable size
      iIndex = t;
  }
  m_pComboFontSizes->setCurrentItem (iIndex);

  QPainter thePainter ( m_pFrameBackgroundColor );
  thePainter.drawLine ( 0, 0, m_pFrameBackgroundColor->width ( ), m_pFrameFontColor->height ( ) );
  
  m_pTextEdit->setTextFormat ( PlainText );
  m_pTextEdit->setAlignment  ( Qt::AlignHCenter | Qt::AlignVCenter );
  m_pTextEdit->setText       ( qsText );
  
  // Finally we set up the callback routines ...
  connect ( m_pListFonts,             SIGNAL ( highlighted (int)), this, SLOT ( slotFontFamilyChanged(int) ) );
  connect ( m_pComboFontStyle,        SIGNAL ( activated   (int)), this, SLOT ( slotFontStyleChanged (int) ) );
  connect ( m_pComboFontSizes,        SIGNAL ( activated   (int)), this, SLOT ( slotFontSizeChanged  (int) ) );
  connect ( m_pButtonBackgroundColor, SIGNAL ( clicked ( ) ),   this, SLOT ( slotBackgroundColor  (      ) ) );
  connect ( m_pButtonFontColor,       SIGNAL ( clicked ( ) ),   this, SLOT ( slotFontColor        (      ) ) );
  connect ( m_pCheckStrikethrough,    SIGNAL ( toggled (bool) ),this, SLOT ( slotStrikethrough    ( bool ) ) );
  connect ( m_pCheckUnderline,        SIGNAL ( toggled (bool) ),this, SLOT ( slotUnderline        ( bool ) ) );
  connect ( m_pSliderTransparency,    SIGNAL ( sliderMoved ( int ) ), this, SLOT ( slotTransparencyChanged  ( int ) ) );
  connect ( m_pSliderBGTransparency,  SIGNAL ( sliderMoved ( int ) ), this, SLOT ( slotBGTransparencyChanged( int ) ) );
}

///////////////////////////////////////////////////////////
//
// signal/slot handler
//
//////////////////////////////////////////////////////////
void DialogFont::slotFontFamilyChanged ( int )
{
  updateFont ( 0 );
}

void DialogFont::slotFontStyleChanged ( int )
{
  updateFont ( 1 );
}

void DialogFont::slotFontSizeChanged ( int )
{
  updateFont ( 2 );
}

void DialogFont::slotBackgroundColor ( )
{
  bool bOkay;
  QRgb rgba = m_backgroundColor.rgb ( );
  QString qsBGTransparency;
  float    fBGTransparency = m_pEditBGTransparency->text ( ).toFloat ( );
  m_iBackgroundTransparency = (unsigned char) ( fBGTransparency * 0xFF );

  rgba = ( rgba & 0x00FFFFFF ) | ( m_iBackgroundTransparency << 24 );
  rgba  = QColorDialog::getRgba ( rgba, &bOkay, this );
  if ( ! bOkay )
    return;

  m_iBackgroundTransparency = ( rgba & 0xFF000000 ) >> 24;
  fBGTransparency = (float)m_iBackgroundTransparency / 0xFF;
  // Set Slider, Color, and Text widgets.
  qsBGTransparency.sprintf ( "%0.2f",  fBGTransparency );
  m_pEditBGTransparency->setText    ( qsBGTransparency );
  m_pSliderBGTransparency->setValue ( m_iBackgroundTransparency );

  QColor newColor ( rgba ); 
  setBackgroundColor ( newColor );
}

void DialogFont::slotFontColor ( )
{
  bool    bOkay;
  QRgb    rgba = m_foregroundColor.rgb ( );
  QString qsTransparency;
  float    fTransparency   = m_pEditTransparency->text   ( ).toFloat ( );
  m_iForegroundTransparency = (unsigned char)( fTransparency * 0xFF );

  rgba  = ( rgba & 0x00FFFFFF ) | ( m_iForegroundTransparency << 24 );
  rgba  = QColorDialog::getRgba ( rgba, &bOkay, this );
  if ( ! bOkay )
    return;
  // Extract the transparency information ...
  m_iForegroundTransparency = ( rgba & 0xFF000000 ) >> 24;
  fTransparency = (float)m_iForegroundTransparency / 0xFF;
  // Set Slider, Color, and Text widgets.
  qsTransparency.sprintf ( "%0.2f",  fTransparency );
  m_pEditTransparency->setText    ( qsTransparency );
  m_pSliderTransparency->setValue ( m_iForegroundTransparency );

  QColor newColor ( rgba ); 
  setForegroundColor ( newColor );
}

void DialogFont::slotStrikethrough ( bool )
{
  updateFont ( 2 );
}

void DialogFont::slotUnderline ( bool )
{
  updateFont ( 2 );
}

void DialogFont::slotTransparencyChanged ( int iValue )
{
  float fValue = (float)iValue / 255.0;
  QString qsValue;
  qsValue.sprintf ( "%0.2f", fValue );
  m_pEditTransparency->setText ( qsValue );
}

void DialogFont::slotBGTransparencyChanged ( int iValue )
{
  float fValue = (float)iValue / 255.0;
  QString qsValue;
  qsValue.sprintf ( "%0.2f", fValue );
  m_pEditBGTransparency->setText ( qsValue );
}

void DialogFont::updateFont(uint iSwitch)
{
  uint t;
  int iIndex;
  // First see what styles are avail ...
  QFontDatabase database;
  QString fontName  = m_pListFonts->text(m_pListFonts->currentItem());
  QString styleName = m_pComboFontStyle->text(m_pComboFontStyle->currentItem());
  int iFontSize     = m_pComboFontSizes->text(m_pComboFontSizes->currentItem()).toInt();

  //  QSize size = m_pTextEdit->size ( );
  //  m_pTextEdit->setFixedSize ( size );

  switch (iSwitch)	{
  case 0:	{
    // The fontName has changed, so we need to get the styles avail for this new font.
    QStringList listStyles = database.styles ( fontName );
    m_pComboFontStyle->clear();
    m_pComboFontStyle->insertStringList ( listStyles );
    iIndex = findString ( listStyles, styleName );
    if (iIndex == -1)
      iIndex = 0;
    styleName = m_pComboFontStyle->text(iIndex);
    m_pComboFontStyle->setCurrentItem(iIndex);
  }
  case 1:
    // The style has changed
    m_pComboFontSizes->clear ( );
    QValueList<int> listSizes = database.pointSizes ( fontName );
    if ( listSizes.isEmpty ( ) )	{
      listSizes = database.smoothSizes ( fontName, styleName );
      if ( listSizes.isEmpty ( ) )	{
	listSizes = database.standardSizes ( );
      }
    }
    iIndex = 0;
    for (t=0;t<listSizes.count();t++)	{
      m_pComboFontSizes->insertItem ( QString ("%1").arg ( listSizes[t] ) );
      if ( listSizes[t] == iFontSize )
	iIndex = t;
    }
    m_pComboFontSizes->setCurrentItem ( iIndex );
  }

  QString qsText = m_pTextEdit->text ( );
  m_pTextEdit->setText ( qsText );
  // and last we update the TextEdit accordingly
  m_pTextEdit->setFont ( getFont ( ) );
}

int DialogFont::findString (QStringList &list, QString string)
{
  for (uint t=0;t<list.count();t++) {
    if (list[t] == string)
      return t;
  }
  return -1;
}

void DialogFont::setTheFont ( QFont &theFont )
{
  m_qfFont = theFont;
  // Here we set the fields ...
  // Underline / strikeout / pointSize / fontFamily / script / fontStyle
  int t, iIndex;
  for ( iIndex=0; iIndex<(int)m_pListFonts->count ( ); iIndex++ )	{
    if ( m_pListFonts->text ( iIndex ) == theFont.family ( ) )	{
      m_pListFonts->setCurrentItem ( iIndex );
      break;
    }
  }
  updateFont ( 0 );
  // Next we try to set the style of the font.
  iIndex = 0;
  QFontDatabase database;
  QString qsStyle = database.styleString ( theFont );
  for ( t=0; t<m_pComboFontStyle->count ( ); t++ )	{
    if ( m_pComboFontStyle->text ( t ) == qsStyle )	{
      iIndex = t;
      break;
    }
  }
  m_pComboFontStyle->setCurrentItem ( iIndex );
  updateFont ( 1 );
  // Here we get the font size which comes closest to the newFont pointSize (or the same).
  int iAvailFontSize, iFontSize = theFont.pointSize ( );
  for ( iIndex=0; iIndex<m_pComboFontSizes->count ( );iIndex++ )	{
    iAvailFontSize = m_pComboFontSizes->text ( iIndex ).toInt ( );
    if ( iAvailFontSize >= iFontSize )
      break;
  }
  m_pComboFontSizes->setCurrentItem(iIndex);
 
  if ( theFont.underline ( ) )
    m_pCheckUnderline->setChecked ( true );
  if ( theFont.strikeOut ( ) )
    m_pCheckStrikethrough->setChecked ( true );
 
  m_pTextEdit->setFont( theFont );
}

QFont &DialogFont::getFont ()
{
  QFontDatabase database;

  QString qsFamily = m_pListFonts->text ( m_pListFonts->currentItem ( ) );
  QString qsStyle  = m_pComboFontStyle->text(m_pComboFontStyle->currentItem ( ) );
  int iPointSize   = m_pComboFontSizes->text(m_pComboFontSizes->currentItem ( ) ).toInt ( );
  m_qfFont =  database.font( qsFamily, qsStyle, iPointSize );
  m_qfFont.setUnderline ( m_pCheckUnderline->isChecked ( ) );
  m_qfFont.setStrikeOut ( m_pCheckStrikethrough->isChecked ( ) );

  return m_qfFont;
}

void DialogFont::setBackgroundColor ( const QRgb rgb )
{
  QColor theColor ( rgb );
  m_iBackgroundTransparency       = ( rgb & 0xFF000000 ) >> 24;
  m_pSliderBGTransparency->setValue ( m_iBackgroundTransparency );
  slotBGTransparencyChanged         ( m_iBackgroundTransparency );
  setBackgroundColor                ( theColor );
}

void DialogFont::setForegroundColor ( const QRgb rgb )
{
  QColor theColor ( rgb );
  m_iForegroundTransparency     = ( rgb & 0xFF000000 ) >> 24;
  m_pSliderTransparency->setValue ( m_iForegroundTransparency );
  slotTransparencyChanged         ( m_iForegroundTransparency );
  setForegroundColor              ( theColor );
}

void DialogFont::setBackgroundColor  ( const QColor &newColor )
{
  // Check if the user pressed cancel ...
  if (!newColor.isValid())
    return;
  m_pFrameBackgroundColor->setPaletteBackgroundColor(newColor);
  m_pTextEdit->setPaletteBackgroundColor   (newColor);
  m_backgroundColor = newColor;
}

void DialogFont::setForegroundColor ( const QColor &newColor )
{
  // Check if the user pressed cancel ...
  if (!newColor.isValid())
    return;
  m_pFrameFontColor->setPaletteBackgroundColor(newColor);
  m_pTextEdit->setPaletteForegroundColor (newColor);
  m_foregroundColor = newColor;
}

QRgb DialogFont::backgroundColor ( )
{
  QRgb     rgba = 0x00000000;
  QColor   clrBackground      = m_pFrameBackgroundColor->paletteBackgroundColor ( );
  unsigned char iTransparency = m_pSliderBGTransparency->value ( );
  rgba  =  clrBackground.rgb ( ) & 0x00FFFFFF;
  rgba |=  iTransparency  <<  24;
  return rgba;
}

QRgb DialogFont::foregroundColor ( )
{
  QRgb     rgba = 0x00000000;
  QColor   clrBackground      = m_pFrameFontColor->paletteBackgroundColor ( );
  unsigned char iTransparency = m_pSliderTransparency->value ( );
  rgba  =  clrBackground.rgb ( ) & 0x00FFFFFF;
  rgba |=  iTransparency  <<  24;
  return rgba;
}

