/***************************************************************************

    Handle preview mode

    It is displayed in 3 layers


    Engine : Call setPreviewMode and amdPreview depending on the actions
            previewMode is the **current** preview mode

    admPreview :
          Allocate/desallocate ressources
          Build preview window
          Call display properly to display it

    GUI_PreviewXXXX
          UI toolkit to actually display the window
          See GUI_ui.h to see them



    copyright            : (C) 2007 by mean
    email                : fixounet@free.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include "ADM_cpp.h"
#include "config.h"

#include "ADM_default.h"
#include "ADM_edit.hxx"
#include "GUI_render.h"

#include "ADM_preview.h"
#include "GUI_ui.h"

#include "DIA_coreToolkit.h"

#define MAX(a, b) ((a) > (b) ? (a) : (b))

/*************************************/
/*************************************/
extern ADM_Composer *video_body;
/**
    \fn getCurrentPts
    \brief returns the PTS in us of the last displayed frame
*/
uint64_t admPreview::getCurrentPts(void)
{
    if (rdrImage)
        return rdrImage->Pts;
    return 0LL;
}
/**
      \fn admPreview::seekToTime
      \brief Seek to any given frame

      @param timeframe Time of the image
*/

bool admPreview::seekToTime(uint64_t timeframe)
{
    if (!video_body->goToTimeVideo(timeframe))
    {
        ADM_warning(" seeking for frame at %" PRIu64 " ms failed\n", timeframe / 1000LL);
        return false;
    }
    return samePicture();
}
/**
      \fn admPreview::seekToIntraPts
      \brief Seek to intra at PTS given as arg

      @param timeframe Time of the image
*/

bool admPreview::seekToIntraPts(uint64_t timeframe)
{
    uint64_t pts = getCurrentPts();
    if (timeframe == pts)
        return true;
    if (!video_body->goToIntraTimeVideo(timeframe))
    {
        ADM_warning(" seeking for frame at %" PRIu64 " ms failed\n", timeframe / 1000LL);
        return false;
    }
    return samePicture();
}
/**
    \fn samePicture
*/
uint8_t admPreview::samePicture(void)
{
    if (!video_body->samePicture(rdrImage))
        return false;
    return updateImage();
}
/**
      \fn admPreview::update
      \brief display data associated with framenum image
      @param image : current main image (input)
      @param framenum, framenumber
*/

uint8_t admPreview::nextPicture(void)
{

    if (!video_body->nextPicture(rdrImage))
        return 0;
    return updateImage();
}

/**
      \fn admPreview::update
      \brief display data associated with framenum image
      @param image : current main image (input)
      @param framenum, framenumber
*/

uint8_t admPreview::previousPicture(void)
{
    if (!video_body->previousPicture(rdrImage))
        return 0;
    return updateImage();
}
/**
    \fn nextKeyFrame

*/
bool admPreview::nextKeyFrame(void)
{
    uint64_t pts = getCurrentPts();
    ADM_info("Current PTS :%" PRId64 " ms\n", pts / 1000LL);
    if (false == video_body->getNKFramePTS(&pts))
    {
        ADM_warning("Cannot find next keyframe\n");
        return false;
    }
    ADM_info("next kf PTS :%" PRId64 " ms\n", pts / 1000LL);
    return seekToIntraPts(pts);
}
/**
    \fn previousKeyFrame

*/
bool admPreview::previousKeyFrame(void)
{
    uint64_t pts = getCurrentPts();
    ADM_info("Current PTS :%" PRId64 " ms\n", pts / 1000LL);
    if (false == video_body->getPKFramePTS(&pts))
    {
        ADM_warning("Cannot find previous keyframe\n");
        return false;
    }
    ADM_info("next kf PTS :%" PRId64 " ms\n", pts / 1000LL);
    return seekToIntraPts(pts);
}
// EOF
