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

   (c) 1996,1997 by Salvador Eduardo Tropea (SET).
   e-mail: salvador@inti.edu.ar

   You can use this code for any purpose if you don't remove the
original copyright.

 Filename -       InfBase.h

 Functions
                  Member functions of following classes
                      TInfTopic
                      TInfIndex
                      TInfFile
                      TInfIndexCollection

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

#ifndef __InfBase_H
#define __InfBase_H

#define cInfColor      "\x37\x3F\x3A\x13\x13\x30\x3E\x1E\x4E\x2E"
#define cInfBlackWhite "\x07\x0F\x07\x70\x70\x07\x0F\x70\x0F\x70"
#define cInfMonochrome "\x07\x0F\x07\x70\x70\x07\x0F\x70\x0F\x70"
#define cInfViewer     "\x06\x07\x08\x09"
#ifdef FOR_EDITOR
#define cInfWindow     "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
#else
#define cInfWindow     "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49"
#endif

#ifndef __STDIO_H
#include <stdio.h>
#endif //__STDIO_H

#ifndef __SET_TNoCasTC_H__
#include "tnocastc.h"
#endif

// 90 because the Ralf Brown list can make that
#define MAX_NODE_NAME 90
#define BUF_SIZE (MAX_NODE_NAME*4+MAX_NODE_NAME/2)

// structure CrossRef

struct CrossRef
{
 char Name[MAX_NODE_NAME];
 char Name2[MAX_NODE_NAME];
 int offset;
 int line;
 int linebreak;
 uchar length;
};


// structure IndirectIndex

typedef struct
{
 long lPos;
 char Name[MAX_NODE_NAME];
} IndirectIndex;


// TInfTopic

class TInfFile;

class TInfTopic
{

public:

    TInfTopic( int mode );
    virtual ~TInfTopic();

    void getCrossRef( int i, TPoint& loc, uchar& length, char *& ref, int &pl );
    char *getCrossRef( int i ) { return crossRefs[i].Name; };
    int getLine( int line, char *buffer );
    int getNumCrossRefs() { return numRefs; };
    int numLines() { return iLines; };
    int maxWidth() { return maxLineWidth; };
    void setWidth( int aWidth ) { width = aWidth; };

    int selBestMatch(char *match,int &PerfectMatch);

    int numRefs;
    CrossRef *crossRefs;

    Boolean Status;
    int modeFlags;

    void *Read( TInfFile& File  );

    // Lo que contiene
    char *Text;
    int  iLines;
    int  maxLineWidth;
    long lSize;

    char Node[MAX_NODE_NAME];
    char Next[MAX_NODE_NAME];
    char Prev[MAX_NODE_NAME];
    char Up[MAX_NODE_NAME];

    int SearchNextWith(char *str,int len,int &selected,int &vislen);

    void ReadNodeInfo(TInfFile &File);

private:

    void ReadText( TInfFile &File );
    void ReadCrossRefs( void );
    int width;

    // Usadas por getLine
    int lastOffset;
    int lastLine;

};

// Valores para modeFlag
const moinCutNodeWord  = 1,
      moinHideNodeLink = 2;

struct TIIC
{
 long pos;
 char name[0];
};

// TInfIndexCollection
//   That's a No case sensitive, No owner and SOStack collection, the data in each
// cell is an TIIC structure.

class TInfIndexCollection : public TNoCaseSOSStringCollection
{
public:
 TInfIndexCollection(ccIndex aLimit, ccIndex aDelta, SOStack *stk) :
   TNoCaseSOSStringCollection(aLimit,aDelta,stk) {};
 void insert(long pos, char *s, int len);
 virtual char *GetString( void *h );
};

struct TListBoxRec
{
 TCollection *items;
 ccIndex selection;
};

// TInfIndex

typedef char NameOfNode[MAX_NODE_NAME];

class TInfIndex
{
public:

    TInfIndex( TInfFile& o, int Indirect );
    TInfIndex( TInfFile& o ); // Para archivos sin Tag Table
    ~TInfIndex();

    long position( int );
    int WhatIndex(char *Nom);

    int size;
    IndirectIndex *IndOffsets;
    int indirects;
    Boolean Status;

    SOStack *stk;
    TInfIndexCollection *coll;

    int SearchFirstWith(int Key,int &selected);
};


// TInfFile

class TInfFile
{

public:

    TInfFile( char *s ) { DoAll(s,1); };
    virtual ~TInfFile();
    void DoAll(char *s, int Verbose=0 );

#if 1
    void seekToNode( const char *Name);
#endif
    TInfTopic *getTopic( char *, int Verbose, int modeForTopic );
    TInfTopic *invalidTopic();

    FILE *stream;
    Boolean Status;
    Boolean IsCompressed;

    TInfIndex *index;
    long indexPos;
    int  iFile;

    char Buffer[BUF_SIZE];
    void GetLine(void) { fgets(Buffer,SizeOfReadBuf,stream); };
    void SkipNode(void);

    // Special I/O for multi-file
    int  fSeek(long Pos);
    FILE *fOpen(char *Nombre);
    int  fClose(FILE *f);

    char NameOfFile[MAX_NODE_NAME];

    int ConvertIt(long Pos);
    static int SizeOfReadBuf;

    char NameOfTemporal[L_tmpnam];

private:
    int ExpandName(char *Buf, char *Nombre, int iExt);

};

#endif // __InfBase_H


