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

/*
 *      handlefile.c -- REALmagic local file playing basic functions
 *
 *      Copyright (C) 2001 Sigma Designs
 *                    written by Pascal Cannenterre <pascal_cannenterre@sdesigns.com>
 *
 *      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.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*****************************************************************************/
#include "define.h"
#include "handlefile.h"
#include "gtk_callbacks.h"

DWORD Event_Notifications_file (DWORD, DWORD, DWORD);
void StartPlaying_file(INFO*);

void stopPlayFile(INFO *info)
{
  if(info->pFileplayer != NULL) 
    {
      info->b_stop = 1;
    }
}

void PlayFileThread(INFO * info)
{
  int fd;
  int bytesread = 1, rc = FMPE_OK;
  FMP_BUFFER FMPBuf;

  info->b_stop = 0;
  info->loop_is_over = 0;
  
  /* Open the file related to filename */
  fd=open(info->sFilename,O_RDONLY|O_LARGEFILE);
  if (fd==-1)
    {
      perror("Open (handlefile.c)failed !!");
      info->pFileplayer = NULL;
      pthread_exit(NULL); 
    }
  // INFOFORSTDOUT("\nReady to play ...\n");
  
  while (bytesread && (!(info->b_stop)))
    {
      // get a pointer to a free buffer
      rc = FMPGetBuffer (&FMPBuf, TRUE);

      // fprintf(stdout, "\n\nOne buffer !\n\n");

      if (rc != FMPE_OK)
	{
	  G_PRINT("FMPError : %s\n", FMPGetLastError(rc));
	  break;
	}
      // signals can cause harmless EINTR
      while (((bytesread=read(fd,FMPBuf.pBuffer,FMPBuf.dwBufferSize))==-1)
	     &&(errno==EINTR));
      if (bytesread==-1) bytesread=0;
      FMPBuf.dwDataSize=bytesread;
      // the buffer is ready to be queued
      FMPPush (&FMPBuf);
    }
  lseek (fd,0,SEEK_SET);
  close(fd);
  info->pFileplayer = NULL;
  if(info->bRepeat > 0)
    info->bRepeat = info->bRepeat - 1;
  pthread_exit(NULL);
  return;
}

void spawnPlayFile(INFO * info)
{
  info->pFileplayer = OSCreateThread("FilePlayerThread",UNUSED_ARG,
				     (FUNCPTR)PlayFileThread,(int)info);
}


void handle_Stop_Close_file(INFO *pInfo)
{
  if(pInfo->playing == PLAYING ||
     pInfo->playing == TRICK_MODE )
    {
      if(pInfo->b_resume)
	{
	  switch_overlay_back(&ovl);
	  FMPPause();
	  pInfo->playing = STOP_FOR_RESUME;
	  displayMsg(MSG_STATUS_ONLY, 0, "Stop for Resume");
	}
      else
	{
	  stopPlayFile(pInfo);
	  while(pInfo->pFileplayer != NULL)
	    usleep(10*TICK);
	  FMPStop();
	  pInfo->dwTime = 0;
	  pInfo->playing = STOPPED;
	  displayMsg(MSG_BOTH, MSG_STOP, NULL);
	}	  
    } 
  else if(pInfo->playing == STOPPED)
    {
      // msg = SHOW_TIME;
      // OSPostMessage(pInfo->osdMsgQ, &msg, 1);
      // FMPStop();
      while(pInfo->pFileplayer != NULL)
	usleep(20*TICK);
      FMPClose();
      pInfo->playing = CLOSED;
      displayMsg(MSG_STOP, MSG_CLOSE, NULL);
      //Before showing splash screen we return to 720x480 resolution
      if(pInfo->IHdtv_c)
	IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params_Init), g_OutputMode);
    }
  else if( pInfo->playing == PAUSED ||
	   (pInfo->playing == TRICK_MODE_PAUSED) )
    {
      if(pInfo->b_resume)
	{
	  switch_overlay_back(&ovl);
	  pInfo->playing = STOP_FOR_RESUME;
	  displayMsg(MSG_STATUS_ONLY, 0, "Stop for Resume!");
	}
      else
	{
	  FMPPlay();
	  stopPlayFile(pInfo);
	  while(pInfo->pFileplayer != NULL)
	    usleep(20*TICK);
	  FMPStop();
	  pInfo->playing = STOPPED;
	  displayMsg(MSG_BOTH, MSG_STOP, NULL);
	}
    } 
  else if(pInfo->playing == STOP_FOR_RESUME)
    {
      FMPPlay();
      stopPlayFile(pInfo);
      while(pInfo->pFileplayer != NULL)
	usleep(20*TICK);
      FMPStop();
      usleep(30*TICK);
      FMPClose();
      pInfo->playing = CLOSED;
      displayMsg(MSG_BOTH, MSG_CLOSE, NULL);
    } 
}

void handle_FForward_file(INFO *pInfo)
{
  
}


void handle_FRewind_file(INFO *pInfo)
{
  LONG sp = (LONG)FMPGet(FMPI_CURRENT_SPEED);
  LONG speed;

  sp = -sp;
  sp = (sp + 2) % 10;
      
  speed = (LONG)FMPGet(FMPI_CURRENT_SPEED);
  
}


void handle_Prev_Track_file(INFO *pInfo)
{
  if(GUI.playlistwin && ovl.b_overlay_access)
    {
      GUI.playlist_selected_row = GUI.playlist_selected_row - 2;
      playlist_play();
      displayMsg(MSG_OSD_ONLY, MSG_BACK, NULL);
    }
}

void handle_Next_Track_file(INFO *pInfo)
{
  if(GUI.playlistwin && ovl.b_overlay_access)
    {
      playlist_play();
      displayMsg(MSG_OSD_ONLY, MSG_NEXT, NULL);
    }
}

void handle_Play_Pause_file(INFO *pInfo)
{ 
  if ( (pInfo->playing == PAUSED) ||
       (pInfo->playing == TRICK_MODE_PAUSED)) 
    {
      FMPPlay();

      if(pInfo->playing == TRICK_MODE_PAUSED)
	pInfo->playing = TRICK_MODE;
      else
	{
	  pInfo->playing = PLAYING;
	  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
	}
    } 
  else if (pInfo->playing == STOP_FOR_RESUME) 
    {
      resumeDisplayFromStop(&ovl);
      FMPPlay();
      pInfo->playing = PLAYING;
      displayMsg(MSG_BOTH, MSG_PLAY, NULL);
    }
  else if (pInfo->playing == CLOSED) 
    {
      StartPlaying_file(pInfo);
    }
  else if (pInfo->playing == STOPPED)
    {
      while(pInfo->pFileplayer != NULL)
	usleep(10*TICK);
     
      FMPPlay();
      spawnPlayFile(pInfo);
      pInfo->playing = PLAYING; 
      displayMsg(MSG_BOTH, MSG_PLAY, NULL);
    }
  else
    {
      FMPPause();
      if(pInfo->playing == TRICK_MODE)
	pInfo->playing = TRICK_MODE_PAUSED;
      else
	pInfo->playing = PAUSED;
      displayMsg(MSG_BOTH, MSG_PAUSE, NULL);
    }
}

void handle_Time_Adjust_file(INFO *pInfo)
{
  
}

void StartPlaying_file(INFO* pInfo) 
{
  DWORD tmp = FMPE_OK;
  if (pInfo->playing == CLOSED)
    {   
      pInfo->maddie = 0;
      pInfo->test = 0;
      
      tmp = FMPOpen(pInfo->dwStreamtype, pInfo->dwBufferSize, pInfo->dwNBuffer, 
		    (PFMPCALLBACK)Event_Notifications_file, (DWORD)pInfo);
      
    }
  if(tmp != 0) 
    {
      pInfo->playing = CLOSED;
      return;
    } 
  pInfo->playing = STOPPED;
 
  if(pInfo->pIHdtv) 
    {
      if((g_OutputMode & FMPV_VIDEOOUT_MODE_MASK) == FMPV_VIDEOOUT_HDTV) 
	{
	  tmp = (WORD)FMPGetProfileWord(RMREG_HDTV_RES) & 0xff;
	  pInfo->IHdtv_c = tmp + 1;
	  IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params[pInfo->IHdtv_c - 1]), g_OutputMode);
	}
      else if((g_OutputMode & FMPV_VIDEOOUT_MODE_MASK) == FMPV_VIDEOOUT_TV) 
	{
	  pInfo->IHdtv_c = 0;
	}
    }
  
  FMPPlay();
  pInfo->dwTime = 0;
  spawnPlayFile(pInfo);
  pInfo->playing = PLAYING;
  displayMsg(MSG_BOTH, MSG_PLAY, NULL);
}


DWORD Event_Notifications_file(DWORD dwContext, DWORD dwMsg, DWORD dwValue)
{
  INFO *a;
  a = (INFO*)dwContext;

  switch (dwMsg)
    {
    case FMPM_ERROR:
      a->maddie = 1;
      break;
    case FMPM_STARVATION:
      a->maddie = 1;
      break;
    case FMPM_EOS:
      FMPStop();
      a->playing = STOPPED;
      a->loop_is_over = 1;
      a->totalTime = a->dwTime;
      a->dwTime = 0;
      /* if( (a->bRepeat == -1) || (a->bRepeat > 0) ) */
      /* 	{ */
      /* 	  if(playlist_next(a) == -1) */
      /* 	    { */
      /* 	      usleep(20*TICK); */
      /* 	      FMPClose(); */
      /* 	      a->playing = CLOSED; */
      /* 	      usleep(20*TICK); */
      /* 	    } */
      /* 	} */
      /*       else if (a->bRepeat == 0) */
      /* 	{ */
      /* 	  gdk_threads_enter(); */
      /* 	  handle_Stop_Close_file(a); */
      /* 	  gdk_threads_leave(); */
      /* 	} */
      break;
    case FMPM_TRICK_MODE_CHANGE:

      break;
	  
    case FMPM_AUTOPAUSE:
      break;
	
    default:
      break;
    }
  return 0;
}
