/*
 * File:     tex2any.h
 * Purpose:  Header file for LaTeX --> wxHelp conversion
 *
 *                       wxWindows 1.50
 * Copyright (c) 1993 Artificial Intelligence Applications Institute,
 *                   The University of Edinburgh
 *
 *                     Author: Julian Smart
 *                        Date: 7-9-93
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice, author statement and this permission
 * notice appear in all copies of this software and related documentation.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
 * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
 * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
 * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
 * THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdio.h>
#include "wx.h"
#include "wx_utils.h"
#include "wx_list.h"
#include "wxhlpblk.h"

/*
 * We have a list of macro definitions which we must define
 * in advance to enable the parsing to recognize macros.
 */

class TexMacroDef: public wxObject
{
 public:
  int no_args;
  char *name;
  Bool ignore;

  TexMacroDef(char *the_name, int n, Bool ig);
  ~TexMacroDef(void);
};

#define CHUNK_TYPE_MACRO    1
#define CHUNK_TYPE_ARG      2
#define CHUNK_TYPE_STRING   3

/*
 We have nested lists to represent the Tex document.
 Each element of a list of chunks can be one of:
  - a plain string
  - a macro with/without arguments. Arguments are lists of TexChunks.

Example (\toplevel is implicit but made explicit here):

AddMacroDef("mymat", 2);

\toplevel{The cat sat on the \mymat{very coarse and {\it cheap}}{mat}}.

Parsed as:

TexChunk: type = macro, name = toplevel, no_args = 1
  Children:

    TexChunk: type = argument

      Children:
        TexChunk: type = string, value = "The cat sat on the "
        TexChunk: type = macro, name = mymat, no_args = 2

          Children:
            TexChunk: type = argument

              Children:
                TexChunk: type = string, value = "very coarse and "
                TexChunk: type = macro, name = it, no_args = 1

                  Children:
                    TexChunk: type = argument

                      Children:
                        TexChunk: type = string, value = "cheap"

            TexChunk: type = argument

              Children:
                TexChunk: type = string, value = mat
 */

class TexChunk: public wxObject
{
 public:
  int type;
  char *name;
  char *value;
  int no_args;
  int argn;
  Bool optional;      // Is an optional argument

  wxList children;
  TexChunk(int the_type);
  TexChunk(TexChunk& toCopy);
  ~TexChunk(void);
};

extern TexChunk     *TopLevel;
extern wxList       MacroDefs;
extern wxStringList IgnorableInputFiles; // Ignorable \input files, e.g. psbox.tex

Bool read_a_line(char *buf);
Bool TexLoadFile(char *filename, char *customMacroDefs = NULL);
int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos,
           char *environment = NULL, Bool parseArgToBrace = TRUE, TexChunk *customMacroArgs = NULL);
int ParseMacroBody(char *macro_name, TexChunk *parent, int no_args,
           char *buffer, int pos, char *environment = NULL, Bool parseArgToBrace = TRUE, TexChunk *customMacroArgs = NULL);
void TraverseDocument(void);
void TraverseFromChunk(TexChunk *chunk, wxNode *thisNode = NULL, Bool childrenOnly = FALSE);
#define TraverseChildrenFromChunk(arg) TraverseFromChunk(arg, NULL, TRUE)
void SetCurrentOutput(FILE *fd);
void SetCurrentOutputs(FILE *fd1, FILE *fd2);
void AddMacroDef(char *name, int n, Bool ignore = FALSE);
void TexInitialize(void);
void TexCleanUp(void);
void TexOutput(char *s, Bool ordinaryText = FALSE);
char *GetArgData(void);             // Get the string for the current argument
int GetNoArgs(void);                // Get the number of arguments for the current macro
TexChunk *GetArgChunk(void);        // Get the chunk for the current argument
TexChunk *GetTopLevelChunk(void);   // Get the chunk for the top level
TexChunk *GetNextChunk(void);       // Look ahead to the next chunk
Bool IsArgOptional(void);           // Is this argument an optional argument?
void DefineDefaultMacros(void);     // Optional set of default macros
int GetCurrentColumn(void);         // number of characters on current line
extern wxPathList TexPathList;      // Path list, can be used for file searching.

// Major document styles
#define LATEX_REPORT    1
#define LATEX_ARTICLE   2
#define LATEX_LETTER    3
#define LATEX_BOOK      4
#define LATEX_SLIDES    5

extern TexChunk *DocumentTitle;
extern TexChunk *DocumentAuthor;
extern TexChunk *DocumentDate;
extern char *CurrentLabel;
extern int DocumentStyle;
extern int MinorDocumentStyle;
extern char *BibliographyStyleString;
extern char *DocumentStyleString;

extern int normalFont;
extern int smallFont;
extern int tinyFont;
extern int largeFont1;
extern int LargeFont2;
extern int LARGEFont3;
extern int hugeFont1;
extern int HugeFont2;
extern int HUGEFont3;

// Section font sizes
extern int chapterFont;
extern int sectionFont;
extern int subsectionFont;

extern int chapterNo;
extern int sectionNo;
extern int subsectionNo;
extern int subsubsectionNo;
extern int figureNo;

extern int ParSkip;
extern int ParIndent;

/*
 * Local to Tex2Any library
 *
 */
 
extern char currentArgData[];
extern Bool haveArgData; // If TRUE, we're simulating the data.
void StartSimulateArgument(char *data);
void EndSimulateArgument(void);

/*
 * Client-defined
 *
 */

// Called on start/end of macro examination
void OnMacro(char *name, int no_args, Bool start);

// Called on start/end of argument examination.
// Return TRUE at the start of an argument to traverse
// (output) the argument.
Bool OnArgument(char *macro_name, int arg_no, Bool start);

// Default: library-defined
void DefaultOnMacro(char *name, int no_args, Bool start);

// Default: library-defined
Bool DefaultOnArgument(char *macro_name, int arg_no, Bool start);

// Called on error
void OnError(char *msg);

// Called for information
void OnInform(char *msg);

/*
 * Useful utilities
 *
 */

// Look for \label macro, use this ref name if found or
// make up a topic name otherwise.
char *FindTopicName(TexChunk *chunk);
void ResetTopicCounter(void);

// Parse unit eg. 14, 12pt, 34cm and return value in points.
int ParseUnitArgument(char *unitArg);

// Set small, large, normal etc. point sizes for reference size
void SetFontSizes(int pointSize);

/*
 * Strip off any extension (dot something) from end of file,
 * IF one exists. Inserts zero into buffer.
 *
 */
 
void StripExtension(char *buffer);

/*
 * Reference structure
 *
 */

class TexRef: public wxObject
{
 public:
  char *refLabel;      // Reference label
  char *refFile;       // Reference filename (can be NULL)
  char *sectionNumber; // Section or figure number (as a string)
  TexRef(char *label, char *file, char *section)
  {
    refLabel = copystring(label);
    refFile = file ? copystring(file) : NULL;
    sectionNumber = section ? copystring(section) : copystring("??");
  }
};

extern wxList TexReferences;

/*
 * Add a reference
 *
 */
 
void AddTexRef(char *name, char *file = NULL, char *sectionName = NULL,
         int chapter = 0, int section = 0, int subsection = 0, int subsubsection = 0);

/*
 * Read and write reference file (.ref), to resolve refs for second pass.
 *
 */
void WriteTexReferences(char *filename);
void ReadTexReferences(char *filename);

/*
 * Bibliography stuff
 *
 */

class BibEntry: public wxObject
{
 public:
  char *key;

  /*
   * book, inbook, article, phdthesis, inproceedings, techreport
   */
  char *type;

  /*
   * Possible fields
   *
   */
  char *editor;
  char *title;
  char *booktitle;
  char *author;
  char *journal;
  char *volume;
  char *number;
  char *year;
  char *month;
  char *pages;
  char *chapter;
  char *publisher;
  char *address;
  char *institution;
  char *organization;
  char *comment;

  inline BibEntry(void)
  {
    key = NULL;
    type = NULL;
    editor = NULL;
    title = NULL;
    booktitle = NULL;
    author = NULL;
    journal = NULL;
    volume = NULL;
    number = NULL;
    chapter = NULL;
    year = NULL;
    month = NULL;
    pages = NULL;
    publisher = NULL;
    address = NULL;
    institution = NULL;
    organization = NULL;
    comment = NULL;
  }
};

extern wxList BibList;
extern wxStringList CitationList;

Bool ReadBib(char *filename);
void OutputBib(void);
void ResolveBibReferences(void);
void AddCitation(char *citeKey);

/*
 * Ability to customize, or at least suppress unknown macro errors
 *
 */

extern wxList CustomMacroList;

#define CUSTOM_MACRO_IGNORE 0
#define CUSTOM_MACRO_OUTPUT 1
#define CUSTOM_MACRO_MARK   2

class CustomMacro: public wxObject
{
 public:
  char *macroName;
  char *macroBody;
  int noArgs;
  inline CustomMacro(char *name, int args, char *body)
  {
    noArgs = args;
    macroName = copystring(name);
    if (body)
      macroBody = copystring(body);
    else
      macroBody = NULL;
  }
};

Bool ReadCustomMacros(char *filename);
void ShowCustomMacros(void);
CustomMacro *FindCustomMacro(char *name);

