/***************************************************************************
 *   Copyright (C) 2005 by Christian Bucher                                *
 *   christian.bucher@amadyne.net                                          *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

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

#include "DVD-stuff.h"

int main(int argc, char *argv[])
{
T_DVD_NODE  *pStartNode, *pNode;

  pStartNode = readDVDFileSingleList("/home/cbx/FH/SE_2004/src/uebung_6_master/DC-DVDs.txt");
  
  // single list  
  for(pNode = pStartNode->pNext; pNode; pNode = pNode->pNext)
    {
    printDVDBlock(pNode);
    }
  
  // wieder aufräumen
  freeDVDBlockList(pStartNode); 
  
  pStartNode = readDVDFileBinaryTree("/home/cbx/FH/SE_2004/src/uebung_6_master/DC-DVDs.txt");
  
  printf("\n*** und nun als Birnbaum ***\n\n");
  // und wieder ausgeben
  traverseDVDBinaryTree(pStartNode);
  
  return EXIT_SUCCESS;
}


//**************************************
// Einen leeren T_DVD_NODE erzeugen

T_DVD_NODE *newDVDNode(void)
{
T_DVD_NODE *pTemp;

if ((pTemp = malloc(sizeof(*pTemp))))
  {
  memset(pTemp, 0, sizeof(*pTemp));
  }

return pTemp;
}

//**************************************
// Ein Datenfile von szPath einlesen und
// in single linkes list einsortieren. 
// Liefert den Rootpointer oder NULL

T_DVD_NODE *readDVDFileSingleList(char *szPath)

{
T_DVD_NODE  *pStartNode, *pNode, *pNewNode;
FILE        *fh;

if ((fh = fopen(szPath,"r")))
  {
  pStartNode = pNode = newDVDNode();

  while ((pNewNode = readDVDBlock(fh))) // so lange Daten im file
    {
    pNode = pStartNode;
    
    while (pNode->pNext && (strcmp(pNode->pNext->szTitel, pNewNode->szTitel) < 0))
      {
      pNode = pNode->pNext;
      }
    // einhängen
    pNewNode->pNext = pNode->pNext; 
    pNode->pNext = pNewNode;  
    
    }
        
  fclose (fh);
  return pStartNode;
  }
else
  {
  return NULL;
  }
}

//**************************************
// Ein Datenfile von szPath einlesen und
// in Binärbaum einsortieren. 
// Liefert den Rootpointer oder NULL

T_DVD_NODE *readDVDFileBinaryTree(char *szPath)

{
T_DVD_NODE  *pStartNode, *pNode, *pNewNode;
FILE        *fh;

if ((fh = fopen(szPath,"r")))
  {
  pStartNode = NULL;

  while ((pNewNode = readDVDBlock(fh))) // so lange Daten im file
    {   
    pStartNode = insertDVDBlockBinaryTree(pStartNode, pNewNode);
    }     
    
  fclose (fh);
  return pStartNode;
  }
else
  {
  return NULL;
  }
}

//*****************************
// Supportfunktion einsortieren
T_DVD_NODE *insertDVDBlockBinaryTree(T_DVD_NODE *pRoot, T_DVD_NODE *pNode)

{
if (pRoot)
  {
  if (strcmp(pRoot->szTitel, pNode->szTitel) > 0)
    {
    pRoot->pLeft = insertDVDBlockBinaryTree(pRoot->pLeft, pNode);
    }
  else
    {
    pRoot->pRight = insertDVDBlockBinaryTree(pRoot->pRight, pNode);
    }
  return pRoot;
  }
else
  {
  
  return pNode;
  }
  
}

//*****************************
// Baum traversieren
T_DVD_NODE *traverseDVDBinaryTree(T_DVD_NODE *pRoot)

{
if (pRoot)
  {
  traverseDVDBinaryTree(pRoot->pLeft);
  printDVDBlock(pRoot);
  traverseDVDBinaryTree(pRoot->pRight); 
  }
}


//**************************************
// Einen Datenblock von fh einlesen. 
// Liefert den Blockpointer oder NULL on EOF
T_DVD_NODE *readDVDBlock(FILE *fh)
{
T_DVD_NODE *pNode;
char        szBuffer[BUFFER_SIZE+4]; // headroom allocation
T_FELD      tFeld;
int         c, i;

i = 0; tFeld = Nummer;

if ((pNode = newDVDNode()))
  {
  while ((c = fgetc(fh)) != EOF)
    {
    // die Anführungszeichen verwerfen
    if ('"' == c) continue;
    
    switch (c)
      {
      case '\n':
      case '\t':
        szBuffer[i] = 0;
        i = 0;
        switch (tFeld)
          {
          case Nummer:
            sscanf(szBuffer, "%d", &pNode->nNummer);
            break;
            
          case Titel:
            strncpy(pNode->szTitel, szBuffer, TITEL_SIZE);
            pNode->szTitel[TITEL_SIZE-1] = 0;
            break;
            
          case PostProc:
            pNode->nPostProc = strlen(szBuffer) ? 1 : 0;
            break;
            
          case Spender:
            strncpy(pNode->szSpender, szBuffer, SPENDER_SIZE);
            pNode->szSpender[SPENDER_SIZE-1] = 0;
            break;
          
          case Format:
            if (!strcmp(VCD_NAME, szBuffer))
              pNode->Format = VCD;
            
            else if (!strcmp(SVCD_NAME, szBuffer))
              pNode->Format = SVCD;
              
            else if (!strcmp(DIVX_NAME, szBuffer))
              pNode->Format = DivX;
            
            else
              pNode->Format = unknown;
            break;
            
          case Datum:
            sscanf(szBuffer, "%d.%d.%d",
                   &pNode->Datum.Tag,
                   &pNode->Datum.Monat,
                   &pNode->Datum.Jahr);
            break;
          } // switch (tFeld)
        
        if ('\n' == c)
          {
          return pNode;
          }
              
        tFeld++;          
        break;
            
      default:
        szBuffer[i] = (char)c;
        // nur inkrementieren, wenns noch platz hat 
        i += (i < BUFFER_SIZE-1) ? 1 : 0; 
      }
    }
  }  
return NULL;
}


//**************************************
// Einen Block schön auswerfen
T_DVD_NODE *printDVDBlock(T_DVD_NODE *pNode)
{

printf ("Nr. %3d: Titel: %s\n", pNode->nNummer, pNode->szTitel);
printf ("Format: ");

switch(pNode->Format)
  {
  case unknown:
    printf("unbekannt");
    break;
  case VCD:
    printf("Video CD");
    break;
  case SVCD:
    printf("Super Video CD");
    break;
  case DivX:
    printf("DivX");
    break;
  }
  
if(pNode->nPostProc)
  {
  printf(", nachbearbeitet");
  }
  
if (strlen(pNode->szSpender))
  printf ("\nGespendet von %s ", pNode->szSpender);
else
  printf ("\nGespendet ");

printf ("am %02d.%02d.%04d\n\n",
        pNode->Datum.Tag, pNode->Datum.Monat, pNode->Datum.Jahr);
}

//***************************
// Liste rekursuiv freigeben 
void freeDVDBlockList(T_DVD_NODE *pNode)
{

if (pNode)
  {
  freeDVDBlockList(pNode->pNext);
  }
}

syntax highlighted by Code2HTML, v. 0.9.1