//
// tardy - a tar post-processor
// Copyright (C) 2011 Peter Miller
//
// 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 3 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, see <http://www.gnu.org/licenses/>.
//

#ifndef LIBTARDY_ROFF_H
#define LIBTARDY_ROFF_H

#include <libtardy/rcstring.h>
#include <map>

/**
  * The roff class is used to represent the processing required to
  * simulate a portion of groff(1) functionality, for the purpose of
  * printing --help text.
  */
class roff
{
public:
    /**
      * The destructor.
      */
    virtual ~roff();

    /**
      * The default constructor.
      */
    roff();

    void interpret(const char **text, size_t text_size);

private:
    /**
      * The ocol instance variable is used to remember the current
      * output column.
      *
      * assert(ocol <= icol);
      */
    size_t ocol;

    /**
      * The icol instance variable is used to remember the current input
      * column.  It differs from ocol when white space has been seen.
      *
      * assert(ocol <= icol);
      */
    size_t icol;

    /**
      * The fill instance variable is used to remember whether or not
      * we are currently filling.
      */
    bool fill;

    /**
      * The in instance variable is used to remember the current
      * indent.
      */
    int in;

    /**
      * The in_base instance variable is used to remember the current
      * paragraph indent.
      */
    int in_base;

    /**
      * The ll instance variable is used to remember the line length.
      */
    size_t ll;

    /**
      * The roff_line instance variable is used to remember the input
      * line we are up to, in the input "file".
      */
    long roff_line;

    /**
      * The roff_file instance variable is used to remember the input
      * file's name.
      */
    char *roff_file;

    /**
      * The TP_line instance variable is used to remember
      * something
      */
    int TP_line;

    typedef std::map<rcstring, rcstring> string_registers_t;

    /**
      * The string_registers instance variable is used to remember the
      * values in the string registers.
      */
    string_registers_t string_registers;

    void br(void);
    void sp(void);
    void ds_guts(const rcstring &name, const rcstring &value);
    void lf(int argc, const char **argv);
    void emit(char c);
    void emit_word(const char *buf, size_t len);
    void interpret_line_of_words(const char *line);
    void error(const char *s, ...);
    void get_name(const char **lp, char *name);
    const char *string_find(const char *name);
    const char *numreg_find(const char *name);
    void prepro(char *buffer, const char *line);
    void interpret_text(const char *line);
    void sub(char *buffer, int argc, const char **argv);
    void interpret_text_args(int argc, const char **argv);
    void interpret_control(const char *line);
    void concat_text_args(int argc, const char **argv);
    void so(int argc, const char **argv);
    void ds(int argc, const char **argv);
    void dot_in(int argc, const char **argv);
    void dot_br(int argc, const char **argv);
    void dot_ce(int argc, const char **argv);
    void dot_fi(int argc, const char **argv);
    void dot_if(int argc, const char **argv);
    void dot_ip(int argc, const char **argv);
    void dot_pp(int argc, const char **argv);
    void dot_nf(int argc, const char **argv);
    void dot_r(int argc, const char **argv);
    void dot_re(int argc, const char **argv);
    void dot_rs(int argc, const char **argv);
    void dot_sp(int argc, const char **argv);
    void dot_tp(int argc, const char **argv);
    void dot_ignore(int argc, const char **argv);
    void dot_sh(int argc, const char **argv);

    /**
      * The copy constructor.  Do not use.
      *
      * @param rhs
      *     The right hand side of the initialisation.
      */
    roff(const roff &rhs);

    /**
      * The assignment operator.  Do not use.
      *
      * @param rhs
      *     The right hand side of the initialisation.
      */
    roff &operator=(const roff &rhs);
};

#endif // LIBTARDY_ROFF_H
