/*
 *  Copyright (c) by Jaroslav Kysela (Perex soft)
 */

#include <sys/ioctl.h>
#include <stdio.h>
#include <stdarg.h>
#include <ncurses.h>
#include "pmod.h"

void fatal( char *fmt, ... )
{
  va_list va;
  
  va_start( va, fmt );
  fprintf( stderr, "\npmod error >>> " );
  vfprintf( stderr, fmt, va );
  fprintf( stderr, "\n" );
  fflush( stderr );
  va_end( va );
  if ( seqfd >= 0 )
    ioctl( seqfd, GUS_IOCTL_ABORT );
  if ( !background && ncursesFlag )
    {
      endwin();
    }
  exit( 1 );
}

void dprintf( char *fmt, ... )
{
  va_list va;
  
  va_start( va, fmt );
  vfprintf( stderr, fmt, va );
  fflush( stderr );
  va_end( va );
}

void wprintf( char *fmt, ... )
{
  va_list va;
  
  if ( warnings )
    {
      va_start( va, fmt );
      fprintf( stderr, "\npmod warning >>> " );
      vfprintf( stderr, fmt, va );
      fflush( stderr );
      va_end( va );
    }
}

void pprintf( char *fmt, ... )
{
  va_list va;
  
  if ( !background )
    {
      va_start( va, fmt );
      vfprintf( stdout, fmt, va );
      va_end( va );
    }
}

static char *convert_to_visible( const char *s )
{
  static char res[ 128 ];
  char *s1;
  
  for ( s1 = res; *s; s++, s1++ )
    if ( *s >= ' ' && *s < 0x7f ) *s1 = *s; else *s1 = ' ';
  *s1 = 0;
  return res;
}

void info()
{
  register i, j, k;
  

  pprintf( "\nSong: %s * Type: %s * Chn: %i * Ins: %i\n\n", 
    convert_to_visible( songName ), songType, songChannels, songInstr );
  for ( i = 0; i < songInstr; i++ )
    {
      struct INSTR *is = songInstrs[ i ];
      if ( is && is -> used )
        {
           for ( j = 0 ; j < MAX_SAMPLES; j++ )
             {
               struct SAMPLE *smp = is -> samples[ j ];
               if ( smp && smp -> used )
                 {
                   pprintf( "%02i %-30s ", i + 1, convert_to_visible( smp -> name ) );
                   pprintf( "L%06li S%06li E%06li %c%05i V%02i %s B%02i\n",
	          	   smp -> length, 
          		   smp -> lstart, 
          		   smp -> lend,
          		   moduleType == MODULE_XM ? 'R' : 'F', 
          	  	   moduleType == MODULE_XM ? (int)smp -> relativeNote : (int)smp -> freqC4,
          		   smp -> volume,
          		   ( smp -> type & SMP_TYPE_UNSIGNED ) ? "UNS" :
          		     ( smp -> type & SMP_TYPE_DELTA ) ? "DLT" : "SIG",
          		   ( smp -> type & SMP_TYPE_16BIT ) ? 16 : 8 
          	         );
          	 }
             }
        }
    }
  if ( moduleType == MODULE_XM )
    {
      pprintf( "-----\n" );
      for ( i = 0; i < songInstr; i++ )
        {
           struct INSTR *is = songInstrs[ i ];
           if ( is && is -> used )
             {
               k = 0;
               for ( j = 0; j < MAX_SAMPLES; j++ )
                 if ( is -> samples[ j ] && is -> samples[ j ] -> used ) k++;
               pprintf( "%02i %-30s EVL[%c%c%c] EVP[%c%c%c] FAD-%04x SMS-%02i\n",
          		i + 1, 
           		convert_to_visible( is -> name ),
           		is -> volType & IS_TYPE_ON 	? '+' : ' ',
          		is -> volType & IS_TYPE_SUSTAIN ? 's' : ' ',
           		is -> volType & IS_TYPE_LOOP 	? 'l' : ' ',
           		is -> panType & IS_TYPE_ON 	? '+' : ' ',
           		is -> panType & IS_TYPE_SUSTAIN ? 's' : ' ',
           		is -> panType & IS_TYPE_LOOP 	? 'l' : ' ',
           		is -> fadeout,
           		k
                   );
             }
        }
    }
  pprintf( "*** GUS memory used: %i bytes, remaining: %i bytes ***\n", gusMemorySize - gusMemFree(), gusMemFree() );
}
