import itk, itkTemplate, os, sys

itk_header_dirs = (@CONFIG_ITK_PATH@)

templates = [key for key in dir(itk) 
  if isinstance(getattr(itk, key), itkTemplate.itkTemplate)]

header_list = []
for t in templates:
  header_name = "itk%s.h" %t
  for d in itk_header_dirs:
    header_path = os.path.join(d, header_name)
    if os.path.exists(header_path):
      header_list.append(header_path)
      break

header_string = '" \\\n           "'.join(header_list)

if len(sys.argv) >= 2:
  outputPath = sys.argv[1]
else:
  outputPath = "@CONFIG_WRAP_ITK_DOXYGEN_ROOT@"

doxygen_conf_contents = """
# This file describes the settings to be used by doxygen for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
#       TAG = value [value, ...]
# Values that contain spaces should be placed between quotes (" ")

#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------

# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
# by quotes) that should identify the project. 

PROJECT_NAME          = ITK

# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
# base path where the generated documentation will be put. 
# If a relative path is entered, it will be relative to the location 
# where doxygen was started. If left blank the current directory will be used.

OUTPUT_DIRECTORY      =  "%s"

# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
# documentation generated by doxygen is written. Doxygen will use this 
# information to generate all constant output in the proper language. 
# The default language is English, other supported languages are: 
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, 
# Spanish and Russian

OUTPUT_LANGUAGE       = English

# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
# top of each HTML page. The value NO (the default) enables the index and 
# the value YES disables it. 

DISABLE_INDEX         = YES


# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
# documentation are documented, even if no documentation was available. 
# Private class members and static file members will be hidden unless 
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES 

EXTRACT_ALL           = NO

# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
# will be included in the documentation. 

EXTRACT_PRIVATE       = NO

# If the EXTRACT_STATIC tag is set to YES all static members of a file 
# will be included in the documentation. 

EXTRACT_STATIC        = YES

# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
# undocumented members of documented classes, files or namespaces. 
# If set to NO (the default) these members will be included in the 
# various overviews, but no documentation section is generated. 
# This option has no effect if EXTRACT_ALL is enabled. 

HIDE_UNDOC_MEMBERS    = NO

# If the HIDE_UNDOC_CLASSESS tag is set to YES, Doxygen will hide all 
# undocumented classes that are normally visible in the class hierarchy. 
# If set to NO (the default) these class will be included in the various 
# overviews. This option has no effect if EXTRACT_ALL is enabled. 

HIDE_UNDOC_CLASSES    = NO

# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
# include brief member descriptions after the members that are listed in 
# the file and class documentation (similar to JavaDoc). 
# Set to NO to disable this. 

BRIEF_MEMBER_DESC     = NO

# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
# the brief description of a member or function before the detailed description. 
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
# brief descriptions will be completely suppressed. 

REPEAT_BRIEF          = YES

# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
# Doxygen will generate a detailed section even if there is only a brief 
# description. 

ALWAYS_DETAILED_SEC   = NO

# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
# path before files name in the file list and in the header files. If set 
# to NO the shortest path that makes the file name unique will be used. 

FULL_PATH_NAMES       = NO

# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
# can be used to strip a user defined part of the path. Stripping is 
# only done if one of the specified strings matches the left-hand part of 
# the path. 

STRIP_FROM_PATH       = 

# The INTERNAL_DOCS tag determines if documentation 
# that is typed after a \internal command is included. If the tag is set 
# to NO (the default) then the documentation will be excluded. 
# Set it to YES to include the internal documentation. 

INTERNAL_DOCS         = NO

# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
# generate a class diagram (in Html and LaTeX) for classes with base or 
# super classes. Setting the tag to NO turns the diagrams off. 

CLASS_DIAGRAMS        = NO

# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
# be generated. Documented entities will be cross-referenced with these sources. 

SOURCE_BROWSER        = NO

# Setting the INLINE_SOURCES tag to YES will include the body 
# of functions and classes directly in the documentation. 

INLINE_SOURCES        = NO

# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
# doxygen to hide any special comment blocks from generated source code 
# fragments. Normal C and C++ comments will always remain visible. 

STRIP_CODE_COMMENTS   = YES

# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen 
# will only generate file names in lower case letters. If set to 
# YES upper case letters are also allowed. This is useful if you have 
# classes or files whose names only differ in case and if your file system 
# supports case sensitive file names. 

CASE_SENSE_NAMES      = NO

# If the SHORT_NAMES tag is set to NO (the default) then Doxygen will
# generate documentation file names that include the class names.  If
# set to YES, short names in the format a00000.html will be used.
# This may be necessary to support 8.3 filesystems.

SHORT_NAMES           = NO

# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
# will show members with their full class and namespace scopes in the 
# documentation. If set to YES the scope will be hidden. 

HIDE_SCOPE_NAMES      = NO

# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
# will generate a verbatim copy of the header file for each class for 
# which an include is specified. Set to NO to disable this. 

VERBATIM_HEADERS      = NO

# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
# will put list of the files that are included by a file in the documentation 
# of that file. 

SHOW_INCLUDE_FILES    = NO

# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen 
# will interpret the first line (until the first dot) of a JavaDoc-style 
# comment as the brief description. If set to NO, the Javadoc-style will 
# behave just like the Qt-style comments. 

JAVADOC_AUTOBRIEF     = NO

# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
# member inherits the documentation from any documented member that it 
# reimplements. 

INHERIT_DOCS          = YES

# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
# is inserted in the documentation for inline members. 

INLINE_INFO           = YES

# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
# will sort the (detailed) documentation of file and class members 
# alphabetically by member name. If set to NO the members will appear in 
# declaration order. 

SORT_MEMBER_DOCS      = YES

# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
# Doxygen uses this value to replace tabs by spaces in code fragments. 

TAB_SIZE              = 8

# The ENABLE_SECTIONS tag can be used to enable conditional 
# documentation sections, marked by \if sectionname ... \endif. 

ENABLED_SECTIONS      = 

#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------

# The QUIET tag can be used to turn on/off the messages that are generated 
# by doxygen. Possible values are YES and NO. If left blank NO is used. 

QUIET                 = NO

# The WARNINGS tag can be used to turn on/off the warning messages that are 
# generated by doxygen. Possible values are YES and NO. If left blank 
# NO is used. 

WARNINGS              = NO

# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
# automatically be disabled. 

WARN_IF_UNDOCUMENTED  = NO

# The WARN_FORMAT tag determines the format of the warning messages that 
# doxygen can produce. The string should contain the $file, $line, and $text 
# tags, which will be replaced by the file and line number from which the 
# warning originated and the warning text. 

WARN_FORMAT           = "$file:$line: $text"

#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------

# The INPUT tag can be used to specify the files and/or directories that
# contain documented source files. You may enter file names like "myfile.cpp"
# or directories like "/usr/src/myproject". Separate the files or directories
# with spaces.

INPUT    = "%s"

# The INPUT_FILTER tag can be used to specify a program that doxygen should 
# invoke to filter for each input file. Doxygen will invoke the filter program 
# by executing (via popen()) the command <filter> <input-file>, where <filter> 
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
# input file. Doxygen will then use the output that the filter program writes 
# to standard output. 

INPUT_FILTER          = "grep -v \\example"

#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------

# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
# of all compounds will be generated. Enable this if the project 
# contains a lot of classes, structs, unions or interfaces. 

ALPHABETICAL_INDEX    = NO

#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------

# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
# generate HTML output. 

GENERATE_HTML         = NO

#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------

# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
# generate Latex output. 

GENERATE_LATEX        = NO

#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------

# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
# For now this is experimental and is disabled by default. The RTF output 
# is optimised for Word 97 and may not look too pretty with other readers 
# or editors.

GENERATE_RTF          = NO

#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------

# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
# generate man pages 

GENERATE_MAN          = YES

# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
# put in front of it. If left blank `man' will be used as the default path. 

MAN_OUTPUT            = .

# The MAN_EXTENSION tag determines the extension that is added to 
# the generated man pages (default is the subroutine's section .3) 

MAN_EXTENSION         = .3

#---------------------------------------------------------------------------
# Configuration options related to the preprocessor   
#---------------------------------------------------------------------------

# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
# evaluate all C-preprocessor directives found in the sources and include 
# files. 

ENABLE_PREPROCESSING  = YES

# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
# names in the source code. If set to NO (the default) only conditional 
# compilation will be performed. 

MACRO_EXPANSION       = YES

# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
# in the INCLUDE_PATH (see below) will be search if a #include is found. 

SEARCH_INCLUDES       = NO

# The PREDEFINED tag can be used to specify one or more macro names that 
# are defined before the preprocessor is started (similar to the -D option of 
# gcc). The argument of the tag is a list of macros of the form: name 
# or name=definition (no spaces). If the definition and the = are 
# omitted =1 is assumed. 

PREDEFINED  =  "itkNotUsed(x)="\
               "itkSetMacro(name,type)= \
                  virtual void Set##name (type _arg);" \
               "itkGetMacro(name,type)= \
                  virtual type Get##name ();" \
               "itkGetConstMacro(name,type)= \
                  virtual type Get##name () const;" \
               "itkSetStringMacro(name)= \
                  virtual void Set##name (const char* _arg);" \
               "itkGetStringMacro(name)= \
                  virtual const char* Get##name () const;" \
               "itkSetClampMacro(name,type,min,max)= \
                  virtual void Set##name (type _arg);" \
               "itkSetObjectMacro(name,type)= \
                  virtual void Set##name (type* _arg);" \
               "itkGetObjectMacro(name,type)= \
                  virtual type* Get##name ();" \
               "itkSetConstObjectMacro(name,type)= \
                  virtual void Set##name ( const type* _arg);" \
               "itkGetConstObjectMacro(name,type)= \
                  virtual const type* Get##name ();" \
               "itkGetConstReferenceMacro(name,type)= \
                  virtual const type& Get##name ();" \
               "itkGetConstReferenceObjectMacro(name,type)= \
                  virtual const type::Pointer& Get##name () const;" \
               "itkBooleanMacro(name)= \
                  virtual void name##On (); \
                  virtual void name##Off ();" \
               "itkSetVector2Macro(name,type)= \
                  virtual void Set##name (type _arg1, type _arg2) \
                  virtual void Set##name (type _arg[2]);" \
               "itkGetVector2Macro(name,type)= \
                  virtual type* Get##name () const; \
                  virtual void Get##name (type& _arg1, type& _arg2) const; \
                  virtual void Get##name (type _arg[2]) const;" \
               "itkSetVector3Macro(name,type)= \
                  virtual void Set##name (type _arg1, type _arg2, type _arg3) \
                  virtual void Set##name (type _arg[3]);" \
               "itkGetVector3Macro(name,type)= \
                  virtual type* Get##name () const; \
                  virtual void Get##name (type& _arg1, type& _arg2, type& _arg3) const; \
                  virtual void Get##name (type _arg[3]) const;" \
               "itkSetVector4Macro(name,type)= \
                  virtual void Set##name (type _arg1, type _arg2, type _arg3, type _arg4) \
                  virtual void Set##name (type _arg[4]);" \
               "itkGetVector4Macro(name,type)= \
                  virtual type* Get##name () const; \
                  virtual void Get##name (type& _arg1, type& _arg2, type& _arg3, type& _arg4) const; \
                  virtual void Get##name (type _arg[4]) const;" \
               "itkSetVector6Macro(name,type)= \
                  virtual void Set##name (type _arg1, type _arg2, type _arg3, type _arg4, type _arg5, type _arg6) \
                  virtual void Set##name (type _arg[6]);" \
               "itkGetVector6Macro(name,type)= \
                  virtual type* Get##name () const; \
                  virtual void Get##name (type& _arg1, type& _arg2, type& _arg3, type& _arg4, type& _arg5, type& _arg6) const; \
                  virtual void Get##name (type _arg[6]) const;" \
               "itkSetVectorMacro(name,type,count)= \
                  virtual void Set##name(type data[]);" \
               "itkGetVectorMacro(name,type,count)= \
                  virtual type* Get##name () const;" \
               "itkNewMacro(type)= \
                  static Pointer New();" \
               "itkTypeMacro(thisClass,superclass)= \
                  virtual const char *GetClassName() const;" \
               "itkEventMacro(thisClass,superclass)= \
                  class thisClass : public superclass {};" \
               "itkConceptMacro(name,concept)= \
                  enum { name = 0 };" \
               "vcl_numeric_limits= \
                  std::numeric_limits" \
               "ITK_TYPENAME= \
                  typename" \
               "FEM_ABSTRACT_CLASS(thisClass,parentClass)= \
                  public:                                               \
                    /** Standard "Self" typedef.*/                      \
                    typedef thisClass Self;                             \
                    /** Standard "Superclass" typedef. */               \
                    typedef parentClass Superclass;                     \
                    /** Pointer or SmartPointer to an object. */        \
                    typedef Self* Pointer;                              \
                    /** Const pointer or SmartPointer to an object. */  \
                    typedef const Self* ConstPointer;                   \
                  private:"                                             \
               "FEM_CLASS(thisClass,parentClass)= \
                  FEM_ABSTRACT_CLASS(thisClass,parentClass)             \
                  public:                                               \
                    /** Create a new object from the existing one  */   \
                    virtual Baseclass::Pointer Clone() const;           \
                    /** Class ID for FEM object factory */              \
                    static const int CLID;                              \
                    /** Virtual function to access the class ID */      \
                    virtual int ClassID() const                         \
                      { return CLID; }                                  \
                    /** Object creation in an itk compatible way */     \
                    static Self::Pointer New()                          \
                      { return new Self(); }                            \
                  private:"                                             \
		"FREEVERSION" "ERROR_CHECKING"                          \
                "HAS_TIFF" "HAS_JPEG" "HAS_NETLIB" "HAS_PNG" "HAS_ZLIB" \
                "HAS_GLUT" "HAS_QT"                                     \
               "VCL_USE_NATIVE_STL=1" "VCL_USE_NATIVE_COMPLEX=1"        \
               "VCL_HAS_BOOL=1" "VXL_BIG_ENDIAN=1" "VXL_LITTLE_ENDIAN=0"\
               "VNL_DLL_DATA=" "size_t=vcl_size_t"

# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
# then the macro expansion is limited to the macros specified with the 
# PREDEFINED tag. 

EXPAND_ONLY_PREDEF    = YES

#---------------------------------------------------------------------------
# Configuration::addtions related to external references   
#---------------------------------------------------------------------------

# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
# in the class index. If set to NO only the inherited external classes 
# will be listed. 

ALLEXTERNALS          = NO
""" % (outputPath, header_string)

f = open('doxygen.config', 'w')
f.write(doxygen_conf_contents)
f.close()