
// This is the implementation of the SimpleDVD plugin for QDVDAuthor.

#include <qprogressdialog.h>
#include <qapplication.h>
#include <qpushbutton.h>
#include <qfileinfo.h>
#include <qimage.h>

#include "uisimpledvd.h"
#include "simpledvd.h"

// The class factories
extern "C"  Plugin::Interface *createPlugin ( ) {
    return new Plugin::SimpleDVD;
}
extern "C" void destroyPlugin ( Plugin::Interface *pDeleteMe ) {
    delete pDeleteMe;
}

#include "../../CONFIG.h"

#ifndef SYSTEM_DIRECTORY
#define SYSTEM_DIRECTORY "/usr"
#endif

namespace Plugin
{

SimpleDVD::SimpleDVD ( )
{
  m_iNrOfMenus   = 0;
  m_qsPluginName = "SimpleDVD" + QString ( " -%1-" ).arg ( getPluginVersion ( ), 0, 'f', 2 );
}

SimpleDVD::~SimpleDVD ( )
{

}

QWidget *SimpleDVD::getConfigWidget ( QWidget * )
{
  return NULL;
}

bool SimpleDVD::execute ( )
{
  int iButtonsPerMenu = 6;
  // Here we create the DVD Structure for the given input arameters
  QValueList<SourceGroup *>::iterator it = m_listOfGroups.begin ( );
  SourceGroup *pGroup = NULL;
  int iMenuNumber, iCount;
  iMenuNumber = iCount = 0;
  // First we should add the Groups ( SourceFIleEntries ...
  while ( it != m_listOfGroups.end ( ) )  {
    pGroup = *it++;
//    printf ( "Group #<%d>: <%s> from<%s> to<%s>\n", (int)pGroup->listFiles.count ( ), pGroup->qsGroupName.ascii ( ), pGroup->dateStart.toString ( ).ascii ( ), pGroup->dateEnd.toString ( ).ascii ( ) );

    emit ( signalNewSource ( pGroup ) ); // calls QDVDAuthor::slotNewSource ( Plugin::SourceGroup *pGroup )
  }

  // The next iteration we generate the DVDMenus.
  m_iNrOfMenus    = (int)( ( m_listOfGroups.count ( ) + iButtonsPerMenu - 1 ) / iButtonsPerMenu );
  int iProgress   = 0;
  int iSlideCount = 1;
  QProgressDialog progressDialog ( NULL );
  progressDialog.setTotalSteps   ( m_iNrOfMenus );
  progressDialog.resize          ( QSize(550, 80) ); //.expandedTo ( progressDialog.minimumSizeHint ( ) ) );
  progressDialog.show            (    );
  progressDialog.setProgress     ( iProgress++ );
  qApp->processEvents            ( 10 );

  QValueList<SourceGroup *> listGroups;
  it = m_listOfGroups.begin ( );
  while ( it != m_listOfGroups.end ( ) )  {
    pGroup = *it++;
    // Next we create the Menus required ...
    // The number of menus depends on the max number of buttons per menu ( m_iButtonsPerMenu )
    listGroups.append ( pGroup );
    if ( iCount++ >= iButtonsPerMenu - 1 )  {
      SourceGroup::type theType = pGroup->enType;
      QString qsMenuXML = getMenuXML ( listGroups, ++iMenuNumber, iSlideCount );
      listGroups.clear ( );

      QString qsMenuName = QString ( "Menu %1" ).arg ( iMenuNumber );
      progressDialog.setCaption ( tr ( "Creating [%1]" ).arg ( qsMenuName ) );

      // Create the DVDMenu
      //printf ( "%s\n\n\n", qsMenuXML.ascii ( ) );
      emit ( signalNewMenuResponse ( theType, qsMenuName, qsMenuXML ) );
      iCount = 0;
    }
    progressDialog.setProgress ( iProgress++ );
    qApp->processEvents        (     10 );
  }
  if ( iCount > 0 )  {
      SourceGroup::type theType = pGroup->enType;
      QString qsMenuName, qsMenuXML;
      qsMenuName.sprintf ( "Menu %d", ++iMenuNumber );
      qsMenuXML = getMenuXML ( listGroups, iMenuNumber, iSlideCount );
      listGroups.clear ( );

      // Create the DVDMenu
      //printf ( "%s\n\n\n", qsMenuXML.ascii ( ) );
      emit ( signalNewMenuResponse ( theType, qsMenuName, qsMenuXML ) );
  }

  return true;
}

QString SimpleDVD::getMenuXML ( QValueList<SourceGroup *> &list, int iMenuNumber, int &iSlideCount )
{
  QFileInfo fileInfo;
  QString qsMenuXML, qsBackgroundFile, qsMenuName, qsFileName, qsGroupName;
  QString qsHeight = "480";
  QString qsButtonName, qsFrameName, qsObjectName, qsJumpTo, qsX, qsY, qsW, qsH;
  int iX, iY, iCount = 0;
  SourceGroup *pGroup = NULL;
  if ( list.count ( ) < 1 )
    return qsMenuXML;

  qsBackgroundFile = SYSTEM_DIRECTORY"/share/qdvdauthor/plugins/simpledvd/background.jpg";
  qsMenuName.sprintf ( "Menu %d", iMenuNumber );
  pGroup = list[0];
  if ( pGroup->enType == SourceGroup::PAL )
    qsHeight = "576";

  qsMenuXML += " <DVDMenu MenuWidth=\"720\" MenuHeight=\""+qsHeight+"\" MenuFormat=\"0\" MenuRatio=\"4:3\" >\n";
  qsMenuXML += "  <MenuVariables>\n";
  qsMenuXML += "   <MenuOffset>00:00:00.000</MenuOffset>\n";
  qsMenuXML += "    <MenuDuration>00:00:01.000</MenuDuration>\n";
  qsMenuXML += "   <MenuBackground ResizeAlgo=\"Normal Qt\" OffsetX=\"0\" OffsetY=\"0\" StretchType=\"2\" >"+qsBackgroundFile+"</MenuBackground>\n";
  qsMenuXML += "   <MenuName>"+qsMenuName+"</MenuName>\n";
  qsMenuXML += "   <MaskColors>#00fefffe,#a0ff1414,#a0fa9632,#ff0f0fff,</MaskColors>\n";
  qsMenuXML += "  </MenuVariables>\n";
  qsMenuXML += "  <PreviewVariables>\n";

  // Semi-transparent area - Top
  qsMenuXML += "   <TextObject BackgroundColor=\"#ffaaff5a\" TextAlign=\"4,64\" ForegroundColor=\"#fff15735\" Font=\"Sans Serif,20,-1,5,75,0,0,0,0,0\" Text=\"\" >\n";
  qsMenuXML += "    <MenuObject Width=\"740\" X=\"0\" Y=\"35\" Height=\"150\" ObjectName=\"\" >\n";
  qsMenuXML += "     <Modifiers Transparency=\"0.60\" />\n";
  qsMenuXML += "    </MenuObject>\n";
  qsMenuXML += "   </TextObject>\n";

  // Semi-transparent area - Bottom
  qsMenuXML += "   <TextObject BackgroundColor=\"#fff4f5f4\" TextAlign=\"4,64\" ForegroundColor=\"#ff000000\" Font=\"Courier,12,-1,5,50,0,0,0,0,0\" Text=\"\" >\n";
  qsMenuXML += "    <MenuObject Width=\"740\" X=\"-8\" Y=\"285\" Height=\"150\" ObjectName=\"\" >\n";
  qsMenuXML += "     <Modifiers Transparency=\"0.60\" />\n";
  qsMenuXML += "    </MenuObject>\n";
  qsMenuXML += "   </TextObject>\n";

  // Next we take care of the Buttons ...
  QValueList<SourceGroup *>::iterator it;
  it = list.begin ( );
  while ( it != list.end ( ) )  {
    pGroup = *it++;

    if ( ! pGroup )
       continue;

    qsGroupName = pGroup->qsGroupName;
    qsFileName  = "";
    if ( pGroup->bSlideshow )  {
      qsGroupName.sprintf ( "[%02d] - %s", iSlideCount++, (const char *)pGroup->qsGroupName.utf8 ( ) );
      qsFileName  = pGroup->qsGroupName + ".vob+-+00:00:00.000";
    }
    else if ( pGroup->listFiles.size ( ) > 0 )  {
      fileInfo.setFile ( pGroup->listFiles[0]->qsFileName );
      qsFileName = fileInfo.fileName ( );
      if ( qsFileName.length ( ) > 0 )
        qsFileName += "+-+00:00:00.000";
    }

    // jump+-+[01] - cordes.mpg+-+001_capture001.mpeg+-+00:00:00.000
    qsJumpTo = QString ( "jump+-+%1+-+%2" ).arg ( qsGroupName ).arg ( qsFileName );
    qsButtonName  = QString ( "Button %1" ).arg ( ++iCount );
    qsObjectName  = QString ( "Object_%1" ).arg (   iCount );
    qsFrameName   = QString ( "Frame %1"  ).arg (   iCount );
    iX = ( iCount-1 )%3 * 210 + 90;
    iY = ( iCount > 3 ) ? 400 : 150;
    qsX = QString ( "%1" ).arg ( iX );
    qsY = QString ( "%1" ).arg ( iY );

    // First we create the assiciated TextObject
    qsMenuXML += "   <TextObject TextAlign=\"4,64\" ForegroundColor=\"#fff15735\" Font=\"Sans Serif,16,-1,5,75,0,0,0,0,0\" Text=\""+pGroup->qsGroupName+"\" >\n";
    qsMenuXML += "    <MenuObject Width=\"150\" X=\""+qsX+"\" Y=\""+qsY+"\" Height=\"41\" ObjectName=\""+pGroup->qsGroupName+"\" />\n";
    qsMenuXML += "   </TextObject>\n";

    iY = ( iCount > 3 ) ? 295 : 45;

    QRect r = scaleScreenshot ( pGroup->qsScreenshot, 150, 115 );

    qsX = QString ( "%1" ).arg ( iX + r.left ( ) );
    qsY = QString ( "%1" ).arg ( iY + r.top  ( ) );
    qsW = QString ( "%1" ).arg ( r.width  ( ) );
    qsH = QString ( "%1" ).arg ( r.height ( ) );
    // Next we create the ButtonObject for the video jump+-+vmgm+-+
    qsMenuXML += "   <ButtonObject Action=\""+qsJumpTo+"\" ButtonName=\""+qsButtonName+"\"  SourceEntry=\""+qsGroupName+"\" >\n";
    qsMenuXML += "    <NormalState>\n";
    qsMenuXML += "     <ImageObject FileName=\""+pGroup->qsScreenshot+"\" >\n";
    qsMenuXML += "      <Manipulator>\n";
    qsMenuXML += "       <Modifiers/>\n";
    qsMenuXML += "      </Manipulator>\n";
    qsMenuXML += "      <MenuObject Width=\""+qsW+"\" X=\""+qsX+"\" Y=\""+qsY+"\" Height=\""+qsH+"\" ObjectName=\""+qsObjectName+"\" ObjectExtractionPath=\""+qsObjectName+"\" />\n";
    qsMenuXML += "     </ImageObject>\n";
    qsMenuXML += "    </NormalState>\n";

    qsMenuXML += "    <SelectedState>\n";
    qsMenuXML += "     <FrameObject Width=\"10\" Color=\"#a0ff1414\" >\n";
    qsMenuXML += "      <MenuObject Width=\""+qsW+"\" X=\""+qsX+"\" Y=\""+qsY+"\" Height=\""+qsH+"\" ObjectName=\""+qsFrameName+"\" />\n";
    qsMenuXML += "     </FrameObject>\n";
    qsMenuXML += "    </SelectedState>\n";
    qsMenuXML += "    <HighlightedState>\n";
    qsMenuXML += "     <FrameObject Width=\"10\" Color=\"#ff0f0fff\" >\n";
    qsMenuXML += "      <MenuObject Width=\""+qsW+"\" X=\""+qsX+"\" Y=\""+qsY+"\" Height=\""+qsH+"\" ObjectName=\""+qsFrameName+"\" />\n";
    qsMenuXML += "     </FrameObject>\n";
    qsMenuXML += "    </HighlightedState>\n";
    qsMenuXML += "    <MenuObject Width=\""+qsW+"\" X=\""+qsX+"\" Y=\""+qsY+"\" Height=\""+qsH+"\" ObjectName=\""+qsButtonName+"\" />\n";
    qsMenuXML += "   </ButtonObject>\n";
  }
  // Create prev/next buttons
  bool bPrev = ( iMenuNumber > 1 );
  bool bNext = ( iMenuNumber < m_iNrOfMenus );
  qsMenuXML += getMenuButtons ( bPrev, bNext, iMenuNumber );

  qsMenuXML += "  </PreviewVariables>\n";
  qsMenuXML += " </DVDMenu>\n";

  return qsMenuXML;
}

QString SimpleDVD::getMenuButtons ( bool bPrev, bool bNext, int iMenuNumber )
{
  QString qsMenuXML, qsMenuName;
  // The three buttons to the previous, next and Main menu ...
  QString qsButtonPrev = SYSTEM_DIRECTORY"/share/qdvdauthor/plugins/simpledvd/prev.png";
  QString qsButtonMain = SYSTEM_DIRECTORY"/share/qdvdauthor/plugins/simpledvd/main.png";
  QString qsButtonNext = SYSTEM_DIRECTORY"/share/qdvdauthor/plugins/simpledvd/next.png";
  if ( bPrev )  {
    if ( iMenuNumber < 3 )
      qsMenuName = QString ( "vmgm" );
    else
      qsMenuName = QString ( "Menu %1" ).arg ( iMenuNumber - 1 );
    qsMenuXML += "   <ButtonObject Action=\"jump+-+"+qsMenuName+"+-+\" ButtonName=\"Button 7\" >\n";
    qsMenuXML += "    <NormalState>\n";
    qsMenuXML += "     <ImageObject FileName=\""+qsButtonPrev+"\" >\n";
    qsMenuXML += "      <Manipulator>\n";
    qsMenuXML += "       <Modifiers/>\n";
    qsMenuXML += "       <ColorKey Color=\"#fffefffe\" />\n";
    qsMenuXML += "      </Manipulator>\n";
    qsMenuXML += "      <MenuObject Width=\"60\" X=\"253\" Y=\"212\" Height=\"45\" ObjectName=\"PrevImg\" ObjectExtractionPath=\"PrevImg\" />\n";
    qsMenuXML += "     </ImageObject>\n";
    qsMenuXML += "    </NormalState>\n";
    qsMenuXML += "    <SelectedState>\n";
    qsMenuXML += "     <MaskObject Color=\"#a0ff1414\" />\n";
    qsMenuXML += "    </SelectedState>\n";
    qsMenuXML += "    <HighlightedState>\n";
    qsMenuXML += "     <MaskObject Color=\"#a0fa9632\" />\n";
    qsMenuXML += "    </HighlightedState>\n";
    qsMenuXML += "    <MenuObject Width=\"60\" X=\"253\" Y=\"212\" Height=\"45\" ObjectName=\"ButtonPrev\" />\n";
    qsMenuXML += "   </ButtonObject>\n";
  }
  if ( bNext )  {
    qsMenuName = QString ( "Menu %1" ).arg ( iMenuNumber + 1 );
    qsMenuXML += "   <ButtonObject Action=\"jump+-+"+qsMenuName+"+-+\" ButtonName=\"Button 8\" >\n";
    qsMenuXML += "    <NormalState>\n";
    qsMenuXML += "     <ImageObject FileName=\""+qsButtonNext+"\" >\n";
    qsMenuXML += "      <Manipulator>\n";
    qsMenuXML += "       <Modifiers/>\n";
    qsMenuXML += "       <ColorKey Color=\"#fffefffe\" />\n";
    qsMenuXML += "      </Manipulator>\n";
    qsMenuXML += "      <MenuObject Width=\"60\" X=\"378\" Y=\"213\" Height=\"45\" ObjectName=\"NextImg\" ObjectExtractionPath=\"NextImg\" />\n";
    qsMenuXML += "     </ImageObject>\n";
    qsMenuXML += "    </NormalState>\n";
    qsMenuXML += "    <SelectedState>\n";
    qsMenuXML += "     <MaskObject Color=\"#a0ff1414\" />\n";
    qsMenuXML += "    </SelectedState>\n";
    qsMenuXML += "    <HighlightedState>\n";
    qsMenuXML += "     <MaskObject Color=\"#a0fa9632\" />\n";
    qsMenuXML += "    </HighlightedState>\n";
    qsMenuXML += "    <MenuObject Width=\"60\" X=\"378\" Y=\"213\" Height=\"45\" ObjectName=\"ButtonNext\" />\n";
    qsMenuXML += "   </ButtonObject>\n";
  }
  // Button to the Main Menu ..
  qsMenuXML += "   <ButtonObject Action=\"jump+-+vmgm+-+\" ButtonName=\"Button 9\" >\n";
  qsMenuXML += "    <NormalState>\n";
  qsMenuXML += "     <ImageObject FileName=\""+qsButtonMain+"\" >\n";
  qsMenuXML += "      <Manipulator>\n";
  qsMenuXML += "       <Modifiers/>\n";
  qsMenuXML += "       <ColorKey Color=\"#fffefffe\" />\n";
  qsMenuXML += "      </Manipulator>\n";
  qsMenuXML += "      <MenuObject Width=\"60\" X=\"315\" Y=\"206\" Height=\"56\" ObjectName=\"MainImg\" ObjectExtractionPath=\"MainImg\" />\n";
  qsMenuXML += "     </ImageObject>\n";
  qsMenuXML += "    </NormalState>\n";
  qsMenuXML += "    <SelectedState>\n";
  qsMenuXML += "     <MaskObject Color=\"#a0ff1414\" />\n";
  qsMenuXML += "    </SelectedState>\n";
  qsMenuXML += "    <HighlightedState>\n";
  qsMenuXML += "     <MaskObject Color=\"#a0fa9632\" />\n";
  qsMenuXML += "    </HighlightedState>\n";
  qsMenuXML += "    <MenuObject Width=\"60\" X=\"315\" Y=\"206\" Height=\"56\" ObjectName=\"ButtonMain\" />\n";
  qsMenuXML += "   </ButtonObject>\n";

  return   qsMenuXML;
}

QRect SimpleDVD::scaleScreenshot ( QString &qsScreenshot, int iWidth, int iHeight )
{
  QRect rect ( 0, 0, iWidth, iHeight );
  QFileInfo fileInfo  ( qsScreenshot );
  if ( ! fileInfo.exists ( ) )
    return rect;

  QString qsTemp = m_qsTempPath + "/" + fileInfo.baseName ( ) + ".png";
  QImage image ( qsScreenshot );
  if (   image.isNull ( ) )
    return rect;

  int x, y, w, h;
  double fScaleX = ( (double)image.height ( ) / image.width  ( ) );
  double fScaleY = ( (double)image.width  ( ) / image.height ( ) );
  x = 0; y = 0; w = iWidth; h = iHeight;

  if ( fScaleX <= fScaleY )  {
    // Here we are scaling based on the width
//    h = (int)( fScaleX * iHeight );
    h = (int)( fScaleX * iWidth );
    y = (int)( (double)( iHeight - h ) / 2.0 );
  }
  else  {
    // Here we are scaling based on the height
    w = (int)( fScaleY * iWidth );
    x = (int)( (double)( iWidth - w ) / 2.0 );
  }

  rect = QRect ( x, y, w, h );
  return rect;
}

}; // end namespace Plugin

