// Please see the README file or the LEGAL NOTES-section in the manual before
// modifying, compiling or using 'xmrm' or 'xmrm_mpeg'
//   Idea: Manfred Kopp
//   Programming: Gerhard Waldhör, Andreas Artmann

#include <tiffio.h>
#include <stdlib.h>
#include <forms.h>
#include <unistd.h>
#include "xmrm_mpeg.h"
#include "const.h"

#define MAX_PIC_NUM 999
#define BORDER_WIDTH -1

FD_CREATE_MPEG *fd_CREATE_MPEG;        // The form the user will see

int got_both_frames = 0;

//----------------------------------------------------
// two instances are derived in main(), one as backup
// because many strings are changed during conversion
// and if the user wants a second run, the old becomes
// the new, and so forth
// maybe not pretty, but easy to do :-)
//----------------------------------------------------
class names_n_numbers
{
  public:
    names_n_numbers();
    
    char *START_Frame;                  // complete filename of first frame
    char START_dir_only [BUFSIZ];
    char *START_fname_only;

    char *END_Frame;                    // complete filename of last frame

    char *filename_ppm, *filename_yuv;
    char *extension;                    // points to '.###.tif' - used to modify '###'
    char number_str[7];                 // holds '.###.'
    char even[7];                       // ".even" if files have to be even-sized, ""(empty) otherwise

    int abs_count;                      // absolute count of valid pictures
    int first_width, first_height;
    int start_number;                   // number of first valid TIFF-file
    int end_number;                     // number of last TIFF-file
} *work_class, *backup_class;

//------------------------------
// constructor
//------------------------------
names_n_numbers::names_n_numbers()
{
  START_Frame = NULL;
  START_fname_only = NULL;
  END_Frame = NULL;
  
  filename_ppm = filename_yuv = extension = NULL;

  abs_count = first_width = first_height = start_number = 0;
  end_number = MAX_PIC_NUM;
}

//--------------------------------------------------------------
// Extract number ### from filename basename.###.tif(f)
// returns: extracted number (MAX_PIC_NUM+1 if invalid filename)
//--------------------------------------------------------------
int Extract_Number(char **ext, char *fname_only)
{
  int count = 0;

  //backup_class->number_str = ".000.";
  strcpy(backup_class->number_str,".000.");

  while ( !(*ext = strstr(fname_only,backup_class->number_str)) && (count <= MAX_PIC_NUM) )
  {
    count++;

    backup_class->number_str[1] = '0' + count/100;
    backup_class->number_str[2] = '0' + (count%100)/10;
    backup_class->number_str[3] = '0' + (count%10);
  }
  
  return count;
}

//----------------------------------------------------------------
// Ask user for starting TIFF-File if necessary and extract number
// returns: 0: success
//          1: error
//          2: cancel
//----------------------------------------------------------------
int Get_START_Frame()
{
  const char *directory;

  // so that START end END-frame isn´t the same !!!
  fl_use_fselector(0);
  
  if ( !backup_class->START_Frame )
  {
    fl_addto_browser(fd_CREATE_MPEG->BR_Log,"Getting the START-Frame...");
    XFlush(fl_get_display());

    if ( backup_class->START_Frame = (char *)fl_show_fselector("Select START-Frame...","","*.tif*",".tif") )
    {
      directory = (char *)fl_get_directory();
      (void) strcpy(backup_class->START_dir_only, directory);
    }
    else
      return 2;
  }
  else
  {
    (void) strcpy(backup_class->START_dir_only, backup_class->START_Frame);
    if ( !(backup_class->START_fname_only = strrchr(backup_class->START_dir_only,'/')) )
    {
      fl_show_alert("ERROR:","Wrong parameter !","Consult the man-page or the manual !",1);
      return 1;
    }
    *backup_class->START_fname_only = '\0';
  }

  do
  {  
    if ( !(backup_class->START_fname_only = strrchr(backup_class->START_Frame,'/')) )
    {
      fl_show_alert("ERROR:","Wrong parameter !","Consult the man-page or the manual !",1);
      return 1;
    }
    backup_class->START_fname_only++;

    backup_class->start_number = Extract_Number(&backup_class->extension, backup_class->START_fname_only);

    if( !backup_class->extension )
    {
      fl_show_alert("ERROR:","Invalid Filename !","Filename example: basename.001.tif(f)",1);
      if ( backup_class->START_Frame = (char *)fl_show_fselector("Select START-Frame...","","*.tif*",".tif") )
      {
        directory = (char *)fl_get_directory();
        (void) strcpy(backup_class->START_dir_only, directory);
      }
      else
        return 1;
    }
  }
  while ( !backup_class->extension );
  
  backup_class->filename_ppm = (char *)malloc( strlen(backup_class->START_fname_only) );
  backup_class->filename_yuv = (char *)malloc( strlen(backup_class->START_fname_only) );

  if ( (!backup_class->filename_ppm) || (!backup_class->filename_yuv) )
  {
    fl_show_alert("ERROR:","Memory Allocation failed !","Aborting...",1);
    return 1;
  }
  
  return 0;
}

//-----------------------------------------------
// Ask user for STOP-TIFF-File and extract number
// returns: 0: success
//          1: user abort
//-----------------------------------------------
int Get_END_Frame()
{
  const char *directory;
  char *filename, *ext;
  int some_error;
  char filter[BUFSIZ]; // filter for fselector()
  
  // so that START end END-frame isn´t the same !!!
  fl_use_fselector(1);

  directory = backup_class->START_dir_only;

  (void) strcpy(filter, backup_class->START_fname_only);
  if ( !(ext = strstr(filter,backup_class->number_str)) )
  {
    fl_show_alert("ERROR:","UNEXPECTED ERROR !!!","Bailing out...",1);
    return 1;
  }
  *ext = '\0';
  (void )strcat(filter,"*");

  if ( !backup_class->END_Frame )
  {
    fl_addto_browser(fd_CREATE_MPEG->BR_Log,"Getting the STOP-Frame...");
    XFlush(fl_get_display());

    if ( backup_class->END_Frame = (char *)fl_show_fselector("Select STOP-Frame...",\
         backup_class->START_dir_only,filter,".tif") )
      directory = fl_get_directory();
    else
      return 1;
  }

  do
  {
    some_error = FALSE;
    
    filename = strrchr(backup_class->END_Frame,'/');
    filename++;

    if ( strcmp(directory, backup_class->START_dir_only) )
    {
      fl_show_alert("ERROR:","START and STOP-Frames must be in SAME directory !","",1);
      some_error = TRUE;
    }
    else
    {
      backup_class->end_number = Extract_Number(&ext, filename);

      if ( backup_class->start_number >= backup_class->end_number )
      {
        fl_show_alert("ERROR:","STOP-Frame number must be HIGHER","than START-Frame number !",1);
        some_error = TRUE;
      }
      else if( !ext )
      {
        fl_show_alert("ERROR:","Invalid Filename !","Filename example: basename.001.tif(f)",1);
        some_error = TRUE;
      }
    }
    
    if ( some_error )
      if ( backup_class->END_Frame = (char *)fl_show_fselector("Select STOP-Frame...",\
           backup_class->START_dir_only,filter,".tif") )
        directory = fl_get_directory();
      else
        return 1;
  }
  while( some_error );

  return 0;
}

//----------------------------------------------------
// make size of picture even or mpeg-encoder won't run
// returns: 0: success
//          1: failure
//----------------------------------------------------
int Even_Size(TIFF *tif, int width, int height)
{
  int even_width, even_height;
  char Logbuf[BUFSIZ];
  char *Save_Name;
  
  size_t npixels;
  uint32 *raster;

  sprintf(Logbuf,"@bMaking %s even-sized -",work_class->START_Frame);
  fl_addto_browser(fd_CREATE_MPEG->BR_Log,Logbuf);
  XFlush(fl_get_display());  
  fl_addto_browser(fd_CREATE_MPEG->BR_Log,"   Creating temporary file...");
  XFlush(fl_get_display());
  
  npixels = (uint32) (width * height);
    
  if ( raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)) )
  {
    if ( TIFFReadRGBAImage(tif, width, height, raster, 0) )
    {
      TIFFClose(tif);

      uint32 *raster_clone;
      
      even_width = width + (width % 2);
      even_height = height + (height % 2);
      
      npixels = (uint32) (even_width * even_height);
      raster_clone = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));

      if ( raster_clone == NULL )
      {
        fl_show_alert("ERROR:","Memory Allocation failed !","Aborting...",1);
        _TIFFfree(raster);
        return 1;
      }

      // copy old raster into new raster and
      // make it even by cloning the last row and/or column
      for (int h=0; h < height; h++)
      {
        if (width % 2) raster_clone[(even_height-h)*even_width-1] = raster[(h+1)*width-1];

        for (int w=0; w < width; w++)
        {
          raster_clone[(even_height-1-h)*even_width+w] = raster[h*width+w];
        }
      }
      if (height % 2)
        for (int i = 0; i < even_width; i++)
          raster_clone[i] = raster_clone[i+even_width];

      _TIFFfree(raster);

      Save_Name = (char *)malloc(strlen(work_class->START_Frame)+6);
      if ( Save_Name == NULL )
      {
        fl_show_alert("ERROR:","Memory Allocation failed !","Aborting...",1);
        _TIFFfree(raster_clone);
        return 1;
      }
      strcpy(Save_Name,work_class->START_Frame);
      strcat(Save_Name,work_class->even);

      // Check if file exists already
      tif = TIFFOpen(Save_Name,"r");
      if ( tif )
      {
        fl_show_alert("ERROR: temporary file exists:",Save_Name,"Aborting...",1);
        _TIFFfree(raster_clone);
        TIFFClose(tif);
        free(Save_Name);
        return 1;
      }

      // Opening TIFF-File:
      tif = TIFFOpen(Save_Name,"w");
      if ( tif == NULL )
      {
        fl_show_alert("ERROR:","Unable to open TIFF File !","Aborting...",1);
        _TIFFfree(raster_clone);
        free(Save_Name);
        return 1;
      }
      // Setting TIFF-Image informations  
      TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,even_width);
      TIFFSetField(tif,TIFFTAG_IMAGELENGTH,even_height);
      TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8);
      TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,4);
      TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_LZW); // free for non-commercial use (so I read)
      TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
      TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_RGB);
      TIFFSetField(tif,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT);
      TIFFSetField(tif,TIFFTAG_RESOLUTIONUNIT,RESUNIT_INCH);
      TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,even_height);
      TIFFSetField(tif,TIFFTAG_XRESOLUTION,1200.0);
      TIFFSetField(tif,TIFFTAG_YRESOLUTION,1200.0);

      if ( TIFFWriteEncodedStrip(tif, 0, (char *)raster_clone, even_width * even_height * sizeof(uint32)) == -1 )
      {
        fl_show_alert("ERROR:","Unable to save TIFF File !","Aborting...",1);
        _TIFFfree(raster_clone);
        TIFFClose(tif);
        free(Save_Name);
        return 1;
      }
      _TIFFfree(raster_clone);
      TIFFClose(tif);
      free(Save_Name);
    }
    else
    {
      fl_show_alert("ERROR:","Unable to read TIFF-File !","Aborting...",1);
      _TIFFfree(raster);
      TIFFClose(tif);
      return 1;
    }
  }
  else
  {
    fl_show_alert("ERROR:","Memory Allocation failed !","Aborting...",1);
    TIFFClose(tif);
    return 1;
  }

  return 0;
}

//-------------------------------------
// convert TIFF to PPM to Y-,U-,V-Files
// returns: 0: success
//          1: failure
//-------------------------------------
int Make_YUV_File(int increase)
{
  char Logbuf[BUFSIZ];
  char cmdbuf[BUFSIZ];
  char TIFF_Name[BUFSIZ];

  int tif_w, tif_h, test;

  FILE *fp;
  TIFF *tif;
  
  strcpy(TIFF_Name,work_class->START_Frame);
  strcat(TIFF_Name,work_class->even);

  // Look if file exists (if stepsize is larger than 1)
  if ( fp=fopen(increase ? work_class->START_Frame:TIFF_Name,"r") )
  {
    fclose(fp);
        
    //test if its a valid TIFF-File
    if ( tif=TIFFOpen(increase ? work_class->START_Frame:TIFF_Name,"r") )
    {
      // Getting TIFF-size
      if ( TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&tif_w) != 1 || TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&tif_h) != 1 )
      {
        fl_show_alert("ERROR:","Unable to get image-size !","Aborting...",1);
        TIFFClose(tif);
        return 1;
      }

      if ( !work_class->first_width ) work_class->first_width = tif_w;
      if ( !work_class->first_height ) work_class->first_height = tif_h;
        
      // Check for unexpected change of size
      if ( (tif_w != work_class->first_width) || (tif_h != work_class->first_height) )
      {
        fl_show_alert("ERROR:","Unexpected change of image-size !","Aborting...",1);
        TIFFClose(tif);
        return 1;
      }
      
      // Check for even picture size
      if ( (tif_w % 2) || (tif_h % 2) )
      {
        strcpy(work_class->even,".even");
        if ( Even_Size( tif, tif_w, tif_h) )
          return 1;
      }
      else
        TIFFClose(tif);

      // Make SAVENAME for PPM
      (void) strcpy(work_class->filename_ppm,work_class->START_fname_only);
      work_class->extension = strstr(work_class->filename_ppm,".tif");
      *(++work_class->extension) = 'p';
      *(++work_class->extension) = 'p';
      *(++work_class->extension) = 'm';
      *(++work_class->extension) = '\0';
          
      // Execute tifftopnm
      sprintf(cmdbuf, "tifftopnm %s/%s%s > %s/%s",work_class->START_dir_only,work_class->START_fname_only,\
              work_class->even,work_class->START_dir_only,work_class->filename_ppm);
      sprintf(Logbuf,"Converting %s%s to ppm...",work_class->START_fname_only,work_class->even);
      fl_addto_browser(fd_CREATE_MPEG->BR_Log,Logbuf);
      XFlush(fl_get_display());

      test = system(cmdbuf);
      if(test==-1 || test==127)
      {
        fl_show_alert("ERROR:","Execution of 'tifftopnm' failed !","Aborting...",1);
        return 1;
      }

      // MAKE SAVENAME for YUV
      (void) strcpy(work_class->filename_yuv,work_class->START_fname_only);
      work_class->extension = strstr(work_class->filename_yuv,work_class->number_str);
      if(work_class->abs_count/100 != 0)
      {
        *work_class->extension = '0' + work_class->abs_count/100;
        *(++work_class->extension) = '0' + (work_class->abs_count%100)/10;
        *(++work_class->extension) = '0' + (work_class->abs_count%10);
        *(++work_class->extension) = '\0';
      }
      else
        if((work_class->abs_count%100)/10 != 0)
        {
          *work_class->extension = '0' + (work_class->abs_count%100)/10;
          *(++work_class->extension) = '0' + (work_class->abs_count%10);
          *(++work_class->extension) = '\0';  
        }
        else
        {
          *work_class->extension = '0' + (work_class->abs_count%10);
          *(++work_class->extension) = '\0';
        }
          
      // Execute ppmtoyuvsplit
      sprintf(cmdbuf, "ppmtoyuvsplit %s/%s %s/%s",work_class->START_dir_only,work_class->filename_yuv,\
              work_class->START_dir_only,work_class->filename_ppm);
      sprintf(Logbuf,"Splitting %s into Y-,U- and V-Files...",work_class->filename_ppm);
      fl_addto_browser(fd_CREATE_MPEG->BR_Log,Logbuf);
      XFlush(fl_get_display());

      test = system(cmdbuf);
      if(test==-1 || test==127)
      {
        fl_show_alert("ERROR","Execution of 'ppmtoyuvsplit' failed !","Aborting...",1);
        return 1;
      }

      ++work_class->abs_count;
    }
    else
    //not a valid TIFF-File...
    {
      fl_show_alert("ERROR:","Invalid TIFF-File encountered !","Aborting...",1);
      return 1;
    }
  }

  return 0;
}

//---------------------------------------------
// Call 'Make_YUV_File' with increasing numbers
// returns: 0: success
//          1: failure
//---------------------------------------------
int Make_YUV_Files_INC()
{
  work_class->abs_count=0;
  
  *work_class->even = '\0';

  work_class->number_str[1] = '0' + work_class->start_number/100;
  work_class->number_str[2] = '0' + (work_class->start_number%100)/10;
  work_class->number_str[3] = '0' + (work_class->start_number%10);

  //try all possible numbers
  for( int i = work_class->start_number; i <= work_class->end_number; i++ )
  {
    work_class->extension = strstr(work_class->START_fname_only,work_class->number_str);
    *(++work_class->extension) = '0' + i/100;
    *(++work_class->extension) = '0' + (i%100)/10;
    *(++work_class->extension) = '0' + (i%10);

    work_class->number_str[1] = '0' + i/100;
    work_class->number_str[2] = '0' + (i%100)/10;
    work_class->number_str[3] = '0' + (i%10);

    if ( Make_YUV_File(TRUE) )
      return 1;
  }

  return 0;
}

//---------------------------------------------
// Call 'Make_YUV_File' with decreasing numbers
// returns: 0: success
//          1: failure
//---------------------------------------------
int Make_YUV_Files_DEC()
{
  for( int i = work_class->end_number; i >= work_class->start_number; i-- )
  {
    work_class->extension = strstr(work_class->START_fname_only,work_class->number_str);
    *(++work_class->extension) = '0' + i/100;
    *(++work_class->extension) = '0' + (i%100)/10;
    *(++work_class->extension) = '0' + (i%10);

    work_class->number_str[1] = '0' + i/100;
    work_class->number_str[2] = '0' + (i%100)/10;
    work_class->number_str[3] = '0' + (i%10);

    if ( Make_YUV_File(FALSE) )
      return 1;
  }

  return 0;
}
  
//-----------------------------------------------------------------
// run the MPEG encoder 'mpeg': converts Y-,U-,V-Files into an MPEG
//
// returns: return value of system call
//          
//-----------------------------------------------------------------
int MPEG_Encoder()
{
  int test;
  char cmdbuf[BUFSIZ];

  // MAKE SAVENAME for MPEG
  work_class->extension = strstr(work_class->START_fname_only,work_class->number_str);
  *work_class->extension = '\0';
    
  fl_addto_browser(fd_CREATE_MPEG->BR_Log,"@bMPEG Encoder Running - Please be patient !");
  XFlush(fl_get_display());
  
  // Execute mpeg-encoder
  sprintf(cmdbuf, "mpeg -PF -a %i -b %i -h %i -v %i %s/%s", 0, work_class->abs_count-1,work_class->first_width,\
          work_class->first_height,work_class->START_dir_only, work_class->START_fname_only);

  test = system(cmdbuf);
  if (test == -1 || test == 127)
  {
    sprintf(cmdbuf,"rm -f %s/%s.mpg",work_class->START_dir_only,work_class->START_fname_only);
    (void) system(cmdbuf);
  }

  return test;
}

//---------
// Clean up
//---------
void Remove_Garbage()
{
  char cmdbuf[BUFSIZ];

  // Get filename for removal
  if ( work_class->extension = strstr(work_class->START_fname_only,work_class->number_str) )
    *work_class->extension = '\0';

  if ( strcmp(work_class->even,".even")==0 )
  {
    fl_addto_browser(fd_CREATE_MPEG->BR_Log,"@iRemoving temporary .even-Files...");
    XFlush(fl_get_display());  

    sprintf(cmdbuf,"rm -f %s/%s.*.even",work_class->START_dir_only,work_class->START_fname_only);
    (void) system(cmdbuf);
  }

  fl_addto_browser(fd_CREATE_MPEG->BR_Log,"@iRemoving temporary ppm-Files...");
  XFlush(fl_get_display());  

  sprintf(cmdbuf,"rm -f %s/%s.*.ppm",work_class->START_dir_only,work_class->START_fname_only);
  (void) system(cmdbuf);

  fl_addto_browser(fd_CREATE_MPEG->BR_Log,"@iRemoving temporary Y-,U- and V-Files...");
  XFlush(fl_get_display());  
  sprintf(cmdbuf,"rm -f %s/%s*.Y",work_class->START_dir_only,work_class->START_fname_only);
  (void) system(cmdbuf);

  sprintf(cmdbuf,"rm -f %s/%s*.U",work_class->START_dir_only,work_class->START_fname_only);
  (void) system(cmdbuf);

  sprintf(cmdbuf,"rm -f %s/%s*.V",work_class->START_dir_only,work_class->START_fname_only);
  (void) system(cmdbuf);
}

//-----------------------------------------------
// callback for ALL BUTTONS/CHECKBUTTONS
//-----------------------------------------------
void callback_Button (FL_OBJECT * ob,long arg)
{
  char cmdbuf[BUFSIZ];
  int test;

  switch (arg)
  {
    case 1: // GO Button
//      (void) fl_show_command_log(FL_FULLBORDER);
      
      // copy backup class
      Get_START_Frame();
      Get_END_Frame();
      delete work_class;
      work_class = backup_class;
      backup_class = new names_n_numbers;
      backup_class->START_Frame = (char *)malloc( strlen(work_class->START_Frame) );
      backup_class->END_Frame = (char *)malloc( strlen(work_class->END_Frame) );
      strcpy(backup_class->START_Frame, work_class->START_Frame);
      strcpy(backup_class->END_Frame, work_class->END_Frame);

      fl_set_cursor(fd_CREATE_MPEG->CREATE_MPEG->window, XC_watch);

      // Do some file-conversion
      // prevent mpeg-encoding when error occured while creating PPM or YUV-files
      if ( Make_YUV_Files_INC() )
      {
        Remove_Garbage();
        fl_call_object_callback(fd_CREATE_MPEG->BT_Exit);
        return;
      }

      // correct size to even numbers
      work_class->first_width += (work_class->first_width % 2);
      work_class->first_height += (work_class->first_height % 2);

      // If 'Cycle' chosen do the same backwards
      if ( fl_get_button(fd_CREATE_MPEG->CB_Create_Cycle) )
        // prevent mpeg-encoding when error occured while creating PPM or YUV-files
        if ( Make_YUV_Files_DEC() )
        {
          Remove_Garbage();
          fl_call_object_callback(fd_CREATE_MPEG->BT_Exit);
          return;
        }

      // Call the MPEG-Encoder
      test = MPEG_Encoder();
      if (test==-1 || test==127)
      {
        fl_show_alert("ERROR:","Execution of MPEG-Encoder 'mpeg' failed !","Aborting...",0);
        Remove_Garbage();
        fl_call_object_callback(fd_CREATE_MPEG->BT_Exit);
        return;
      }

      sprintf(cmdbuf,"@bMPEG-Encoder 'mpeg' exit code: %i !",test);
      fl_addto_browser(fd_CREATE_MPEG->BR_Log, cmdbuf);
      XFlush(fl_get_display());  
      Remove_Garbage();

      fl_set_browser_hscrollbar(fd_CREATE_MPEG->BR_Log,FL_ON);
      fl_set_browser_vscrollbar(fd_CREATE_MPEG->BR_Log,FL_ON);
      XFlush(fl_get_display());

      fl_reset_cursor(fd_CREATE_MPEG->CREATE_MPEG->window);
      
      fl_show_alert("INFORMATION:","Conversion complete !",\
        fl_get_button(fd_CREATE_MPEG->CB_mpeg_play) ? "Running 'mpeg_play'...":"",0);
  
      // Run MPEG-Player ?
      if ( fl_get_button(fd_CREATE_MPEG->CB_mpeg_play) && !test )
      {
        XFlush(fl_get_display());
        sprintf(cmdbuf,"mpeg_play -quiet -loop -controls on -dither color -framerate %i %s/%s%s &",\
                15,work_class->START_dir_only,work_class->START_fname_only,".mpg");
        if ( system(cmdbuf) )
        {
          fl_show_alert("ERROR:","Execution of 'mpeg-play' failed !","Aborting...",1);
          fl_call_object_callback(fd_CREATE_MPEG->BT_Exit);
        }
      }
      break;
      
    case 2: // Choose Start/Stop Frame
      backup_class->START_Frame = NULL;
      backup_class->END_Frame = NULL;

      fl_hide_object(fd_CREATE_MPEG->BT_Go);

      // Ask user for start file
      if( Get_START_Frame() )
        break;
      else
      // Ask user for stop file
      if ( Get_END_Frame() )
        break;

      fl_show_object(fd_CREATE_MPEG->BT_Go);

      break;
      
    case 3: // Cycle Checkbutton
      break;
      
    case 4: // mpeg_play Ckeckbutton
      break;

    case 5: // EXIT
//      fl_hide_command_log();
      fl_hide_form(fd_CREATE_MPEG->CREATE_MPEG);
      exit(0);
      break;

    default:
      ;
  }
}

//-----------------------------------------------
// returns: 0: success
//          1: failure
//-----------------------------------------------
int main(int argc, char *argv[])
{
  int c;
  
  // allocate classes
  work_class = new names_n_numbers;
  backup_class = new names_n_numbers;

  // initialize...
  fl_initialize(&argc, argv, 0, 0, 0);

  // Set global borderwidth
  fl_set_border_width(BORDER_WIDTH);

  fl_set_goodies_font(FL_BOLD_STYLE,FL_NORMAL_SIZE);
  
  // Create the form so we can set checkbuttons
  fd_CREATE_MPEG = create_form_CREATE_MPEG();

  opterr = 0; // suppress Error-messages from getopt
  
  while( (c=getopt(argc, argv, "h")) != -1)
    switch (c)
    {
      case 'h':
        fprintf(stderr,"\nusage: %s: [-h] [xforms]\n\n",argv[0]);
        fprintf(stderr,"  -h: this information\n");
        fprintf(stderr,"  xforms: These options will be passed to fl_initialize() of the XForms library.\n");
        fprintf(stderr,"          You shouldn't need these options.\n\n");
        return 0;
      case '?':
        break;
    }

  // redirect TIFF-Error- and Warnig-Handler
  (void) TIFFSetErrorHandler(NULL);
  (void) TIFFSetWarningHandler(NULL);
  
  // show the first form
  fl_hide_object(fd_CREATE_MPEG->BT_Go);
  fl_set_form_position(fd_CREATE_MPEG->CREATE_MPEG,-fd_CREATE_MPEG->CREATE_MPEG->w-15,0);
  fl_show_form(fd_CREATE_MPEG->CREATE_MPEG,FL_PLACE_GEOMETRY,FL_FULLBORDER,"XMRM_MPEG V1.0");
  XFlush( fl_get_display() );
  fl_set_browser_fontsize(fd_CREATE_MPEG->BR_Log,FL_NORMAL_SIZE);
  fl_set_browser_hscrollbar(fd_CREATE_MPEG->BR_Log,FL_OFF);
  fl_set_browser_vscrollbar(fd_CREATE_MPEG->BR_Log,FL_OFF);
  
  fl_do_forms();
}

