/***************************************************************************
                          cmdlineoptions.cpp  -  description
                             -------------------
    begin                : Sun Nov 25 2001
    copyright            : (C) 2001-2008 by Andre Simon
    email                : andre.simon1@gmx.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "cmdlineoptions.h"
#include "platform_fs.h"
#include "configurationreader.h"
#include "datadir.h"
#include <sstream>
#include <cstdio>
#include <set>

#include "arg_parser.h"

using namespace std;

CmdLineOptions::CmdLineOptions( const int argc, const char *argv[] ):
    numberSpaces(0),
    lineNrWidth(5),
    lineLength(80),
    lineNrStart(1),
    wrappingStyle(highlight::WRAP_DISABLED),
    outputType (highlight::HTML),
    keywordCase( StringTools::CASE_UNCHANGED ),
    className("hl"),
    opt_syntax (false),
    opt_include_style (false),
    opt_help (false),
    opt_version (false),
    opt_verbose (false),
    opt_print_config(false),
    opt_linenumbers (false),
    opt_style (false),
    opt_batch_mode (false),
    opt_fragment (false) ,
    opt_attach_line_anchors (false),
    opt_show_themes (false),
    opt_show_langdefs (false),
    opt_printindex(false),
    opt_quiet(false),
    opt_replacequotes(false),
    opt_babel(false),
    opt_print_progress(false),
    opt_fill_zeroes(false),
    opt_stylepath_explicit(false),
    opt_force_output(false),
    opt_ordered_list(false),
    opt_fnames_as_anchors(false),
    opt_validate(false),
    opt_inlineCSS(false),
    opt_enclosePreTag(false),
    opt_charStyles(false),
    configFileRead(false),
    anchorPrefix("l"),
    helpLang("en"),
    encodingName("ISO-8859-1")
{

  loadConfigurationFile();

  enum Optcode
    {
    S_OPT_ADDCONFDIR = 256, S_OPT_ENCLOSE_PRE, S_OPT_FORCE_OUTPUT,
    S_OPT_HELP_LANG, S_OPT_INLINE_CSS, S_OPT_KW_CASE,
    S_OPT_MARK_LINES, S_OPT_PRINT_CONFIG, S_OPT_TEST_INPUT,
    S_OPT_SVG_WIDTH, S_OPT_SVG_HEIGHT, S_OPT_CLASSNAME, S_OPT_RTF_CHAR_STYLES,
    S_OPT_SKIP_UNKNOWN,
    S_OPT_COMPAT_DOC, S_OPT_COMPAT_NODOC, S_OPT_COMPAT_TAB, S_OPT_COMPAT_CSS,
    S_OPT_COMPAT_OUTDIR, S_OPT_COMPAT_FAILSAFE, S_OPT_COMPAT_OUTFORMAT,
    S_OPT_COMPAT_SRCLANG, S_OPT_COMPAT_LINENUM, S_OPT_COMPAT_LINEREF, 
    S_OPT_CTAGS_FILE
    };

  const Arg_parser::Option options[] =
    {
    { 'a', OPT_ANCHORS,        Arg_parser::no  },
    { 'A', OPT_ANSI,           Arg_parser::no  },
    { 'b', OPT_BABEL,          Arg_parser::no  },
    { 'B', OPT_BATCHREC,       Arg_parser::yes },
    { 'c', OPT_STYLE_OUT,      Arg_parser::yes },
    { 'C', OPT_INDEXFILE,      Arg_parser::no  },
    { 'd', OPT_DOC_TITLE,      Arg_parser::yes },
    { 'D', OPT_DATADIR,        Arg_parser::yes },
    { 'e', OPT_STYLE_IN,       Arg_parser::yes },
    { 'E', OPT_ADDDATADIR,     Arg_parser::yes },
    { 'f', OPT_FRAGMENT,       Arg_parser::no  },
    { 'F', OPT_FORMAT,         Arg_parser::yes },
    { S_OPT_CLASSNAME, OPT_CLASSNAME,      Arg_parser::yes },
    { 'h', OPT_HELP,           Arg_parser::no  },
    { 'H', OPT_HTML,           Arg_parser::no  },
    { 'i', OPT_IN,             Arg_parser::yes },
    { 'I', OPT_INC_STYLE,      Arg_parser::no  },
    { 'j', OPT_LNR_LEN,        Arg_parser::yes },
    { 'J', OPT_LINE_LEN,       Arg_parser::yes },
    { 'k', OPT_BASE_FONT,      Arg_parser::yes },
    { 'K', OPT_BASE_FONT_SIZE, Arg_parser::yes },
    { 'l', OPT_LINENO,         Arg_parser::no  },
    { 'L', OPT_LATEX,          Arg_parser::no  },
    { 'm', OPT_LNR_START,      Arg_parser::yes },
    { 'M', OPT_XTERM256,       Arg_parser::no  },
    { 'n', OPT_ORDERED_LIST,   Arg_parser::no  },
    { 'N', OPT_ANCHOR_FN,      Arg_parser::no  },
    { 'o', OPT_OUT,            Arg_parser::yes },
    { 'O', OPT_OUTDIR,         Arg_parser::yes },
    { 'p', OPT_LISTLANGS,      Arg_parser::no  },
    { 'P', OPT_PROGRESSBAR,    Arg_parser::no  },
    { 'q', OPT_QUIET,          Arg_parser::no  },
    { 'Q', OPT_VERSION,        Arg_parser::no  },
    { 'r', OPT_REPLACE_QUOTES, Arg_parser::no  },
    { 'R', OPT_RTF,            Arg_parser::no  },
    { 's', OPT_STYLE,          Arg_parser::yes },
    { 'S', OPT_SYNTAX,         Arg_parser::yes },
    { 't', OPT_DELTABS,        Arg_parser::yes },
    { 'T', OPT_TEX,            Arg_parser::no  },
    { 'u', OPT_ENCODING,       Arg_parser::yes },
    { 'v', OPT_VERBOSE,        Arg_parser::no  },
    { 'V', OPT_WRAPSIMPLE,     Arg_parser::no  },
    { 'w', OPT_LISTTHEMES,     Arg_parser::no  },
    { 'W', OPT_WRAP,           Arg_parser::no  },
    { 'x', OPT_RTF_PAGE_SIZE,  Arg_parser::yes },
    { 'X', OPT_XHTML,          Arg_parser::no  },
    { 'y', OPT_ANCHOR_PFX,     Arg_parser::yes },
    { 'z', OPT_FILLZEROES,     Arg_parser::no  },
    { 'Z', OPT_XML,            Arg_parser::no  },
    { 'G', OPT_SVG,            Arg_parser::no  },
    { S_OPT_SVG_WIDTH,    OPT_SVG_WIDTH,    Arg_parser::yes  },
    { S_OPT_SVG_HEIGHT,   OPT_SVG_HEIGHT,   Arg_parser::yes  },
    { S_OPT_ADDCONFDIR,   OPT_ADDCONFDIR,   Arg_parser::yes },
    { S_OPT_ENCLOSE_PRE,  OPT_ENCLOSE_PRE,  Arg_parser::no  },
    { S_OPT_FORCE_OUTPUT, OPT_FORCE_OUTPUT, Arg_parser::no  },
    { S_OPT_HELP_LANG,    OPT_HELP_LANG,    Arg_parser::yes },
    { S_OPT_INLINE_CSS,   OPT_INLINE_CSS,   Arg_parser::no  },
    { S_OPT_KW_CASE,      OPT_KW_CASE,      Arg_parser::yes },
    { S_OPT_MARK_LINES,   OPT_MARK_LINES,   Arg_parser::yes },
    { S_OPT_PRINT_CONFIG, OPT_PRINT_CONFIG, Arg_parser::no  },
    { S_OPT_TEST_INPUT,   OPT_TEST_INPUT,   Arg_parser::no  },
    { S_OPT_RTF_CHAR_STYLES, OPT_RTF_CHAR_STYLES, Arg_parser::no  },
    { S_OPT_SKIP_UNKNOWN, OPT_SKIP_UNKNOWN, Arg_parser::yes },
    { S_OPT_CTAGS_FILE,   OPT_CTAGS_FILE, Arg_parser::maybe },

    { S_OPT_COMPAT_DOC,   OPT_COMPAT_DOC, Arg_parser::no },
    { S_OPT_COMPAT_NODOC, OPT_COMPAT_NODOC, Arg_parser::no },
    { S_OPT_COMPAT_TAB, OPT_COMPAT_TAB, Arg_parser::yes },
    { S_OPT_COMPAT_CSS, OPT_COMPAT_CSS, Arg_parser::yes },
    { S_OPT_COMPAT_OUTDIR, OPT_COMPAT_OUTDIR, Arg_parser::yes },
    { S_OPT_COMPAT_FAILSAFE, OPT_COMPAT_FAILSAFE, Arg_parser::no },
    { S_OPT_COMPAT_OUTFORMAT, OPT_COMPAT_OUTFORMAT, Arg_parser::yes },
    { S_OPT_COMPAT_SRCLANG, OPT_COMPAT_SRCLANG, Arg_parser::yes },
    { S_OPT_COMPAT_LINENUM, OPT_COMPAT_LINENUM, Arg_parser::maybe },
    { S_OPT_COMPAT_LINEREF, OPT_COMPAT_LINEREF, Arg_parser::maybe },

    { 0,                  0,                Arg_parser::no  } };


  Arg_parser parser( argc, argv, options );
  if( parser.error().size() )				// bad option
    {
    cerr << "highlight: "<< parser.error()<<"\n";
    cerr << "Try `highlight --help' for more information.\n";
    exit( 1 );
    }

  int argind = 0;
  for( ; argind < parser.arguments(); ++argind )
    {
    const int code = parser.code( argind );
    const std::string & arg = parser.argument( argind );
    if( !code ) break;					// no more options
    switch( code )
      {
      case 'a':
        opt_attach_line_anchors = true;
        break;
      case 'A':
        outputType=highlight::ANSI;
        break;
      case 'b':
        opt_babel=true;
        break;
      case 'B':
        opt_batch_mode = true;
        readDirectory(arg);
        break;
      case 'c':
      case S_OPT_COMPAT_CSS:
        styleOutFilename = arg;
        opt_stylepath_explicit=true;
        break;
      case 'C':
        opt_printindex=true;
        break;
      case 'd':
        docTitle = arg;
        break;
      case 'D':
        dataDir=validateDirPath(arg);
        break;
      case 'e':
        styleInFilename = arg;
        break;
      case 'E':
        additionalDataDir=validateDirPath(arg);
        break;
      case 'f':
      case S_OPT_COMPAT_NODOC:
        opt_fragment = true;
        break;
      case 'F':
        indentScheme = arg;
        break;
      case S_OPT_CLASSNAME:
        className = arg;
        break;
      case 'h':
        opt_help = true;
        break;
      case 'H':
        outputType=highlight::HTML;
        break;
      case 'i':
        inputFileNames.push_back(arg);
        break;
      case 'I':
        opt_include_style = true;
        break;
      case 'j':
        StringTools::str2num<int>(lineNrWidth, arg, std::dec);
        break;
      case 'J':
        StringTools::str2num<int>(lineLength, arg, std::dec);
        break;
      case 'k':
        baseFont = arg;
        break;
      case 'K':
        baseFontSize = arg;
        break;
      case S_OPT_COMPAT_LINENUM:
        if (arg=="0") opt_fill_zeroes=true;
      case 'l':
        opt_linenumbers = true;
        break;
      case 'L':
        outputType=highlight::LATEX;
        break;
      case 'm':
        StringTools::str2num<int>(lineNrStart, arg, std::dec);
        break;
      case 'M':
        outputType=highlight::XTERM256;
        break;
      case 'n':
        opt_ordered_list = opt_linenumbers = true;
        break;
      case 'N':
        opt_fnames_as_anchors=true;
        break;
      case 'o':
        outFilename = arg;
        break;
      case 'O':
      case S_OPT_COMPAT_OUTDIR:
        outDirectory = validateDirPath(arg);
        break;
      case 'p':
        opt_show_langdefs = true;
        break;
      case 'P':
        opt_print_progress=true;
        break;
      case 'q':
        opt_quiet = true;
        break;
      case 'Q':
        opt_version = true;
        break;
      case 'r':
        opt_replacequotes=true;
        break;
      case 'R':
        outputType=highlight::RTF;
        break;
      case 's':
        styleName = arg;
        opt_style = true;
        break;
      case 'S':
      case S_OPT_COMPAT_SRCLANG:
        syntax = arg;
        opt_syntax = true;
        break;
      case 't':
      case S_OPT_COMPAT_TAB:
        StringTools::str2num<int> (numberSpaces, arg, std::dec);
        break;
      case 'T':
        outputType=highlight::TEX;
        break;
      case 'u':
        encodingName = arg;
        break;
      case 'v':
        opt_verbose = true;
        break;
      case 'V':
        wrappingStyle = highlight::WRAP_SIMPLE;
        break;
      case 'w':
        opt_show_themes = true;
        break;
      case 'W':
        wrappingStyle = highlight::WRAP_DEFAULT;
        break;
      case 'x':
        pageSize = arg;
        break;
      case 'X':
        outputType=highlight::XHTML;
        break;
      case 'y':
        anchorPrefix = arg;
        break;
      case 'z':
        opt_fill_zeroes=true;
        break;
      case 'Z':
        outputType=highlight::XML;
        break;
      case 'G':
        outputType=highlight::SVG;
        break;
      case S_OPT_SVG_WIDTH:
        svg_width = arg;
        break;
      case S_OPT_SVG_HEIGHT:
        svg_height = arg;
        break;
      case S_OPT_ADDCONFDIR:
	     additionalConfigDir = validateDirPath(arg);
        break;
      case S_OPT_ENCLOSE_PRE:
        opt_enclosePreTag=true;
	    break;
      case S_OPT_FORCE_OUTPUT:
      case S_OPT_COMPAT_FAILSAFE:
        opt_force_output = true;
        break;
      case S_OPT_HELP_LANG:
	    helpLang = arg;
	    opt_help = true;
	    break;
      case S_OPT_INLINE_CSS:
	    opt_inlineCSS=true;
	     break;
      case S_OPT_KW_CASE:
        {
		const string tmp = StringTools::change_case( arg );
		if( tmp == "upper" ) 
			keywordCase = StringTools::CASE_UPPER;
		else if( tmp == "lower" ) 
			keywordCase = StringTools::CASE_LOWER;
		else if( tmp == "capitalize" ) 
			keywordCase = StringTools::CASE_CAPITALIZE;
        }
	break;
      case S_OPT_COMPAT_OUTFORMAT:
        {
		const string tmp = StringTools::change_case( arg );
		if( tmp == "xhtml" ) 
			outputType = highlight::XHTML;
		else if( tmp == "tex" ) 
			outputType = highlight::TEX;
		else if( tmp == "latex" ) 
			outputType = highlight::LATEX;
		else if( tmp == "rtf" ) 
			outputType = highlight::RTF;
		else if( tmp == "xml" ) 
			outputType = highlight::XML;
		else if( tmp == "ansi" || tmp == "esc") // gnu source-highlight esc parameter 
			outputType = highlight::ANSI;
		else if( tmp == "xterm256" ) 
			outputType = highlight::XTERM256;
		else if( tmp == "svg" ) 
			outputType = highlight::SVG;
		else 
			outputType = highlight::HTML;
        }
	break;
      case S_OPT_MARK_LINES:
	    markLinesArg = arg;
	    break;
      case S_OPT_PRINT_CONFIG:
        opt_print_config = true;
        break;
      case S_OPT_TEST_INPUT:
	    opt_validate=true;
	    break;
      case S_OPT_RTF_CHAR_STYLES:
	    opt_charStyles=true;
	    break;
      case S_OPT_SKIP_UNKNOWN:
	    skipArg=arg;
            break;
      case S_OPT_CTAGS_FILE:
            ctagsFile = (arg.empty())? "tags" :arg; 
            break;
      case S_OPT_COMPAT_DOC:
            opt_fragment = false;
            break;
      case S_OPT_COMPAT_LINEREF:
            opt_linenumbers = true;
            opt_attach_line_anchors = true;
            anchorPrefix =(arg.empty())? "line":arg;
            break;
      default:
        cerr << "highlight: option parsing failed" << endl;
      }
    }

  if (argind < parser.arguments())   //still args left
    {
      if  (inputFileNames.empty()) {
        while (argind < parser.arguments()){
          inputFileNames.push_back( parser.argument( argind++ ) );
         }
      }
    } else if (inputFileNames.empty()) {
       inputFileNames.push_back("");
    }
  if (printDebugInfo() && configFileRead) {
    cout << "Configuration file \""<<configFilePath<<"\" was read.\n";
  }

  if (skipArg.size()){
	istringstream valueStream;
	string elem;
	string wildcard;
	valueStream.str(skipArg);
	set <string> skip;
	while (getline(valueStream, elem, ';')){
		skip.insert(elem);
	}
	for (vector<string>::iterator file=inputFileNames.begin();file!=inputFileNames.end();file++){
		for (set<string>::iterator ext=skip.begin();ext!=skip.end();ext++){
			wildcard="*."+*ext;
			if (Platform::wildcmp(wildcard.c_str(), (*file).c_str())){
				inputFileNames.erase(file);
				file--;
				break;
			}
		}
	}
  }
}

CmdLineOptions::~CmdLineOptions(){}

const string &CmdLineOptions::getSingleOutFilename()
  {
   if (!inputFileNames.empty() && !outDirectory.empty()) {
      if (outFilename.empty()) {
        outFilename = outDirectory;
        int delim = getSingleInFilename().find_last_of(Platform::pathSeparator)+1;
        outFilename += getSingleInFilename().substr((delim>-1)?delim:0)
                       + getOutFileSuffix();
      }
   }
   return outFilename;
  }

const string &CmdLineOptions::getSingleInFilename()  const
  {
  return inputFileNames[0];
  }

const string &CmdLineOptions::getOutDirectory()
  {
    if (!outFilename.empty() && !enableBatchMode()){
      outDirectory=getDirName(outFilename);
    }
    return outDirectory;
  }

const string CmdLineOptions::getStyleOutFilename() const
  {
      if (!styleOutFilename.empty()) return styleOutFilename;

      if (outputType==highlight::TEX || outputType==highlight::LATEX) {
         return "highlight.sty";
      } else {
         return "highlight.css";
      }
  }
const string &CmdLineOptions::getStyleInFilename() const
  {
    return styleInFilename;
  }
const string& CmdLineOptions::getSVGWidth() const
 {
   return svg_width;
 }
const string& CmdLineOptions::getSVGHeight() const
 {
      return svg_height;
}
int CmdLineOptions::getNumberSpaces() const
  {
    return numberSpaces;
  }
bool CmdLineOptions::printVersion()const
  {
    return opt_version;
  }
bool CmdLineOptions::printHelp()const
  {
    return opt_help;
  }
bool CmdLineOptions::printDebugInfo()const
  {
    return opt_verbose;
  }
bool CmdLineOptions::printConfigInfo()const
  {
    return opt_print_config;
  }
bool CmdLineOptions::quietMode()const
  {
    return opt_quiet;
  }
bool CmdLineOptions::includeStyleDef()const
  {
      return opt_include_style;
  }
bool CmdLineOptions::useFNamesAsAnchors() const
{
        return opt_fnames_as_anchors;
}

bool CmdLineOptions::formatSupportsExtStyle(){
      return outputType==highlight::HTML ||
             outputType==highlight::XHTML ||
             outputType==highlight::LATEX ||
             outputType==highlight::TEX ||
             outputType==highlight::SVG;
}

bool CmdLineOptions::printLineNumbers()const
  {
    return opt_linenumbers;
  }

string CmdLineOptions::getThemeName()const
  {
    return ( ( opt_style) ? styleName+".style" : "kwrite.style" );
  }
bool CmdLineOptions::enableBatchMode()const{
    return inputFileNames.size()>1 || opt_batch_mode;
}
bool CmdLineOptions::fragmentOutput()const{
    return opt_fragment;
}
string CmdLineOptions::getOutFileSuffix()const{
    switch (outputType){
      case highlight::XHTML: return ".xhtml";
      case highlight::RTF:   return ".rtf";
      case highlight::TEX:
      case highlight::LATEX: return ".tex";
      case highlight::XML:   return ".xml";
      case highlight::SVG:   return ".svg";
      case highlight::ANSI:  return ".ansi";
      case highlight::XTERM256: return ".xterm";
      default:    return ".html";
    }
}
string CmdLineOptions::getDirName(const string & path) {
  size_t dirNameLength=path.rfind(Platform::pathSeparator);
  return (dirNameLength==string::npos)?string():path.substr(0, dirNameLength+1);
}
bool CmdLineOptions::attachLineAnchors()const{
    return opt_attach_line_anchors;
}
bool CmdLineOptions::showThemes()const{
    return opt_show_themes;
}
bool CmdLineOptions::showLangdefs()const{
    return opt_show_langdefs;
}
bool CmdLineOptions::outDirGiven()const{
    return !outFilename.empty();
}
bool CmdLineOptions::replaceQuotes() const {
   return opt_replacequotes;
}
bool CmdLineOptions::disableBabelShorthands() const {
  return opt_babel;
}
bool CmdLineOptions::getFlag( const string& paramVal){
   return StringTools::change_case(paramVal)=="true";
}
bool CmdLineOptions::formattingEnabled(){
    return !indentScheme.empty();
}
bool CmdLineOptions::orderedList() const {
  return opt_ordered_list;
}
const string &CmdLineOptions::getDataDir() const {
 return dataDir;
}
const string &CmdLineOptions::getIndentScheme() const {
 return indentScheme;
}
const string &CmdLineOptions::getAdditionalDataDir()const{
 return additionalDataDir;
}
const string &CmdLineOptions::getAdditionalConfDir()const{
 return additionalConfigDir;
}
const string &CmdLineOptions::getLanguage() const {
 return syntax;
}
const string&CmdLineOptions::getEncoding() const{
    return encodingName;
}

const string& CmdLineOptions::getAnchorPrefix() const {
    return anchorPrefix;
}

const string &CmdLineOptions::getPageSize() const{
   return pageSize;
}
bool CmdLineOptions::printIndexFile() const{
 return opt_printindex && (outputType==highlight::HTML ||
                           outputType==highlight::XHTML);
}
bool CmdLineOptions::printProgress() const{
 return opt_print_progress;
}
bool CmdLineOptions::fillLineNrZeroes() const {
  return opt_fill_zeroes;
}
bool CmdLineOptions::syntaxGiven() const {
  return opt_syntax;
}
bool CmdLineOptions::omitEncoding() const{
    return StringTools::change_case(encodingName)=="none";
}
bool CmdLineOptions::forceOutput() const {
    return opt_force_output;
}
bool CmdLineOptions::validateInput() const {
    return opt_validate;
}
bool CmdLineOptions::inlineCSS() const {
    return opt_inlineCSS;
}
bool CmdLineOptions::enclosePreTag() const {
    return opt_enclosePreTag;
}
bool CmdLineOptions::includeCharStyles() const {
    return opt_charStyles;
}
const string  CmdLineOptions::getHelpLang() const {
  return helpLang+".help";
}
const string &CmdLineOptions::getConfigFilePath() const {
  return configFilePath;
}

const string& CmdLineOptions::getDocumentTitle() const {
   return docTitle;
}

highlight::WrapMode CmdLineOptions::getWrappingStyle() const {
  return wrappingStyle;
}
const vector <string> & CmdLineOptions::getInputFileNames() const{
  return inputFileNames;
}

const map <int,string> & CmdLineOptions::getMarkLines() {
	markLines.clear();
	istringstream valueStream;
	string elem;
	size_t delimPos;
	int markLineNo;
	valueStream.str(markLinesArg);
	// Format: "1=help line one; 3=help line three; 5 "
	while (getline( valueStream, elem, ';')){
		delimPos = elem.find('=');
		markLineNo=0;
		StringTools::str2num<int> (markLineNo, elem.substr(0,delimPos), std::dec);
		if (markLineNo) {
			markLines[markLineNo] =
			(delimPos!=string::npos)?elem.substr(delimPos+1):"";
		}
	}
	return markLines;
}
void CmdLineOptions::readDirectory(const string & wildcard){
  // get matching files, use  recursive search
  bool directoryOK=Platform::getDirectoryEntries(inputFileNames, wildcard, true);
  if (!directoryOK)
    {
       cerr << "highlight: No files matched the pattern \""
            << wildcard << "\"."<< endl;
    }
}

string CmdLineOptions::validateDirPath(const string & path){
   return (path[path.length()-1] !=Platform::pathSeparator)?
              path+Platform::pathSeparator : path;
}

highlight::OutputType CmdLineOptions::getOutputType() const {
    return outputType;
}

StringTools::KeywordCase CmdLineOptions::getKeywordCase() const {
    return keywordCase;
}

bool CmdLineOptions::hasBaseFont() const {
   return (! baseFont.empty()) ;
}

const string& CmdLineOptions::getBaseFont() const {
   return baseFont ;
}

bool CmdLineOptions::hasBaseFontSize() const {
   return (! baseFontSize.empty()) ;
}

const string& CmdLineOptions::getBaseFontSize() const {
   return baseFontSize ;
}

const string& CmdLineOptions::getClassName() const {
   return className ;
}

/** \return ctags file name */
const string& CmdLineOptions::getTagsFile() const {
   return ctagsFile;
}

int CmdLineOptions::getNumberWidth(){
   return lineNrWidth;
}

int CmdLineOptions::getLineLength(){
   return lineLength;
}

int CmdLineOptions::getNumberStart(){
   return lineNrStart;
}

void CmdLineOptions::loadConfigurationFile()
{
  #ifndef _WIN32
    #ifdef CONFIG_FILE_PATH
       configFilePath=CONFIG_FILE_PATH;
    #else
      char* homeEnv=getenv("HOME");
      if (homeEnv==NULL) return;
      configFilePath=string(homeEnv)+"/.highlightrc";
    #endif
  #else
    configFilePath = Platform::getAppPath() + "highlight.conf";
  #endif
  ConfigurationReader userConfig(configFilePath);

  if (userConfig.found())
    {
      string paramVal;
      configFileRead=true;

      styleOutFilename = userConfig.getParameter(OPT_STYLE_OUT);
      styleInFilename = userConfig.getParameter(OPT_STYLE_IN);
      styleName = userConfig.getParameter(OPT_STYLE);
      opt_style = !styleName.empty();
      syntax = userConfig.getParameter(OPT_SYNTAX);
      opt_syntax = !syntax.empty();
      StringTools::str2num<int>(numberSpaces, userConfig.getParameter(OPT_DELTABS), std::dec);
      indentScheme = userConfig.getParameter(OPT_FORMAT);
      baseFontSize = userConfig.getParameter(OPT_BASE_FONT_SIZE);
      baseFont = userConfig.getParameter(OPT_BASE_FONT);
      skipArg = userConfig.getParameter(OPT_SKIP_UNKNOWN);

      paramVal = userConfig.getParameter(OPT_DATADIR);
      if (!paramVal.empty()) {
         dataDir=validateDirPath( paramVal);
      }
      paramVal = userConfig.getParameter(OPT_ADDDATADIR);
      if (!paramVal.empty()) {
        additionalDataDir=validateDirPath(paramVal);
      }
      paramVal = userConfig.getParameter(OPT_ADDCONFDIR);
      if (!paramVal.empty()) {
        additionalConfigDir=validateDirPath(paramVal);
      }
      paramVal = userConfig.getParameter(OPT_OUTDIR);
      if (!paramVal.empty()) {
        outDirectory=validateDirPath(paramVal);
      }
      paramVal = userConfig.getParameter(OPT_ENCODING);
      if (!paramVal.empty()) {
          encodingName=paramVal;
      }
      paramVal = userConfig.getParameter(OPT_LNR_LEN);
      if (!paramVal.empty()) {
          StringTools::str2num<int>(lineNrWidth, string(paramVal), std::dec);
      }
      paramVal = userConfig.getParameter(OPT_LNR_START);
      if (!paramVal.empty()) {
          StringTools::str2num<int>(lineNrStart, string(paramVal), std::dec);
      }
      paramVal = userConfig.getParameter(OPT_ANCHOR_PFX);
      if (!paramVal.empty()) {
          anchorPrefix=paramVal;
      }

      opt_include_style=getFlag(userConfig.getParameter(OPT_INC_STYLE));
      opt_verbose=getFlag(userConfig.getParameter(OPT_VERBOSE));
      opt_ordered_list=getFlag(userConfig.getParameter(OPT_ORDERED_LIST));
      opt_linenumbers=opt_ordered_list || getFlag(userConfig.getParameter(OPT_LINENO));
      opt_fragment=getFlag(userConfig.getParameter(OPT_FRAGMENT));
      opt_attach_line_anchors=getFlag(userConfig.getParameter(OPT_ANCHORS));
      opt_printindex=getFlag(userConfig.getParameter(OPT_INDEXFILE));
      opt_quiet=getFlag(userConfig.getParameter(OPT_QUIET));
      opt_replacequotes=getFlag(userConfig.getParameter(OPT_REPLACE_QUOTES));
      opt_print_progress=getFlag(userConfig.getParameter(OPT_PROGRESSBAR));
      opt_fill_zeroes=getFlag(userConfig.getParameter(OPT_FILLZEROES));
      opt_fnames_as_anchors=getFlag(userConfig.getParameter(OPT_ANCHOR_FN));
      opt_validate=getFlag(userConfig.getParameter(OPT_TEST_INPUT));
      opt_fnames_as_anchors=getFlag(userConfig.getParameter(OPT_ANCHOR_FN));
      opt_inlineCSS=getFlag(userConfig.getParameter(OPT_INLINE_CSS));

      if (getFlag(userConfig.getParameter(OPT_WRAP))) {
          wrappingStyle=highlight::WRAP_DEFAULT;
      }
      if (getFlag(userConfig.getParameter(OPT_WRAPSIMPLE))) {
          wrappingStyle=highlight::WRAP_SIMPLE;
      }
      if (getFlag(userConfig.getParameter(OPT_XHTML))) {
          outputType=highlight::XHTML;
      } else if (getFlag(userConfig.getParameter(OPT_RTF))) {
          outputType=highlight::RTF;
      } else if (getFlag(userConfig.getParameter(OPT_TEX))) {
          outputType=highlight::TEX;
      } else if (getFlag(userConfig.getParameter(OPT_LATEX))) {
          outputType=highlight::LATEX;
      } else if (getFlag(userConfig.getParameter(OPT_ANSI))) {
          outputType=highlight::ANSI;
      } else if (getFlag(userConfig.getParameter(OPT_XML))) {
          outputType=highlight::XML;
      } else if (getFlag(userConfig.getParameter(OPT_SVG))) {
          outputType=highlight::SVG;
      } else if (getFlag(userConfig.getParameter(OPT_XTERM256))) {
          outputType=highlight::XTERM256;
      }
    }
}

