// =========================================================================
// Media catalogue generator program - Version #109.
// Kapitany Csaba - 2008
// 
// Compile: cc GenerateCatalogue109.c
// =========================================================================

/* Example Parameter file:

#
# Kapitány Csaba katalógus paraméter fájl
#
# Vezérlősorok felépítése:
# 
# # = megjegyzés, ha az első oszlopban van a # jel.
# ! = Új táblázat fejléc kezdete.
# ; = mezőelválasztó (CSV separator)
#
# A legelső tételsor a fájl egészére vonatkozó paramétereket adja meg:
#
# 1. oszlop = Média típus           pl: CD, LP
# 2. oszlop = Author (Public)       pl: Capitanio
# 3. oszlop = Author (Private)      pl: Kapitány Csaba
# 4. oszlop = Catalogue type        pl: Classical Music, Wishlist
#
# Tételsorok felépítése:
#
# 1. oszlop = kiadó         pl: Harmonia Mundi xxx
# 2. oszlop = zeneszerző    pl: J.S.Bach
# 3. oszlop = zenemű címe   pl: Magnificat
# 4. oszlop = előadó(k)     pl: J.P.Jaroussky
# 5. oszlop = adathordozó,  pl: 3CD, 2LP
# 6. oszlop = megjegyzés,   pl: Évszám
# 

! Példa tételek

CD; Capitanio; Csabi; Classical Music
Harmonia Mundi HMX 2907182; Arvo Part; De Profundis; Theatre of voices; 1CD; 1996.

*/


// =========================================================================

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

#define LEN_MAX         100   // Filename's max. length
#define L_RECORD        1000  // Record buffer size
#define L_FIELD         300   // Field buffer size

#define TRUE  1
#define FALSE 0

#define SEPARATOR       ";"   // Field separator
#define COMMENT         '#'   // Comment sign in the 1st column
#define NEW_TABLE       '!'   // New Table directive sign in the 1st column

static  FILE    *pFileI;
static  char    *pcToken;
static  char     acInpFile [ LEN_MAX+1 ] = { "nofile" };

static  char     acMediaType [ 100 ] = { "CD" };
static  char     acAuthorPri [ 100 ] = { "Kapitány" };
static  char     acAuthorPub [ 100 ] = { "Capitanio" };
static  char     acPageHeader[ 100 ] = { "Classical Music" };

static  iSerialNumber;
static  iTableHeaderFlag = TRUE;
static  iCommonParamFlag = FALSE;
static  iFidelioFlag = FALSE;

static  unsigned char acBuff [ L_RECORD+1 ];
static  unsigned char acIdentifier [ L_FIELD+1 ];
static  unsigned char acComposer [ L_FIELD+1 ];
static  unsigned char acTitle [ L_FIELD+1 ];
static  unsigned char acPerformer [ L_FIELD+1 ];
static  unsigned char acMedia [ L_FIELD+1 ];
static  unsigned char acComment [ L_FIELD+1 ];

// =========================================================================

#define HTML_FILE_HEADER "\
<html>\n\
<head>\n\
\n\
\n\
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n\
  <meta http-equiv=\"description\" content=\"%s, Homepage, Website\">\n\
  <meta http-equiv=\"keywords\" content=\"%s, Early music, Baroque, Barokk, Opera, Chamber music\">\n\
\n\
  <meta name=\"author\" content=\"%s\">\n\
  <meta name=\"description\" content=\"%s, Homepage, Website\">\n\
  <meta name=\"keywords\" content=\"%s, Early music, Baroque, Barokk, Opera, Chamber music\">\n\
  <meta name=\"generator\" content=\"Generator script on Linux for Netscape\">\n\
\n\
  <title> %s %s %s Catalogue </title>\n\
\n\
</head>\n\
\n\
<body lang=EN-US BGCOLOR=\"#F8DDBA\" LINK=\"#009900\" VLINK=\"#FF0000\" ALINK=\"#000088\">\n\
<BR>\n\
<h1><center><FONT COLOR=\"#800000\">\n\
%s%s %s%s %s Catalogue\n\
</FONT></center></h1>\n\
"

// ------------------------------------------------------------------------

#define HTML_FILE_FOOTER "\
<BR><HR>\n\
\n\
<!-- Author's logo: -->\n\
\n\
<h3>\n\
 <i><font SIZE=-1> Last updated: %s\
 , EmaiI: <img title=\"go_robot_here@gmail.com\" src=\"logo_100.gif\"\n\
 alt=\"go_robot_here@gmail.com\" style=\"height: 24px; width: 226px;\"\n\
 align=\"middle\"></font></i>\n\
</h3>\n\
\n\
</body>\n\
</html>\n\
"

// ------------------------------------------------------------------------

#define HTML_LOGO_REF "\
<h3><i><font><i><font size=\"-1\"> Home:\n\
 <a href=\"index.html\"> Csaba Kapitany </a>\n\
 <a href=\"http://www.geocities.com/csaba_kapitany\"> (www.geocities.com/csaba_kapitany) </a>\n\
</font></i></font></i></h3>\n\
"

// ------------------------------------------------------------------------

#define HTML_TABLE_BEGIN "\
<table border=1 cellspacing=0 cellpadding=0 style='border-collapse:collapse'>\n\
"

// ------------------------------------------------------------------------

#define HTML_SEPARATOR_LINE "\
<BR><FONT COLOR=\"#800000\"><B> %s </B></FONT><BR>\n\
"

// ------------------------------------------------------------------------

#define HTML_TABLE_END "\
</table>\n\
"

// ------------------------------------------------------------------------

#define HTML_HOME_REF "\
 <a href=\"http://www.geocities.com/csaba_kapitany\">\
"

// ------------------------------------------------------------------------

#define HTML_HOME_REF_END "</a>"

// ------------------------------------------------------------------------

#define HTML_TABLE_HEADER_ROW "\
 <tr align=center>\n\
  <td width=40 bgcolor=\"#E0E0E0\"><B> Nr </B></td>\n\
  <td width=100 bgcolor=\"#E0E0E0\"><B> Identifier </B></td>\n\
  <td width=159 bgcolor=\"#E0E0E0\"><B> Composer </B></td>\n\
  <td width=200 bgcolor=\"#E0E0E0\"><B> Title </B></td>\n\
  <td width=200 bgcolor=\"#E0E0E0\"><B> Performer </B></td>\n\
  <td width=50 bgcolor=\"#E0E0E0\"><B> Media </B></td>\n\
  <td width=159 bgcolor=\"#E0E0E0\"><B> Comment </B></td>\n\
 </tr>\n\
"

// ------------------------------------------------------------------------

#define HTML_TABLE_ITEM_ROW "\
 <tr>\n\
  <td width=40 style='padding:0pt 5pt'> %d </td>\n\
  <td width=100 style='padding:0pt 5pt'> %s </td>\n\
  <td width=159 style='padding:0pt 5pt'> %s </td>\n\
  <td width=200 style='padding:0pt 5pt'> %s </td>\n\
  <td width=200 style='padding:0pt 5pt'> %s </td>\n\
  <td width=50 style='padding:0pt 5pt'> %s </td>\n\
  <td width=159 style='padding:0pt 5pt'> %s </td>\n\
 </tr>\n\
"


// =========================================================================

static int fDisplayAllField( int iNumberOfFields );
static int fClearAllField();
static int fNewTable( char *pacDisplay );

// =========================================================================

int main( argc, argv )
int argc;
char **argv;
{
  iFidelioFlag = FALSE;
  iCommonParamFlag = FALSE;
  time_t unix_time;

  if( argc < 2 )
  {
      printf( "\nusage: %s Catal.txt X >! Catal.html -> Realname HTML Catalog", argv[0] );
      printf( "\n       %s Catal.txt   >! Catal.html -> Nickname HTML Catalog\n\n", argv[0] );

      exit( 1 );
  }

  if( argc > 1 )
  {
      strncpy( acInpFile, argv[1], LEN_MAX ); // Read file name
  }

  if( argc > 2 )
  {
      iFidelioFlag = TRUE; // Set Fidelio->Capitanio
  }

  if(( pFileI = fopen( acInpFile , "r" )) == NULL )
  {
      printf( "\nCatalogue file '%s' is failed to open.\n\n", acInpFile );

      exit( 1 );
  }

  iTableHeaderFlag = TRUE; // Print Header before the next item

  iSerialNumber = 0;

  while( fgets( acBuff, L_RECORD, pFileI ) != NULL ) 
  {   /* `fgets` reads until CR,LF but max. L_RECORD */

    if(( acBuff[0] == COMMENT )
    || ( acBuff[0] == '\0' )
    || ( acBuff[0] == '\r' )
    || ( acBuff[0] == '\n' )) /* Comment in the 1st column, or Empty line */
    {
        continue;
    }

    if( acBuff[0] == NEW_TABLE ) /* New Table directive in the 1st column */
    {
        fNewTable( &acBuff[1] ); // Display the content after the 1st column
        continue;
    }

    fClearAllField();

    if(( pcToken = strtok( acBuff, SEPARATOR )) == NULL ) /* Error */
    {
        continue;
    }

    strncpy( acIdentifier, pcToken, sizeof( acIdentifier )); // Field #1

    if(( pcToken = strtok( NULL, SEPARATOR )) == NULL ) /* No 2. */
    {
        fDisplayAllField( 1 );
        continue;
    }

    strncpy( acComposer, pcToken, sizeof( acComposer )); // Field #2

    if(( pcToken = strtok( NULL, SEPARATOR )) == NULL ) /* No 3. */
    {
        fDisplayAllField( 2 );
        continue;
    }

    strncpy( acTitle, pcToken, sizeof( acTitle )); // Field #3

    if(( pcToken = strtok( NULL, SEPARATOR )) == NULL ) /* No 4. */
    {
        fDisplayAllField( 3 );
        continue;
    }

    strncpy( acPerformer, pcToken, sizeof( acPerformer )); // Field #4

    if(( pcToken = strtok( NULL, SEPARATOR )) == NULL ) /* No 5. */
    {
        fDisplayAllField( 4 );
        continue;
    }

    strncpy( acMedia, pcToken, sizeof( acMedia )); // Field #5

    if(( pcToken = strtok( NULL, "\n" )) == NULL ) /* No 6. (last) */
    {
        fDisplayAllField( 5 );
        continue;
    }

    strncpy( acComment, pcToken, sizeof( acComment )); // Field #6

    fDisplayAllField( 6 );

  }

  printf( "%s", HTML_TABLE_END );

  unix_time = time(&unix_time);

  if( iFidelioFlag == TRUE ) // Fidelio->Capitanio data
  {
    printf( HTML_FILE_FOOTER, ctime(&unix_time));
  }
  else // Public Home Page data (default)
  {
    printf( HTML_FILE_FOOTER, ctime(&unix_time));
    printf( HTML_LOGO_REF );
  }

  fclose( pFileI );

  printf( "\n" );

  exit( 0 );
}

// =========================================================================

static int fDisplayAllField( int iNumberOfFields )
{
  /* Test:
  printf( "NumberOfFields='%d'\t", (int)iNumberOfFields );
  printf( "Identifier='%s'\t", acIdentifier );
  printf( "Composer='%s'\t", acComposer );
  printf( "Title='%s'\t", acTitle );
  printf( "Performer='%s'\t", acPerformer );
  printf( "Media='%s'\t", acMedia );
  printf( "Comment='%s'\n", acComment );
  */

  if( iCommonParamFlag == FALSE ) // Common parameters in the 1st row
  {
    sprintf( acMediaType , "%s", acIdentifier  ); // Convert 1
    sprintf( acAuthorPri , "%s", acComposer    ); // Convert 2
    sprintf( acAuthorPub , "%s", acTitle       ); // Convert 3
    sprintf( acPageHeader, "%s", acPerformer   ); // Convert 4

    iCommonParamFlag = TRUE; // Common parameters are read in

    if( iFidelioFlag == TRUE ) // Fidelio->Capitanio data
    {
        printf( HTML_FILE_HEADER
          , acAuthorPri
          , acAuthorPri
          , acAuthorPri
          , acAuthorPri
          , acAuthorPri
          , acAuthorPri
          , acPageHeader
          , acMediaType
          , ""              // No Web Home reference
          , acAuthorPri
          , ""
          , acPageHeader
          , acMediaType ); // LP or CD
    }
    else // Public Home Page data (default)
    {
        printf( HTML_FILE_HEADER
          , acAuthorPub
          , acAuthorPub
          , acAuthorPub
          , acAuthorPub
          , acAuthorPub
          , acAuthorPub
          , acPageHeader
          , acMediaType
          , HTML_HOME_REF // Web Home reference
          , acAuthorPub
          , HTML_HOME_REF_END
          , acPageHeader
          , acMediaType ); // LP or CD
    }

    return( 0 );
  }

  iSerialNumber++;

  if( iTableHeaderFlag == TRUE )
  {
    printf( "%s", HTML_TABLE_BEGIN );
    printf( "%s", HTML_TABLE_HEADER_ROW );
  }

  printf( HTML_TABLE_ITEM_ROW
        , (int)iSerialNumber
        , acIdentifier
        , acComposer
        , acTitle
        , acPerformer
        , acMedia
        , acComment
        );

  iTableHeaderFlag = FALSE; // Do not print Header before the next item

  return( 0 );
}

// =========================================================================

static int fNewTable( char *pacDisplay )
{
  if( iTableHeaderFlag != TRUE ) // Header is not printed yet
  {
    printf( "%s", HTML_TABLE_END );
  }

  printf( HTML_SEPARATOR_LINE, pacDisplay );

  iTableHeaderFlag = TRUE; // Print Header before the next item

  return( 0 );
}

// =========================================================================

static int fClearAllField()
{
  strncpy( acIdentifier, "*", sizeof( acIdentifier )); // Field #1
  strncpy( acComposer, "*", sizeof( acComposer )); // Field #2
  strncpy( acTitle, "*", sizeof( acTitle )); // Field #3
  strncpy( acPerformer, "*", sizeof( acPerformer )); // Field #4
  strncpy( acMedia, "*", sizeof( acMedia )); // Field #5
  strncpy( acComment, "*", sizeof( acComment )); // Field #6

  return( 0 );
}


/* ========================== end of source =============================== */
