//@copyright_begin
// ================================================================
// Copyright Notice
// Copyright (C) 1998-2004 by Joe Linoff
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL JOE LINOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// 
// Comments and suggestions are always welcome.
// Please report bugs to http://ccdoc.sourceforge.net/ccdoc
// ================================================================
//@copyright_end

// MULTIPLE INCLUSION GUARD
#ifndef ccdoc_switches_h
#define ccdoc_switches_h

/**
 * This variable allows the header version
 * to be queried at runtime.
 */
namespace {
   char ccdoc_switches_h_rcsid[] = "$Id: switches.h,v 1.10 2004/09/30 04:16:07 jlinoff Exp $";
}

#include "exceptions.h"
#include "log.h"
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>

using namespace std;

namespace ccdoc {
  /**
   * Command line switch processor.
   * @author Joe Linoff
   * @version $Id: switches.h,v 1.10 2004/09/30 04:16:07 jlinoff Exp $
   */
  class switches {
  public:
    typedef map<string,string,less<string> > defines_type;
    typedef set<string,less<string> > undefines_type;
    typedef vector<string> files_type;
  public:
    /**
     * Constructor.
     * @param argc The number of switches.
     * @param argv The array of switch values.
     */
    switches(int argc,char** argv);
    /**
     * Destructor.
     */
    ~switches();
  private:
    /**
     * Make the default constructor private
     * so that it is not inadvertently used.
     */
    switches();
    /**
     * Make the copy constructor private
     * so that it is not inadvertently used.
     */
    switches(const switches&);
  public:
    /**
     * Are the switches ok?
     * @returns True if they are ok or false otherwise.
     */
    bool ok() const {return m_ok;}
  public:
    /**
     * Get the program name.
     * @returns The program name.
     */
    string program_name() const {return m_program_name;}
    /**
     * Display the help message.
     */
    void help() const;
  public:
    /**
     * Was the verbose switch specified?
     * @returns True if verbose mode was specified or false otherwise.
     */
    bool verbose() const {return m_verbose;}
    /**
     * Was the verbose format switch specified?
     * @returns True if verbose format mode was specified or false otherwise.
     */
    bool verbose_format() const {return m_verbose_format;}
    /**
     * Was the index switch specified?
     * If it was, phase 2 is enabled.
     * @returns True if -index was specified or false otherwise.
     */
    bool index() const {return m_index;}
    /**
     * Get the name of the specified database.
     * @returns The database name.
     */
    const string& db() const {return m_db;}
    /**
     * Get the package name for this run.
     * The existence of a package name indicates that
     * that phase 1 is enabled.
     * @returns The package name.
     */
    const string& pkg() const {return m_pkg;}
    /**
     * Get the HTML output directory for this run.
     * The existence of the HTML output directory indicates that
     * that phase 3 is enabled.
     * @returns The HTML output directory.
     */
    const string& html() const {return m_html;}
    /**
     * Get the default root package name.
     * This name never changes. It is used internally.
     * @returns The default root package name for the database.
     */
    const string& default_root() const {return m_default_root;}
    /**
     * Get the root package name.
     * @returns The root package name for the database.
     */
    const string& root() const {return m_root;}
    /**
     * Get the root package file name.
     * @returns The root package name for the database.
     */
    const string& rootfile() const {return m_rootfile;}
    /**
     * Get the URL of the parent of the root package.
     * @returns The URL.
     */
    const string& rooturl() const {return m_rooturl;}
    /**
     * Get the -header file name.
     * @returns The -header file name.
     */
    const string& header() const {return m_header;}
    /**
     * Get the -meta file name.
     * @returns The -meta file name.
     */
    const string& meta() const {return m_meta;}
    /**
     * Get the -trailer file name.
     * @returns The -trailer file name.
     */
    const string& trailer() const {return m_trailer;}
    /**
     * Get the -bg color name.
     * @returns The -bg color name.
     */
    const string& bgcolor() const {return m_bgcolor;}
    /**
     * Get the -fgtext color name.
     * @returns The -fgtext color name.
     */
    const string& fgtextcolor() const {return m_fgtextcolor;}
    /**
     * Get the -fglink color name.
     * @returns The -fglink color name.
     */
    const string& fglinkcolor() const {return m_fglinkcolor;}
    /**
     * Get the -fgvlink color name.
     * @returns The -fgvlink color name.
     */
    const string& fgvlinkcolor() const {return m_fgvlinkcolor;}
    /**
     * Get the -srcurl (or -sourceurl) path name.
     * @returns The source url.
     */
    const string& srcurl() const {return m_srcurl;}
    /**
     * Get the -imgurl (or -imageurl) path name.
     * This is not used in this version.
     * @returns The image url.
     */
    const string& imgurl() const {return m_imgurl;}
    /**
     * Do the file paths contains backslashes that
     * need to be converted (-dospaths).
     * This must be determined at run-time because
     * dospaths are not needed for users that run
     * under unix shells.
     */
    bool dospaths() const {return m_dospaths;}
    /**
     * Report whether the user specified -cdsm or -nocdsm on the
     * command line.
     */
    bool cdsm() const {return m_cdsm;}
    /**
     *  Report whether the user specified -tcms or -notcms on the
     * command line.
     * @since v08r33
     */
    bool tcms() const {return m_tcms;}
    /**
     * Report whether the user specified -rptmac1 or -norptmac1 on the
     * command line.
     * @since v08r34
     */
    bool rptmac1() const {return m_rptmac1;}
  public:
    /**
     * Get the program version.
     * @returns The program version.
     */
    const string& version() const {return m_version;}
  public:
    /**
     * Load the defines map.
     * Each define has a value.
     * @param out The map to update.
     */
    void defines( defines_type& out ) const;
    /**
     * Load the undefines set.
     * @param out The set to update.
     */
    void undefines( undefines_type& out ) const;
    /**
     * Load the files vector.
     * @param out The files vector to update.
     */
    void files( files_type& out ) const {out = m_files;}
    /**
     * Return the number of files.
     * @returns The number of files.
     */
    size_t num_files() const {return m_files.size();}
    /**
     * Returns the maximum file name size.
     */
    unsigned maxpathlen() const {return m_maxpathlen;}
  public:
    /**
     * Report the comments for undocumented namespaces.
     * @returns True for -rptcfuns or false for -norptcfuns.
     */
    bool rptcfuns() const {return m_rptcfuns;}
    /**
     * Report the class summary details.
     * @returns True for -rptcsd or false for -norptcsd.
     */
    bool rptcsd() const {return m_rptcsd;}
    /**
     * Define the class summary indent level for the report.
     * @returns The class summary indent level. The default is 4.
     */
    unsigned rptcsi() const {return m_rptcsi;}
    /**
     * Report the default package author as unascribed?
     * @returns True for -rptdpa or false for -norptdpa.
     */
    bool rptdpa() const {return m_rptdpa;}
    /**
     * Report the default package description as unknown?
     * @returns True for -rptdpd or false for -norptdpd.
     */
    bool rptdpd() const {return m_rptdpd;}
    /**
     * Report the default package version as unknown?
     * @returns True for -rptdpv or false for -norptdpv.
     */
    bool rptdpv() const {return m_rptdpv;}
    bool rpthpc() const {return m_rpthpc;}
    bool rptim() const {return m_rptim;}
    bool rptmac() const {return m_rptmac;}
    bool rptpri() const {return m_rptpri;}
    bool rptpro() const {return m_rptpro;}
    bool rptpub() const {return m_rptpub;}
    bool rpttyp() const {return m_rpttyp;}
    bool rptun() const {return m_rptun;}
    /**
     * Report the code section using a fixed with font.
     * @returns True if the code section should use a
     * a fixed width font or false otherwise. The
     * default is false.
     */
    bool rptfwcf() const {return m_rptfwcf;}
  public:
    /**
     * Get the default author string.
     * The default value is "unascribed".
     * @returns The default author string.
     */
    const char* rptdefa() const {return m_rptdefa.c_str();}
    /**
     * Get the default automatic short description string.
     * The default value is "automatically generated".
     * @returns The default automatic short description string.
     */
    const char* rptdefasd() const {return m_rptdefasd.c_str();}
    /**
     * Get the default short description string.
     * The default value is "undocumented".
     * @returns The default short description string.
     */
    const char* rptdefsd() const {return m_rptdefsd.c_str();}
    /**
     * Get the default version string.
     * The default value is "unknown".
     * @returns The default version string.
     */
    const char* rptdefv() const {return m_rptdefv.c_str();}
  public:
    /**
     * Get the content type charset (issue 0074).
     * The default value is "iso-8859-1". This field
     * is required for HTML compliance.
     * @returns The content-type charset.
     */
    const char* rptctcs() const {return m_rptctcs.c_str();}
  public:
    /**
     * Sort class information (issue 0072). The default is true. If this
     * flag is false, the class contents and details are not
     * sorted.
     * @returns The sort flag.
     */
    bool rptsci() const {return m_rptsci;}
  public:
    /**
     * Report source information in the contents table.
     * @returns The flag.
     */
    bool rptsrc() const {return m_rptsrc;}
  public:
    /**
     * Get the maximum length of the contents id.
     * @returns The maximum length of the contents id.
     */
    unsigned rptmlcei() const {return m_rptmlcei;}
    /**
     * Get the maximum length of the contents inherited from id.
     * @returns The maximum length of the contents id.
     */
    unsigned rptmlcifi() const {return m_rptmlcifi;}
  public:
    /**
     * Enable javadoc short description syntax (-[no]jdsds, issue 0082).
     *
     * That is, terminate the short description when a period is found that
     * is followed by a space, tab, newline or other directive. Blank lines
     * are ignored.
     *
     * If this mode is not specified, the old ccdoc style for determining
     * short descriptions is used. Ccdoc parses until it finds a blank line
     * and uses that to determine that a short description has been found.
     * @returns True for -jdsds or false for -nojdsds. The default is -jdsds.
     * @since r24
     */
    bool jdsds() const {return m_jdsds;}
  public:
    /**
     * Doxygen compatibility mode (-[no]doxygen).
     * This provides limited support for commonly used doxygen
     * directives.
     * @returns whether doxygen support is enabled.
     */
    bool doxygen() const {return m_doxygen;}
  private:
    bool get_arg(const char* sw,string& str,int& i,int argc,char** argv);
    void load_file(const string& file);
    void load_files(const string& file,const char* prefix=0);
    void putenv(string&) const;
  private:
    bool m_jdsds;
    bool m_cdsm;
    bool m_tcms;
    bool m_dospaths;
    bool m_ok;
    bool m_doxygen;
    bool m_help;
    bool m_verbose;
    bool m_verbose_format;
    bool m_index;
    bool m_rptcfuns;
    bool m_rptcsd;
    unsigned m_rptcsi;
    bool m_rptdpa;
    bool m_rptdpd;
    bool m_rptdpv;
    bool m_rptfwcf;
    bool m_rpthpc;
    bool m_rptim;
    bool m_rptmac;
    bool m_rptmac1;
    bool m_rptpri;
    bool m_rptpro;
    bool m_rptpub;
    bool m_rptsci;
    bool m_rpttyp;
    bool m_rptun;
    bool m_rptsrc;
    string m_rptdefa;
    string m_rptdefasd;
    string m_rptdefsd;
    string m_rptdefv;
    string m_rptctcs;
    unsigned m_maxpathlen;
    vector<string> m_switches;
    string m_default_root;
    string m_program_name;
    string m_db;
    string m_pkg;
    string m_html;
    string m_header;
    string m_imgurl;
    string m_meta;
    string m_trailer;
    string m_root;
    string m_rootfile;
    string m_rooturl;
    string m_bgcolor;
    string m_fgtextcolor;
    string m_fglinkcolor;
    string m_fgvlinkcolor;
    string m_srcurl;
    string m_version;
    unsigned m_rptmlcei;
    unsigned m_rptmlcifi;
    defines_type m_defines;
    undefines_type m_undefines;
    files_type m_files;
  };
};

#endif
