]> Creatis software - bbtk.git/commitdiff
Initial revision
authorguigues <guigues>
Tue, 22 Jan 2008 15:02:00 +0000 (15:02 +0000)
committerguigues <guigues>
Tue, 22 Jan 2008 15:02:00 +0000 (15:02 +0000)
103 files changed:
CMakeLists.txt [new file with mode: 0644]
kernel/CMakeLists.txt [new file with mode: 0644]
kernel/appli/CMakeLists.txt [new file with mode: 0644]
kernel/appli/bbCreatePackage/CMakeLists.txt [new file with mode: 0644]
kernel/appli/bbCreatePackage/bbCreatePackage.bat.in [new file with mode: 0755]
kernel/appli/bbCreatePackage/bbCreatePackage.bbs [new file with mode: 0644]
kernel/appli/bbCreatePackage/bbCreatePackage.sh.in [new file with mode: 0755]
kernel/appli/bbCreatePackage/bbCreatePackageLinux.bbs [new file with mode: 0755]
kernel/appli/bbfy/CMakeLists.txt [new file with mode: 0644]
kernel/appli/bbfy/bbfy.cpp [new file with mode: 0644]
kernel/appli/bbi/CMakeLists.txt [new file with mode: 0644]
kernel/appli/bbi/bbi.cxx [new file with mode: 0644]
kernel/cmake/ADD_DEF.cmake [new file with mode: 0644]
kernel/cmake/BBTKConfigurePackage.cmake [new file with mode: 0644]
kernel/cmake/BBTKConfigurePackage_doc.cmake [new file with mode: 0644]
kernel/cmake/BBTKConfigurePackage_src.cmake [new file with mode: 0644]
kernel/cmake/BBTKDefineOptions.cmake [new file with mode: 0644]
kernel/cmake/BBTKFindGTK2.cmake [new file with mode: 0644]
kernel/cmake/BBTKFindLibraries.cmake [new file with mode: 0644]
kernel/cmake/BBTKFindWX_WIN.cmake [new file with mode: 0644]
kernel/cmake/BBTKPreventInSourceBuild.cmake [new file with mode: 0644]
kernel/cmake/BBTKResolveOptions.cmake [new file with mode: 0644]
kernel/cmake/BBTKSingleOutputPath.cmake [new file with mode: 0644]
kernel/cmake/FIND_AND_USE_WXWIDGETS.cmake [new file with mode: 0644]
kernel/cmake/MARK_AS_ADVANCED_UNWANTED.cmake [new file with mode: 0644]
kernel/cmake/bbPackage.cxx.in [new file with mode: 0644]
kernel/cmake/bbPackage.h.in [new file with mode: 0644]
kernel/src/CMakeLists.txt [new file with mode: 0644]
kernel/src/bbtkAny.cxx [new file with mode: 0644]
kernel/src/bbtkAny.h [new file with mode: 0644]
kernel/src/bbtkBlackBox.cxx [new file with mode: 0644]
kernel/src/bbtkBlackBox.h [new file with mode: 0644]
kernel/src/bbtkBlackBoxDescriptor.cxx [new file with mode: 0644]
kernel/src/bbtkBlackBoxDescriptor.h [new file with mode: 0644]
kernel/src/bbtkBlackBoxInputConnector.cxx [new file with mode: 0644]
kernel/src/bbtkBlackBoxInputConnector.h [new file with mode: 0644]
kernel/src/bbtkBlackBoxInputDescriptor.h [new file with mode: 0644]
kernel/src/bbtkBlackBoxOutputConnector.cxx [new file with mode: 0644]
kernel/src/bbtkBlackBoxOutputConnector.h [new file with mode: 0644]
kernel/src/bbtkBlackBoxOutputDescriptor.h [new file with mode: 0644]
kernel/src/bbtkComplexBlackBox.cxx [new file with mode: 0644]
kernel/src/bbtkComplexBlackBox.h [new file with mode: 0644]
kernel/src/bbtkComplexBlackBoxDescriptor.cxx [new file with mode: 0644]
kernel/src/bbtkComplexBlackBoxDescriptor.h [new file with mode: 0644]
kernel/src/bbtkComplexBlackBoxInputDescriptor.cxx [new file with mode: 0644]
kernel/src/bbtkComplexBlackBoxInputDescriptor.h [new file with mode: 0644]
kernel/src/bbtkComplexBlackBoxOutputDescriptor.cxx [new file with mode: 0644]
kernel/src/bbtkComplexBlackBoxOutputDescriptor.h [new file with mode: 0644]
kernel/src/bbtkConfigurationFile.cxx [new file with mode: 0644]
kernel/src/bbtkConfigurationFile.h [new file with mode: 0644]
kernel/src/bbtkConnection.cxx [new file with mode: 0644]
kernel/src/bbtkConnection.h [new file with mode: 0644]
kernel/src/bbtkData.h [new file with mode: 0644]
kernel/src/bbtkDynamicLibraryHandling.h [new file with mode: 0644]
kernel/src/bbtkException.h [new file with mode: 0644]
kernel/src/bbtkExecuter.cxx [new file with mode: 0644]
kernel/src/bbtkExecuter.h [new file with mode: 0644]
kernel/src/bbtkFactory.cxx [new file with mode: 0644]
kernel/src/bbtkFactory.h [new file with mode: 0644]
kernel/src/bbtkInterpreter.cxx [new file with mode: 0644]
kernel/src/bbtkInterpreter.h [new file with mode: 0644]
kernel/src/bbtkMessageManager.cxx [new file with mode: 0644]
kernel/src/bbtkMessageManager.h [new file with mode: 0644]
kernel/src/bbtkPackage.cxx [new file with mode: 0644]
kernel/src/bbtkPackage.h [new file with mode: 0644]
kernel/src/bbtkRTTI.cxx [new file with mode: 0644]
kernel/src/bbtkRTTI.h [new file with mode: 0644]
kernel/src/bbtkSystem.h [new file with mode: 0644]
kernel/src/bbtkTypeMapping.h [new file with mode: 0644]
kernel/src/bbtkUserBlackBox.cxx [new file with mode: 0644]
kernel/src/bbtkUserBlackBox.h [new file with mode: 0644]
kernel/src/bbtkUserBlackBoxDescriptor.h [new file with mode: 0644]
kernel/src/bbtkUserBlackBoxGetSetFunctor.h [new file with mode: 0644]
kernel/src/bbtkUserBlackBoxInputDescriptor.cxx [new file with mode: 0644]
kernel/src/bbtkUserBlackBoxInputDescriptor.h [new file with mode: 0644]
kernel/src/bbtkUserBlackBoxMacros.h [new file with mode: 0644]
kernel/src/bbtkUserBlackBoxOutputDescriptor.cxx [new file with mode: 0644]
kernel/src/bbtkUserBlackBoxOutputDescriptor.h [new file with mode: 0644]
kernel/src/bbtkUtilities.cxx [new file with mode: 0644]
kernel/src/bbtkUtilities.h [new file with mode: 0644]
kernel/src/bbtkVirtualExec.h [new file with mode: 0644]
kernel/src/bbtkWx.cxx [new file with mode: 0644]
kernel/src/bbtkWx.h [new file with mode: 0644]
kernel/src/bbtkWxBlackBox.cxx [new file with mode: 0644]
kernel/src/bbtkWxBlackBox.h [new file with mode: 0644]
kernel/src/bbtkWxBrowser.cxx [new file with mode: 0644]
kernel/src/bbtkWxBrowser.h [new file with mode: 0644]
kernel/src/bbtkWxConsole.cxx [new file with mode: 0644]
kernel/src/bbtkWxConsole.h [new file with mode: 0644]
kernel/src/cmake/bbtkConfigure.h.in [new file with mode: 0644]
kernel/src/cmake/bbtkTestFUNCTION.cxx [new file with mode: 0644]
kernel/src/cmake/bbtkTestIstringStream.cxx [new file with mode: 0644]
kernel/src/xmlParser.cpp [new file with mode: 0644]
kernel/src/xmlParser.h [new file with mode: 0644]
packages/CMakeLists.txt [new file with mode: 0644]
packages/wx/CMakeLists.txt [new file with mode: 0644]
packages/wx/bbs/appli/testSlider.bbs [new file with mode: 0644]
packages/wx/bbs/appli/testSplit.bbs [new file with mode: 0644]
packages/wx/src/CMakeLists.txt [new file with mode: 0644]
packages/wx/src/bbwxSlider.cxx [new file with mode: 0644]
packages/wx/src/bbwxSlider.h [new file with mode: 0644]
packages/wx/src/bbwxSplit.cxx [new file with mode: 0644]
packages/wx/src/bbwxSplit.h [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..366cbc4
--- /dev/null
@@ -0,0 +1,29 @@
+#-----------------------------------------------------------------------------
+PROJECT(BBTK) 
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# BBTK version number
+SET(BBTK_MAJOR_VERSION 0)
+SET(BBTK_MINOR_VERSION 5)
+SET(BBTK_BUILD_VERSION 0)
+SET(BBTK_VERSION 
+  "${BBTK_MAJOR_VERSION}.${BBTK_MINOR_VERSION}.${BBTK_BUILD_VERSION}")
+# Now in bbtkConfigure.h file (cf. core/src)
+#ADD_DEFINITIONS( -DBBTK_VERSION=${BBTK_VERSION} )
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Set global configuration of the toolkit
+INCLUDE(cmake/BBTKGlobalConfiguration.cmake)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# The toolkit kernel (bbtk lib; appli : bbi, bbfy; docs; ...)
+SUBDIRS(kernel)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# The "standard" packages 
+SUBDIRS(packages)
+#-----------------------------------------------------------------------------
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
new file mode 100644 (file)
index 0000000..af6806c
--- /dev/null
@@ -0,0 +1,18 @@
+#-----------------------------------------------------------------------------
+# bbtk library 
+SUBDIRS(src)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Documentation
+#SUBDIRS(doc)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Applications (bbi, bbfy...)
+OPTION(BUILD_APPLICATIONS "Build Applications (bbi, bbfy, ...)" ON)
+IF(BUILD_APPLICATIONS)
+   SUBDIRS(appli)
+ENDIF(BUILD_APPLICATIONS)
+#-----------------------------------------------------------------------------
+
diff --git a/kernel/appli/CMakeLists.txt b/kernel/appli/CMakeLists.txt
new file mode 100644 (file)
index 0000000..51c109f
--- /dev/null
@@ -0,0 +1,12 @@
+# The BlackBox Interpreter
+SUBDIRS(bbi)
+
+# Creates html documentation of a package
+#SUBDIRS(bbdoc)
+
+# Black box code generator from xml
+#SUBDIRS(bbfy)
+
+# Utility that creates the file architecture for a new user package 
+#SUBDIRS(bbCreatePackage)
+
diff --git a/kernel/appli/bbCreatePackage/CMakeLists.txt b/kernel/appli/bbCreatePackage/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c005114
--- /dev/null
@@ -0,0 +1,48 @@
+# Installs bbCreatePackage.bat/.sh  
+# used to creates the file architecture for a new user package
+
+# go to data which install the input data to the script
+SUBDIRS(data)
+
+# Sets the data install path
+SET(bbCreatePackage_DATA_PATH 
+  ${CMAKE_INSTALL_PREFIX}/bin/Data_bbCreatePackage)
+
+IF(WIN32)
+  CONFIGURE_FILE(
+    ${CMAKE_CURRENT_SOURCE_DIR}/bbCreatePackage.bat.in
+    ${CMAKE_CURRENT_BINARY_DIR}/bbCreatePackage.bat
+    @ONLY IMMEDIATE
+    )
+  INSTALL_FILES(/bin .bat bbCreatePackage)
+  INSTALL_FILES(/bin .bbs bbCreatePackage)
+ENDIF(WIN32)
+
+
+IF(UNIX)
+  CONFIGURE_FILE(
+    ${CMAKE_CURRENT_SOURCE_DIR}/bbCreatePackage.sh.in
+    ${CMAKE_CURRENT_BINARY_DIR}/bbCreatePackage
+    @ONLY IMMEDIATE
+    )
+  CONFIGURE_FILE(
+    ${CMAKE_CURRENT_SOURCE_DIR}/bbCreatePackage.bbs
+    ${CMAKE_CURRENT_BINARY_DIR}/bbCreatePackage.bbs
+    @ONLY IMMEDIATE
+    )
+
+  INSTALL(
+    FILES ${CMAKE_CURRENT_BINARY_DIR}/bbCreatePackage
+    DESTINATION bin
+    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+  )
+  INSTALL(
+    FILES ${CMAKE_CURRENT_BINARY_DIR}/bbCreatePackage.bbs
+    DESTINATION bin
+    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+  )
+ENDIF(UNIX)
+
+
+
+
diff --git a/kernel/appli/bbCreatePackage/bbCreatePackage.bat.in b/kernel/appli/bbCreatePackage/bbCreatePackage.bat.in
new file mode 100755 (executable)
index 0000000..c72ae29
--- /dev/null
@@ -0,0 +1,51 @@
+@echo off
+
+echo creates the file architecture for a new user package
+
+
+if %0%1==%0 goto ERROR01
+
+
+set BBTKINPUT="@bbCreatePackage_DATA_PATH@"
+set BBTKOUTPUT=%1
+
+
+echo "----- Creating black box package '%BBTKNAME%' in repository '%BBTKOUTPUT%' -----"
+
+
+IF EXIST %BBTKOUTPUT% GOTO ERROR02
+
+echo "-> Packages repository '%BBTKOUTPUT%' does not exist : creating it"
+mkdir %BBTKOUTPUT%
+
+
+
+    echo "-> Creating file '%BBTKOUTPUT%/CMakeLists.txt' "
+    copy %BBTKINPUT%\PackageCMakeLists.txt %BBTKOUTPUT%\CMakeLists.txt
+    echo "-> Creating file directory '%BBTKOUTPUT%/cmake' "
+    mkdir %BBTKOUTPUT%\cmake
+    echo "-> Coping files in '%BBTKOUTPUT%/cmake' "
+    copy %BBTKINPUT%\cmake\*.cmake %BBTKOUTPUT%\cmake
+    copy %BBTKINPUT%\cmake\*.in %BBTKOUTPUT%\cmake
+
+echo "Done !"
+echo "Edit the file '%BBTKOUTPUT%/CMakeLists.txt' to customize your package"
+
+
+goto END
+
+
+
+
+:ERROR01
+echo bbCreatePackage.bat "<path-to-package-repository>"
+goto END
+
+:ERROR02
+echo "ERROR : Directory '%BBTKOUTPUT%/%BBTKNAME%' already exists !"  
+goto end
+
+
+
+:END
+
diff --git a/kernel/appli/bbCreatePackage/bbCreatePackage.bbs b/kernel/appli/bbCreatePackage/bbCreatePackage.bbs
new file mode 100644 (file)
index 0000000..9c685a3
--- /dev/null
@@ -0,0 +1,59 @@
+load std
+load wx
+
+new Sizer sizer
+new StaticText statictext
+new StaticText statictextDirectory
+new TextCtrl textctrl
+new CommandButton commandbutton
+new CommandButton dirbutton
+new DirDialog dirdialog
+new ExecSys execsys
+#new ConcatStrings concatstringPackagename
+new MakeFileName makeFilePackagename
+new ConcatStrings concatstringCommand
+new Print print
+new StaticText msg1
+new StaticText msg2
+new Execbbi execbbi
+
+set sizer.Title "Creat Package"
+set sizer.WxWidth 400
+set sizer.WxHeight 200
+
+set statictext.In "This script creates a new BBTK Package" 
+set textctrl.Title "2)    Name of the Package" 
+set textctrl.In "MyPackageBBTK" 
+set commandbutton.Label  "3)    Create Package" 
+set msg1.In "Missing directory ..?????"
+set msg2.In "Ok, See result of the command in the console window"
+set commandbutton.In  "exec msg1" 
+set dirbutton.Label  "1)    Choose directory" 
+set execbbi.In "exec print;  exec msg2; exec execsys;"
+set dirbutton.In  "connect dirdialog.Out statictextDirectory.In; exec dirdialog; exec statictextDirectory;   set commandbutton.In  'exec execbbi' " 
+set statictextDirectory.Title "Directory" 
+set statictextDirectory.ProcessMode 1 
+
+
+connect dirdialog.Out makeFilePackagename.Directory
+connect textctrl.Out makeFilePackagename.File
+
+set msg1.WxWidth 600
+set msg1.WxHeight 80
+set msg2.WxWidth 600
+set msg2.WxHeight 80
+
+set concatstringCommand.In1 "bbCreatePackage "
+connect makeFilePackagename.Out concatstringCommand.In2
+connect concatstringCommand.Out execsys.In  
+connect concatstringCommand.Out print.In  
+
+connect sizer.Child statictext.Parent
+connect sizer.Child dirbutton.Parent
+connect sizer.Child statictextDirectory.Parent
+connect sizer.Child textctrl.Parent
+connect sizer.Child commandbutton.Parent
+
+set dirbutton.ProcessMode 1
+graph CURRENT 0
+exec sizer
diff --git a/kernel/appli/bbCreatePackage/bbCreatePackage.sh.in b/kernel/appli/bbCreatePackage/bbCreatePackage.sh.in
new file mode 100755 (executable)
index 0000000..8a25868
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+# creates the file architecture for a new user package
+
+if [ $# -ne 1 ]
+    then
+    echo "usage : bbCreatePackage <package-folder-with-complete-path>"  
+    exit
+fi
+
+INPUT=@bbCreatePackage_DATA_PATH@
+OUTPUT=$1
+
+echo "----- Creating new black box package '$1' in repository '$OUTPUT' -----"
+
+if [ -e $OUTPUT ] 
+    then 
+    echo "ERROR : Directory '$OUTPUT' already exists !"  
+    exit
+fi
+
+
+echo "-> Creating directory '$OUTPUT'"
+mkdir $OUTPUT
+echo "-> Creating file '$OUTPUT/CMakeLists.txt'"
+cp ${INPUT}/PackageCMakeLists.txt ${OUTPUT}/CMakeLists.txt
+echo "-> Creating directory '$OUTPUT/cmake'"
+mkdir ${OUTPUT}/cmake
+echo "-> Copying files in '$OUTPUT/cmake'"
+cp ${INPUT}/cmake/*.cmake ${OUTPUT}/cmake/
+cp ${INPUT}/cmake/*.in ${OUTPUT}/cmake/
+echo "Done !" 
+echo "Edit the file '$OUTPUT/CMakeLists.txt' to customize your package"
diff --git a/kernel/appli/bbCreatePackage/bbCreatePackageLinux.bbs b/kernel/appli/bbCreatePackage/bbCreatePackageLinux.bbs
new file mode 100755 (executable)
index 0000000..ceada36
--- /dev/null
@@ -0,0 +1,67 @@
+# -------------------------------------------------------
+# This one, waiting the troubles with DirDialog are fixed
+# -------------------------------------------------------
+
+load std
+load wx
+
+new Sizer sizer
+new StaticText statictext
+new StaticText statictextDirectory
+new TextCtrl textctrl
+new TextCtrl textctrlDirectory
+new CommandButton commandbutton
+new CommandButton dirbutton
+new DirDialog dirdialog
+new ExecSys execsys
+
+new MakeFileName makeFilePackagename
+new ConcatStrings concatstringCommand
+new Print print
+new StaticText msg1
+new StaticText msg2
+new Execbbi execbbi
+
+set sizer.Title "Create Package"
+set sizer.WxWidth  400
+set sizer.WxHeight 300
+
+set statictext.In "This script creates a new BBTK Package" 
+set textctrl.Title "2)    Name of the Package" 
+set textctrl.In "MyPackageBBTK" 
+set commandbutton.Label  "3)    Create Package" 
+set msg1.In "Missing directory ..?????"
+set msg2.In "Ok, See result of the command in the console window"
+set commandbutton.In  "exec msg1" 
+set dirbutton.Label  "1)    Write directory name, then click here" 
+set execbbi.In "exec print;  exec msg2; exec execsys;"
+
+#set dirbutton.In "connect dirdialog.Out statictextDirectory.In; exec dirdialog; exec statictextDirectory; set commandbutton.In 'exec execbbi' " 
+set dirbutton.In  "connect textctrlDirectory.Out statictextDirectory.In ;        exec statictextDirectory; set commandbutton.In 'exec execbbi' " 
+
+set statictextDirectory.Title "Directory" 
+set statictextDirectory.ProcessMode 1
+
+connect textctrlDirectory.Out makeFilePackagename.Directory 
+connect textctrl.Out makeFilePackagename.File
+
+set msg1.WxWidth 600
+set msg1.WxHeight 80
+set msg2.WxWidth 600
+set msg2.WxHeight 80
+
+set concatstringCommand.In1 "bbCreatePackage "
+connect makeFilePackagename.Out concatstringCommand.In2
+connect concatstringCommand.Out execsys.In  
+connect concatstringCommand.Out print.In  
+
+connect sizer.Child statictext.Parent
+connect sizer.Child textctrlDirectory.Parent
+connect sizer.Child dirbutton.Parent
+connect sizer.Child statictextDirectory.Parent
+connect sizer.Child textctrl.Parent
+connect sizer.Child commandbutton.Parent
+
+set dirbutton.ProcessMode 1
+#graph CURRENT 0
+exec sizer
diff --git a/kernel/appli/bbfy/CMakeLists.txt b/kernel/appli/bbfy/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cf5814d
--- /dev/null
@@ -0,0 +1,7 @@
+SET(SOURCES
+  bbfy
+  )
+
+ADD_EXECUTABLE(bbfy ${SOURCES})  
+TARGET_LINK_LIBRARIES(bbfy bbtk)
+INSTALL_TARGETS(/bin/ bbfy)
diff --git a/kernel/appli/bbfy/bbfy.cpp b/kernel/appli/bbfy/bbfy.cpp
new file mode 100644 (file)
index 0000000..0c7972a
--- /dev/null
@@ -0,0 +1,1001 @@
+#ifdef WIN32
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#include <stdio.h>
+#include "xmlParser.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+
+//==========================================================================
+class bbfyException
+{
+public: 
+  bbfyException(const std::string& message) : mMessage(message) {}
+
+  std::string mMessage;
+};
+//==========================================================================
+
+//==========================================================================
+class bbfy
+{
+public:
+  bbfy(const std::string& filename, const std::string& output_path = "",
+       bool verbose = false);
+  
+  void CreateBlackBox();
+  void ParseXML();
+  void CreateHeader();
+  void CreateCode();
+
+  void WriteGenericITKFilterHeader();
+
+  void BeginNamespace();
+  void EndNamespace();
+
+private:
+  //
+  std::string mFilename;
+  std::string mOutputPath;
+  bool mVerbose;
+
+  //
+  std::string mName;
+  typedef enum 
+    {
+      STD,
+      itkImageToImageFilter,
+      vtkImageAlgorithm,
+      vtkPolyDataAlgorithm,
+    }
+    BoxType;
+  BoxType mType;
+  std::string mParentBlackBox;
+  std::string mItkParent;
+  std::string mVtkParent;
+  bool mGeneric;
+  std::string mAuthor;
+  std::string mDescription;
+  std::string mPackage;
+  bool mIsInNamespace;
+  std::string mNamespace;
+  // int mNbTemplateParam;
+  std::vector<std::string> mTemplateParam;
+  std::string mTemplateDeclaration;
+  std::string mTemplateImplementation;
+
+  std::vector<std::string> mInclude;
+
+  std::string mUserConstructor;
+  std::string mUserCopyConstructor;
+  std::string mUserDestructor;
+
+  typedef struct
+  {
+    std::string name;
+    std::string type;
+    std::string help;
+    std::string special;
+    std::string generic_type;
+  }
+    IO;
+  
+  std::vector<IO> mInput;
+  std::vector<IO> mOutput;
+
+  std::string mProcess;
+
+  //
+  std::ofstream mFile;
+  std::string mHName;
+  std::string mCxxName;
+
+};
+//==========================================================================
+
+
+
+//==========================================================================
+bbfy::bbfy(const std::string& filename, 
+          const std::string& output_path,
+          bool verbose)
+{
+  mFilename = filename;
+  mOutputPath = output_path;
+  mVerbose = verbose;
+
+  CreateBlackBox();
+}
+//==========================================================================
+
+//==========================================================================
+void bbfy::CreateBlackBox()
+{
+  // Parse XML input file
+  ParseXML();
+  // Create output files
+  CreateHeader();
+  CreateCode();
+}
+//==========================================================================
+
+
+//==========================================================================
+void GetTextOrClear(const XMLNode& node, std::string& var) 
+{
+  if (node.nText()>0) 
+    {
+      var = node.getText();
+    }
+  else if (node.nClear()>0) 
+    {
+      var = node.getClear().lpszValue;
+    }
+  else 
+    {
+      std::string mess("Error : element <");
+      mess += node.getName();
+      mess += "> : no text nor <PRE></PRE> clear tag found";
+      throw bbfyException(mess);
+    }
+}
+//==========================================================================
+
+
+//==========================================================================
+void bbfy::ParseXML()
+{
+  XMLResults* res = new XMLResults;
+  XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res);
+
+  if ( res->error != eXMLErrorNone ) 
+    {
+      std::ostringstream str;
+      str << XMLNode::getError(res->error);
+      str << " [line " << res->nLine << ", col "<<res->nColumn<<"]"; 
+      delete res;
+      throw bbfyException(str.str());
+    }
+  delete res;
+
+  // Name
+  if (!BB.isAttributeSet("name")) 
+    {
+      throw bbfyException("Error : no 'name' attribute found (mandatory)");
+    }
+  mName = BB.getAttribute("name");
+
+  if (mVerbose) std::cout << "* Creating BlackBox '"<<mName<<"'"<<std::endl;
+
+  // Type 
+  mGeneric = false;
+  mType = STD;
+  if (BB.isAttributeSet("type")) 
+    {
+      std::string bbtype = BB.getAttribute("type");
+      if (bbtype=="standard")
+       {
+         mGeneric = false;
+         mType = STD;
+       }
+      else if (bbtype=="itkImageToImageFilter")
+       {
+         mType = itkImageToImageFilter;
+         // Looks for <itkparent> tag
+         if (!BB.nChildNode("itkparent")) 
+           {
+             throw bbfyException("Error : blackbox type 'itkImageToImageFilter' but no <itkparent> tag found (mandatory)");
+           }
+         GetTextOrClear(BB.getChildNode("itkparent"),mItkParent);
+         // 
+         mGeneric = false;
+         if (BB.isAttributeSet("generic")) mGeneric=true;
+       }
+      else if ((bbtype=="vtkImageAlgorithm") || (bbtype=="vtkPolyDataAlgorithm"))
+       {
+         mType = vtkImageAlgorithm;
+         // Looks for <vtkparent> tag
+         if (!BB.nChildNode("vtkparent")) 
+           {
+             throw bbfyException("Error : blackbox type 'vtkImageAlgorithm' but no <vtkparent> tag found (mandatory)");
+           }
+         GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
+         // 
+       }
+      else 
+       {
+         std::string mess("Error : blackbox type '");
+         mess += bbtype;
+         mess += "' unknown (types are 'standard','itkfilter')";
+         throw bbfyException(mess);
+       }
+    }
+
+  // Parent black box
+  if (!BB.nChildNode("parentblackbox")) 
+    {
+      throw bbfyException("Error : no <parentblackbox> tag found (mandatory)");
+   }
+  GetTextOrClear(BB.getChildNode("parentblackbox"),mParentBlackBox);
+
+  // Package
+  if (!BB.nChildNode("package")) 
+    {
+      throw bbfyException("Error : no <package> tag found (mandatory)");
+   }
+  GetTextOrClear(BB.getChildNode("package"),mPackage);
+
+  // Author
+  int i,j;
+  for (i=0,j=0; i<BB.nChildNode("author"); i++) 
+    {
+      std::string val;
+      GetTextOrClear(BB.getChildNode("author",&j),val);
+      mAuthor += val;
+    }
+
+  // Description
+  for (i=0,j=0; i<BB.nChildNode("description"); i++) 
+    {
+      std::string val;
+      GetTextOrClear(BB.getChildNode("description",&j),val);
+      mDescription += val;
+    }
+  
+  // Namespace
+  mIsInNamespace = false;
+  if (BB.nChildNode("namespace"))
+    {
+      mIsInNamespace = true;
+      GetTextOrClear(BB.getChildNode("namespace"),mNamespace);
+    }
+  // UserConstructor body
+  if (BB.nChildNode("constructor"))
+    {
+      GetTextOrClear(BB.getChildNode("constructor"),mUserConstructor);
+    }
+  // UserCopyConstructor body
+  if (BB.nChildNode("copyconstructor"))
+    {
+      GetTextOrClear(BB.getChildNode("copyconstructor"),mUserCopyConstructor);
+    }
+  // UserDestructor body
+  if (BB.nChildNode("destructor"))
+    {
+      GetTextOrClear(BB.getChildNode("destructor"),mUserDestructor);
+    }
+    // Template parameters
+  //  mNbTemplateParam = BB.nChildNode("template");
+
+  if ( BB.nChildNode("template") > 0)
+    {
+      mTemplateDeclaration = "<";
+      mTemplateImplementation = "<";
+      
+      for (i=0,j=0; i<BB.nChildNode("template")-1; i++) 
+       {
+         mTemplateDeclaration += "class ";
+         std::string val;
+         GetTextOrClear(BB.getChildNode("template",&j),val);
+         mTemplateDeclaration += val;
+         mTemplateDeclaration +=  ",";
+         mTemplateImplementation += val;
+         mTemplateImplementation +=  ",";
+         mTemplateParam.push_back(val);
+       }
+      mTemplateDeclaration += "class ";
+      std::string val;
+      GetTextOrClear(BB.getChildNode("template",&j),val);
+      mTemplateDeclaration += val;
+      mTemplateDeclaration +=  ">";
+      mTemplateImplementation += val;
+      mTemplateImplementation +=  ">";
+      mTemplateParam.push_back(val);
+    }
+
+  // Includes 
+  for (i=0,j=0; i<BB.nChildNode("include"); i++) 
+    {
+      std::string val;
+      GetTextOrClear(BB.getChildNode("include",&j),val);
+      mInclude.push_back(val);
+    }
+  
+  // Inputs
+  for (i=0,j=0; i<BB.nChildNode("input"); i++) 
+    {
+      XMLNode n = BB.getChildNode("input",&j); 
+      if (!n.isAttributeSet("name"))
+       {
+         throw bbfyException("Error : <input> attribute 'name' not found (mandatory)");
+       }
+      if (!n.isAttributeSet("type"))
+       {
+         throw bbfyException("Error : <input> attribute 'type' not found (mandatory)");
+       }
+
+      IO io;
+      io.name = n.getAttribute("name");
+      io.type = n.getAttribute("type"); 
+      GetTextOrClear(n,io.help);
+
+      if (n.isAttributeSet("special")) 
+       {
+         io.special =  n.getAttribute("special");  
+       }
+
+      if (n.isAttributeSet("generic_type")) 
+       {
+         io.generic_type =  n.getAttribute("generic_type");  
+       }
+
+      mInput.push_back(io);
+    }
+  
+  // Outputs
+  for (i=0,j=0; i<BB.nChildNode("output"); i++) 
+    {
+      XMLNode n = BB.getChildNode("output",&j); 
+      if (!n.isAttributeSet("name"))
+       {
+         throw bbfyException("Error : <output> attribute 'name' not found (mandatory)");
+       }
+      if (!n.isAttributeSet("type"))
+       {
+         throw bbfyException("Error : <output> attribute 'type' not found (mandatory)");
+       }
+
+      IO io;
+      io.name = n.getAttribute("name"); 
+      io.type = n.getAttribute("type"); 
+      GetTextOrClear(n,io.help);
+
+      if (n.isAttributeSet("special")) 
+       {
+         io.special =  n.getAttribute("special");  
+       }
+
+      if (n.isAttributeSet("generic_type")) 
+       {
+         io.generic_type =  n.getAttribute("generic_type");  
+       }
+
+      mOutput.push_back(io);
+    }
+
+
+  // Process
+  // Process tag given ?
+   if (BB.nChildNode("process"))
+     {
+       GetTextOrClear(BB.getChildNode("process"),mProcess);
+     }
+}
+//==========================================================================
+
+
+//==========================================================================
+void bbfy::BeginNamespace()
+{
+  if (mIsInNamespace)
+    {
+      mFile << "namespace "<<mNamespace <<"\n{\n\n";
+    }
+}
+//==========================================================================
+
+//==========================================================================
+void bbfy::EndNamespace()
+{
+  if (mIsInNamespace)
+    {
+      mFile << "}\n// EO namespace "<<mNamespace<<"\n\n";
+    }
+}
+//==========================================================================
+
+
+//==========================================================================
+void bbfy::CreateHeader()
+{
+
+  mHName = "bb";
+  mHName += mPackage;
+  mHName += mName;
+  mHName += ".h";
+  if (mVerbose) std::cout << " - Creating header '"<<mHName<<"'"<<std::endl;
+  std::string fullname = mOutputPath + mHName;
+  mFile.open(fullname.c_str());
+  if (!mFile.good())
+    {
+      std::string mess("Error : could not open file \"");
+      mess += fullname + "\"";
+      throw bbfyException(mess);
+    }
+  
+
+  // Includes 
+  mFile << "#include \"bbtkUserBlackBox.h\"\n";
+  std::vector<std::string>::iterator i;
+  for (i=mInclude.begin(); i!=mInclude.end(); ++i) 
+    {
+      mFile << "#include \"" << *i <<"\"\n";
+    }
+  if (mGeneric) mFile << "#include \"bbitkImage.h\"\n";
+  mFile << "\n";
+
+  // Namespace
+  BeginNamespace();
+
+  // Interface
+
+  // If it is a template class
+  if (mTemplateParam.size() > 0)
+    {
+      mFile << "template " << mTemplateDeclaration <<"\n";
+    }
+  
+  // Class declaration and parents
+  mFile << "class /*BBTK_EXPORT*/ "<<mName<<"\n";
+  mFile << " : \n";
+  mFile << "   public "<<mParentBlackBox;
+
+  /*
+  if (mBB.nChildNode("inherits"))
+    {
+      mFile << ",\n";
+      for (i=0,j=0; i<mBB.nChildNode("inherits")-1; i++) 
+       {
+         mFile << "   public " 
+               << mBB.getChildNode("inherits",&j).getText()
+               << ",\n";
+       }
+      mFile << "   public " 
+           << mBB.getChildNode("Inherits",&j).getText()
+           <<"\n";
+    }
+  */
+
+  if (mType == itkImageToImageFilter )
+    {
+      mFile << ",\n   public " << mItkParent <<"\n";
+    }
+  else if ( (mType == vtkImageAlgorithm) ||
+           (mType == vtkPolyDataAlgorithm) )
+    {
+      mFile << ",\n   public " << mVtkParent <<"\n";
+    }
+  else 
+    {
+      mFile << "\n";
+    }
+
+  mFile << "{\n";
+
+  // Interface
+  mFile << "  BBTK_USER_BLACK_BOX_INTERFACE("
+       << mName << ","
+       << mParentBlackBox << ");\n";
+
+  // typedef on itkfilter
+  if (mType == itkImageToImageFilter)
+    {
+      mFile << "  typedef " <<mItkParent <<" itkParent;"<<std::endl;
+      mFile << "  void bbDelete() { itkParent::UnRegister(); }"<<std::endl;
+    }
+  // typedef on itkfilter
+  if ( (mType == vtkImageAlgorithm) ||
+       (mType == vtkPolyDataAlgorithm) )
+    {
+      mFile << "  typedef " <<mVtkParent <<" vtkParent;"<<std::endl;
+      mFile << "  void bbDelete() { vtkParent::Delete(); }"<<std::endl;
+    }
+
+  // Declare user constructor / copy cons /destr 
+  mFile << "//=================================================================="<<std::endl;
+  mFile << "/// User callback called in the box contructor"<<std::endl;
+
+  mFile << "virtual void bbUserConstructor();"<<std::endl;
+  mFile << "/// User callback called in the box copy constructor"<<std::endl;
+  mFile << "virtual void bbUserCopyConstructor();"<<std::endl;
+  mFile << "/// User callback called in the box destructor"<<std::endl;
+  mFile << "virtual void bbUserDestructor();"<<std::endl;
+  mFile << "//=================================================================="<<std::endl; 
+
+
+
+  // Inputs
+  std::vector<IO>::iterator ioi;
+  for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
+    {
+      if (ioi->special=="") 
+       {
+         mFile << "  BBTK_DECLARE_INPUT(" 
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+       }
+      else if (ioi->special=="itk input")
+       {
+         mFile << "  BBTK_DECLARE_ITK_INPUT(" 
+               << "itkParent,"
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+       }
+      else if (ioi->special=="vtk input")
+       {
+         if (mType == vtkImageAlgorithm) {
+         mFile << "  BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT(" 
+               << "vtkParent,"
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+         } 
+         else if (mType == vtkPolyDataAlgorithm) {
+         mFile << "  BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT(" 
+               << "vtkParent,"
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+         }
+       }
+      else if (ioi->special=="itk parameter")
+       {
+         mFile << "  BBTK_DECLARE_ITK_PARAM(" 
+               << "itkParent,"
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+       }
+      else if (ioi->special=="vtk parameter")
+       {
+         mFile << "  BBTK_DECLARE_VTK_PARAM(" 
+               << "vtkParent,"
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+       }
+      else 
+       {
+         std::string mess("Error : input '");
+         mess += ioi->name;
+         mess += "', 'special' attribute '";
+         mess += ioi->special;
+         mess += "' unknown";
+         throw bbfyException(mess);
+       }
+    }
+  
+  // Outputs
+  for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
+    {
+      if (ioi->special=="") 
+       {
+         mFile << "  BBTK_DECLARE_OUTPUT(" 
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+       }
+      else if (ioi->special=="itk output")
+       {
+         mFile << "  BBTK_DECLARE_ITK_OUTPUT(" 
+               << "itkParent,"
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+       }  
+      else if (ioi->special=="vtk output")
+       {
+         mFile << "  BBTK_DECLARE_VTK_OUTPUT(" 
+               << "vtkParent,"
+               << ioi->name
+               << ","
+               << ioi->type
+               << ");\n";
+       }  
+      else 
+       {
+         std::string mess("Error : output '");
+         mess += ioi->name;
+         mess += "', 'special' attribute '";
+         mess += ioi->special;
+         mess += "' unknown";
+         throw bbfyException(mess);
+       }
+    }
+  
+
+  // Process
+  if ((mType == STD)||(mProcess.size()))
+    {
+      mFile << "  BBTK_PROCESS(DoProcess);\n" ;
+      mFile << "  void DoProcess();\n";
+    }
+  else if (mType == itkImageToImageFilter)
+    {   
+      mFile << "  BBTK_PROCESS(itkParent::Update);\n" ;
+    }
+  else if ((mType == vtkImageAlgorithm) ||
+          (mType == vtkPolyDataAlgorithm) )
+
+    {   
+      mFile << "  BBTK_PROCESS(vtkParent::Update);\n" ;
+    }
+
+  // EO black box declaration
+  mFile << "};\n\n";
+
+
+
+  // BO black box description
+  if (mTemplateParam.size()==0)
+    {
+      mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
+           << mName << ","
+           << mParentBlackBox << ");\n";
+      mFile << "BBTK_NAME(\"" << mName <<"\");\n";
+    }
+  else if (mTemplateParam.size()==1)
+    {
+      mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
+           << mName //<< ","
+       //<< mParentBlackBox //<< ","
+       //   << mTemplateParam[0] 
+           << ");\n";
+      mFile << "BBTK_NAME(\"" << mName 
+           << "<\"+bbtk::TypeName<" << mTemplateParam[0]
+           <<">()+\">\");\n";
+    }
+ else 
+    {
+      throw bbfyException("template bb with more than 1 templ param not impl");
+    } 
+  
+  // Author
+  mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
+
+  // Description
+  mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
+  
+  // Inputs
+  for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
+    {
+      if (mTemplateParam.size()>0)
+       {
+         mFile << "BBTK_TEMPLATE_INPUT(";
+       } 
+      else 
+       {
+         mFile << "BBTK_INPUT(";
+       } 
+      mFile << mName << "," << ioi->name << ",\""
+           << ioi->help << "\"," <<  ioi->type <<");\n";
+    }
+  
+  // Outputs
+  for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
+    {
+      if (mTemplateParam.size()>0)
+       {
+         mFile << "BBTK_TEMPLATE_OUTPUT(";
+       } 
+      else 
+       {
+         mFile << "BBTK_OUTPUT(";
+       } 
+      mFile << mName << "," << ioi->name << ",\""
+           << ioi->help << "\"," <<  ioi->type <<");\n";
+    }
+  
+  // EO black box description
+  if (mTemplateParam.size()==0)
+    {
+      mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
+           << mName << ");\n";
+    }
+  else if (mTemplateParam.size()==1)
+    {
+      mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
+           << mName //<< ","
+       // << mTemplateParam[0] 
+           << ");\n";
+    }
+  else 
+    {
+      throw bbfyException("template bb with more than 1 templ param not impl");
+     
+    } 
+  
+  // Untemplatization of itk filters
+  if ( mGeneric )
+    {
+      WriteGenericITKFilterHeader();
+    }
+
+
+  // EO namespace
+  EndNamespace();
+
+  // EOF
+  mFile << "\n";
+
+  mFile.close();
+}
+//==========================================================================
+
+
+
+//==========================================================================
+void bbfy::WriteGenericITKFilterHeader()
+{
+  mFile << "\n//===================================================\n";
+  mFile << "// Generic \"untemplatized\" filter\n";
+  mFile << "//===================================================\n";
+
+  // Class declaration and parents
+  mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
+  mFile << " : \n";
+  mFile << "   public bbtk::UserBlackBox\n";
+  mFile << "{\n";
+
+  // Interface
+  mFile << "  BBTK_USER_BLACK_BOX_INTERFACE("
+       << mName << "Generic,bbtk::UserBlackBox);\n";
+
+  // Inputs
+  std::vector<IO>::iterator ioi;
+  for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
+    {
+      mFile << "  BBTK_DECLARE_INPUT(" 
+           << ioi->name
+           << ","
+           << ioi->generic_type
+           << ");\n";
+    }
+  
+  // Outputs
+  for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
+    {
+      mFile << "  BBTK_DECLARE_OUTPUT(" 
+           << ioi->name
+           << ","
+           << ioi->generic_type
+           << ");\n";
+    }
+    
+  // Process
+  mFile << "  BBTK_PROCESS(ProcessSwitch);\n";
+  mFile << "  private :\n";
+  mFile << "    inline void ProcessSwitch();\n";
+  mFile << "    template <class T, unsigned int D> void Process();\n";
+  // EO black box declaration
+  mFile << "};\n\n";
+
+
+
+  // BO black box description
+  mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
+       << mName << "Generic,bbtk::UserBlackBox);\n";
+  mFile << "BBTK_NAME(\"" << mName <<"\");\n";
+
+  // Author
+  mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
+
+  // Description
+  mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
+  
+  // Inputs
+  for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
+    {
+      mFile << "BBTK_INPUT(";
+      mFile << mName << "Generic," << ioi->name << ",\""
+           << ioi->help << "\"," <<  ioi->generic_type <<");\n";
+    }
+  
+  // Outputs
+  for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
+    {
+      mFile << "BBTK_OUTPUT(";
+      mFile << mName << "Generic," << ioi->name << ",\""
+           << ioi->help << "\"," <<  ioi->generic_type <<");\n";
+    }
+  
+  // EO black box description
+  mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
+       << mName << "Generic);\n";
+
+
+  //=================================================================
+  // ProcessSwitch implementation
+  mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
+       << "{\n"
+       << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
+       << "                           bbGetInputIn()->GetDimension(),\n"
+       << "                           Process);\n"
+       << "}\n";
+  //=================================================================
+
+
+  //=================================================================
+  // Template process implementation
+  mFile << "template <class T, unsigned int D>\n"
+       << "void "<<mName<<"Generic::Process()\n"
+       << "{\n"
+       << "  bbtkDebugMessageInc(\"Core\",9,\n"
+       << "      \""<<mName 
+       << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
+    
+       << "  typedef itk::Image<T,D> ImageType;\n"
+       << "  typedef "<<mName<<"<ImageType> FilterType;\n"
+    
+       << "  FilterType* f = new FilterType(\"Temp\");\n"
+    
+       << "  f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
+  
+  for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
+    {
+      if (ioi->name == "In") continue;
+      mFile << "  f->bbSetInput"<<ioi->name<<" ( this->bbGetInput" 
+           << ioi->name << "() );\n";
+    }
+  
+  mFile << "  f->bbUpdate();\n"
+       << "  this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
+       << "  f->UnRegister();\n"
+       << "  bbtkDebugDecTab(\"Core\",9);\n"
+       << "}\n\n";
+  //=================================================================
+
+
+}
+//==========================================================================
+
+
+//==========================================================================
+void bbfy::CreateCode()
+{
+  mCxxName = "bb";
+  mCxxName += mPackage;
+  mCxxName += mName;
+  mCxxName += ".cxx";
+  if (mVerbose) std::cout << " - Creating code   '"<<mCxxName<<"'"<<std::endl;
+  std::string fullname = mOutputPath + mCxxName;
+  mFile.open(fullname.c_str());
+  if (!mFile.good()) 
+    {
+      std::string mess("Error : could not open file \"");
+      mess += fullname;
+      mess += "\"";
+      throw bbfyException(mess);
+    }
+  
+  // Includes
+  // Header of the class
+  mFile << "#include \"" << mHName << "\"\n";
+
+  // Include Package header
+  mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
+
+  // BO namespace
+  BeginNamespace();
+  
+  // Template class ?
+  if (mTemplateParam.size()>0) 
+    {
+      // Implementation
+      mFile << "BBTK_USER_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
+           << mName << ","  
+           << mParentBlackBox << ");\n";
+     
+      if (mGeneric) 
+       {       
+         // Implementation
+         mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
+               << mName << "Generic,bbtk::UserBlackBox);\n";
+         // Package
+         mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
+               << mPackage << ","
+               << mName << "Generic)\n";
+       }
+    }
+  else 
+    {
+      // Non template class
+      // Package
+      mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
+           << mPackage << ","
+           << mName << ")\n";
+
+      // Implementation
+      mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
+           << mName << ","  
+           << mParentBlackBox << ");\n";
+      // Process
+      if ((mType == STD)||(mProcess.size()))
+       {
+         mFile << "void "<<mName<<"::DoProcess()\n{\n";
+         mFile << mProcess << "\n";
+         mFile << "}\n";
+       }
+    }
+  
+  // User constr / copy constr / destr implementation
+  mFile <<"void "<<mName<<"::bbUserConstructor()"<<std::endl;
+  mFile << "{"<<std::endl;
+  //mFile<<"bbtkDebugMessage(\"Core\",9,\""<<mName<<::bbUserConstructor()"<<std::endl);"<<std::endl;
+  mFile << mUserConstructor << std::endl;
+  mFile << "}" << std::endl;
+
+  mFile <<"void "<<mName<<"::bbUserCopyConstructor()"<<std::endl;
+  mFile << "{"<<std::endl;
+  //mFile<<"bbtkDebugMessage(\"Core\",9,\""<<mName<<::bbUserCopyConstructor()"<<std::endl);"<<std::endl;
+  mFile << mUserCopyConstructor << std::endl;
+  mFile << "}" << std::endl;
+
+  mFile <<"void "<<mName<<"::bbUserDestructor()"<<std::endl;
+  mFile << "{"<<std::endl;
+  //mFile<<"bbtkDebugMessage(\"Core\",9,\""<<mName<<::bbUserDestructor()"<<std::endl);"<<std::endl;
+  mFile << mUserDestructor << std::endl;
+  mFile << "}" << std::endl;
+
+
+  // EO namespace
+  EndNamespace();
+
+  mFile << "\n";
+  
+  // EOF
+  mFile.close();
+  
+}
+//==========================================================================
+
+
+
+
+//==========================================================================
+int main(int argc, char **argv)
+{
+  
+  if (argc<2 || argc>4) 
+    {
+      std::cerr << "usage : "<< argv[0] <<" xml_file [output_path] [-q]" << std::endl;
+      return 1;
+    }
+
+  try 
+    {
+      std::string output_path("");
+      bool verbose = true;
+      if (argc>2) output_path = argv[2];
+      if (argc>3) verbose = false;
+      
+      bbfy B(argv[1],output_path,verbose);
+    }
+  catch (bbfyException e)
+    {
+      std::cerr << e.mMessage << std::endl;
+      return 1;
+    }
+  return 0;
+}
+//==========================================================================
+
+
diff --git a/kernel/appli/bbi/CMakeLists.txt b/kernel/appli/bbi/CMakeLists.txt
new file mode 100644 (file)
index 0000000..11857f8
--- /dev/null
@@ -0,0 +1,23 @@
+
+#OPTION(BUILD_bbi_GRAPHICAL "Build bbi in graphical mode (requires wxWidgets)" OFF)
+#SWITCH_ON_IF_ALL_BUILD(BUILD_bbi_GRAPHICAL)
+#IF (BUILD_bbi_GRAPHICAL)
+#  SET(USE_WXWIDGETS ON CACHE BOOL "Use WxWidgets" FORCE)
+#ENDIF (BUILD_bbi_GRAPHICAL)
+
+
+SET(SOURCES
+  bbi
+  )
+
+
+IF(bbtk_USE_WXWIDGETS AND WIN32)
+  ADD_EXECUTABLE(bbi WIN32 ${SOURCES})  
+  SET_TARGET_PROPERTIES(bbi PROPERTIES LINK_FLAGS /subsystem:console )
+ELSE(bbtk_USE_WXWIDGETS AND WIN32)
+  ADD_EXECUTABLE(bbi ${SOURCES})  
+ENDIF(bbtk_USE_WXWIDGETS AND WIN32)
+
+
+TARGET_LINK_LIBRARIES(bbi bbtk)
+INSTALL_TARGETS(/bin/ bbi)
diff --git a/kernel/appli/bbi/bbi.cxx b/kernel/appli/bbi/bbi.cxx
new file mode 100644 (file)
index 0000000..a4c9c8a
--- /dev/null
@@ -0,0 +1,202 @@
+#ifdef _USE_WXWIDGETS_
+
+//==========================================================================
+// WITH WX
+//==========================================================================
+#include "bbtkInterpreter.h"
+#include "bbtkWxBlackBox.h"
+#include "bbtkWxConsole.h"
+
+#include <wx/cmdline.h>
+#include <vector>
+#include <map>
+
+
+static const wxCmdLineEntryDesc cmdLineDesc[] =
+{
+  { wxCMD_LINE_SWITCH, _T("c"), _T("command"), _T("turn to command line mode after file(s) processing") },
+  { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"),   _T("be quiet") },
+  { wxCMD_LINE_SWITCH, _T("h"), _T("help"),   _T("print help") },
+  { wxCMD_LINE_SWITCH, _T("g"), _T("graphical-dialog"),   _T("prompts the user for the parameters values using dialog boxes") },
+  { wxCMD_LINE_SWITCH, _T("t"), _T("text-dialog"),   _T("prompts the user for the parameters values in text mode") },
+  { wxCMD_LINE_SWITCH, _T("n"), _T("no-command"),   _T("do not show command window") },
+  { wxCMD_LINE_PARAM,  NULL, NULL, _T("input_file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },
+  { wxCMD_LINE_NONE }
+};
+
+
+
+class wxBBIApp : public wxApp
+{
+public:
+  bool OnInit( );
+  int  OnExit() { 
+    //    std::cout << "wxBBIApp::OnExit()"<<std::endl;
+    return true; }
+  void OnInitCmdLine(wxCmdLineParser& parser);
+  bool OnCmdLineParsed(wxCmdLineParser& parser);
+  void Run(bbtk::Interpreter*);
+
+  bbtk::Interpreter* I;
+  int argc;
+  std::vector<std::string> argv;
+  bool command;
+  bool quiet;
+  bool help;
+  bool graphical_dialog;
+  bool text_dialog;
+  bool no_command;
+
+  std::map<std::string,std::string> param_map;
+  std::vector<std::string> input_file;
+  
+};
+
+IMPLEMENT_APP(wxBBIApp);
+
+void wxBBIApp::OnInitCmdLine(wxCmdLineParser& parser)
+{
+  //    std::cout << "OnInitCmdLine"<<std::endl;
+  parser.SetDesc(cmdLineDesc);
+}
+
+bool wxBBIApp::OnCmdLineParsed(wxCmdLineParser& parser)
+{
+  quiet = ( parser.Found(_T("q")) );
+  help = ( parser.Found(_T("h")) );
+  graphical_dialog = ( parser.Found(_T("g")) );
+  text_dialog = ( parser.Found(_T("t")) );
+  no_command = ( parser.Found(_T("n")) );
+
+  // parse the arguments and consider those which contain a "=" 
+  // as set input commands, other as files
+  int argc = parser.GetParamCount();
+  for (int i=0; i<argc; ++i) 
+    {
+      std::string s = bbtk::wx2std(parser.GetParam(i));
+      std::string::size_type pos = s.find_first_of("=");
+      if (std::string::npos != pos) 
+       {
+         std::string left = s.substr(0,pos);
+         std::string right = s.substr(pos+1,s.size());
+         param_map[left]=right;
+         //      std::cout << "'"<<left << "' = '"<<right<<"'"<<std::endl;
+       }
+      else 
+       {
+         //      std::cout << "input file = ["<<s<<"]"<<std::endl;
+         input_file.push_back(s);
+       }
+    }
+
+  bool usage = (help && (input_file.size()==0));
+  if (usage) {
+    std::cout << "BBI (The Black Box Interpreter) - bbtk "
+             << bbtk::GetVersion() << " - (c) Creatis 2007-2008"
+             << std::endl;
+    parser.Usage();
+  }
+
+  command = ( parser.Found(_T("c")) || 
+             ((input_file.size() == 0) && 
+              (!no_command) &&
+              (!usage) ) );
+
+
+
+  return true;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// The `main program' equivalent, creating the windows and returning the
+// main frame
+bool wxBBIApp::OnInit( )
+{
+  //    std::cout << "OnInit"<<std::endl;
+  wxApp::OnInit();
+#ifdef __WXGTK__
+  //See http://www.wxwindows.org/faqgtk.htm#locale
+  setlocale(LC_NUMERIC, "C");
+#endif
+
+  bbtk::WxConsole *I = new bbtk::WxConsole(0,_T("bbi"),wxSize(600,400));
+  SetTopWindow(I);  
+  if (!no_command) I->Show(true);
+
+  I->SetInputs(param_map);
+
+  bool help_on_script = help && (input_file.size() > 0);
+  if (help_on_script) I->SetNoExecMode(true);
+
+  if (graphical_dialog) I->SetDialogMode(bbtk::Executer::GraphicalDialog);
+  if (text_dialog) I->SetDialogMode(bbtk::Executer::TextDialog);
+
+  std::vector<std::string>::const_iterator i;
+  for (i=input_file.begin(); i!=input_file.end(); ++i) I->InterpretFile(*i);
+  I->SetNoExecMode(false);
+
+  if (help_on_script) bbtk::HelpBlackBox("workspace",false);
+
+  if (!(command || bbtk::WxBlackBox::bbGlobalIsSomeWindowShown() ))
+    {
+      I->Close();
+    }
+  return true;
+
+}
+
+
+#if defined(_WIN32) 
+
+//  How to have a Console and wxWidgets
+//  http://www.wxwidgets.org/wiki/index.php/MSVC_Setup_Guide
+//   In Visual C++ 6 (7 should be similar), to create an application that is both a console application 
+//  (cout's to the console are visible) and has a wxWidgets GUI, 
+//  you need to use the linker option "/subsystem:console" and the following code:
+int main(int argc, char* argv[])
+{
+       return WinMain(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), SW_SHOWNORMAL);
+}
+
+#endif // defined(_WIN32) 
+
+
+#else
+//==========================================================================
+// WITHOUT WX
+//==========================================================================
+
+#include "bbtkInterpreter.h"
+
+int main(int argc, char* argv[])
+{  
+
+  if (argc>2) return 0;
+
+  std::cout << "BBI (Black Box Interpreter) - bbtk "
+           << bbtk::GetVersion()<< " - (c) Creatis 2007"
+           <<std::endl;
+
+  bbtk::Interpreter I;
+  if (argc==1) 
+    {
+      I.CommandLineInterpreter();
+    }
+  else 
+    {
+      std::string f(argv[1]);
+      I.InterpretFile(f);
+    }
+    
+  return 0;
+
+}
+
+// EOF
+#endif //#ifdef _USE_WXWIDGETS_
+
+
+
diff --git a/kernel/cmake/ADD_DEF.cmake b/kernel/cmake/ADD_DEF.cmake
new file mode 100644 (file)
index 0000000..a76413d
--- /dev/null
@@ -0,0 +1,33 @@
+#-----------------------------------------------------------------------------
+# MACRO TO ADD A COMPILER DEFINITION WHICH ADDS ALSO THE DEF 
+# INTO DOXYGEN PREDEFINED VAR 
+# (OTHERWISE DOXYGEN WOULD NOT PARSE THE FILES BLOCKED)
+MACRO(ADD_DEF DEF)
+  MESSAGE(STATUS "* Added definition -D${DEF}")
+  ADD_DEFINITIONS( -D${DEF} )
+  SET(DOXYGEN_DOC_PREDEFINED 
+    ${DOXYGEN_DOC_PREDEFINED};${DEF}
+    CACHE 
+    STRING 
+    ""
+    FORCE)
+  MARK_AS_ADVANCED(DOXYGEN_DOC_PREDEFINED)
+ENDMACRO(ADD_DEF)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# MACRO TO ADD A COMPILER DEFINITION WITH VALUE WHICH ADDS ALSO THE DEF 
+# INTO DOXYGEN PREDEFINED VAR 
+# (OTHERWISE DOXYGEN WOULD NOT PARSE THE FILES BLOCKED)
+MACRO(ADD_DEF_WITH_VAL DEF VAL)
+  MESSAGE(STATUS "* Added definition -D${DEF}=${VAL}")
+  ADD_DEFINITIONS( -D${DEF}=${VAL} )
+  SET(DOXYGEN_DOC_PREDEFINED 
+    ${DOXYGEN_DOC_PREDEFINED};${DEF}=${VAL}
+    CACHE 
+    STRING 
+    ""
+    FORCE)
+  MARK_AS_ADVANCED(DOXYGEN_DOC_PREDEFINED)
+ENDMACRO(ADD_DEF_WITH_VAL)
+#-----------------------------------------------------------------------------
diff --git a/kernel/cmake/BBTKConfigurePackage.cmake b/kernel/cmake/BBTKConfigurePackage.cmake
new file mode 100644 (file)
index 0000000..0e5fe48
--- /dev/null
@@ -0,0 +1,69 @@
+#---------------------------------------------------------------------------
+# Package dependencies
+IF(${BBTK_PACKAGE_NAME}_USE_VTK)
+  SET(USE_VTK ON CACHE BOOL "Use VTK" FORCE)
+  SET(BBTK_PACKAGE_LIBS
+    ${BBTK_PACKAGE_LIBS}
+    ${BBTK_VTK_LIBRARIES}
+    )
+ENDIF(${BBTK_PACKAGE_NAME}_USE_VTK)
+
+IF(${BBTK_PACKAGE_NAME}_USE_ITK)
+  SET(USE_ITK ON CACHE BOOL "Use ITK" FORCE)
+  SET(BBTK_PACKAGE_LIBS
+    ${BBTK_PACKAGE_LIBS}
+    ${BBTK_ITK_LIBRARIES}
+    )
+ENDIF(${BBTK_PACKAGE_NAME}_USE_ITK)
+
+IF(${BBTK_PACKAGE_NAME}_USE_GDCM)
+  SET(USE_GDCM ON CACHE BOOL "Use GDCM" FORCE)
+  SET(BBTK_PACKAGE_LIBS
+    ${BBTK_PACKAGE_LIBS}
+    ${BBTK_GDCM_LIBRARIES}
+    )
+ENDIF(${BBTK_PACKAGE_NAME}_USE_GDCM)
+
+IF(${BBTK_PACKAGE_NAME}_USE_GSMIS)
+  SET(USE_GSMIS ON CACHE BOOL "Use GSMIS" FORCE)
+  SET(BBTK_PACKAGE_LIBS
+    ${BBTK_PACKAGE_LIBS}
+    ${BBTK_GSMIS_LIBRARIES}
+    )
+ENDIF(${BBTK_PACKAGE_NAME}_USE_GSMIS)
+
+IF(${BBTK_PACKAGE_NAME}_USE_WXWIDGETS)
+  SET(BBTK_USE_WXWIDGETS ON CACHE BOOL "Use wxWidgets" FORCE)
+  MESSAGE(STATUS "BBTK_USE_WXWIDGETS forced to ON by the compilation of the package ${BBTK_PACKAGE_NAME}")
+  # bbtk already links against wx ...
+  #    SET(BBTK_PACKAGE_LIBS
+  #      ${BBTK_PACKAGE_LIBS}
+  #      ${BBTK_WXWIDGETS_LIBRARIES}
+  #      )
+ENDIF(${BBTK_PACKAGE_NAME}_USE_WXWIDGETS)
+
+
+#---------------------------------------------------------------------------
+
+
+
+
+#----------------------------------------------------------------------------
+# DEFINES ${PACKAGE_NAME}_AUTHOR
+# ADD_DEFINITIONS( -D${PACKAGE_NAME}_AUTHOR="${PACKAGE_AUTHOR}")
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+# DEFINES ${PACKAGE_NAME}_DESCRIPTION
+# ADD_DEFINITIONS( -D${PACKAGE_NAME}_DESCRIPTION="${PACKAGE_DESCRIPTION}")
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+# DEFINES ${BBTK_PACKAGE_NAME}_VERSION
+SET(BBTK_PACKAGE_VERSION 
+  "${BBTK_PACKAGE_MAJOR_VERSION}.${BBTK_PACKAGE_MINOR_VERSION}.${BBTK_PACKAGE_BUILD_VERSION}")
+#ADD_DEFINITIONS( -D${BBTK_PACKAGE_NAME}_VERSION=${BBTK_PACKAGE_VERSION})
+#----------------------------------------------------------------------------
+
+
+
+
+
diff --git a/kernel/cmake/BBTKConfigurePackage_doc.cmake b/kernel/cmake/BBTKConfigurePackage_doc.cmake
new file mode 100644 (file)
index 0000000..bd7f771
--- /dev/null
@@ -0,0 +1,128 @@
+  #----------------------------------------------------------------------------
+
+
+
+  IF(BUILD_bbtk_DOC_DOXYGEN) 
+       FIND_PACKAGE(Doxygen)
+       IF(DOXYGEN)
+               # Build the package documentation
+               SET(DOXYGEN_HTML_OUTPUT "html")
+               SET(DOXYGEN_LOGFILE "${CMAKE_CURRENT_BINARY_DIR}/bbtk_${BBTK_PACKAGE_NAME}_Doxygen.log")
+
+               # Input : Sources
+               SET(DOXYGEN_INPUT 
+                 ${DOXYGEN_INPUT}
+                 ${PROJECT_SOURCE_DIR}/src/packages/${BBTK_PACKAGE_NAME}
+               )
+
+               STRING(REGEX REPLACE ";" " " DOXYGEN_INPUT "${DOXYGEN_INPUT}")
+
+               # Output dir
+               SET(DOXYGEN_OUTPUT 
+                 ${PROJECT_BINARY_DIR}/doc/packages/${BBTK_PACKAGE_NAME}/)
+
+               # Doc exclude
+               SET(DOXYGEN_EXCLUDE "")
+               STRING(REGEX REPLACE ";" " " DOXYGEN_EXCLUDE "${DOXYGEN_EXCLUDE}")
+
+               # Predefined symbols
+               SET(DOXYGEN_PROJECT_NAME "BBTK ${BBTK_PACKAGE_NAME} BBTK_PACKAGE")
+
+               STRING(REGEX REPLACE ";" " " DOXYGEN_DOC_PREDEFINED "${DOXYGEN_DOC_PREDEFINED}")
+
+               #-----------------------------------------------------------------------------
+               # DOT verification
+
+               IF(DOT)
+                  GET_FILENAME_COMPONENT(DOXYGEN_DOT_PATH ${DOT} PATH)
+                  SET(DOXYGEN_HAVE_DOT "YES")
+               ELSE(DOT)
+                  SET(DOXYGEN_DOT_PATH "")
+                  SET(DOXYGEN_HAVE_DOT "NO")
+               ENDIF(DOT)
+
+               #-----------------------------------------------------------------------------
+               # Create file and project
+               CONFIGURE_FILE(
+                  ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Doxyfile.txt
+                  ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.txt
+                  IMMEDIATE
+               )
+
+               ADD_CUSTOM_COMMAND(
+                 OUTPUT ${PROJECT_BINARY_DIR}/doc/packages/${BBTK_PACKAGE_NAME}/html/index.html
+                 COMMAND 
+                 ${DOXYGEN} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.txt
+                 DEPENDS bb${BBTK_PACKAGE_NAME} 
+               )
+
+               ADD_CUSTOM_TARGET(doxygen-bbtk-${BBTK_PACKAGE_NAME} ALL
+                  DEPENDS ${PROJECT_BINARY_DIR}/doc/packages/${BBTK_PACKAGE_NAME}/html/index.html 
+               )
+       ELSE(DOXYGEN)
+               MESSAGE(FATAL_ERROR "Doxygen not found. Required to build the doxygen documentation")
+       ENDIF(DOXYGEN)
+
+  ENDIF(BUILD_bbtk_DOC_DOXYGEN) 
+
+
+
+
+  #----------------------------------------------------------------------------
+  # bbdoc
+  #---------------------------------------------------------------------------
+  IF(BUILD_bbtk_DOC_BBTK_PACKAGE) 
+    
+    #    MARK_AS_ADVANCED( bbdoc_PATH )
+
+    FILE(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc/packages)
+    FILE(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc/packages/${BBTK_PACKAGE_NAME})
+      
+
+    IF(WIN32)
+      IF(CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+       SET(bbdoc_EXECUTABLE ${EXECUTABLE_OUTPUT_PATH}/$(IntDir)/bbdoc.exe)
+      ELSE(CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+       SET(bbdoc_EXECUTABLE $(SolutionDir)/bin/$(OutDir)/bbdoc.exe)
+      ENDIF(CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+    ELSE(WIN32)
+      SET(bbdoc_EXECUTABLE ${EXECUTABLE_OUTPUT_PATH}/bbdoc)
+    ENDIF(WIN32)      
+  
+# NEVER USE CONFIGURATION FILE BUT ALWAYS BUILD WITH THE JUST COMPILED LIBS 
+# NOT THE INSTALLED ONES !  
+ #   IF(-bbtk_USE_CONFIGURATION_FILE)
+      # just pass the package name, not the full path name!
+      # and pass the option '1' to bbdoc to use config file
+ #     SET(bbdoc_INPUT ${BBTK_PACKAGE_NAME} 1)    
+ #   ELSE(-bbtk_USE_CONFIGURATION_FILE)
+      
+      
+      
+      IF(WIN32)
+       IF(CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+         SET(bbdoc_INPUT ${EXECUTABLE_OUTPUT_PATH}/$(IntDir)/${BBTK_PACKAGE_NAME})
+       ELSE(CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+         SET(bbdoc_INPUT $(SolutionDir)/bin/$(OutDir)/${BBTK_PACKAGE_NAME})
+       ENDIF(CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+      ELSE(WIN32)
+        SET(bbdoc_INPUT ${LIBRARY_OUTPUT_PATH}/${BBTK_PACKAGE_NAME})
+      ENDIF(WIN32)    
+ #   ENDIF(-bbtk_USE_CONFIGURATION_FILE)
+    
+
+    ADD_CUSTOM_COMMAND(
+      OUTPUT ${PROJECT_BINARY_DIR}/doc/packages/${BBTK_PACKAGE_NAME}/${BBTK_PACKAGE_NAME}.html
+      COMMAND 
+      ${bbdoc_EXECUTABLE} ${bbdoc_INPUT} ${PROJECT_BINARY_DIR}/doc/packages/${BBTK_PACKAGE_NAME}/${BBTK_PACKAGE_NAME}.html
+      DEPENDS 
+      bb${BBTK_PACKAGE_NAME}
+      ${bbdoc_EXECUTABLE}
+      )     
+    
+    ADD_CUSTOM_TARGET(${BBTK_PACKAGE_NAME}.html ALL
+      DEPENDS ${PROJECT_BINARY_DIR}/doc/packages/${BBTK_PACKAGE_NAME}/${BBTK_PACKAGE_NAME}.html)
+    
+  ENDIF(BUILD_bbtk_DOC_BBTK_PACKAGE) 
+  
+  
diff --git a/kernel/cmake/BBTKConfigurePackage_src.cmake b/kernel/cmake/BBTKConfigurePackage_src.cmake
new file mode 100644 (file)
index 0000000..43179ea
--- /dev/null
@@ -0,0 +1,172 @@
+
+#----------------------------------------------------------------------------
+# BINARY DIR MUST BE IN INCLUDE DIRS 
+# TO FIND .h OF AUTOMATICALLY GENERATED FILES (e.g. FROM XML)
+INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ) 
+# SOURCES DIR MUST ALSO BE IN INCLUDE DIRS FOR FILES COMPILED IN BINARY DIR 
+# WHICH NEED TO INCLUDE OTHER FILES OF THE PACKAGE
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES bb${BBTK_PACKAGE_NAME}Package.h
+CONFIGURE_FILE(
+  ${BBTK_DIR}/bbPackage.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/bb${BBTK_PACKAGE_NAME}Package.h
+  @ONLY IMMEDIATE
+  ) 
+INSTALL_FILES(/include/bb${BBTK_PACKAGE_NAME} FILES bb${BBTK_PACKAGE_NAME}Package.h)  
+#----------------------------------------------------------------------------
+  
+#----------------------------------------------------------------------------
+# CREATES bb${BBTK_PACKAGE_NAME}Package.cxx
+CONFIGURE_FILE(
+  ${BBTK_DIR}/bbPackage.cxx.in
+  ${CMAKE_CURRENT_BINARY_DIR}/bb${BBTK_PACKAGE_NAME}Package.cxx
+  @ONLY IMMEDIATE
+  )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+SET_SOURCE_FILES_PROPERTIES(
+  ${CMAKE_CURRENT_BINARY_DIR}/bb${BBTK_PACKAGE_NAME}Package.cxx
+  PROPERTIES GENERATED ON)
+#----------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------
+IF(BBTK_PACKAGE_COMPILE_ALL_CXX) 
+  FILE(GLOB BBTK_PACKAGE_CXX_SOURCES "." "*.cxx")
+  FILE(GLOB BBTK_PACKAGE_H_SOURCES "." "*.h")
+ENDIF(BBTK_PACKAGE_COMPILE_ALL_CXX) 
+
+
+SET(BBTK_PACKAGE_CXX_SOURCES
+  ${BBTK_PACKAGE_CXX_SOURCES}
+  #${CMAKE_CURRENT_BINARY_DIR_NAME}/
+  bb${BBTK_PACKAGE_NAME}Package
+  )
+#----------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+# bbfy
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+IF(BBTK_PACKAGE_COMPILE_ALL_XML) 
+  FILE(GLOB BBTK_PACKAGE_XML_SOURCES "." "*.xml")
+ENDIF(BBTK_PACKAGE_COMPILE_ALL_XML) 
+#----------------------------------------------------------------------------
+FOREACH(xmlfile ${BBTK_PACKAGE_XML_SOURCES})
+  
+  GET_FILENAME_COMPONENT(filename "${xmlfile}" NAME_WE) 
+  
+  IF(WIN32)
+    SET(bbfy_EXECUTABLE $(TargetDir)/bbfy.exe)
+  ELSE(WIN32)
+    SET(bbfy_EXECUTABLE ${EXECUTABLE_OUTPUT_PATH}/bbfy)
+  ENDIF(WIN32)      
+  
+  IF(BBFY_DEPENDENCY)
+    SET(BBFY_DEPENDENCY_STR ${bbfy_EXECUTABLE})
+  ENDIF(BBFY_DEPENDENCY)
+  
+  SET(BBFY_CXX_OUT ${CMAKE_CURRENT_BINARY_DIR}/${filename}.cxx)
+  
+  ADD_CUSTOM_COMMAND(
+    OUTPUT ${BBFY_CXX_OUT}
+    COMMAND 
+    ${bbfy_EXECUTABLE} ${xmlfile} ${CMAKE_CURRENT_BINARY_DIR}/ -q
+    DEPENDS ${xmlfile}
+    # LG : REMOVE AUTOMATIC DEPEDENCY ON bbfy BECAUSE CAUSED ALWAYS REBUILD xml BOXES WHEN bbtk CHANGED HENCE bbfy CHANGED
+    ${BBFY_DEPENDENCY_STR} 
+    #${bbfy_EXECUTABLE} 
+    )
+  
+  SET_SOURCE_FILES_PROPERTIES(
+    ${BBFY_CXX_OUT}
+    PROPERTIES GENERATED ON)
+  
+  
+  IF(NOT BBTK_PACKAGE_CXX_SOURCES MATCHES "${filename}")
+    SET(BBTK_PACKAGE_CXX_SOURCES
+      ${BBTK_PACKAGE_CXX_SOURCES}
+      ${filename}
+      )
+  ENDIF(NOT BBTK_PACKAGE_CXX_SOURCES MATCHES "${filename}") 
+  
+  INSTALL_FILES(/include/bb${BBTK_PACKAGE_NAME} FILES ${filename}.h)  
+ENDFOREACH(xmlfile)
+#----------------------------------------------------------------------------
+
+
+
+#----------------------------------------------------------------------------
+# CREATES LIBRARY
+ADD_LIBRARY(bb${BBTK_PACKAGE_NAME} SHARED 
+  ${BBTK_PACKAGE_CXX_SOURCES} ${BBTK_PACKAGE_H_SOURCES}
+  )
+TARGET_LINK_LIBRARIES(bb${BBTK_PACKAGE_NAME} 
+  bbtk
+  #  ${BBP_LINK_LIBRARIES} 
+  ${BBTK_PACKAGE_LIBS}
+  )
+#----------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------
+# INSTALLS LIBRARY
+# NOW USES THE InstallLibrary.cmake 
+SET( LIBRARY_NAME bb${BBTK_PACKAGE_NAME} )
+# SET THE LIB VERSION
+SET(${LIBRARY_NAME}_MAJOR_VERSION ${BBTK_PACKAGE_MAJOR_VERSION})
+SET(${LIBRARY_NAME}_MINOR_VERSION ${BBTK_PACKAGE_MINOR_VERSION})
+SET(${LIBRARY_NAME}_BUILD_VERSION ${BBTK_PACKAGE_BUILD_VERSION})
+# 
+#SET(INSTALL_LIBRARY_PATH ../cmake)
+# Include the file 'InstallLibrary.cmake' which does the clean install job
+#INCLUDE(${INSTALL_LIBRARY_PATH}/InstallLibrary.cmake)
+
+# OLD VERSION :
+# DEPRECATED SYNTAX BUT WHICH WORKS !!
+INSTALL_FILES(/include/bb${BBTK_PACKAGE_NAME} "\\.h$")  
+#INSTALL(FILES "$.h" DESTINATION include/${BBTK_PACKAGE_NAME})  
+INSTALL(TARGETS bb${BBTK_PACKAGE_NAME} DESTINATION lib)
+#  INSTALL_TARGETS(/lib bb${BBTK_PACKAGE_NAME})
+#----------------------------------------------------------------------------
+
+
+
+
+#---------------------------------------------------------------------------
+IF(CHCON_LIBRARIES)
+  # On recent linux running SELinux : 
+  # Have to change the context of the library created 
+  # to be able to load it dynamically and avoid the error : 
+  # "cannot restore segment prot after reloc: Permission denied"
+  # see e.g. 
+  # http://www.ittvis.com/services/techtip.asp?ttid=3092
+  # Try to find chcon
+  FIND_PROGRAM(CHCON_EXECUTABLE
+    NAMES chcon
+    PATHS
+    /usr/bin
+    /usr/local/bin
+    )
+  MARK_AS_ADVANCED(CHCON_EXECUTABLE)
+  IF(CHCON_EXECUTABLE)
+    # chcon found 
+    # custom post_build command to change the context of the .so generated
+    ADD_CUSTOM_COMMAND(
+      TARGET bb${BBTK_PACKAGE_NAME}
+      POST_BUILD
+      COMMAND chcon -t texrel_shlib_t ${LIBRARY_OUTPUT_PATH}/libbb${BBTK_PACKAGE_NAME}.so
+      ) 
+    # custom post-install command to change the context of the .so installed
+    INSTALL(CODE "EXEC_PROGRAM(chcon ARGS -t texrel_shlib_t ${CMAKE_INSTALL_PREFIX}/lib/libbb${BBTK_PACKAGE_NAME}.so)")
+  ENDIF(CHCON_EXECUTABLE)
+ENDIF(CHCON_LIBRARIES)
+#----------------------------------------------------------------------------
+
diff --git a/kernel/cmake/BBTKDefineOptions.cmake b/kernel/cmake/BBTKDefineOptions.cmake
new file mode 100644 (file)
index 0000000..1eb5973
--- /dev/null
@@ -0,0 +1,7 @@
+#-----------------------------------------------------------------------------
+# messages compilation options 
+OPTION ( BBTK_COMPILE_MESSAGES         "Compile bbtk messages ?"         ON)
+OPTION ( BBTK_COMPILE_DEBUG_MESSAGES   "Compile bbtk debug messages ?"   OFF)
+OPTION ( BBTK_COMPILE_WARNING_MESSAGES "Compile bbtk warning messages ?" ON)
+OPTION ( BBTK_COMPILE_ERROR_MESSAGES   "Compile bbtk error messages ?"   ON)
+#-----------------------------------------------------------------------------
diff --git a/kernel/cmake/BBTKFindGTK2.cmake b/kernel/cmake/BBTKFindGTK2.cmake
new file mode 100644 (file)
index 0000000..1ee6a74
--- /dev/null
@@ -0,0 +1,331 @@
+
+IF (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS)
+  # in cache already
+  SET(GTK2_FOUND TRUE)
+ELSE (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS)
+  IF(UNIX)
+    # use pkg-config to get the directories and then use these values
+    # in the FIND_PATH() and FIND_LIBRARY() calls
+    INCLUDE(UsePkgConfig)
+
+    PKGCONFIG(gtk-2.0 _GTK22IncDir _GTK22LinkDir _GTK22LinkFlags _GTK22Cflags)
+
+    FIND_PATH(GTK2_GTK_INCLUDE_PATH gtk/gtk.h
+      $ENV{GTK2_HOME}
+      ${_GTK22IncDir}
+      /usr/include/gtk-2.0
+      /usr/local/include/gtk-2.0
+      /opt/include/gtk-2.0
+      /opt/gnome/include/gtk-2.0
+      /sw/include/gtk-2.0
+    )
+
+    # Some Linux distributions (e.g. Red Hat) have glibconfig.h
+    # and glib.h in different directories, so we need to look
+    # for both.
+    #  - Atanas Georgiev <atanas@cs.columbia.edu>
+    PKGCONFIG(glib-2.0 _GLIB2IncDir _GLIB2inkDir _GLIB2LinkFlags _GLIB2Cflags)
+    PKGCONFIG(gmodule-2.0 _GMODULE2IncDir _GMODULE2inkDir _GMODULE2LinkFlags _GMODULE2Cflags)
+    SET(GDIR /opt/gnome/lib/glib-2.0/include)
+
+    FIND_PATH(GTK2_GLIBCONFIG_INCLUDE_PATH glibconfig.h
+      ${_GLIB2IncDir}
+      /opt/gnome/lib64/glib-2.0/include
+      /opt/gnome/lib/glib-2.0/include
+      /opt/lib/glib-2.0/include
+      /usr/lib64/glib-2.0/include
+      /usr/lib/glib-2.0/include
+      /sw/lib/glib-2.0/include
+    )
+    #MESSAGE(STATUS "DEBUG: GTK2_GLIBCONFIG_INCLUDE_PATH = ${GTK2_GLIBCONFIG_INCLUDE_PATH}")
+
+    FIND_PATH(GTK2_GLIB_INCLUDE_PATH glib.h
+      ${_GLIB2IncDir}
+      /opt/include/glib-2.0
+      /opt/gnome/include/glib-2.0
+      /usr/include/glib-2.0
+      /sw/include/glib-2.0
+    )
+    #MESSAGE(STATUS "DEBUG: GTK2_GLIBCONFIG_INCLUDE_PATH = ${GTK2_GLIBCONFIG_INCLUDE_PATH}")
+
+    FIND_PATH(GTK2_GTKGL_INCLUDE_PATH gtkgl/gtkglarea.h
+      ${_GLIB2IncDir}
+      /usr/include
+      /usr/local/include
+      /usr/openwin/share/include
+      /opt/gnome/include
+      /opt/include
+      /sw/include
+    )
+
+    PKGCONFIG(pango _PANGOIncDir _PANGOinkDir _PANGOLinkFlags _PANGOCflags)
+
+    FIND_PATH(GTK2_PANGO_INCLUDE_PATH pango/pango.h
+      ${_PANGOIncDir}
+      /opt/gnome/include/pango-1.0
+      /opt/include/pango-1.0
+      /usr/include/pango-1.0
+      /sw/include/pango-1.0
+    )
+
+    PKGCONFIG(gdk-2.0 _GDK2IncDir _GDK2inkDir _GDK2LinkFlags _GDK2Cflags)
+
+    FIND_PATH(GTK2_GDKCONFIG_INCLUDE_PATH gdkconfig.h
+      ${_GDK2IncDir}
+      /opt/gnome/lib/gtk-2.0/include
+      /opt/gnome/lib64/gtk-2.0/include
+      /opt/lib/gtk-2.0/include
+      /usr/lib/gtk-2.0/include
+      /usr/lib64/gtk-2.0/include
+      /sw/lib/gtk-2.0/include
+    )
+
+    # Dave:
+    FIND_PATH(GTK2_GDK_INCLUDE_PATH gdk.h
+      ${_GDK2IncDir}
+      /usr/include/gtk-2.0
+      /usr/include/gtk-2.0/gdk
+    )
+    #MESSAGE(STATUS "DEBUG: GTK2_GLIBCONFIG_INCLUDE_PATH = ${GTK2_GLIBCONFIG_INCLUDE_PATH}")
+
+    PKGCONFIG(cairo _CAIROIncDir _CAIROinkDir _CAIROLinkFlags _CAIROCflags)
+
+    FIND_PATH(GTK2_CAIRO_INCLUDE_PATH cairo.h
+      ${_CAIROIncDir}
+      /opt/gnome/include/cairo
+      /usr/include
+      /usr/include/cairo
+      /opt/include
+      /opt/include/cairo
+      /sw/include
+      /sw/include/cairo
+    )
+    #MESSAGE(STATUS "DEBUG: GTK2_CAIRO_INCLUDE_PATH = ${GTK2_CAIRO_INCLUDE_PATH}")
+
+    PKGCONFIG(atk _ATKIncDir _ATKinkDir _ATKLinkFlags _ATKCflags)
+
+    FIND_PATH(GTK2_ATK_INCLUDE_PATH atk/atk.h
+      ${_ATKIncDir}
+      /opt/gnome/include/atk-1.0
+      /usr/include/atk-1.0
+      /opt/include/atk-1.0
+      /sw/include/atk-1.0
+    )
+    #MESSAGE(STATUS "DEBUG: GTK2_ATK_INCLUDE_PATH = ${GTK2_ATK_INCLUDE_PATH}")
+
+    FIND_LIBRARY(GTK2_GTKGL_LIBRARY
+      NAMES
+        gtkgl
+      PATHS
+        ${_GTK22IncDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+    FIND_LIBRARY(GTK2_GTK_LIBRARY
+      NAMES
+        gtk-x11-2.0
+      PATHS
+        ${_GTK22LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+    FIND_LIBRARY(GTK2_GDK_LIBRARY
+      NAMES
+        gdk-x11-2.0
+      PATHS
+        ${_GDK2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+    FIND_LIBRARY(GTK2_GMODULE_LIBRARY
+      NAMES
+        gmodule-2.0
+      PATHS
+        ${_GMODULE2inkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+    FIND_LIBRARY(GTK2_GLIB_LIBRARY
+      NAMES
+        glib-2.0
+      PATHS
+        ${_GLIB2inkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+    FIND_LIBRARY(GTK2_Xi_LIBRARY 
+      NAMES
+        Xi
+      PATHS 
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+    FIND_LIBRARY(GTK2_GTHREAD_LIBRARY
+      NAMES
+        gthread-2.0
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+
+    FIND_LIBRARY(GTK2_GOBJECT_LIBRARY
+      NAMES
+        gobject-2.0
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+
+    IF(GTK2_GTK_INCLUDE_PATH)
+      IF(GTK2_GLIBCONFIG_INCLUDE_PATH)
+        IF(GTK2_GLIB_INCLUDE_PATH)
+          IF(GTK2_GTK_LIBRARY)
+            IF(GTK2_GLIB_LIBRARY)
+              IF(GTK2_PANGO_INCLUDE_PATH)
+                IF(GTK2_ATK_INCLUDE_PATH)
+                  IF(GTK2_CAIRO_INCLUDE_PATH)
+                    # Assume that if gtk and glib were found, the other
+                    # supporting libraries have also been found.
+
+                    SET(GTK2_FOUND TRUE)
+
+                    SET(GTK2_INCLUDE_DIRS
+                      ${GTK2_GTK_INCLUDE_PATH}
+                      ${GTK2_GLIBCONFIG_INCLUDE_PATH}
+                      ${GTK2_GLIB_INCLUDE_PATH}
+                      ${GTK2_PANGO_INCLUDE_PATH}
+                      ${GTK2_GDKCONFIG_INCLUDE_PATH}
+                      # Dave:
+                      ${GTK2_GDK_INCLUDE_PATH}
+                      ${GTK2_ATK_INCLUDE_PATH}
+                      ${GTK2_CAIRO_INCLUDE_PATH}
+                    )
+
+                    SET(GTK2_LIBRARIES
+                      ${GTK2_GTK_LIBRARY}
+                      ${GTK2_GDK_LIBRARY}
+                      ${GTK2_GLIB_LIBRARY}
+                    )
+                    #${GTK2_GOBJECT_LIBRARY})
+
+                    IF(GTK2_GMODULE_LIBRARY)
+                      SET(GTK2_LIBRARIES
+                        ${GTK2_LIBRARIES}
+                        ${GTK2_GMODULE_LIBRARY}
+                      )
+                    ENDIF(GTK2_GMODULE_LIBRARY)
+
+                    IF(GTK2_GTHREAD_LIBRARY)
+                      SET(GTK2_LIBRARIES
+                        ${GTK2_LIBRARIES}
+                        ${GTK2_GTHREAD_LIBRARY}
+                      )
+                    SET(GTK2_LIBRARIES ${GTK2_LIBRARIES})
+                    ENDIF(GTK2_GTHREAD_LIBRARY)
+                  ELSE(GTK2_CAIRO_INCLUDE_PATH)
+                    MESSAGE(STATUS "Can not find cairo")
+                  ENDIF(GTK2_CAIRO_INCLUDE_PATH)
+                ELSE(GTK2_ATK_INCLUDE_PATH)
+                  MESSAGE(STATUS "Can not find atk")
+                ENDIF(GTK2_ATK_INCLUDE_PATH)
+              ELSE(GTK2_PANGO_INCLUDE_PATH)
+                MESSAGE(STATUS "Can not find pango includes")
+              ENDIF(GTK2_PANGO_INCLUDE_PATH)
+            ELSE(GTK2_GLIB_LIBRARY)
+              MESSAGE(STATUS "Can not find glib lib")
+            ENDIF(GTK2_GLIB_LIBRARY)
+          ELSE(GTK2_GTK_LIBRARY)
+            MESSAGE(STATUS "Can not find gtk lib")
+          ENDIF(GTK2_GTK_LIBRARY)
+        ELSE(GTK2_GLIB_INCLUDE_PATH)
+          MESSAGE(STATUS "Can not find glib includes")
+        ENDIF(GTK2_GLIB_INCLUDE_PATH)
+      ELSE(GTK2_GLIBCONFIG_INCLUDE_PATH)
+        MESSAGE(STATUS "Can not find glibconfig")
+      ENDIF(GTK2_GLIBCONFIG_INCLUDE_PATH)
+    ELSE (GTK2_GTK_INCLUDE_PATH)
+      MESSAGE(STATUS "Can not find gtk includes")
+    ENDIF (GTK2_GTK_INCLUDE_PATH)
+
+    IF (GTK2_FOUND)
+      IF (NOT GTK2_FIND_QUIETLY)
+        MESSAGE(STATUS "Found GTK2: ${GTK2_LIBRARIES}")
+      ENDIF (NOT GTK2_FIND_QUIETLY)
+    ELSE (GTK2_FOUND)
+      IF (GTK2_FIND_REQUIRED)
+        MESSAGE(SEND_ERROR "Could NOT find GTK2")
+      ENDIF (GTK2_FIND_REQUIRED)
+    ENDIF (GTK2_FOUND)
+
+    MARK_AS_ADVANCED(
+      GTK2_GDK_LIBRARY
+      GTK2_GLIB_INCLUDE_PATH
+      GTK2_GLIB_LIBRARY
+      GTK2_GLIBCONFIG_INCLUDE_PATH
+      GTK2_GMODULE_LIBRARY
+      GTK2_GTHREAD_LIBRARY
+      GTK2_Xi_LIBRARY
+      GTK2_GTK_INCLUDE_PATH
+      GTK2_GTK_LIBRARY
+      GTK2_GTKGL_INCLUDE_PATH
+      GTK2_GTKGL_LIBRARY
+      GTK2_ATK_INCLUDE_PATH
+      GTK2_GDKCONFIG_INCLUDE_PATH
+      # Dave:
+      GTK2_GDK_INCLUDE_PATH
+      #GTK2_GOBJECT_LIBRARY
+      GTK2_PANGO_INCLUDE_PATH
+      # LG :
+      GTK2_CAIRO_INCLUDE_PATH
+      GTK2_GOBJECT_LIBRARY
+    )
+  ENDIF(UNIX)
+ENDIF (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS)
+
diff --git a/kernel/cmake/BBTKFindLibraries.cmake b/kernel/cmake/BBTKFindLibraries.cmake
new file mode 100644 (file)
index 0000000..96ff1c8
--- /dev/null
@@ -0,0 +1,179 @@
+#-----------------------------------------------------------------------------
+#OPTION(USE_VTK "Build VTK-based black boxes" OFF)
+IF(USE_VTK)
+  # Search VTK
+  FIND_PACKAGE(VTK)
+  # If vtk found
+  IF(VTK_FOUND)
+    MESSAGE ( STATUS "VTK FOUND - VERSION = ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}.${VTK_BUILD_VERSION}")
+    INCLUDE(${VTK_USE_FILE})
+    ADD_DEF( _USE_VTK_ )
+    SET(BBTK_VTK_LIBRARIES
+      #     vtkCommon 
+      vtkImaging  vtkGraphics vtkRendering vtkFiltering vtkCommon vtkWidgets
+      # LG : removed vtkIO because conflict with itktiff lib in ITKIO 
+      ) 
+    MARK_AS_ADVANCED(VTK_DIR)
+  ENDIF(VTK_FOUND)
+ENDIF(USE_VTK)
+#-----------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------
+#OPTION(USE_ITK "Build ITK-based black boxes" OFF)
+IF(USE_ITK)
+  # Search ITK
+  FIND_PACKAGE(ITK)
+  # If itk found
+  IF(ITK_FOUND)
+     MESSAGE ( STATUS "ITK FOUND - VERSION = ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}")
+    INCLUDE(${ITK_USE_FILE})
+    ADD_DEF( _USE_ITK_ )
+    SET(BBTK_ITK_LIBRARIES
+      ITKCommon ITKIO ITKBasicFilters ITKAlgorithms
+      )  
+    MARK_AS_ADVANCED(ITK_DIR)
+   # images compilation option 
+    OPTION ( itk_IMAGE_DIM_2 "itk : Compile 2D images" ON)
+    OPTION ( itk_IMAGE_DIM_3 "itk : Compile 3D images" ON)
+    OPTION ( itk_IMAGE_DIM_4 "itk : Compile 4D images" ON)
+    OPTION ( itk_IMAGE_TYPE_CHAR "itk : Compile char images" ON)
+    OPTION ( itk_IMAGE_TYPE_UCHAR "itk : Compile unsigned char images" ON)
+    OPTION ( itk_IMAGE_TYPE_SHORT "itk : Compile short images" ON)
+    OPTION ( itk_IMAGE_TYPE_USHORT "itk : Compile unsigned short images" ON)
+    OPTION ( itk_IMAGE_TYPE_INT "itk : Compile int images" ON)
+    OPTION ( itk_IMAGE_TYPE_UINT "itk : Compile unsigned int images" ON)
+    OPTION ( itk_IMAGE_TYPE_FLOAT "itk : Compile float images" ON)
+    OPTION ( itk_IMAGE_TYPE_DOUBLE "itk : Compile double images" ON)
+    
+    IF ( itk_IMAGE_DIM_2 ) 
+      ADD_DEF( BBTK_ITK_IMAGE_DIM_2 )
+    ENDIF ( itk_IMAGE_DIM_2 )
+    
+    IF ( itk_IMAGE_DIM_3 ) 
+      ADD_DEF( BBTK_ITK_IMAGE_DIM_3 )
+    ENDIF ( itk_IMAGE_DIM_3 )
+    
+    IF ( itk_IMAGE_DIM_4 ) 
+      ADD_DEF( BBTK_ITK_IMAGE_DIM_4 )
+    ENDIF ( itk_IMAGE_DIM_4 )
+
+    IF ( itk_IMAGE_TYPE_CHAR ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_int8_t )
+    ENDIF ( itk_IMAGE_TYPE_CHAR )
+
+    IF ( itk_IMAGE_TYPE_UCHAR ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_uint8_t )
+    ENDIF ( itk_IMAGE_TYPE_UCHAR )
+    
+    IF ( itk_IMAGE_TYPE_SHORT ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_int16_t )
+    ENDIF ( itk_IMAGE_TYPE_SHORT )
+    
+    IF ( itk_IMAGE_TYPE_USHORT ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_uint16_t )
+    ENDIF ( itk_IMAGE_TYPE_USHORT )
+    
+    IF ( itk_IMAGE_TYPE_INT ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_int32_t )
+    ENDIF ( itk_IMAGE_TYPE_INT )
+    
+    IF ( itk_IMAGE_TYPE_UINT ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_uint32_t )
+    ENDIF ( itk_IMAGE_TYPE_UINT )
+    
+    IF ( itk_IMAGE_TYPE_FLOAT ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_float )
+    ENDIF ( itk_IMAGE_TYPE_FLOAT )
+    
+    IF ( itk_IMAGE_TYPE_DOUBLE ) 
+      ADD_DEF( BBTK_ITK_IMAGE_TYPE_double )
+    ENDIF ( itk_IMAGE_TYPE_DOUBLE )
+  ENDIF(ITK_FOUND)
+ENDIF(USE_ITK)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+#OPTION(USE_GDCM "Build GDCM-based black boxes" OFF)
+IF(USE_GDCM)
+  # Search GDCM
+  FIND_PACKAGE(GDCM)
+  # If gdcm found
+  IF(GDCM_FOUND)
+    INCLUDE(${GDCM_USE_FILE})
+    ADD_DEF( _USE_GDCM_ )
+    
+    SET(BBTK_GDCM_LIBRARIES
+# TO DO : USE GDCM LINK LIBRARIES !!!
+      libgdcm libgdcmjpeg8 libgdcmjpeg12libgdcmjpeg16
+      )
+  ENDIF(GDCM_FOUND)
+ENDIF(USE_GDCM)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+#OPTION(USE_WXWIDGETS "Build wxWidgets-based black boxes" OFF)
+IF(USE_WXWIDGETS)
+
+IF(WIN32)
+  # Search WXWIDGETS
+
+  #  WXWINDOWS_LIBRARY         = full path to the wxWindows library and linker flags on unix
+  #  CMAKE_WX_CXX_FLAGS        = compiler flags for building wxWindows 
+  #  WXWINDOWS_INCLUDE_PATH    = include path of wxWindows
+  SET(WXWINDOWS_USE_GL 1)
+
+  #wxWidgets build related stuff
+  SET(WXW_USE_DEBUG ON)
+  SET(WXW_USE_UNICODE OFF)
+  SET(WXW_USE_SHARED ON)
+  SET(WXW_USE_UNIV OFF)
+  SET(WXW_USE_MONO OFF)
+  SET(WXW_FILE_VERSION "28")
+  SET(WXW_VERSION "2.8")
+
+  #CMake Options
+  # Why forcing verbosity ?
+  # SET(CMAKE_VERBOSE_MAKEFILE TRUE)
+
+  INCLUDE (${BBTK_DIR}/BBTKFindWX_WIN)
+  #
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}${WXWIDGETS_CXX_FLAGS}")
+  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}${WXWIDGETS_EXE_LINKER_FLAGS}")
+  ADD_DEFINITIONS( ${WXWIDGETS_DEFINITIONS}  )
+  #
+  INCLUDE_DIRECTORIES(${WXWIDGETS_INCLUDE_DIR})
+  LINK_DIRECTORIES( ${WXWIDGETS_LINK_DIRECTORIES} )
+  SET(THE_WXWIDGETS_LIBRARIES
+    ${WXWIDGETS_LIBRARIES}     
+    debug msvcrtd
+    debug msvcprtd
+    optimized msvcrt
+    optimized msvcprt
+    )
+ENDIF(WIN32)
+IF(UNIX)
+  # GTK2
+  INCLUDE(${BBTK_DIR}/BBTKFindGTK2.cmake)
+  INCLUDE_DIRECTORIES(${GTK2_INCLUDE_DIRS})
+  LINK_DIRECTORIES(${GTK2_LIBRARY_DIRS})
+  LINK_LIBRARIES(${GTK2_LIBRARIES})
+  # WX
+  # LG : Do not force but use what is installed !
+  # SET(wxWidgets_USE_LIBS base core gl)
+  FIND_PACKAGE( wxWidgets REQUIRED) 
+  INCLUDE( ${wxWidgets_USE_FILE} )
+  MARK_AS_ADVANCED(wxWidgets_CONFIG_EXECUTABLE)
+  SET(THE_WXWIDGETS_LIBRARIES
+    ${GTK2_LIBRARIES}
+    ${wxWidgets_LIBRARIES}
+   )
+ENDIF(UNIX)
+
+ADD_DEF( _USE_WXWIDGETS_ )
+SET(BBTK_WXWIDGETS_LIBRARIES
+  ${THE_WXWIDGETS_LIBRARIES}
+  )
+
+ENDIF(USE_WXWIDGETS)
+#-----------------------------------------------------------------------------
diff --git a/kernel/cmake/BBTKFindWX_WIN.cmake b/kernel/cmake/BBTKFindWX_WIN.cmake
new file mode 100644 (file)
index 0000000..a03d731
--- /dev/null
@@ -0,0 +1,573 @@
+#
+# FindwxW.cmake
+# v1.06 2006-03-27
+# Jerry Fath 2005
+# Based on work by Jorgen Bodde
+#
+# This module finds if wxWindows is installed and determines where the
+# include files and libraries are. It also determines what the name of
+# the library is. This code sets the following variables:
+#
+#  WXWIDGETS_FOUND =     wxWidgets was found
+#  WXWIDGETS_ROOT_DIR =  base wxWidgets directory
+#  WXWIDGETS_LINK_DIRECTORIES = link directories, useful for rpath on Unix
+#  WXWIDGETS_LIBRARIES       = all the wxWindows libraries ( and  linker flags on unix )
+#  WXWIDGETS_CXX_FLAGS        = compiler flags for building wxWindows
+#  WXWIDGETS_EXE_LINKER_FLAGS  = compiler flags for building wxWindows
+#  WXWIDGETS_INCLUDE_DIR    = all include path of wxWindows
+#  WXWIDGETS_DEFINITIONS  = all flags of wxWindows
+#
+#  WXWIDGETS_RELEASE_LIBRARIES       = release wxWindows libraries (Win32 only)
+#  WXWIDGETS_DEBUG_LIBRARIES       = debug wxWindows libraries (Win32 only)
+#  WXWIDGETS_COMMON_LIBRARIES  = libraries common to Release and Debug (Win32 only)
+
+# NOTE: This module REQUIRES that an environment variable named WXWIN
+# be set to the base wxWidgets installation directory.
+# Under Unix, you must also set and environment variable named WXWINCFG
+# to the name of the active build subdirectory (eg buildgtk).  As an alternative
+# to the WXWINCFG environment variable, you can set a sym link in the wxWidgets
+# root directory called wx-config which points to the active build subdirectory.
+#
+
+# These variable should be set before including this module
+#
+# WXWIDGETS_FILE_VERSION (26)
+# WXWIDGETS_VERSION (2.6)
+#
+#
+
+####################### EXAMPLE CMakeLists.txt ###################
+#
+##Required project specific settings
+#PROJECT( myprojectname )
+#SET(PROJECT_SOURCE_FILES  myfile.cpp myfile2.cpp)
+#IF( WIN32)
+#    SET(PROJECT_RC_FILE myresfile.rc)
+#ELSE( WIN32)
+#    SET(PROJECT_RC_FILE "")
+#ENDIF( WIN32)
+#
+##Optional project specific settings
+#SET(PROJECT_DEFINITIONS -D_MYPROJECT_ -D_MYPROJECT2_)
+#SET(PROJECT_INCLUDE_PATH e:/myproject/include e:/myproject2/include)
+#SET(PROJECT_LINK_DIRECTORIES e:/myproject/lib e:/myproject2/lib)
+#SET(PROJECT_LIBRARIES myprojectlib myproject2lib)
+#
+##wxWidgets build related stuff
+#SET(WXW_USE_DEBUG OFF)
+#SET(WXW_USE_UNICODE OFF)
+#SET(WXW_USE_SHARED OFF)
+#SET(WXW_USE_UNIV OFF)
+#SET(WXW_USE_MONO OFF)
+#SET(WXW_FILE_VERSION "26")
+#SET(WXW_VERSION "2.6")
+#
+#INCLUDE (FindwxW)
+#INCLUDE (UsewxW)
+#
+####################### END EXAMPLE CMakeLists.txt ###################
+
+#
+# Set WX_USE vars in CMakeLists if you don't want to default to all off
+#
+SET(WXWIDGETS_USE_DEBUG ${WXW_USE_DEBUG} CACHE BOOL "Use Debug versions of wxWindows libraries")
+SET(WXWIDGETS_USE_UNICODE ${WXW_USE_UNICODE} CACHE BOOL "Use Unicode versions of wxWindows libraries")
+SET(WXWIDGETS_USE_SHARED ${WXW_USE_SHARED} CACHE BOOL "Use shared versions of wxWindows libraries")
+SET(WXWIDGETS_USE_UNIV ${WXW_USE_UNIV} CACHE BOOL "Use Universal versions of wxWindows libraries")
+SET(WXWIDGETS_USE_MONO ${WXW_USE_MONO} CACHE BOOL "Use monolithic versions of wxWindows libraries")
+
+#
+# Style can be non-Win32 even under Windows when using MinGW
+#
+IF(WIN32)
+  SET(WIN32_STYLE_FIND 1)
+ENDIF(WIN32)
+IF(MINGW)
+  SET(WIN32_STYLE_FIND 0)
+  SET(UNIX_STYLE_FIND 1)
+ENDIF(MINGW)
+IF(UNIX)
+  SET(UNIX_STYLE_FIND 1)
+ENDIF(UNIX)
+
+#
+# Versions should be set before this file is included.  If not,
+# default to 2.6
+#
+IF(WXW_FILE_VERSION)
+  SET( WXVERSIONSUFFIX ${WXW_FILE_VERSION})
+ELSE(WXW_FILE_VERSION)
+  SET( WXVERSIONSUFFIX "26")
+ENDIF(WXW_FILE_VERSION)
+
+IF(WXW_VERSION)
+  SET( WXVERSION ${WXW_VERSION})
+ELSE(WXW_VERSION)
+  SET( WXVERSION "2.6")
+ENDIF(WXW_VERSION)
+
+#
+# Find the base wxWidgets install path
+# NOTE: WXWIN must be set
+#
+FIND_PATH( WXWIDGETS_ROOT_DIR
+   wx-config.in
+   $ENV{WXWIN}
+)
+IF(WXWIDGETS_ROOT_DIR STREQUAL "WXWIDGETS_ROOT_DIR-NOTFOUND")
+    MESSAGE( FATAL_ERROR "FATAL_ERROR: wx-config.in NOT found.  Set WXWIN")
+ENDIF(WXWIDGETS_ROOT_DIR STREQUAL "WXWIDGETS_ROOT_DIR-NOTFOUND")
+SET(WXWIDGETS_CONFIG_PATH ${WXWIDGETS_ROOT_DIR})
+
+#
+# Find library path (platform specific)
+#
+IF( WIN32_STYLE_FIND )
+
+    IF( WXWIDGETS_USE_SHARED )
+        SET(WXWIDGETS_LIB_PATH "${WXWIDGETS_ROOT_DIR}/lib/vc_dll" )
+    ELSE( WXWIDGETS_USE_SHARED )
+        SET(WXWIDGETS_LIB_PATH "${WXWIDGETS_ROOT_DIR}/lib/vc_lib" )
+    ENDIF( WXWIDGETS_USE_SHARED )
+    SET( WXWIDGETS_LINK_DIRECTORIES ${WXWIDGETS_LIB_PATH} )
+
+ELSE( WIN32_STYLE_FIND )
+  IF (UNIX_STYLE_FIND) 
+
+    #
+    # Unix uses a config specific directory under the install path
+    # specified in the WXWINCFG environment variable.
+    # If the WXWINCFG variable isn't set, we try a sym link within
+    # the WX root dir called wx-config, or the current PATH
+    #
+    FIND_PROGRAM( WX_WXCONFIG_EXECUTABLE
+                    wx-config
+                    "${WXWIDGETS_ROOT_DIR}/$ENV{WXWINCFG}"
+                    "${WXWIDGETS_ROOT_DIR}/wx-config" )
+    #
+    # Check wether wx-config can be found
+    #
+    IF(NOT EXISTS ${WX_WXCONFIG_EXECUTABLE})    
+      # we really need wx-config...
+      MESSAGE(FATAL_ERROR "FATAL_ERROR: Cannot find wx-config. Set WXWIN and WXWINCFG environment variables.")
+    ENDIF(NOT EXISTS ${WX_WXCONFIG_EXECUTABLE})    
+
+    GET_FILENAME_COMPONENT( WXWIDGETS_CONFIG_PATH
+                            WX_WXCONFIG_EXECUTABLE
+                            PATH )
+
+    SET(WXWIDGETS_LIB_PATH "${WXWIDGETS_CONFIG_PATH}/lib" )
+    SET( WXWIDGETS_LINK_DIRECTORIES ${WXWIDGETS_LIB_PATH} )
+
+  ELSE(UNIX_STYLE_FIND)
+    MESSAGE(FATAL_ERROR "FATAL_ERROR: FindwxWindows.cmake:  Platform unsupported by FindwxW.cmake. It's neither WIN32 nor UNIX")
+  ENDIF(UNIX_STYLE_FIND)
+ENDIF( WIN32_STYLE_FIND )
+
+#
+# Check options against installed libraries
+#
+SET(WX_CONFIG_ARGS "")
+SET( LIBRARYWANT  "${WXWIDGETS_LIB_PATH}/msw" )
+
+IF( WXWIDGETS_USE_UNIV )
+    SET( LIBRARYWANT "${LIBRARYWANT}univ")
+    SET( PFUNIV  "univ" )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --universal=yes")
+ELSE( WXWIDGETS_USE_UNIV )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --universal=no")
+ENDIF( WXWIDGETS_USE_UNIV )
+
+IF( WXWIDGETS_USE_UNICODE )
+    SET( LIBRARYWANT "${LIBRARYWANT}u" )
+    SET( PFUNICODE "u" )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --unicode=yes")
+ELSE( WXWIDGETS_USE_UNICODE )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --unicode=no")
+ENDIF( WXWIDGETS_USE_UNICODE )
+
+IF( WXWIDGETS_USE_DEBUG )
+    SET( PFDEBUG "d" )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --debug=yes")
+ELSE( WXWIDGETS_USE_DEBUG )
+    SET( PFDEBUG "" )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --debug=no")
+ENDIF( WXWIDGETS_USE_DEBUG )
+
+IF( WXWIDGETS_USE_SHARED )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --static=no")
+ELSE( WXWIDGETS_USE_SHARED )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS} --static=yes")
+ENDIF( WXWIDGETS_USE_SHARED )
+
+# Not sure how to check this yet!!!!!
+IF( WXWIDGETS_USE_MONO )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS}")
+ELSE( WXWIDGETS_USE_MONO )
+    SET(WX_CONFIG_ARGS "${WX_CONFIG_ARGS}")
+ENDIF( WXWIDGETS_USE_MONO )
+
+SET(WX_CONFIG_ARGS_LIBS "${WX_CONFIG_ARGS} --libs")
+
+#
+# Platform specific method for testing installed wx Builds
+#
+IF( WIN32_STYLE_FIND )
+
+    #
+    # See if we have both release and debug wx versions
+    #
+    SET ( WX_DEBUGANDRELEASE FALSE )
+    IF( EXISTS "${LIBRARYWANT}/wx/setup.h" )
+        IF( EXISTS "${LIBRARYWANT}d/wx/setup.h" )
+            SET ( WX_DEBUGANDRELEASE TRUE )
+        ENDIF( EXISTS "${LIBRARYWANT}d/wx/setup.h" )
+    ENDIF( EXISTS "${LIBRARYWANT}/wx/setup.h" )
+
+    SET( LIBRARYWANT "${LIBRARYWANT}${PFDEBUG}" )
+    IF( NOT EXISTS "${LIBRARYWANT}/wx/setup.h" )
+        MESSAGE( SEND_ERROR "ERROR: WXWidgets config NOT found ${WX_CONFIG_ARGS}")
+    ENDIF( NOT EXISTS "${LIBRARYWANT}/wx/setup.h" )
+
+ELSE( WIN32_STYLE_FIND )
+
+    EXEC_PROGRAM(${WX_WXCONFIG_EXECUTABLE}
+        ARGS ${WX_CONFIG_ARGS_LIBS}
+        OUTPUT_VARIABLE WXWIDGETS_LIBRARIES
+        RETURN_VALUE BAD_WXCONFIG )
+    IF(BAD_WXCONFIG)
+        MESSAGE( SEND_ERROR "ERROR: WXWidgets config NOT found ${WX_CONFIG_ARGS}")
+    ENDIF(BAD_WXCONFIG)
+
+ENDIF( WIN32_STYLE_FIND )
+
+#
+#  Get compiler flags
+#
+IF( WIN32_STYLE_FIND )
+    # Not used for Windows
+    SET( WXWIDGETS_CXX_FLAGS "" )
+ELSE( WIN32_STYLE_FIND )
+    #
+    # Get CXXFLAGS from wx-config
+    #
+    EXEC_PROGRAM(${WX_WXCONFIG_EXECUTABLE}
+      ARGS "--cxxflags"
+      OUTPUT_VARIABLE WXWIDGETS_CXX_FLAGS
+      RETURN_VALUE BAD_WXCONFIG )
+    IF (BAD_WXCONFIG)
+      MESSAGE( SEND_ERROR "ERROR: wx-config --cxxflags returned an error")
+    ENDIF (BAD_WXCONFIG)
+ENDIF( WIN32_STYLE_FIND )
+
+#
+# Find include directories (platform specific)
+#
+IF( WIN32_STYLE_FIND )
+    #
+    # Set non-build specific include directories
+    #
+    SET ( WX_INCLUDE_PATH ${WXWIDGETS_ROOT_DIR}/include )
+    SET ( WXWIDGETS_INCLUDE_DIR ${WX_INCLUDE_PATH} )
+    SET( WXWIDGETS_INCLUDE_DIR ${WXWIDGETS_INCLUDE_DIR} ${WXWIDGETS_INCLUDE_DIR}/../contrib/include )
+    #
+    # Append the build specific include dir for wx/setup.h:
+    #
+    IF ( EXISTS ${LIBRARYWANT}/wx/setup.h )
+        SET( WX_INCLUDE_LIB_PATH ${LIBRARYWANT})
+        SET( WXWIDGETS_INCLUDE_DIR  ${WXWIDGETS_INCLUDE_DIR}  ${LIBRARYWANT} )
+    ELSE ( EXISTS ${LIBRARYWANT}/wx/setup.h )
+        SET( WX_INCLUDE_LIB_PATH, "")
+        MESSAGE(SEND_ERROR "ERROR: Can't find ${LIBRARYWANT}/wx/setup.h")
+    ENDIF ( EXISTS ${LIBRARYWANT}/wx/setup.h )
+
+ELSE( WIN32_STYLE_FIND )
+
+    # Pull out -I options
+    # evaluate wx-config output to separate include dirs
+    SET(WX_INCLUDE_DIR ${WXWIDGETS_CXX_FLAGS})
+    # extract include dirs (-I)
+    # use regular expression to match wildcard equivalent "-I*<endchar>"
+    # with <endchar> is a space or a semicolon
+    STRING(REGEX MATCHALL "[-][I]([^ ;])+" WX_INCLUDE_DIRS_WITH_PREFIX "${WX_INCLUDE_DIR}" )
+    # remove prefix -I because we need the pure directory
+    IF(WX_INCLUDE_DIRS_WITH_PREFIX)
+      STRING(REGEX REPLACE "[-][I]" ";" WXWIDGETS_INCLUDE_DIR ${WX_INCLUDE_DIRS_WITH_PREFIX} )
+    ENDIF(WX_INCLUDE_DIRS_WITH_PREFIX)
+    # replace space separated string by semicolon separated vector
+    SEPARATE_ARGUMENTS(WXWIDGETS_INCLUDE_DIR)
+    # Remove the -I options from the CXX_FLAGS no need to duplicate
+    STRING(REGEX REPLACE "[-][I]([^ ;])+" "" WXWIDGETS_CXX_FLAGS ${WXWIDGETS_CXX_FLAGS} )
+
+    #
+    # Find XWindows
+    #
+    IF( NOT CYGWIN OR MINGW )
+        INCLUDE( ${CMAKE_ROOT}/Modules/FindX11.cmake )
+        SET( WXWIDGETS_INCLUDE_DIR ${WXWIDGETS_INCLUDE_DIR}  ${X11_INCLUDE_DIR} )
+    ENDIF( NOT CYGWIN OR MINGW )
+ENDIF( WIN32_STYLE_FIND )
+
+#
+# Find library list (platform specific)
+#
+IF( WIN32_STYLE_FIND )
+    #
+    #Misc vars used to build lib names
+    #
+    SET( PFLIBEXT ${CMAKE_STATIC_LIBRARY_SUFFIX} )
+    SET( WXPF "${WXPF}${WXVERSIONSUFFIX}" )
+    SET( PFVERSION ${WXVERSIONSUFFIX} )
+    SET( PFCOMPILER "" )
+
+    #
+    # Build the libraries list
+    #
+    SET( WX_TOKEN_LIBS "" )
+    SET( WX_MULTI_LIBRARIES "" )
+    SET( WX_MONO_LIBRARIES "" )
+    SET( WX_DEBUG_TOKEN "@1" )
+
+    #start filling library string with needed libraries for the choosen configuration.
+    #note we use tokens for debug/release and the debug suffix so we can replace later
+    SET( WXPF "${PFVERSION}${PFUNICODE}${WX_DEBUG_TOKEN}" )
+    SET(WX_MULTI_LIBRARIES ${WX_MULTI_LIBRARIES}
+        wxbase${WXPF}${PFCOMPILER}${PFLIBEXT}
+        wxbase${WXPF}_net${PFCOMPILER}${PFLIBEXT}
+        wxbase${WXPF}_xml${PFCOMPILER}${PFLIBEXT}
+    )
+
+    SET( WXPF "${PFVERSION}${PFUNICODE}${WX_DEBUG_TOKEN}" )
+    SET(WX_MULTI_LIBRARIES ${WX_MULTI_LIBRARIES}
+        wxmsw${WXPF}_adv${PFCOMPILER}${PFLIBEXT}
+        wxmsw${WXPF}_core${PFCOMPILER}${PFLIBEXT}
+        wxmsw${WXPF}_html${PFCOMPILER}${PFLIBEXT}
+        wxmsw${WXPF}_xrc${PFCOMPILER}${PFLIBEXT}
+    )
+    IF (WXWIDGETS_USE_MEDIA)
+        SET(WX_MULTI_LIBRARIES ${WX_MULTI_LIBRARIES}
+            wxmsw${WXPF}_media${PFCOMPILER}${PFLIBEXT}
+        )
+    ENDIF (WXWIDGETS_USE_MEDIA)
+
+    IF( NOT WXWIDGETS_USE_SHARED )
+        SET( WXPF "${PFVERSION}${PFUNICODE}${WX_DEBUG_TOKEN}" )
+        IF (WXWIDGETS_USE_ODBC)
+            SET(WX_MULTI_LIBRARIES ${WX_MULTI_LIBRARIES}
+                wxbase${WXPF}_odbc${PFCOMPILER}${PFLIBEXT}
+             )
+        ENDIF (WXWIDGETS_USE_ODBC)
+
+        SET( WXPF "${PFVERSION}${PFUNICODE}${WX_DEBUG_TOKEN}" )
+        IF (WXWIDGETS_USE_DBGRID)
+            SET(WX_MULTI_LIBRARIES ${WX_MULTI_LIBRARIES}
+                wxmsw${WXPF}_dbgrid${PFLIBEXT}
+            )
+        ENDIF (WXWIDGETS_USE_DBGRID)
+        IF (WXWIDGETS_USE_GL)
+            SET(WX_MULTI_LIBRARIES ${WX_MULTI_LIBRARIES}
+                wxmsw${WXPF}_gl${PFCOMPILER}${PFLIBEXT}
+            )
+        ENDIF (WXWIDGETS_USE_GL)
+    ENDIF( NOT WXWIDGETS_USE_SHARED )
+
+    IF ( WXWIDGETS_USE_UNIV )
+        SET( WXPF "${PFUNIV}${PFVERSION}${PFUNICODE}${WX_DEBUG_TOKEN}" )
+        SET(WX_MULTI_LIBRARIES ${WX_MULTI_LIBRARIES}
+            wxmsw${WXPF}_core${PFCOMPILER}${PFLIBEXT}
+        )
+    ENDIF ( WXWIDGETS_USE_UNIV )
+
+    SET(WX_MONO_LIBRARIES ${WX_MONO_LIBRARIES}
+        wxmsw${WXPF}${PFCOMPILER}${PFLIBEXT}
+    )
+
+    IF ( WXWIDGETS_USE_MONO )
+        SET(WX_TOKEN_LIBS ${WX_TOKEN_LIBS} ${WX_MONO_LIBRARIES})
+    ELSE ( WXWIDGETS_USE_MONO )
+        SET(WX_TOKEN_LIBS ${WX_TOKEN_LIBS} ${WX_MULTI_LIBRARIES})
+    ENDIF ( WXWIDGETS_USE_MONO )
+
+    SET( WXPF "${PFUNICODE}${WX_DEBUG_TOKEN}" )
+    SET(WX_TOKEN_LIBS ${WX_TOKEN_LIBS}
+        wxregex${WXPF}.lib
+    )
+
+    SET( WXPF "${WX_DEBUG_TOKEN}" )
+    SET(WX_TOKEN_LIBS ${WX_TOKEN_LIBS}
+            wxexpat${WXPF}.lib
+            wxpng${WXPF}.lib
+            wxtiff${WXPF}.lib
+            wxjpeg${WXPF}.lib
+            wxzlib${WXPF}.lib
+    )
+
+
+    SET( WXWIDGETS_COMMON_LIBRARIES 
+        comctl32${PFLIBEXT} wsock32${PFLIBEXT} rpcrt4${PFLIBEXT}
+    )
+    #
+    #Build release/debug lists by replacing tokens
+    #
+    SET( WXWIDGETS_RELEASE_LIBRARIES "" )
+    FOREACH(LOOPLIB ${WX_TOKEN_LIBS})
+        SET(WX_TMPLIB ${LOOPLIB})
+        STRING(REGEX REPLACE "[@][1]" "" WX_TMPLIB ${WX_TMPLIB} )
+        SET( WXWIDGETS_RELEASE_LIBRARIES ${WXWIDGETS_RELEASE_LIBRARIES}
+            ${WX_TMPLIB}
+        ) 
+    ENDFOREACH(LOOPLIB ${WX_TOKEN_LIBS})
+    SET( WXWIDGETS_DEBUG_LIBRARIES "" )
+    FOREACH(LOOPLIB ${WX_TOKEN_LIBS})
+        SET(WX_TMPLIB ${LOOPLIB})
+        STRING(REGEX REPLACE "[@][1]" "d" WX_TMPLIB ${WX_TMPLIB} )
+        SET( WXWIDGETS_DEBUG_LIBRARIES ${WXWIDGETS_DEBUG_LIBRARIES}
+            ${WX_TMPLIB}
+        ) 
+    ENDFOREACH(LOOPLIB ${WX_TOKEN_LIBS})
+
+    #
+    # Set full lib list to requested type
+    #
+    IF( WXWIDGETS_USE_DEBUG )
+        SET( WXWIDGETS_LIBRARIES ${WXWIDGETS_COMMON_LIBRARIES}
+            ${WXWIDGETS_DEBUG_LIBRARIES}
+        ) 
+    ELSE( WXWIDGETS_USE_DEBUG )
+        SET( WXWIDGETS_LIBRARIES ${WXWIDGETS_COMMON_LIBRARIES}
+            ${WXWIDGETS_RELEASE_LIBRARIES}
+        ) 
+    ENDIF( WXWIDGETS_USE_DEBUG )
+
+    #Not used under Windows
+    SET( WXWIDGETS_EXE_LINKER_FLAGS "" )
+
+ELSE( WIN32_STYLE_FIND )
+    #
+    # Get Library list from wx-config
+    #
+    # do we need additionial wx GL stuff like GLCanvas ?
+    IF(WXWIDGETS_USE_GL)
+      SET(WX_CONFIG_ARGS_LIBS "${WX_CONFIG_ARGS_LIBS} --gl-libs" )
+    ENDIF(WXWIDGETS_USE_GL)
+      
+    EXEC_PROGRAM(${WX_WXCONFIG_EXECUTABLE}
+      ARGS ${WX_CONFIG_ARGS_LIBS}
+      OUTPUT_VARIABLE WX_CONFIGARGS
+      RETURN_VALUE BAD_WXCONFIG )
+    IF (BAD_WXCONFIG)
+      MESSAGE( SEND_ERROR "ERROR: Specified WXWidgets config NOT found")
+    ENDIF (BAD_WXCONFIG)
+      
+    #Pull lib dirs, linker opts, and libs from wx-config --libs return
+    SET(WXWIDGETS_LINK_DIRECTORIES "")
+    SET(WXWIDGETS_EXE_LINKER_FLAGS "")
+    SET(WXWIDGETS_LIBRARIES "")
+    SEPARATE_ARGUMENTS(WX_CONFIGARGS)
+    FILE( WRITE "${PROJECT_BINARY_DIR}/findwxw-args.log" "WXWIDGETS ARGS\n" )
+    FOREACH(WXARG ${WX_CONFIGARGS})
+      FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw-args.log" "WXARG: ${WXARG}\n" )
+      IF(WXARG MATCHES "^-L")
+        SET(WXWIDGETS_LINK_DIRECTORIES ${WXWIDGETS_LINK_DIRECTORIES} ${WXARG})
+      ELSE(WXARG MATCHES "^-L")
+        IF(WXARG MATCHES "^-l")
+          SET(WXWIDGETS_LIBRARIES "${WXWIDGETS_LIBRARIES} ${WXARG}")
+        ELSE(WXARG MATCHES "^-l")
+          IF(WXARG MATCHES "^-")
+            SET(WXWIDGETS_EXE_LINKER_FLAGS "${WXWIDGETS_EXE_LINKER_FLAGS} ${WXARG}")
+          ELSE(WXARG MATCHES "^-")
+            SET(WXWIDGETS_LIBRARIES "${WXWIDGETS_LIBRARIES} ${WXARG}")
+          ENDIF(WXARG MATCHES "^-")
+        ENDIF(WXARG MATCHES "^-l")
+      ENDIF(WXARG MATCHES "^-L")
+    ENDFOREACH(WXARG ${WX_CONFIGARGS})
+
+    #Separate library names with ;
+    SEPARATE_ARGUMENTS(WXWIDGETS_LIBRARIES)
+
+    # remove prefix -L because we need the pure directory for LINK_DIRECTORIES
+    # replace -L by ; because the separator seems to be lost otherwise (bug or
+    # feature?)
+    SET(WX_LINK_DIRECTORIES_WITH_PREFIX ${WXWIDGETS_LINK_DIRECTORIES})
+    IF(WX_LINK_DIRECTORIES_WITH_PREFIX)
+      STRING(REGEX REPLACE "[-][L]" ";" WXWIDGETS_LINK_DIRECTORIES ${WX_LINK_DIRECTORIES_WITH_PREFIX} )
+      #MESSAGE("DBG  WXWIDGETS_LINK_DIRECTORIES=${WXWIDGETS_LINK_DIRECTORIES}")
+    ENDIF(WX_LINK_DIRECTORIES_WITH_PREFIX)
+    # replace space separated string by semicolon separated vector to make it
+    # work with LINK_DIRECTORIES
+    SEPARATE_ARGUMENTS(WXWIDGETS_LINK_DIRECTORIES)
+
+
+    #
+    # Unix puts all the libs in the WXWIDGETS_LIBRARIES var
+    # We don't know debug/release libs under unix, so we set the
+    # common var to full set as well and leave debug/release sets blank
+    #
+    SET( WXWIDGETS_RELEASE_LIBRARIES "" )
+    SET( WXWIDGETS_DEBUG_LIBRARIES "" )
+    SET(WXWIDGETS_COMMON_LIBRARIES ${WXWIDGETS_LIBRARIES})
+
+ENDIF( WIN32_STYLE_FIND )
+
+
+#
+# Find wx.rc
+#
+SET( WXWIDGETS_RC ${WXWIDGETS_ROOT_DIR}/include/wx/msw/wx.rc )
+IF( NOT WIN32_STYLE_FIND )
+    IF( NOT CYGWIN OR MINGW )
+        SET( WXWIDGETS_RC "" )
+    ENDIF( NOT CYGWIN OR MINGW )
+ENDIF( NOT WIN32_STYLE_FIND )
+
+#
+# Set preprocessor defs
+#
+STRING(TOUPPER ${CMAKE_SYSTEM_NAME} WX_SYSNAME)
+SET( WXWIDGETS_DEFINITIONS ${WXWIDGETS_DEFINITIONS} "-D${WX_SYSNAME}" )
+
+IF(WIN32_STYLE_FIND)
+    SET( WXWIDGETS_DEFINITIONS ${WXWIDGETS_DEFINITIONS} -DWIN32 -D__WXMSW__  )
+ELSE(WIN32_STYLE_FIND)
+    IF( CYGWIN )
+        SET( WXWIDGETS_DEFINITIONS ${WXWIDGETS_DEFINITIONS} -D__GNUWIN32__  -O2 -D_WIN32_IE=0x400 -MMD -Wall  )
+    ENDIF( CYGWIN )
+ENDIF(WIN32_STYLE_FIND)
+
+IF( WXWIDGETS_USE_SHARED )
+    SET( WXWIDGETS_DEFINITIONS ${WXWIDGETS_DEFINITIONS} -DWXUSINGDLL  )
+ENDIF( WXWIDGETS_USE_SHARED )
+
+IF( WXWIDGETS_USE_DEBUG )
+    SET( WXWIDGETS_DEFINITIONS ${WXWIDGETS_DEFINITIONS} -D_DEBUG_  -D__WXDEBUG__  -DWXDEBUG=1 )
+ENDIF( WXWIDGETS_USE_DEBUG )
+
+IF ( WXWIDGETS_USE_UNICODE )
+    SET( WXWIDGETS_DEFINITIONS ${WXWIDGETS_DEFINITIONS} -DwxUSE_UNICODE  )
+ENDIF ( WXWIDGETS_USE_UNICODE )
+
+#
+# Set the WXWIDGETS_FOUND var
+#
+IF(WXWIDGETS_LIBRARIES AND WXWIDGETS_INCLUDE_DIR)
+    SET(WXWIDGETS_FOUND 1)
+ENDIF(WXWIDGETS_LIBRARIES AND WXWIDGETS_INCLUDE_DIR)
+
+#
+# Mark advanced vars
+#
+MARK_AS_ADVANCED(WXWIDGETS_ROOT_DIR)
+
+#
+# Log results
+#
+FILE( WRITE "${PROJECT_BINARY_DIR}/findwxw.log" "FindwxW.cmake version 1.06\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_FOUND: ${WXWIDGETS_FOUND}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_LINK_DIRECTORIES: ${WXWIDGETS_LINK_DIRECTORIES}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_LIBRARIES: ${WXWIDGETS_LIBRARIES}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_RELEASE_LIBRARIES: ${WXWIDGETS_RELEASE_LIBRARIES}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_DEBUG_LIBRARIES: ${WXWIDGETS_DEBUG_LIBRARIES}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_CXX_FLAGS: ${WXWIDGETS_CXX_FLAGS}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_EXE_LINKER_FLAGS: ${WXWIDGETS_EXE_LINKER_FLAGS}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_INCLUDE_DIR: ${WXWIDGETS_INCLUDE_DIR}\n" )
+FILE( APPEND "${PROJECT_BINARY_DIR}/findwxw.log" "WXWIDGETS_DEFINITIONS: ${WXWIDGETS_DEFINITIONS}\n" )
diff --git a/kernel/cmake/BBTKPreventInSourceBuild.cmake b/kernel/cmake/BBTKPreventInSourceBuild.cmake
new file mode 100644 (file)
index 0000000..de12a49
--- /dev/null
@@ -0,0 +1,6 @@
+#-----------------------------------------------------------------------------
+# Building in the source tree is forbidden ! 
+IF(PROJECT_BINARY_DIR STREQUAL ${PROJECT_SOURCE_DIR})
+  MESSAGE(FATAL_ERROR "Building in the source tree is not allowed !! Quit; remove the file 'CMakeCache.txt' and the folder 'CMakeFiles' and build outside the sources")
+ENDIF(PROJECT_BINARY_DIR STREQUAL ${PROJECT_SOURCE_DIR})
+#-----------------------------------------------------------------------------
diff --git a/kernel/cmake/BBTKResolveOptions.cmake b/kernel/cmake/BBTKResolveOptions.cmake
new file mode 100644 (file)
index 0000000..bc784da
--- /dev/null
@@ -0,0 +1,18 @@
+#-----------------------------------------------------------------------------
+# messages compilation options 
+IF (BBTK_COMPILE_MESSAGES) 
+  ADD_DEF( BBTK_COMPILE_MESSAGES )
+ENDIF (BBTK_COMPILE_MESSAGES) 
+
+IF (BBTK_COMPILE_DEBUG_MESSAGES) 
+  ADD_DEF( BBTK_COMPILE_DEBUG_MESSAGES )
+ENDIF (BBTK_COMPILE_DEBUG_MESSAGES) 
+
+IF (BBTK_COMPILE_WARNING_MESSAGES) 
+  ADD_DEF( BBTK_COMPILE_WARNING_MESSAGES )
+ENDIF (BBTK_COMPILE_WARNING_MESSAGES) 
+
+IF (BBTK_COMPILE_ERROR_MESSAGES) 
+  ADD_DEF( BBTK_COMPILE_ERROR_MESSAGES )
+ENDIF (BBTK_COMPILE_ERROR_MESSAGES) 
+#-----------------------------------------------------------------------------
diff --git a/kernel/cmake/BBTKSingleOutputPath.cmake b/kernel/cmake/BBTKSingleOutputPath.cmake
new file mode 100644 (file)
index 0000000..15f63a7
--- /dev/null
@@ -0,0 +1,6 @@
+#-----------------------------------------------------------------------------
+# Path for binaries : default = bin 
+SET (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single output directory for building all executables.")
+SET (LIBRARY_OUTPUT_PATH    ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single output directory for building all libraries.")
+MARK_AS_ADVANCED(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)
+#-----------------------------------------------------------------------------
diff --git a/kernel/cmake/FIND_AND_USE_WXWIDGETS.cmake b/kernel/cmake/FIND_AND_USE_WXWIDGETS.cmake
new file mode 100644 (file)
index 0000000..c9a748c
--- /dev/null
@@ -0,0 +1,63 @@
+
+
+MACRO(FIND_AND_USE_WXWIDGETS)
+
+  IF(WIN32)
+    # Search WXWIDGETS
+    
+    #  WXWINDOWS_LIBRARY         = full path to the wxWindows library and linker flags on unix
+    #  CMAKE_WX_CXX_FLAGS        = compiler flags for building wxWindows
+    #  WXWINDOWS_INCLUDE_PATH    = include path of wxWindows
+    #  WXWIDGETS_LIBRARIES       = wx libraries
+    
+    SET(WXWINDOWS_USE_GL 1)
+
+    #wxWidgets build related stuff
+    SET(WXW_USE_DEBUG    ON)
+    SET(WXW_USE_UNICODE  OFF)
+    SET(WXW_USE_SHARED   ON)
+    SET(WXW_USE_UNIV     OFF)
+    SET(WXW_USE_MONO     OFF)
+    SET(WXW_FILE_VERSION "28")
+    SET(WXW_VERSION      "2.8")
+    
+    #CMake Options
+    SET(CMAKE_VERBOSE_MAKEFILE TRUE)
+    
+    INCLUDE (cmake/FindwxW.cmake)
+    #
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}${WXWIDGETS_CXX_FLAGS}")
+    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}${WXWIDGETS_EXE_LINKER_FLAGS}")
+    ADD_DEFINITIONS( ${WXWIDGETS_DEFINITIONS}  )
+    #
+    INCLUDE_DIRECTORIES(${WXWIDGETS_INCLUDE_DIR})
+    LINK_DIRECTORIES( ${WXWIDGETS_LINK_DIRECTORIES} )
+    SET(WXWIDGETS_LIBRARIES
+      ${WXWIDGETS_LIBRARIES}     
+      debug msvcrtd
+      debug msvcprtd
+      optimized msvcrt
+      optimized msvcprt
+      )
+  ENDIF(WIN32)
+  IF(UNIX)
+    # GTK2
+    INCLUDE(cmake/FindGTK2.cmake)
+    INCLUDE_DIRECTORIES(${GTK2_INCLUDE_DIRS})
+    LINK_DIRECTORIES(${GTK2_LIBRARY_DIRS})
+    LINK_LIBRARIES(${GTK2_LIBRARIES})
+    # WX
+    #SET(wxWidgets_USE_LIBS base core gl)
+    FIND_PACKAGE( wxWidgets REQUIRED) 
+    INCLUDE( ${wxWidgets_USE_FILE} )
+    MARK_AS_ADVANCED(wxWidgets_CONFIG_EXECUTABLE)
+    SET(WXWIDGETS_LIBRARIES
+      ${wxWidgets_LIBRARIES}
+      ${GTK2_LIBRARIES}
+      )
+    MARK_AS_ADVANCED(GTK2_CAIRO_INCLUDE_PATH)
+    MARK_AS_ADVANCED(GTK2_GOBJECT_LIBRARY)
+  ENDIF(UNIX)
+
+ENDMACRO(FIND_AND_USE_WXWIDGETS)
+  
diff --git a/kernel/cmake/MARK_AS_ADVANCED_UNWANTED.cmake b/kernel/cmake/MARK_AS_ADVANCED_UNWANTED.cmake
new file mode 100644 (file)
index 0000000..a7c7192
--- /dev/null
@@ -0,0 +1,5 @@
+#-----------------------------------------------------------------------------
+# DO NOT WANT TO SEE THIS
+MARK_AS_ADVANCED(CMAKE_BACKWARDS_COMPATIBILITY)
+#-----------------------------------------------------------------------------
+
diff --git a/kernel/cmake/bbPackage.cxx.in b/kernel/cmake/bbPackage.cxx.in
new file mode 100644 (file)
index 0000000..21d47fc
--- /dev/null
@@ -0,0 +1,6 @@
+#include "bb@BBTK_PACKAGE_NAME@Package.h"
+
+BBTK_IMPLEMENT_PACKAGE(@BBTK_PACKAGE_NAME@,
+       "@BBTK_PACKAGE_AUTHOR@",
+       "@BBTK_PACKAGE_DESCRIPTION@",
+       "@BBTK_PACKAGE_VERSION@")
diff --git a/kernel/cmake/bbPackage.h.in b/kernel/cmake/bbPackage.h.in
new file mode 100644 (file)
index 0000000..102f8b3
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __bb@BBTK_PACKAGE_NAME@Package_h_INCLUDED__
+#define __bb@BBTK_PACKAGE_NAME@Package_h_INCLUDED__
+
+#include "bbtkPackage.h"
+
+BBTK_DECLARE_PACKAGE(@BBTK_PACKAGE_NAME@)
+
+#endif
diff --git a/kernel/src/CMakeLists.txt b/kernel/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6182ac1
--- /dev/null
@@ -0,0 +1,206 @@
+#-----------------------------------------------------------------------------
+# BUILDS AND INSTALLS THE LIBRARY BBTK
+#-----------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------
+# Tests 
+#-----------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------
+# Test if compiler defines the pseudo-macro __FUNCTION__
+IF("BBTK_COMPILER_HAS_FUNCTION" MATCHES "^BBTK_COMPILER_HAS_FUNCTION$")
+  MESSAGE(STATUS "Checking support for __FUNCTION__ in compiler")
+  TRY_COMPILE(BBTK_COMPILER_HAS_FUNCTION
+              ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp/Function
+              ${CMAKE_CURRENT_SOURCE_DIR}/cmake/bbtkTestFUNCTION.cxx
+              OUTPUT_VARIABLE OUTPUT)
+  IF(BBTK_COMPILER_HAS_FUNCTION)
+    MESSAGE(STATUS "Checking support for __FUNCTION__ -- yes")
+    SET(BBTK_COMPILER_HAS_FUNCTION 1 CACHE INTERNAL "Support for extension C __FUNCTION__")
+    WRITE_FILE(${CMAKE_CURRENT_BINARY_DIR}/CMakeOutput.log
+      "Determining if the C compiler supports __FUNCTION__ "
+      "passed with the following output:\n"
+      "${OUTPUT}\n" APPEND)
+  ELSE(BBTK_COMPILER_HAS_FUNCTION)
+    MESSAGE(STATUS "Checking support for __FUNCTION__ -- no")
+    SET(BBTK_COMPILER_HAS_FUNCTION 0 CACHE INTERNAL "Support for extension C __FUNCTION__")
+    WRITE_FILE(${CMAKE_CURRENT_BINARY_DIR}/CMakeError.log
+      "Determining if the C compiler supports __FUNCTION__ "
+      "failed with the following output:\n"
+      "${OUTPUT}\n" APPEND)
+  ENDIF(BBTK_COMPILER_HAS_FUNCTION)
+ENDIF("BBTK_COMPILER_HAS_FUNCTION" MATCHES "^BBTK_COMPILER_HAS_FUNCTION$")
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Test is compiler support istringstream
+IF("BBTK_TEST_ISTRINGSTREAM" MATCHES "^BBTK_TEST_ISTRINGSTREAM$")
+  MESSAGE(STATUS "Checking istringstream")
+  TRY_RUN(BBTK_TEST_ISTRINGSTREAM BBTK_TEST_ISTRINGSTREAM_COMPILED
+          ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp/
+          ${CMAKE_CURRENT_SOURCE_DIR}/cmake/bbtkTestIstringStream.cxx)
+  IF(BBTK_TEST_ISTRINGSTREAM_COMPILED)
+    IF(BBTK_TEST_ISTRINGSTREAM)
+      MESSAGE(STATUS "Checking istringstream works -- yes")
+      SET(BBTK_TEST_ISTRINGSTREAM 1 CACHE INTERNAL "Whether istringstream works.")
+    ELSE(BBTK_TEST_ISTRINGSTREAM)
+      MESSAGE(STATUS "Checking istringstream works -- no")
+      SET(BBTK_TEST_ISTRINGSTREAM 0 CACHE INTERNAL "Whether istringstream works.")
+    ENDIF(BBTK_TEST_ISTRINGSTREAM)
+  ELSE(BBTK_TEST_ISTRINGSTREAM_COMPILED)
+    MESSAGE(STATUS "Checking istringstream -- failed")
+  ENDIF(BBTK_TEST_ISTRINGSTREAM_COMPILED)
+ENDIF("BBTK_TEST_ISTRINGSTREAM" MATCHES "^BBTK_TEST_ISTRINGSTREAM$")
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+INCLUDE (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
+CHECK_INCLUDE_FILE("stdint.h"       CMAKE_HAVE_STDINT_H)
+IF(UNIX) #Avoid polluting Win32 cmakecache
+  CHECK_INCLUDE_FILE("inttypes.h"   CMAKE_HAVE_INTTYPES_H)
+  # termios 
+  CHECK_INCLUDE_FILE("termios.h"   CMAKE_HAVE_TERMIOS_H)
+ENDIF(UNIX)
+# Special Time support, two conventions: *NIX vs Win32
+CHECK_INCLUDE_FILE("sys/times.h"    CMAKE_HAVE_SYS_TIMES_H)
+CHECK_INCLUDE_FILE("sys/timeb.h"    CMAKE_HAVE_SYS_TIMEB_H)
+#-----------------------------------------------------------------------------
+
+  
+
+#-----------------------------------------------------------------------------
+# bbtk library dependencies
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# WXWIDGETS
+OPTION(BBTK_USE_WXWIDGETS "Build bbtk library and applications in graphical mode using the wxWidgets library" OFF)
+
+IF(BBTK_USE_WXWIDGETS)
+  SET(USE_WXWIDGETS ON CACHE BOOL "Use WxWidgets" FORCE)
+
+#  INCLUDE(cmake/FIND_AND_USE_WXWIDGETS.cmake)
+#  FIND_AND_USE_WXWIDGETS()
+#  ADD_DEF( _USE_WXWIDGETS_ )
+  SET(BBTK_LINK_LIBRARIES
+    ${BBTK_LINK_LIBRARIES}
+    ${BBTK_WXWIDGETS_LIBRARIES} 
+    )
+ENDIF(BBTK_USE_WXWIDGETS)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# On unix systems, need to link against dl for dynamic librairies open/close
+IF(UNIX)
+  SET(BBTK_LINK_LIBRARIES
+    ${BBTK_LINK_LIBRARIES}
+    dl) 
+ENDIF(UNIX)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# EO bbtk library dependencies
+#-----------------------------------------------------------------------------
+
+
+
+
+
+
+
+#-----------------------------------------------------------------------------
+# Generates the bbtkConfigure.h file
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/bbtkConfigure.h.in
+               ${CMAKE_CURRENT_BINARY_DIR}/bbtkConfigure.h 
+              @ONLY IMMEDIATE
+               )
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+IF(NOT BBTK_INSTALL_NO_DEVELOPMENT)
+  INSTALL_FILES(/include/bbtk FILES bbtkConfigure.h)
+ENDIF(NOT BBTK_INSTALL_NO_DEVELOPMENT)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Add the path to current dir for apps to find bbtkConfigure.h
+# LG : already done in upper dir
+#INCLUDE_DIRECTORIES(
+#  ${CMAKE_CURRENT_BINARY_DIR} #for bbtkConfigure.h
+#)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# EO Generates the bbtkConfigure.h file
+#-----------------------------------------------------------------------------
+
+
+
+
+
+
+
+#-----------------------------------------------------------------------------
+# bbtk library creation
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Sources files 
+FILE(GLOB SOURCES "." "*.cxx" "*.cpp")
+FILE(GLOB SOURCES_H "." "*.h" )
+#-----------------------------------------------------------------------------
+# lib definition
+ADD_LIBRARY(bbtk SHARED ${SOURCES} ${SOURCES_H})
+#-----------------------------------------------------------------------------
+TARGET_LINK_LIBRARIES(bbtk ${BBTK_LINK_LIBRARIES})
+#-----------------------------------------------------------------------------
+
+#IF(UNIX)
+# for gnu linker : version script used to define exported symbols
+#SET_TARGET_PROPERTIES(bbtk PROPERTIES 
+#  LINK_FLAGS_DEBUG -Wl,--version-script=bbtk.map)
+#SET_TARGET_PROPERTIES(bbtk PROPERTIES
+#  LINK_FLAGS_RELEASE -Wl,--version-script=bbtk.map)
+#ENDIF(UNIX)
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# EO bbtk library creation
+#-----------------------------------------------------------------------------
+
+
+
+
+
+
+#-----------------------------------------------------------------------------
+# bbtk library installation
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+INSTALL_FILES(/include/bbtk "\\.h$")
+INSTALL_TARGETS(/lib bbtk)
+#-----------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------
+# TO DO : create FindBBTK.cmake
+#INCLUDE(InstallFindBBTK.cmake)
+#-----------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------
+# EO bbtk library installation
+#-----------------------------------------------------------------------------
+
+
+
+#-----------------------------------------------------------------------------
+# EOF
+#-----------------------------------------------------------------------------
+
diff --git a/kernel/src/bbtkAny.cxx b/kernel/src/bbtkAny.cxx
new file mode 100644 (file)
index 0000000..97d39f1
--- /dev/null
@@ -0,0 +1,23 @@
+#include "bbtkAny.h"
+
+
+namespace bbtk
+{
+  /// The TypeTraits which validates all integer types
+  template <> const bool integer<char>::value = true; 
+  template <> const bool integer<short>::value = true;
+  template <> const bool integer<int>::value = true; 
+  template <> const bool integer<long>::value = true; 
+  template <> const bool integer<long long>::value = true; 
+  template <> const bool integer<unsigned char>::value = true; 
+  template <> const bool integer<unsigned short>::value = true;
+  template <> const bool integer<unsigned int>::value = true; 
+  template <> const bool integer<unsigned long>::value = true; 
+  template <> const bool integer<unsigned long long>::value = true; 
+
+  /// The TypeTraits which validates all floating point number types
+  template <> const bool floating_point<float>::value = true;
+  template <> const bool floating_point<double>::value = true;
+}
+
+  
diff --git a/kernel/src/bbtkAny.h b/kernel/src/bbtkAny.h
new file mode 100644 (file)
index 0000000..45ed576
--- /dev/null
@@ -0,0 +1,555 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkAny.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *\file
+ *\brief  Defines the class any which can store any type of data (adapted from boost::any).
+ */
+#ifndef __BBTKANY_H_INCLUDED__
+#define __BBTKANY_H_INCLUDED__
+
+/*
+#include <string>
+#include <iostream>
+#include <typeinfo>
+#include <set>
+#include <map>
+#include <sstream>
+#include <exception>
+
+#include <cxxabi.h>
+*/
+#include <sstream>
+#include "bbtkRTTI.h"
+#include "bbtkMessageManager.h"
+#include "bbtkException.h"
+
+#ifdef _USE_BOOST_
+#include <boost/type_traits/is_pointer.hpp>
+#endif 
+
+namespace bbtk 
+{
+
+
+
+
+
+  //=========================================================
+  /// Abstract class used by the any class to store values
+  class anyplaceholder
+  {
+  public: // structors
+    
+    virtual ~anyplaceholder() {}
+    
+  public: // queries
+    
+    /// returns the type of the held value
+    virtual const std::type_info & type() const = 0;
+    /// returns the type of the pointed held value
+    virtual const std::type_info & pointed_type() const = 0;
+    
+    /// returns true iff the stored value is a pointer
+    virtual bool is_pointer() const = 0;
+    
+    /// If the held value is a pointer then 
+    /// returns its value
+    virtual void* get_pointer() const = 0;
+    /// 
+    virtual void* get_pointer_to( const std::type_info& ) const = 0;
+   
+    virtual anyplaceholder * clone() const = 0;
+    
+  };
+  //=========================================================
+  
+  //=========================================================
+  /// Concrete template class used by the any class to store values
+  /// which stores a value of type ValueType
+  template<typename ValueType>
+  class anyholder : public anyplaceholder
+  {
+  public: // structors
+    
+    anyholder(const ValueType & value)
+      : held(value)
+    {}
+    
+  public: // queries
+    
+    virtual const std::type_info & type() const { return typeid(ValueType);}
+    virtual bool is_pointer() const { return false; }
+    virtual const std::type_info & pointed_type() const { return typeid(void); }
+    virtual void* get_pointer() const { return 0; }
+    virtual void* get_pointer_to( const std::type_info& ) const { return 0; }
+    virtual anyplaceholder * clone() const { return new anyholder(held); }
+    
+    public: // representation
+    
+    ValueType held;
+    
+  };
+  //=========================================================
+  
+  //=========================================================
+  /// specialization of anyholder for pointer types
+  template<typename ValueType>
+  class anyholder<ValueType*> : public anyplaceholder
+  {
+  public: // structors
+    
+    anyholder(ValueType* const & value)
+      : held(value)
+    { }
+    
+  public: // queries
+    
+    virtual const std::type_info & type() const
+    {
+      return typeid(ValueType*);
+    }
+    
+    virtual bool is_pointer() const { return true; }
+    virtual const std::type_info & pointed_type() const { return typeid(ValueType); }
+    virtual void* get_pointer() const { 
+      return (void*)held; 
+    }
+    virtual void* get_pointer_to( const std::type_info& t) const 
+    { 
+      return run_time_up_or_down_cast(t,typeid(ValueType),held);
+    }
+
+    virtual anyplaceholder * clone() const { return new anyholder(held); }
+    
+  public: // representation
+    
+    ValueType* held;
+    
+  };
+  //=========================================================
+
+
+  /** A magic class which can store any type of data which 
+   * is allowed by the template template parameter TypeTrait.
+   *
+   * The only requirement on TypeTrait<T> is to have the member :
+   *    static const bool value;
+   * which is true iff the type T is an allowed type 
+   * 
+   * TypeTraits compliant objects are usually template structs 
+   * for which the initialisation of value is set to false by default 
+   * and set to true for the allowed types (template specialisation)
+   * Example :
+   *   template <typename T> struct mytypes { static const bool value; };
+   *   template <typename T> const bool mytypes<T>::value = false;
+   *   template <> const bool mytypes<int>::value = true;
+   *   template <> const bool mytypes<float>::value = true; 
+   * etc.
+   * You can use any boost type_trait, like is_pointer, is_floating_point, etc.
+   *
+   * The class any is a generalisation of the boost::any class 
+   * (see http://www.boost.org/doc/html/any.html).
+   * The boost::any class itself is reproduced by any<thing>,
+   * where thing is a TypeTrait whose value is true for all types.
+   **/
+  template <template <class> class TypeTraits >
+  class any
+  {
+  public:
+    typedef any< TypeTraits > self;
+    // structors
+  
+    /// Default constructor
+    any()
+      : content(0)
+    {
+    }
+  
+    /// Constructor with a value of template type
+    template<typename ValueType>
+    any(const ValueType & value)
+      : content(0)
+    {
+      bbtkDebugMessage("Data",1,
+                      bbtk::HumanTypeName<self>()<<" construction with <"
+                      <<bbtk::HumanTypeName<ValueType>()<<">"<<std::endl);
+      //      ValueType v = value;
+      //      int** i = (int**)(&v);
+      //      std::cout << "v="<<*i<<std::endl;
+      
+      if (accepts<ValueType>()) 
+       { 
+         content = new anyholder<ValueType>(value);
+       }
+      else 
+       {
+         bbtkError(bbtk::HumanTypeName<self>()
+                   <<" constructor : data of type <"
+                   <<bbtk::HumanTypeName<ValueType>()
+                   <<"> are not accepted by traits <"
+                   <<bbtk::HumanTypeName<TypeTraits<void> >()<<"> ");
+       }
+    }
+  
+    /// Copy constructor
+    any(const any & other)
+      : content(other.content ? other.content->clone() : 0)
+    {
+      bbtkDebugMessage("Data",1,
+                      HumanTypeName<self>()
+                      <<" copy construction with new content : "
+                      <<HumanTypeName(type())
+                      <<std::endl);
+    }
+  
+    /// Destructor
+    ~any()
+    {
+      delete content;
+    }
+  
+
+    /// Swaps the content of this with another any
+    any & swap(any & rhs)
+    {
+      std::swap(content, rhs.content);
+      return *this;
+    }
+
+    /// Affectation of a value of template type
+    template<typename ValueType>
+    any & operator=(const ValueType & rhs)
+    {
+      bbtkDebugMessage("Data",1,
+                      HumanTypeName<self>()
+                      <<" operator= with data of type <"
+                      <<HumanTypeName<ValueType>()
+                      <<">"<<std::endl);
+      if (accepts<ValueType>()) 
+       {
+         any(rhs).swap(*this);
+         return *this;
+       }
+      else 
+       {
+         bbtkError(HumanTypeName<self>()
+                   <<" operator= : data of type <"
+                   <<HumanTypeName<ValueType>()
+                   <<"> are not accepted by traits <"
+                   <<HumanTypeName<TypeTraits<void> >()<<"> ");
+       }
+    
+    }
+  
+    /// Affectation of another any
+    any & operator=(const any & rhs)
+    {
+       bbtkDebugMessage("Data",1,
+                        HumanTypeName<self >()
+                        <<" operator=(const any&) with content : "
+                        <<HumanTypeName(rhs.type())<<std::endl);
+
+      any(rhs).swap(*this);
+      return *this;
+    }
+  
+
+    /// Is it empty (no value held) ?
+    bool empty() const
+    {
+      return !content;
+    }
+  
+    /// Returns the type_info of the held value
+    const std::type_info & type() const
+    {
+      return content ? content->type() : typeid(void);
+    }
+
+    /// Returns the type_info of the pointed held value
+    const std::type_info & pointed_type() const
+    {
+      return content ? content->pointed_type() : typeid(void);
+    }
+
+
+    /// Returns true iff the contained type is Type
+    template<typename Type>
+    inline bool contains()
+    {
+      return ( type() == typeid(Type) );
+    }
+
+    /// Returns true iff the contained type is a pointer
+    inline bool contains_pointer()
+    {
+      return content->is_pointer() ;
+    }
+
+    /// Returns true iff the contained type is t
+    inline bool contains(TypeInfo t)
+    {
+      return ( type() == t );
+     }
+
+    /// Returns true iff any of type ValueType can be held 
+    template<typename Type>
+    inline bool accepts()
+    {
+      return TypeTraits<Type>::value; //is_valid();
+    }
+
+    /// Returns a const reference on the held value iff its type matches 
+    /// the template parameter  
+    template<typename ValueType>
+    inline const ValueType& get() const
+    {
+       bbtkDebugMessage("Data",1,
+                        HumanTypeName<self >()
+                        <<" get<"<<HumanTypeName<ValueType>()
+                        <<"> with content : "
+                        <<HumanTypeName(type())<<std::endl);
+
+      if ( type() == typeid(ValueType) )
+       return static_cast< anyholder<ValueType> *>(content)->held;
+
+      bbtkError(HumanTypeName<self >()
+               <<" get with type <"
+               <<bbtk::HumanTypeName<ValueType>()
+               <<"> does not match content type <"
+               <<bbtk::HumanTypeName<>(type())<<">");
+    }
+
+    template<typename ValueType>
+    inline const ValueType* getP() const
+    {
+      if ( type() == typeid(ValueType) )
+       return &static_cast< anyholder<ValueType> *>(content)->held;
+      bbtkError(HumanTypeName<self >()
+               <<" getP with type <"
+               <<bbtk::HumanTypeName<ValueType>()
+               <<"> does not match content type <"
+               <<bbtk::HumanTypeName<>(type())<<">");
+    }
+
+    /// Returns a const reference on the held value 
+    /// ** EVEN IF ITS TYPE DOES NOT MATCH THE TEMPLATE PARAMETER **
+    /// Hence must be used when one knows that the type is good
+    /// Otherwise can lead to unpredictible results 
+    template<typename ValueType>
+    inline const ValueType& unsafe_get() const
+    {
+       bbtkDebugMessage("Data",1,
+                        HumanTypeName<self>()
+                        <<"::unsafe_get<"
+                        <<HumanTypeName<ValueType>()<<"> with content : "
+                        <<HumanTypeName(this->type())
+                        <<std::endl);
+
+       //      PrintValueIfIsPointer<ValueType>(static_cast< anyholder<ValueType> * >(content)->held);
+       //      int** i = (int**)(&static_cast< anyholder<ValueType> * >(content)->held);
+       //      std::cout << "v="<<*i<<std::endl;
+
+       if (content) 
+         return static_cast< anyholder<ValueType> * >(content)->held;
+       
+       bbtkError(HumanTypeName<self >()
+                 <<"::usafe_get<"
+                 <<bbtk::HumanTypeName<ValueType>()
+                 <<"> : void content");
+    }
+
+
+    inline void* get_pointer() const 
+    {
+      void* p = content->get_pointer();
+      bbtkDebugMessage("Data",1,
+                      HumanTypeName<self>()
+                      <<"::get_pointer() with content <"
+                      <<HumanTypeName(this->type())
+                      <<"> : result = "
+                      << p
+                      <<std::endl);
+      return p;
+    }
+    
+    inline void* get_pointer_to(const std::type_info& t) const 
+    {
+      void* p = content->get_pointer_to(t);
+      bbtkDebugMessage("Data",1,
+                      HumanTypeName<self>()
+                      <<"::get_pointer_to("<<HumanTypeName(t)
+                      <<") with content <"
+                      <<HumanTypeName(this->type())
+                      <<"> : result = "
+                      << p
+                      <<std::endl);
+      return p;
+    }
+    
+  private: 
+    /// content
+    anyplaceholder * content;
+    
+  };
+
+  
+
+  /// The TypeTraits which validates any type 
+  template <typename T> struct thing { static const bool value = true; };
+
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(bbtk::any<bbtk::thing>,"anything");
+
+
+  /// The TypeTraits which validates all integer types
+  template <typename T> struct integer { static const bool value; };
+  template <class T> const bool integer<T>::value = false;
+
+  /// The TypeTraits which validates all floating point number types
+  template <typename T> struct floating_point { static const bool value; };
+  template <class T> const bool floating_point<T>::value = false;
+
+
+  /// The TypeTraits which validates all numerical types
+  template <typename T> struct number { static const bool value; };
+  template <class T> const bool number<T>::value = 
+            integer<T>::value || floating_point<T>::value ;
+  
+  
+  /// Macro to begin the enumeration of types included into a 
+  /// any_type_collection previously declared with 
+  /// DECLARE_any_type_collection. 
+  /// Must be placed in the implementation part of the code.
+#define BBTK_DECLARE_TYPE_TRAITS(NAME)                                 \
+  template <typename T> struct NAME { static const bool value; };      \
+    template <class T> const bool NAME<T>::value = false;
+  
+#define BBTK_ADD_TO_TYPE_TRAITS(NAME,TYPE)     \
+  template <> bool NAME<TYPE>::value = true;
+
+
+}
+
+
+
+
+
+/*
+
+// TRY TO INCLUDE BOOST DIRECTLY : OK WORKS !
+#include <algorithm>
+#include <typeinfo>
+
+#include "boost/config.hpp"
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/static_assert.hpp>
+
+
+namespace bbtk
+{
+
+
+  class bad_any_cast : public std::bad_cast
+  {
+  public:
+    virtual const char * what() const throw()
+    {
+      return "boost::bad_any_cast: "
+       "failed conversion using boost::any_cast";
+    }
+  };
+  
+  typedef any<thing> anything;
+
+  template<typename ValueType>
+  ValueType * any_cast(anything * operand)
+  {
+    return operand && operand->type() == typeid(ValueType)
+      ? &static_cast<anything::holder<ValueType> *>(operand->content)->held
+      : 0;
+  }
+  
+    template<typename ValueType>
+    const ValueType * any_cast(const anything * operand)
+    {
+        return any_cast<ValueType>(const_cast<anything *>(operand));
+    }
+
+    template<typename ValueType>
+    ValueType any_cast(const anything & operand)
+    {
+      typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<ValueType>::type nonref;
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+        // If 'nonref' is still reference type, it means the user has not
+        // specialized 'remove_reference'.
+
+        // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
+        // to generate specialization of remove_reference for your class
+        // See type traits library documentation for details
+      BOOST_STATIC_ASSERT(!boost::is_reference<nonref>::value);
+#endif
+
+        const nonref * result = any_cast<nonref>(&operand);
+        if(!result)
+            boost::throw_exception(bad_any_cast());
+        return *result;
+    }
+
+    template<typename ValueType>
+    ValueType any_cast(anything & operand)
+    {
+      typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<ValueType>::type nonref;
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+        // The comment in the above version of 'any_cast' explains when this
+        // assert is fired and what to do.
+        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
+#endif
+
+        nonref * result = any_cast<nonref>(&operand);
+        if(!result)
+            boost::throw_exception(bad_any_cast());
+        return *result;
+    }
+
+    // Note: The "unsafe" versions of any_cast are not part of the
+    // public interface and may be removed at any time. They are
+    // required where we know what type is stored in the any and can't
+    // use typeid() comparison, e.g., when our types may travel across
+    // different shared libraries.
+    template<typename ValueType>
+    inline ValueType * unsafe_any_cast(anything * operand)
+    {
+        return &static_cast<anything::holder<ValueType> *>(operand->content)->held;
+    }
+
+    template<typename ValueType>
+    inline const ValueType * unsafe_any_cast(const anything * operand)
+    {
+        return unsafe_any_cast<ValueType>(const_cast<anything *>(operand));
+    }
+}
+*/ // EO TRY TO INCLUDE BOOST
+
+#endif
+
diff --git a/kernel/src/bbtkBlackBox.cxx b/kernel/src/bbtkBlackBox.cxx
new file mode 100644 (file)
index 0000000..3aa696a
--- /dev/null
@@ -0,0 +1,1028 @@
+/*=========================================================================
+                                                                                
+Program:   bbtk
+Module:    $RCSfile: bbtkBlackBox.cxx,v $
+Language:  C++
+Date:      $Date: 2008/01/22 15:02:00 $
+Version:   $Revision: 1.1 $
+                                                                                
+Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+l'Image). All rights reserved. See doc/license.txt or
+http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBox : abstract black-box interface. 
+ */
+#include "bbtkBlackBox.h"
+#include "bbtkPackage.h"
+#include "bbtkMessageManager.h"
+#include "bbtkFactory.h"
+
+#include "bbtkConfigurationFile.h"
+#include "bbtkWxBlackBox.h"
+
+#include <fstream>
+//#include <vector>
+
+
+namespace bbtk
+{
+  //=========================================================================
+  BlackBox::BlackBox(const std::string &name) 
+    : bbmName(name), bbmStatus(MODIFIED), 
+      bbmBoxProcessMode("Pipeline"),bbmParent(NULL)
+  {
+    bbtkDebugMessage("Core",7,"BlackBox::BlackBox(\""
+                    <<name<<"\")"<<std::endl);
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  BlackBox::BlackBox(BlackBox& from, const std::string &name) 
+    : bbmName(name), 
+      bbmStatus(from.bbmStatus), 
+      bbmBoxProcessMode(from.bbmBoxProcessMode),bbmParent(NULL)
+  {
+    bbtkDebugMessage("Core",7,"BlackBox::BlackBox("
+                    <<from.bbGetFullName()<<",\""
+                    <<name<<"\")"<<std::endl);
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  BlackBox::~BlackBox()
+  {
+    //    std::cout << "EED BlackBox::~BlackBox 01 [" << bbGetName()<<"]\n";
+    bbtkDebugMessageInc("Core",7,"BlackBox::~BlackBox()"<<std::endl);
+    this->bbDesallocateConnectors();
+    //printf("EED BlackBox::~BlackBox 02 \n");
+    bbtkDebugDecTab("Core",7);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  /// Destruction method of a black box
+  void BlackBox::bbDelete()
+  {
+    bbtkDebugMessage("Core",5,"BlackBox::bbDelete() ["
+                    <<bbGetFullName()<<"]"<<std::endl);    
+    this->bbUserDelete();
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Main processing method of the box.
+  void BlackBox::bbExecute(bool force)
+  {
+    bbtkDebugMessageInc("Process",1,
+                       "=> BlackBox::bbExecute() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+    wx::BeginBusyCursor();
+
+    // If execution frozen : return
+    if (bbGlobalGetFreezeExecution()) 
+      {
+       bbtkDebugMessage("Process",1,
+                        " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
+      }
+
+    // If force is true then update is triggered even if the box is UPTODATE
+    if (force) bbSetModifiedStatus();
+
+    // Calls the main recursive update method 
+    bbBackwardUpdate(0);
+
+    wx::EndBusyCursor();
+
+    bbtkDebugMessageDec("Process",1,
+                       "<= BlackBox::bbExecute() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  std::string BlackBox::bbGetFullName() const
+  { 
+    return bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
+  }
+  //=========================================================================
+     
+
+
+  //=========================================================================
+  /// Returns the name with the name of the parent prepended if any
+  std::string BlackBox::bbGetNameWithParent() const
+  {
+    if (bbmParent) 
+      {
+       return bbmParent->bbGetNameWithParent() + ":" + bbmName;
+      }
+    else 
+      {
+       return bbmName;
+      }
+  } 
+  //=========================================================================
+
+  //=========================================================================
+  /// Prints the Help on the BlackBox type 
+  void BlackBox::bbGetHelp(bool full) const
+  {
+    bbGetDescriptor()->GetHelp(full); 
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Returns true if the UserBlackBox has an input of name name
+  bool BlackBox::bbHasInput(const std::string& name) const
+  {
+    bbtkDebugMessageInc("Core",8,
+                       "BlackBox::bbHasInput(\""
+                       <<name<<"\") ["<<bbGetFullName()<<"]"
+                       <<std::endl);
+    bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
+              != bbGetDescriptor()->GetInputDescriptorMap().end());
+    bbtkDebugDecTab("Core",8);
+    return r;
+  }
+  //=========================================================================
+
+
+  //=========================================================================  
+  /// Returns true if the UserBlackBox has an output of name name
+  bool BlackBox::bbHasOutput(const std::string& name) const
+  {
+    bbtkDebugMessageInc("Core",8,"BlackBox::bbHasOutput(\""
+                       <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
+    bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
+              != bbGetDescriptor()->GetOutputDescriptorMap().end());
+    bbtkDebugDecTab("Core",8);
+    return r;
+  }
+  //=========================================================================
+
+
+  //=========================================================================  
+  ///  Gets the output type of a given name
+  TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const 
+  {
+    bbtkDebugMessageInc("Core",8,
+                       "BlackBox::bbGetOutputType(\""
+                       <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
+    TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
+    bbtkDebugDecTab("Core",8); 
+    return r;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  ///  Gets the input type of a given name
+  TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
+  {
+    bbtkDebugMessageInc("Core",8,
+                       "BlackBox::bbGetInputType(\""
+                       <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
+    TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
+    bbtkDebugDecTab("Core",8);
+    return r;
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Allocates the i/o connectors of the black box
+  void BlackBox::bbAllocateConnectors()
+  {  
+    bbtkDebugMessageInc("Core",8,
+                       "BlackBox::bbAllocateConnectors() ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);                                   
+    const BlackBoxDescriptor::InputDescriptorMapType& imap 
+      = bbGetDescriptor()->GetInputDescriptorMap(); 
+    BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;      
+    for ( i = imap.begin(); i != imap.end(); ++i )                     
+      {                                                                        
+       bbtkDebugMessage("Core",8,"* Allocate \""<<i->first<<"\""<<std::endl);
+       bbGetInputConnectorMap()[i->second->GetName()] 
+         = new BlackBoxInputConnector(this);
+      }                                                                        
+    const BlackBoxDescriptor::OutputDescriptorMapType& omap 
+      = bbGetDescriptor()->GetOutputDescriptorMap();                  
+    BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
+    for ( o = omap.begin(); o != omap.end(); ++o )
+      {                                                        
+       bbtkDebugMessage("Core",8,"* Allocate \""<<o->first<<"\""<<std::endl);
+       bbGetOutputConnectorMap()[o->second->GetName()] 
+         = new BlackBoxOutputConnector();
+      }
+    bbtkDebugDecTab("Core",8);  
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Desallocates the i/o connectors of the black box
+  void BlackBox::bbDesallocateConnectors()
+  {
+    bbtkDebugMessageInc("Core",8,
+                       "BlackBox::bbDesallocateConnectors()"
+                       <<std::endl);                                   
+
+    InputConnectorMapType::const_iterator i;
+    for ( i = bbGetInputConnectorMap().begin();
+         i != bbGetInputConnectorMap().end(); ++i )                   
+      {                                                                        
+       bbtkDebugMessage("Core",8,"* Delete \""<<i->first<<"\""<<std::endl);
+       delete (i->second);
+      }                                                                        
+    OutputConnectorMapType::const_iterator o;  
+    for ( o = bbGetOutputConnectorMap().begin(); 
+         o != bbGetOutputConnectorMap().end(); ++o )                   
+      {                                                                        
+       bbtkDebugMessage("Core",8,"* Delete \""<<o->first<<"\""<<std::endl);           
+       delete (o->second);
+      }                                                                        
+   
+    bbtkDebugDecTab("Core",8);  
+
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Copies the input / output values from another box
+  void BlackBox::bbCopyIOValues(BlackBox& from)
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "BlackBox::bbCopyIOValues("
+                       <<from.bbGetFullName()<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    // copies the input values
+    const BlackBoxDescriptor::InputDescriptorMapType& imap 
+      = bbGetDescriptor()->GetInputDescriptorMap(); 
+    BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;      
+    for ( i = imap.begin(); i != imap.end(); ++i )                     
+      {                
+       if (! i->second->GetCopyConstruct() ) continue;
+       std::string input = i->second->GetName();
+       this->bbSetInput(input, from.bbGetInput(input) );
+      }                                                                        
+    // copies the output values
+    const BlackBoxDescriptor::OutputDescriptorMapType& omap 
+      = bbGetDescriptor()->GetOutputDescriptorMap();                  
+    BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
+    for ( o = omap.begin(); o != omap.end(); ++o )
+      {                                                        
+       if (! o->second->GetCopyConstruct() ) continue;
+       std::string output = o->second->GetName();
+       this->bbSetOutput(output, from.bbGetOutput(output) );
+      }
+
+    bbtkDebugDecTab("Core",9);
+
+  }
+  //=========================================================================
+
+
+
+  //=========================================================================
+  bool BlackBox::bbCanReact() const 
+  { 
+    return ( bbGlobalGetSomeBoxExecuting() 
+#ifdef _USE_WXWIDGETS_
+            || WxBlackBox::bbGlobalIsSomeWindowAlive() 
+#endif
+            ); 
+  }
+  //=========================================================================
+
+
+
+  //=========================================================================
+  /// User overloadable destruction method of a black box
+  void BlackBox::bbUserDelete() 
+  {   
+    bbtkDebugMessage("Process",5,
+                    "=> BlackBox::bbUserDelete() ["
+                    <<bbGetFullName()<<"]"
+                    <<" : not overloaded; using standard deletion"
+                    <<std::endl);
+    delete this;
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
+  {
+    const std::string& p = bbmBoxProcessMode;
+    if ( (p == "0") ||
+        (p == "P") || (p == "p") ||
+        (p == "Pipeline") || (p == "pipeline") ) return Pipeline;
+    if ( (p == "1") ||
+        (p == "A") || (p == "a") ||
+        (p == "Always") || (p == "always") ) return Always;
+    if ( (p == "2") ||
+        (p == "R") || (p == "r") ||
+        (p == "Reactive") || (p == "reactive") ) return Reactive;
+    bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
+             <<"' unknown. Possible values : "
+             <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
+             <<"'1'/'A'/'a'/'Always'/'always' | "
+             <<"'2'/'R'/'r'/'Reactive'/'reactive'"<<std::endl);
+  }
+  //=========================================================================
+  
+  //=========================================================================
+  bool  BlackBox::bbBoxProcessModeIsReactive() const
+  {
+    return (bbGetBoxProcessModeValue() == Reactive);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  bool  BlackBox::bbBoxProcessModeIsAlways() const
+  {
+    return (bbGetBoxProcessModeValue() == Always);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  ///  Signals that the BlackBox has been modified
+  void BlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
+  {
+    bbtkDebugMessageInc("Process",5,
+                       "=> BlackBox::bbSetModifiedStatus("<<c<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+   
+    if ( (c==bbGetInputConnectorMap().find("WinHide")->second) )
+        //      && (bbCanReact()))
+      {
+       bbtkDebugMessage("Process",9,
+                        "-> Hide triggered by WinHide input change"
+                        <<std::endl);
+       this->bbHideWindow();
+       this->bbSetStatus(MODIFIED); 
+       return;
+      }
+    if ( ( bbBoxProcessModeIsReactive()  ||
+          (c==bbGetInputConnectorMap().find("BoxExecute")->second))
+        && (bbCanReact() ) )
+      {
+       bbtkDebugMessage("Process",9,
+                        "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
+       this->bbSetStatus(MODIFIED); 
+        bbGlobalAddToExecutionList( this );
+      }
+    else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
+      { 
+       bbtkDebugMessage("Process",5,"-> Already modified"<<std::endl);
+       bbtkDebugDecTab("Process",5);
+       return;
+      }
+    else 
+      {
+       bbtkDebugMessage("Process",5,"-> Status set to modified"<<std::endl);
+       bbtkDebugDecTab("Process",5);
+       this->bbSetStatus(MODIFIED); 
+      }
+    this->bbSignalOutputModification(false);
+
+   bbtkDebugMessageDec("Process",5,
+                       "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+  }  
+  //=========================================================================
+
+  //=========================================================================  
+  void BlackBox::bbSignalOutputModification(bool reaction)
+  {
+    bbtkDebugMessageInc("Process",5,
+                       "=> BlackBox::bbSignalOutputModification() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
+    OutputConnectorMapType::iterator change = bbGetOutputConnectorMap().end();
+    OutputConnectorMapType::iterator i;
+    for ( i  = bbGetOutputConnectorMap().begin(); 
+         i != bbGetOutputConnectorMap().end(); ++i) {
+      /*     if ( i->first == "BoxChange" ) 
+       {
+         change = i;
+         continue;
+       }
+      */
+      i->second->SetModifiedStatus();
+    } 
+    //    if (change != bbGetOutputConnectorMap().end()) 
+    // change->second->SetModifiedStatus();
+
+    if (reaction) bbGlobalProcessExecutionList();
+
+    bbtkDebugMessageDec("Process",5,
+                       "<= BlackBox::bbSignalOutputModification() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
+  }  
+  //=========================================================================   
+  //=========================================================================  
+  void BlackBox::bbSignalOutputModification(const std::string& output,
+       bool reaction)
+  {
+    bbtkDebugMessageInc("Process",5,
+                       "=> BlackBox::bbSignalOutputModification("
+                       <<output<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
+    OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(output);
+    if ( i == bbGetOutputConnectorMap().end() ) 
+       {
+         bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
+       }
+    i->second->SetModifiedStatus();
+    // Has to notify the output "BoxChange" also
+    if (output != "BoxChange") 
+      {
+       i = bbGetOutputConnectorMap().find("BoxChange");
+       if ( i != bbGetOutputConnectorMap().end() ) 
+         {
+           i->second->SetModifiedStatus();
+         }
+      }
+  if (reaction) bbGlobalProcessExecutionList();
+
+    bbtkDebugMessageDec("Process",5,
+                       "<= BlackBox::bbSignalOutputModification("
+                       <<output<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+  }  
+  //=========================================================================   
+  //=========================================================================  
+  void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
+       bool reaction)
+  {
+    bbtkDebugMessageInc("Process",5,
+                       "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    OutputConnectorMapType::iterator i;
+    std::vector<std::string>::const_iterator o;
+    for (o=output.begin();o!=output.end();++o) 
+      {
+       // the output "BoxChange" must be signaled **AFTER** all others
+       if (*o == "BoxChange") continue;
+       // Look for the connector
+       i = bbGetOutputConnectorMap().find(*o);
+       if ( i == bbGetOutputConnectorMap().end() ) 
+         {
+           bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
+         }
+       i->second->SetModifiedStatus();
+      }
+    // Has to notify the output "BoxChange" also
+    i = bbGetOutputConnectorMap().find("BoxChange");
+    if ( i != bbGetOutputConnectorMap().end() ) 
+      {
+       i->second->SetModifiedStatus();
+      }
+  if (reaction) bbGlobalProcessExecutionList();
+
+   bbtkDebugMessageDec("Process",5,
+                      "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+  }  
+  //=========================================================================   
+
+  //=========================================================================
+  /// Updates the BlackBox inputs
+  /// \returns UPTODATE if all inputs are in UPTODATE status after update
+  ///          else MODIFIED 
+  IOStatus BlackBox::bbUpdateInputs(bool excludeParent)
+  {
+    bbtkDebugMessageInc("Process",4,
+                       "=> BlackBox::bbUpdateInputs() ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);   
+
+    IOStatus s = UPTODATE;
+    
+    InputConnectorMapType::iterator i;
+    for ( i = bbGetInputConnectorMap().begin(); 
+         i!= bbGetInputConnectorMap().end(); ++i) 
+      {
+       if (excludeParent && (i->first=="WinParent")) continue;
+       if (i->first=="WinHide") continue;
+       // If input type is Void : no recurse
+       //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
+       //      == typeid(Void) ) 
+       //  continue;
+
+       IOStatus t = i->second->BackwardUpdate();
+       if (t==MODIFIED) s = MODIFIED;
+      }
+    
+   bbtkDebugMessageDec("Process",4,
+                       "<= BlackBox::bbUpdateInputs() ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);   
+
+
+    return s;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  /// Connects the input <name> to the connection c
+  void BlackBox::bbConnectInput( const std::string& name, Connection* c)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "BlackBox::bbConnectInput(\""<<name<<"\","<<c<<") ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);       
+    InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
+    if (i==bbGetInputConnectorMap().end())
+      {
+       bbtkError("no input called '"<<name<<"'");
+      }
+    i->second->SetConnection(c);
+    
+    //  bbSetModifiedStatus();
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //=========================================================================
+
+
+  //=========================================================================  
+  /// Connects the output <name> to the connection c
+  void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "BlackBox::bbConnectOutput(\""<<name<<"\","<<c<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);       
+
+    OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
+    if (i==bbGetOutputConnectorMap().end())
+      {
+       bbtkError("no output called '"<<name<<"'");
+      }
+    i->second->SetConnection(c);
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Disconnects the input <name> from the connection c
+  void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "BlackBox::bbDisconnectInput(\""<<name
+                       <<"\","<<c<<") ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);      
+
+    InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
+    if (i==bbGetInputConnectorMap().end())
+      {
+       bbtkError("no input called '"<<name<<"'");
+      }
+    i->second->UnsetConnection(c);
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Disconnects the output <name> from the connection c
+  void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "BlackBox::bbDisconnectOutput(\""<<name
+                       <<"\","<<c<<") ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);       
+
+    OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
+    if (i==bbGetOutputConnectorMap().end())
+      {
+       bbtkError("no output called '"<<name<<"'");
+      }
+    i->second->UnsetConnection(c);
+
+    bbtkDebugDecTab("Core",7);
+  } 
+  //=========================================================================
+
+  //=========================================================================
+  /// Virtual
+  void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
+  {
+    fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  std::string BlackBox::bbGetOutputAsString( const std::string &output ) 
+  {
+    std::string v;
+    // Looks for the adaptor
+    if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
+      {
+       BlackBox* a = 0;
+       try
+         {
+           a = NewAdaptor(  
+                          bbGetOutputType(output),
+                          typeid(std::string),
+                          "");
+         } catch (bbtk::Exception e) 
+         {
+         }
+       if (a!=NULL){
+         //                    bbUpdate();
+         a->bbSetInput("In",bbGetOutput(output));
+         a->bbExecute();
+         v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
+       } else {
+         v="? (no adaptor found)";
+       }
+      } else {
+      //         bbUpdate();
+      v = bbGetOutput(output).unsafe_get<std::string>() ;
+    }
+    return v;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  std::string BlackBox::bbGetInputAsString( const std::string &input ) 
+  {
+    std::string v;
+    // Looks for the adaptor
+    if (bbGetInputType(input) != typeid(std::string)) 
+      {
+       BlackBox* a = 0;
+       try
+         {
+           a = NewAdaptor(  
+                          bbGetInputType(input),
+                          typeid(std::string),
+                          "");
+         }catch (bbtk::Exception e) 
+         {
+         }
+       if (a!=NULL)
+         {
+           //                  bbUpdate();
+           a->bbSetInput("In",bbGetInput(input));
+           a->bbExecute();
+           v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
+         } 
+       else 
+         {
+           v="? (no adaptor found)";
+         }
+      } 
+    else 
+      {
+       v = bbGetInput(input).unsafe_get<std::string>() ;
+      }
+    return v;
+  }
+  //=======================================================================
+
+  //=======================================================================
+  // Replaces substrings "<" by "["
+  void SubsBrackets ( std::string& s )
+  {
+    //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
+    std::string ss("<");
+    std::string::size_type pos = 0;
+    pos = s.find(ss,0);
+    char* cr = "[";
+    while ( pos != std::string::npos )
+      {
+       //      std::cout << "*** find one "<<std::endl;
+       s.replace(pos,1,cr,1);
+       pos = s.find(ss, pos);
+      } 
+    ss = ">";
+    pos = 0;
+    pos = s.find(ss,0);
+    cr = "]";
+    while ( pos != std::string::npos )
+      {
+       //      std::cout << "*** find one "<<std::endl;
+       s.replace(pos,1,cr,1);
+       pos = s.find(ss, pos);
+      } 
+    ss = ",";
+    pos = 0;
+    pos = s.find(ss,0);
+    cr = "-";
+    while ( pos != std::string::npos )
+      {
+       //      std::cout << "*** find one "<<std::endl;
+       s.replace(pos,1,cr,1);
+       pos = s.find(ss, pos);
+      }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
+  }
+  //=======================================================================
+
+  //=========================================================================
+  /// Write Graphviz-dot description in file
+  void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
+                                       BlackBox *parentblackbox, 
+                                       int detail, int level,
+                                       bool instanceOrtype,
+                                       bool relative_link )
+
+  {
+    InputConnectorMapType::iterator i;
+    // label
+    std::string labelStr;
+    std::string valueStr("");
+    if (detail==0)
+      {
+       labelStr = bbGetName() ; 
+      } else {
+      labelStr = bbGetName();
+      labelStr = labelStr + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]  ";
+    }
+
+    SubsBrackets(labelStr);
+    if (detail==1)
+      {
+       labelStr = labelStr + " | {{ "; 
+       std::string tempStrTypeName;
+       bool tmp; 
+       tmp=false;
+       for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
+         {
+           if (tmp==true)
+             {
+               labelStr=labelStr+" | ";
+             }
+           tmp=true;
+           if (instanceOrtype==true)
+             {
+               valueStr = this->bbGetInputAsString(i->first) + " = ";
+             } 
+           const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
+           tempStrTypeName=id->GetTypeName();
+           SubsBrackets(tempStrTypeName);
+           std::string Name(i->first);
+           SubsBrackets(Name);
+           labelStr=labelStr + "<"+i->first.c_str()+"> "  + valueStr +  Name.c_str() + "  [" + tempStrTypeName.c_str() + "]";
+         }
+       labelStr=labelStr+ " } | {";
+       tmp = false;
+       OutputConnectorMapType::iterator ii;
+       for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) 
+       {
+          if (tmp==true)
+          {
+                  labelStr=labelStr+" | ";
+          }
+          tmp = true;
+          if (instanceOrtype==true)
+          {
+                  valueStr = this->bbGetOutputAsString(ii->first) + " = ";
+          }
+          const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); 
+          tempStrTypeName=id->GetTypeName();
+          SubsBrackets(tempStrTypeName);
+           std::string Name(ii->first);
+           SubsBrackets(Name);
+          labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + "  ["+tempStrTypeName+"]";
+       }
+       labelStr = labelStr+ "      } }" ;
+} // detail
+
+    fprintf(ff,"  " );
+    bbWriteDotInputOutputName(ff,true,detail,level);
+    std::string tmp ( bbGetTypeName() );
+    SubsBrackets(tmp);
+    std::string url;
+    if (relative_link) 
+      url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
+    else 
+      url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
+  
+    fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
+    //    std::cout  << labelStr << std::endl;
+
+    // Relation Input
+    if (this!=parentblackbox){
+      for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
+       {
+         if (i->second)
+           {
+             Connection* con = i->second->GetConnection();
+             if (con!=NULL){
+               BlackBox *a=con->GetBlackBoxFrom();
+               BlackBox *b=con->GetBlackBoxTo();
+               fprintf(ff,"  ");
+               a->bbWriteDotInputOutputName(ff,false,detail,level);
+               if (detail==1)
+                 {
+                   fprintf(ff,":%s",con->GetBlackBoxFromOutput().c_str());
+                 }
+               fprintf(ff,"->");
+               b->bbWriteDotInputOutputName(ff,true,detail,level);
+               if (detail==1)
+                 {
+                   fprintf(ff,":%s",con->GetBlackBoxToInput().c_str());
+                 }
+               fprintf(ff,"%s\n",";");
+             }  // if con
+           } // if second
+       } // for
+    } // if parentblackbox
+  }
+  //=========================================================================
+
+
+
+
+  //=========================================================================
+  void BlackBox::bbShowRelations(BlackBox *parentblackbox, 
+                                int detail, int level
+                                /*,Factory *factory*/ )
+  {
+     
+    if (this->bbGetDescriptor()->GetPackage()) 
+      {
+       bbtkMessage("Help",1,"Black Box '"<<bbGetName()<<"' <"<<
+                   this->bbGetDescriptor()->GetPackage()->GetName()
+                   <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
+      }
+    else 
+      {
+       bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
+      }
+    //    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
+    //    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
+
+    std::vector<std::string> iname;
+    std::vector<std::string> ivalue;
+    std::vector<std::string> iconn;
+
+    InputConnectorMapType::iterator i;
+    unsigned int namelmax = 0;
+    unsigned int valuelmax = 0;
+    unsigned int connlmax = 0;
+    for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
+      {
+       iname.push_back(i->first);
+       if (iname.back().size()>namelmax) namelmax = iname.back().size();
+       ivalue.push_back(bbGetInputAsString(i->first));
+       if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
+       std::string s("");
+       Connection* con = i->second->GetConnection();
+       if (con!=0){
+         s = con->GetBlackBoxFrom()->bbGetName();
+         s += ".";
+         s += con->GetBlackBoxFromOutput();
+       }  // if con
+       iconn.push_back(s);
+      }
+    OutputConnectorMapType::iterator o;
+    std::vector<std::string> oname;
+    std::vector<std::string> ovalue;
+    std::vector<std::vector<std::string> > oconn;
+    for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
+      {
+       oname.push_back(o->first);
+       if (oname.back().size()>namelmax) namelmax = oname.back().size();
+       ovalue.push_back(bbGetOutputAsString(o->first));
+       if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
+       std::vector<std::string> ss;
+       const std::vector<Connection*>& con = o->second->GetConnectionVector();
+       std::vector<Connection*>::const_iterator c;
+       for (c=con.begin();c!=con.end();++c) 
+         {
+           std::string s;
+           s = (*c)->GetBlackBoxTo()->bbGetName();
+           s += ".";
+           s += (*c)->GetBlackBoxToInput();
+           ss.push_back(s);
+       }  // if con
+       oconn.push_back(ss);
+      }
+
+    if (iname.size()) 
+      bbtkMessage("Help",1," * Inputs : "<<std::endl);
+    else 
+      bbtkMessage("Help",1," * No inputs"<<std::endl);
+
+    std::vector<std::string>::iterator i1,i2,i3;
+    for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin();
+        i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end();
+        ++i1,++i2,++i3)
+      {
+       std::string name(*i1);
+       name += "'";
+       name.append(1+namelmax-name.size(),' ');
+       std::string value(*i2);
+       value += "'";
+       value.append(1+valuelmax-value.size(),' ');
+       if (i3->size()) 
+         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"<<*i3<<"'"<<std::endl);
+       else 
+         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
+      }
+
+    if (oname.size()) 
+      bbtkMessage("Help",1," * Outputs : "<<std::endl);
+    else 
+      bbtkMessage("Help",1," * No outputs"<<std::endl);
+
+    std::vector<std::vector<std::string> >::iterator i4;
+
+    for (i1=oname.begin(),i2=ovalue.begin(),i4=oconn.begin();
+        i1!=oname.end(),i2!=ovalue.end(),i4!=oconn.end();
+        ++i1,++i2,++i4)
+      {
+       std::string name(*i1);
+       name += "'";
+       name.append(1+namelmax-name.size(),' ');
+       std::string value(*i2);
+       value += "'";
+       value.append(1+valuelmax-value.size(),' ');
+       if (!(*i4).size())
+         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
+       else 
+         {
+           std::string pref = "    '"+name+" = '"+value;
+           for (i3=i4->begin();i3!=i4->end();++i3)
+             {
+               bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'"<<std::endl);
+               pref.replace(0,pref.size(),pref.size(),' ');
+             }
+         }
+      }
+
+   }
+  //=========================================================================
+
+
+  //=========================================================================
+   void BlackBox::bbGlobalProcessExecutionList()
+   {   
+     bbtkDebugMessageInc("Process",1,
+                        "=> BlackBox::bbGlobalProcessExecutionList()"
+                        <<std::endl);     
+     
+     std::set<BlackBox*>::iterator i;
+     for (i=bbmgExecutionList.begin();
+         i!=bbmgExecutionList.end();
+         ++i)
+       {
+        bbtkDebugMessage("Process",2,
+                         " -> Executing "<<(*i)->bbGetFullName()<<std::endl);
+        (*i)->bbExecute(true);
+       }
+     
+     bbmgExecutionList.clear();
+     bbtkDebugMessageDec("Process",1,
+                        "<= BlackBox::bbGlobalProcessExecutionList()"
+                        <<std::endl);     
+     
+     
+   }
+  //=========================================================================
+
+  //=========================================================================
+  // Static members initialization
+  bool BlackBox::bbmgSomeBoxExecuting = false;
+  bool BlackBox::bbmgFreezeExecution = false;
+  std::set<BlackBox*> BlackBox::bbmgExecutionList;
+   //=========================================================================
+
+
+}  // EO namespace bbtk
+
+// EOF
+
diff --git a/kernel/src/bbtkBlackBox.h b/kernel/src/bbtkBlackBox.h
new file mode 100644 (file)
index 0000000..1c80963
--- /dev/null
@@ -0,0 +1,423 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBox.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBox : abstract black-box interface. 
+ */
+
+/**
+ * \class bbtk::BlackBox
+ * \brief Abstract black-box interface 
+ */
+#ifndef __bbtkBlackBox_h__
+#define __bbtkBlackBox_h__
+
+#include "bbtkBlackBoxDescriptor.h"
+//#include "bbtkConnection.h"
+#include "bbtkBlackBoxInputConnector.h"
+#include "bbtkBlackBoxOutputConnector.h"
+#include <set>
+
+namespace bbtk
+{
+
+  
+  struct Void { Void(int = 0) {} };
+  
+  class Factory;
+
+  class BBTK_EXPORT BlackBox 
+  {
+
+
+  public: 
+    //==================================================================
+    // INTERFACE
+    //==================================================================
+    /// The type of pointer on a BlackBox
+    typedef BlackBox* Pointer;
+
+    /// The type of map of output connector pointers
+    typedef std::map<std::string, BlackBoxOutputConnector*> 
+    OutputConnectorMapType;
+    /// The type of map of input connector pointers
+    typedef std::map<std::string, BlackBoxInputConnector*> 
+    InputConnectorMapType;
+
+    /// Returns the pointer on the descriptor of the box
+    virtual BlackBoxDescriptor* bbGetDescriptor() const = 0;
+
+    /// Returns a pointer on a clone of the box with name <name>
+    virtual BlackBox* bbClone(const std::string& name) = 0;
+
+    /// Destruction method of a black box
+    virtual void bbDelete();
+    /// User overloadable destruction method of a black box
+    virtual void bbUserDelete();
+
+    /// Returns the Name of the Type of the BlackBox
+    const std::string& bbGetTypeName() const 
+      { return bbGetDescriptor()->GetTypeName(); }
+    
+    /// Returns the name of the BlackBox (instance)
+    const std::string& bbGetName() const { return bbmName; }
+
+    /// Returns the full name of the BlackBox (instance+type)
+    virtual std::string bbGetFullName() const;
+
+    /// Returns the name with the name of the parent prepended if any
+    std::string bbGetNameWithParent() const;
+    
+    /// Sets the parent of the BlackBox
+    void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
+    /// Returns the parent of the BlackBox, i.e the BlackBox that contains it (0 if none)
+    BlackBox::Pointer bbGetParent() const { return bbmParent; }
+
+
+    /// Main processing method of the box.
+    virtual void bbExecute(bool force = false);
+
+    ///  Signals that the BlackBox has been modified through the input connector c
+    /// and propagates it downward
+    virtual void bbSetModifiedStatus(BlackBoxInputConnector* c = 0);
+    /// Signals that the BlackBox outputs have been modified 
+    /// without marking the box as MODIFIED because its output state is ok. 
+    /// This method should be used by widgets in response 
+    /// to user interaction when **ALL** outputs have been modified
+    /// (after the outputs has been updated !)
+    virtual void bbSignalOutputModification(bool reaction = true);
+    ///  Signals that the BlackBox output "output_name" have been modified 
+    /// without marking the box as MODIFIED because its output state is ok. 
+    /// This method should be used by widgets in response to user interaction 
+    /// only when **ONE** output has been modified
+    /// (after the output has been updated !)
+    virtual void bbSignalOutputModification( const std::string& output_name,
+bool reaction = true);
+    ///  Signals that the BlackBox vector of outputs "output_name" 
+    ///  have been modified 
+    /// without marking the box as MODIFIED because its output state is ok. 
+    /// This method should be used by widgets in response to user interaction 
+    /// When more than one output has been changed but not all
+    /// (after the outputs have been updated of course!)
+    virtual void bbSignalOutputModification( const std::vector<std::string>& output_name,
+bool reaction = true);
+
+    /// Gets the status of the box
+    virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
+
+
+    /// Returns true iff the BlackBox has an input of name label
+    virtual bool bbHasInput(const std::string& label) const;
+    /// Returns true iff the BlackBox has an output of name label
+    virtual bool bbHasOutput(const std::string& label) const;
+
+    ///  Gets the input type of a given label
+    virtual TypeInfo bbGetInputType( const std::string &label ) const;
+    ///  Gets the output type of a given label
+    virtual TypeInfo bbGetOutputType( const std::string &label ) const;
+
+    ///  Gets the data of the input called <name>
+    virtual Data bbGetInput( const std::string &name )  = 0;
+    ///  Gets the data of the output called <name>
+    virtual Data bbGetOutput( const std::string &name ) = 0;
+
+    /// Sets the data of the input called <name>.
+    /// If setModified is false then does not call bbSetModifiedStatus()
+    virtual void bbSetInput( const std::string &name, Data data,
+                            bool setModified = true ) = 0;
+    virtual void bbBruteForceSetInputPointer( const std::string &name, 
+                                             void* data, 
+                                             bool setModified = true) =0;
+    ///  Sets the data of the output called <name>
+    virtual void bbSetOutput( const std::string &name, Data data) = 0;
+
+    /// Connects the input <name> to the connection c
+    virtual void bbConnectInput( const std::string& name, Connection* c);
+    /// Connects the output <name> to the connection c
+    virtual void bbConnectOutput( const std::string& name, Connection* c);
+
+    /// Disconnects the input <name> from the connection c
+    virtual void bbDisconnectInput( const std::string& name, Connection* c);
+    /// Disconnects the output <name> from the connection c
+    virtual void bbDisconnectOutput( const std::string& name, Connection* c);
+
+    ///  Returns the input connectors map
+    InputConnectorMapType&  bbGetInputConnectorMap() 
+    { return mInputConnectorMap; }
+    ///  Returns the output connectors map
+    OutputConnectorMapType& bbGetOutputConnectorMap() 
+    { return mOutputConnectorMap; }
+    ///  Returns the input connectors map (const)
+    const InputConnectorMapType&  bbGetInputConnectorMap() const 
+    { return mInputConnectorMap; } 
+    ///  Returns the output connectors map (const)
+    const OutputConnectorMapType& bbGetOutputConnectorMap() const 
+    { return mOutputConnectorMap; }      
+
+    /// Prints the Help on the BlackBox type 
+    virtual void bbGetHelp(bool full=true) const;
+
+
+    //==================================================================
+    // Common inputs / outputs to all boxes
+    /// Returns the value of the input "BoxProcessMode"
+    std::string bbGetInputBoxProcessMode() { return bbmBoxProcessMode; }
+    /// Sets the value of the input "BoxProcessMode"
+    void bbSetInputBoxProcessMode(std::string a) { bbmBoxProcessMode = a; }
+    typedef enum
+      {
+       Pipeline,
+       Always,
+       Reactive
+      }
+      BoxProcessModeValue;
+    /// Returns the "decoded" value of the input "BoxProcessMode"
+    BoxProcessModeValue bbGetBoxProcessModeValue() const;
+  
+    virtual bool bbBoxProcessModeIsReactive() const;
+
+    virtual bool bbBoxProcessModeIsAlways() const;
+
+    /// Returns the value of the input "Execute" 
+    Void bbGetInputBoxExecute() { return Void(); }
+    /// Sets the value of the input "Execute"
+    void bbSetInputBoxExecute(Void = 0) {}
+
+    /// Returns the value of the output "Change"
+    Void bbGetOutputBoxChange() { return Void(); }
+    /// Sets the value of the output "Change" : signal a modification
+    void bbSetOutputBoxChange(Void = 0) { bbSetModifiedStatus(); }
+
+    //==================================================================    
+
+
+    //==================================================================    
+
+    /// Does nothing here : overloaded in ComplexBlackBox
+    void bbInsertHTMLGraph(  std::ofstream& s, 
+                            int detail, 
+                            int level,
+                            bool instanceOrtype,
+                            const std::string& output_dir,
+                            bool relative_link ) 
+    {}
+
+    /// Write Graphviz-dot description in file. 
+    /// Here dumps a single box description (i/o) but overloaded 
+    /// in ComplexBlackBox to dump the internal pipeline representation 
+    /// recursing into internal boxes descriptions if level>0.
+    /// detail = 1 : draw inputs and outputs (do not draw otherwise)
+    /// instanceOrtype = true : draw inputs and outputs VALUES 
+    ///  (uses bbGetInputAsString / bbGetOutputAsString which use adaptors)
+    /// If relative_link is true then creates relative hrefs
+    virtual void bbWriteDotFileBlackBox(FILE *ff,
+                                       BlackBox *parentblackbox, 
+                                       int detail, int level, 
+                                       bool instanceOrtype,
+                                       bool relative_link );
+    /// Auxiliary method for bbWriteDotFileBlackBox
+    virtual void bbWriteDotInputOutputName(FILE *ff,
+                                          bool inputoutput, 
+                                          int detail, int level);
+    
+     
+    virtual void bbShowRelations(BlackBox *parentblackbox, 
+                                int detail, int level
+                                );
+    
+    std::string bbGetOutputAsString( const std::string &output ); //,Factory *factory);
+    std::string bbGetInputAsString( const std::string &input); //,Factory *factory);
+    virtual BlackBox *bbFindBlackBox(const std::string &blackboxname) { return NULL;}
+
+  protected:
+    //==================================================================
+    // PROTECTED PART : ACCESSIBLE TO THE BlackBox DEVELOPER 
+    // (IN INHERITED CLASSES)
+    /// Constructor that take the BlackBox's name
+    BlackBox(const std::string &name);
+    /// Constructor from an existing box (copy) with a new name 
+    BlackBox(BlackBox& from, const std::string &name);
+    ///  Destructor
+    virtual ~BlackBox();
+    //==================================================================
+
+
+    //==================================================================
+    ///  Sets the status of the box
+    void bbSetStatus( IOStatus t) { bbmStatus = t; } 
+    //==================================================================
+    
+
+    /// @name Pipeline processing methods
+    ///  Methods which participate to (forward or backward) pipeline processing.
+    ///  Some are pure virtual and prepare particular update mechanism which are implemented by descendents (e.g. ForwardUpdate and UpdateChildren are made for WxContainerBlackBox particular update mechanism which must recurse a piece of the pipeline top-down).
+    /// The main method is bbBackwardUpdate which is called by bbExecute and implemented in UserBlackBox and ComplexBlackBox.
+    /// 
+    //@{
+
+    //==================================================================   
+    /// Recursive pipeline processing in backward direction 
+    /// (recursion is in backward direction however execution always goes forward).
+    /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
+    /// 
+    /// \returns The final status of the box (UPTODATE or MODIFIED)
+    /// \param caller : The connection which invoked the method; null if called by bbExecute
+    ///
+    /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
+    /// then : 
+    /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on amont boxes)
+    /// - calls bbCreateWidget
+    /// - calls bbProcess which is the user callback which does the actual processing
+    /// - calls bbUpdateChildren
+    /// - calls bbShowWidget which shows the widget associated to the box (if any)
+  public:
+    virtual IOStatus bbBackwardUpdate(Connection* caller) = 0;
+    //==================================================================
+
+    //==================================================================
+    /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
+    /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
+    /// 
+    /// \param caller : The connection which invoked the method
+    ///
+    /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
+    /// then : 
+    /// - calls bbCreateWidget
+    /// - calls bbProcess which is the user callback which does the actual processing
+    /// - calls bbUpdateChildren which recursively calls bbForwardUpdate on connections attached the "Child" output
+    // virtual void bbForwardUpdate(Connection* caller) = 0;
+    //==================================================================
+  protected:
+    //==================================================================
+    /// Updates the BlackBox inputs and returns the final status of the inputs 
+    /// (==UPTODATE iff all inputs are UPTODATE)  
+    // If excludeParent == true then excludes the amont box connected to input 'Parent' from recursive update
+    IOStatus bbUpdateInputs(bool excludeParent=false);
+    //==================================================================
+
+    //==================================================================
+    /// Updates the pipeline in amont-aval direction along the "Child"-"Parent" connections only.
+    /// Does nothing here. Overloaded in WxContainerBlackbox
+    //virtual void bbUpdateChildren( Connection* caller ) { }
+    //==================================================================
+
+    //==================================================================
+    /// Specific methods for window creation during pipeline execution
+    /// Creates the window associated to the box (called after bbUpdateInputs)
+    /// Does nothing here. Overloaded in WxBlackBox.
+    // virtual void bbCreateWindow() { }
+    /// Shows the window associated to the box 
+    /// (called after bbProcess during bbExecute)
+    /// Does nothing here but overloaded in WxBlackBox and WxContainerBlackBox
+    virtual void bbShowWindow(Connection* caller) { }
+    virtual void bbHideWindow() {}
+   //==================================================================
+
+    //@}
+  public: 
+
+    static bool bbGlobalGetSomeBoxExecuting() 
+    { return bbmgSomeBoxExecuting; }
+    static void bbGlobalSetSomeBoxExecuting(bool b) 
+    { bbmgSomeBoxExecuting = b; }
+
+
+    static void bbGlobalSetFreezeExecution(bool b) { bbmgFreezeExecution = b;}
+    static bool bbGlobalGetFreezeExecution() { return bbmgFreezeExecution; }
+
+    /// Returns true if the box can "react",
+    /// which means execute in response to an input change 
+    virtual bool bbCanReact() const;
+    
+    
+    static void bbGlobalAddToExecutionList( BlackBox* b ) 
+   { 
+     bbmgExecutionList.insert(b);   
+} 
+
+    static void bbGlobalProcessExecutionList();
+
+    //==================================================================
+  protected:
+    //==================================================================
+    /// Allocates the i/o connectors of the black box
+    virtual void bbAllocateConnectors();
+    /// Desallocates the i/o connectors of the black box
+    virtual void bbDesallocateConnectors();
+    /// Copies the values of the inputs/output from the BlackBox from
+    virtual void bbCopyIOValues(BlackBox& from);
+    //==================================================================
+
+  private:
+    
+    //==================================================================
+    // PRIVATE PART 
+    /// Default constructor is private : derived classes must use the constructor with the BlackBox's name
+    BlackBox() {}
+    /// The status of the box
+    IOStatus bbmStatus;
+    /// The name of the black-box
+    std::string bbmName;
+    /// The name of the package to which it belongs
+    std::string bbmPackageName;
+       
+    /// 0 : "Pipeline" mode : bbUpdate() only calls Process if Status == MODIFIED (normal pipeline processing)
+    /// 1 : "Always" mode : bbUpdate() always calls Process  
+    /// 2 : "Reactive" mode : bbSetModifiedStatus() calls bbUpdate()
+    std::string bbmBoxProcessMode;
+
+    /// The parent of the black box in the ComplexBlackBox hierarchy
+    BlackBox::Pointer bbmParent;
+    //==================================================================
+
+   //==================================================================
+    // ATTRIBUTES
+    ///  Map that contains the output connectors of the black box
+    OutputConnectorMapType mOutputConnectorMap; 
+    ///  Map that contains the input connectors of the black box
+    InputConnectorMapType mInputConnectorMap;
+    //==================================================================
+
+    
+    static bool bbmgSomeBoxExecuting;
+    static bool bbmgFreezeExecution;
+
+
+   static std::set<BlackBox*> bbmgExecutionList;
+ };
+  // Class BlackBox
+
+
+
+
+
+
+
+}
+// namespace bbtk
+#endif
+
diff --git a/kernel/src/bbtkBlackBoxDescriptor.cxx b/kernel/src/bbtkBlackBoxDescriptor.cxx
new file mode 100644 (file)
index 0000000..1fe23c8
--- /dev/null
@@ -0,0 +1,305 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxDescriptor.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxDescriptor : (abstract) describes a BlackBox (name, description, author) and is able to create an instance of it.
+ */
+#include "bbtkBlackBoxDescriptor.h"
+#include "bbtkMessageManager.h"
+#include "bbtkPackage.h"
+#include "bbtkUtilities.h"
+
+namespace bbtk
+{
+  
+  //=========================================================================
+  /// Default ctor
+  BlackBoxDescriptor::BlackBoxDescriptor()  
+    : mTypeName("Unknown"), 
+      mDescription(""), 
+      mAuthor(""),
+      mCategory(STANDARD),
+      mPackage(NULL)
+  {
+    bbtkDebugMessage("Core",9,
+                    "BlackBoxDescriptor::BlackBoxDescriptor()"<<std::endl);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  /// Dtor
+  BlackBoxDescriptor::~BlackBoxDescriptor()
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "BlackBoxDescriptor::~BlackBoxDescriptor() ["
+                       <<mTypeName<<"]"<<std::endl);
+
+    // deletes all I/O descriptors
+    InputDescriptorMapType::iterator i;
+    for (i=mInput.begin(); i!=mInput.end(); ++i) delete i->second;
+    OutputDescriptorMapType::iterator o;
+    for (o=mOutput.begin(); o!=mOutput.end(); ++o) delete o->second;
+
+    bbtkDebugDecTab("Core",9);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  /// Adds the string to the BlackBox's description
+  void BlackBoxDescriptor::AddToDescription( const std::string& s, bool clear)
+  {
+    bbtkDebugMessage("Core",9,"BlackBoxDescriptor::AddToDescription(\""<<s<<
+                    "\") ["<<GetTypeName()<<"]"<<std::endl);
+    if (clear) mDescription = s; 
+    else mDescription += s;
+   }
+  /// Adds the string to the BlackBox's author list
+  void BlackBoxDescriptor::AddToAuthor( const std::string& s, bool clear)
+  {
+    bbtkDebugMessage("Core",9,"BlackBoxDescriptor::AddToAuthor(\""<<s<<"\") ["
+                    <<GetTypeName()<<"]"<<std::endl);
+    if (clear) mAuthor = s;
+    else mAuthor += s;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  const BlackBoxDescriptor::InputDescriptor* 
+  BlackBoxDescriptor::GetInputDescriptor(const std::string & name) const
+  {
+    bbtkDebugMessageInc("Core",9,"BlackBoxDescriptor::GetInputDescriptor('"
+                       <<name<<"') ["<<GetTypeName()<<"]"<<std::endl);
+
+    InputDescriptorMapType::const_iterator i;
+    i = mInput.find(name);
+    if ( i == mInput.end() ) 
+      {
+       bbtkError("input '"<<name<<"' does not exist");
+      }
+    bbtkDebugDecTab("Core",9);
+    return i->second;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  const BlackBoxDescriptor::OutputDescriptor* 
+  BlackBoxDescriptor::GetOutputDescriptor(const std::string & name) const
+  {
+    bbtkDebugMessageInc("Core",9,"BlackBoxDescriptor::GetOutputDescriptor('"
+                       <<name<<"') ["<<GetTypeName()<<"]"<<std::endl);
+
+    OutputDescriptorMapType::const_iterator i;
+    i = mOutput.find(name);
+    if ( i == mOutput.end() ) 
+      {
+       bbtkError("output '"<<name<<"' does not exist");
+      }
+    bbtkDebugDecTab("Core",9);
+    return i->second;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void BlackBoxDescriptor::GetHelp(bool full) const
+  {
+    bbtkDebugMessageInc("Core",9,"BlackBoxDescriptor::GetHelp() ["<<GetTypeName()<<"]"<<std::endl);
+    if (GetPackage()) 
+        {
+    bbtkMessage("Help",1,"Black Box <"<<
+               GetPackage()->GetName()<<"::"<<GetTypeName()<<">"<<std::endl);
+               }
+               else 
+               {
+          bbtkMessage("Help",1,"Black Box <::"<<GetTypeName()<<">"<<std::endl);
+       }
+    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
+    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
+    if (mInput.size()) 
+      bbtkMessage("Help",1," * Inputs : "<<std::endl);
+    else 
+      bbtkMessage("Help",1," * No inputs"<<std::endl);
+    InputDescriptorMapType::const_iterator i;
+    unsigned int namelmax = 0;
+    unsigned int typelmax = 0;
+    for ( i = mInput.begin();  i != mInput.end(); ++i ) 
+      {
+       if (i->second->GetName().size()>namelmax) 
+         namelmax = i->second->GetName().size();
+       if (i->second->GetHumanTypeName().size()>typelmax) 
+         typelmax = i->second->GetHumanTypeName().size();
+      }
+    OutputDescriptorMapType::const_iterator o;
+    for ( o = mOutput.begin();  o != mOutput.end(); ++o ) 
+      {
+       if (o->second->GetName().size()>namelmax) 
+         namelmax = o->second->GetName().size();
+       if (o->second->GetHumanTypeName().size()>typelmax) 
+         typelmax = o->second->GetHumanTypeName().size();
+      }
+    //
+    for ( i = mInput.begin();  i != mInput.end(); ++i ) 
+      {
+       std::string name(i->second->GetName());
+       name += "'";
+       name.append(1+namelmax-name.size(),' ');
+       std::string type(i->second->GetHumanTypeName());
+       type += ">";
+       type.append(1+typelmax-type.size(),' ');
+       bbtkMessage("Help",1,
+                   "    '"<<name
+                   <<" <"<<type
+                   <<" : "<<i->second->GetDescription()<<std::endl);
+      }
+    if (mOutput.size()) 
+      bbtkMessage("Help",1," * Outputs : "<<std::endl);
+    else 
+      bbtkMessage("Help",1," * No outputs"<<std::endl);
+    for ( o = mOutput.begin();  o != mOutput.end(); ++o ) 
+      {
+       std::string name(o->second->GetName());
+       name += "'";
+       name.append(1+namelmax-name.size(),' ');
+       std::string type(o->second->GetHumanTypeName());
+       type += ">";
+       type.append(1+typelmax-type.size(),' ');
+       bbtkMessage("Help",1,
+                   "    '"<<name
+                   <<" <"<<type
+                   <<" : "<<o->second->GetDescription()<<std::endl);
+      }
+   
+     bbtkDebugDecTab("Core",9);
+  
+
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void BlackBoxDescriptor::InsertHtmlHelp ( std::ofstream& s, 
+                                           int detail, int level,
+                                           const std::string& output_dir,
+                                           bool relative_link )
+  {
+    bbtkDebugMessageInc("Core",9,"BlackBoxDescriptor::InsertHtmlHelp() ["<<GetTypeName()<<"]"<<std::endl);
+    
+    //-------------
+    // General info 
+    std::string name = GetTypeName();
+    Utilities::html_format(name);
+
+    (s) << "<p><hr>\n";
+    (s) << "<a name=\""<<name<<"\"></a>\n";
+    (s) << //"Top:&nbsp;
+      "<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
+    // (s) << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
+    // (s) << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
+    (s) << "<h2 class=\"section\">"<<name<<"</h2>\n";
+
+
+    std::string descr = GetDescription();
+    //Utilities::html_format(descr);
+    std::string author = GetAuthor();
+    Utilities::html_format(author);
+    
+    (s) << "<p><TABLE cellspacing=0  cellpadding=3>\n";
+    (s) << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
+      << descr << "</TD></TR>\n";
+    (s) << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
+      << author << "</TD></TR>\n";
+    (s) << "</TABLE>\n";
+    
+    //-------------
+    // Graph
+    //i->second->InsertHTMLGraph( &s , detail,level,dir);
+    
+    //-------------
+    // Inputs
+    std::string col("#CCCCFF");
+    
+    // (s) << "<h3 class=\"subsection\">Inputs</h3>\n";
+    (s) << "<p><TABLE border=1 cellspacing=0 cellpadding=3>\n";
+    (s) << "<TR><TD colspan=3 align=center bgcolor=\""<<col
+      <<"\">Inputs</TD></TR>\n";
+    const BlackBoxDescriptor::InputDescriptorMapType& imap = 
+      GetInputDescriptorMap();
+    
+    InputDescriptorMapType::const_iterator in;
+    
+    for ( in = imap.begin();  in != imap.end(); ++in ) 
+      {
+       std::string name(in->second->GetName());
+       Utilities::html_format(name);
+       
+       std::string type("<");
+       type += in->second->GetTypeName();    
+       type += ">";
+       Utilities::html_format(type);
+       
+       std::string descr(in->second->GetDescription());
+       //Utilities::html_format(descr);
+
+       (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
+         << "<TD style='vertical-align: top;'><I><PRE> "<<type<<" </PRE></I></TD>"
+         << "<TD style='vertical-align: top;'>"<<descr<<"</TD></TR>\n";
+       
+      }
+    // (s) << "</TABLE>\n";
+    
+    
+    //-------------
+    // Outputs
+    // (s) << "<h3 class=\"subsection\">Outputs</h3>\n";
+    // (s) << "<TABLE border=1 cellspacing=0>\n";
+    (s) << "<TR><TD colspan=3 align=center bgcolor=\""<<col
+      <<"\">Outputs</TD></TR>\n";
+    
+    const BlackBoxDescriptor::OutputDescriptorMapType& omap = 
+      GetOutputDescriptorMap();
+    
+    BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
+    
+    for ( o = omap.begin();  o != omap.end(); ++o ) 
+      {
+       std::string name(o->second->GetName());
+       Utilities::html_format(name);
+       
+       std::string type("<");
+       type += o->second->GetTypeName();    
+       type += ">";
+       Utilities::html_format(type);
+       
+       std::string descr(o->second->GetDescription());
+       //Utilities::html_format(descr);
+       
+       
+       (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
+         << "<TD style='vertical-align: top;'><I><PRE> "<<type<<" </PRE></I></TD>"
+         << "<TD style='vertical-align: top;'>"<<descr<<"</TD></TR>\n";
+       
+      }
+    (s) << "</TABLE>\n";
+
+    //------------
+    // End
+
+    bbtkDebugDecTab("Core",9);
+   }
+  //=========================================================================
+}
diff --git a/kernel/src/bbtkBlackBoxDescriptor.h b/kernel/src/bbtkBlackBoxDescriptor.h
new file mode 100644 (file)
index 0000000..f4694a7
--- /dev/null
@@ -0,0 +1,156 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxDescriptor : (abstract) describes of a BlackBox (name, description, author) and is able to create an instance of it.
+ */
+/**
+ * \class bbtk::BlackBoxDescriptor
+ * \brief (Abstract) Contains information on a BlackBox type (name, description, author, inputs, outputs) and is able to create an instance of it.
+ */
+
+#ifndef __bbtkBlackBoxDescriptor_h__
+#define __bbtkBlackBoxDescriptor_h__
+
+#include "bbtkBlackBoxInputDescriptor.h"
+#include "bbtkBlackBoxOutputDescriptor.h"
+#include <map>
+#include <fstream>
+
+namespace bbtk
+{
+
+  class BlackBox;
+  class Package;
+
+  //==========================================================================
+  class BBTK_EXPORT BlackBoxDescriptor
+  {
+  public:
+    /// The type of descriptor of inputs 
+    typedef BlackBoxInputDescriptor InputDescriptor;
+    /// The type of descriptor of outputs 
+    typedef BlackBoxOutputDescriptor OutputDescriptor;
+    /// The type of dictionnary of inputs = map of input descriptors pointers 
+    typedef std::map<std::string, InputDescriptor*> InputDescriptorMapType;
+    /// The type of dictionnary of outputs= map of output descriptors pointers 
+    typedef std::map<std::string, OutputDescriptor*> OutputDescriptorMapType;
+    /// The categories of black box
+    typedef enum
+    {
+      STANDARD,
+      ADAPTOR,
+      DEFAULT_ADAPTOR
+    }
+    Category;
+
+    /// Default ctor
+    BlackBoxDescriptor(); 
+    /// Default dtor
+    virtual ~BlackBoxDescriptor();
+    /// Creates an instance with name boxname of the BlackBox
+    /// of which this is the descriptor 
+    virtual BlackBox* CreateInstance(const std::string& boxname) = 0;
+
+    /// Returns the name of the **TYPE** of the black box
+    const std::string& GetTypeName() const { return mTypeName; }
+    /// Returns the description of the BlackBox 
+    const std::string& GetDescription() const { return mDescription; }
+    /// Returns the author(s) of the BlackBox
+    const std::string& GetAuthor() const { return mAuthor; }
+    /// Returns the Package to which the box belongs
+    Package* GetPackage() { return mPackage; }
+    /// Returns the Package to which the box belongs
+    const Package* GetPackage() const { return mPackage; }
+    /// Returns the category of box 
+    Category GetCategory() const { return mCategory; }
+
+
+    /// Prints help on the black box
+    virtual void GetHelp(bool full=true) const;
+
+    /// Returns a const ref on the map of input descriptors
+    const InputDescriptorMapType& GetInputDescriptorMap() const 
+      { return mInput; }
+    /// Returns a const ref on the map of output descriptors
+    const OutputDescriptorMapType& GetOutputDescriptorMap() const 
+      { return mOutput; }
+    /// Returns a const pointer on the descriptor of the input of name <name> 
+    const InputDescriptor* GetInputDescriptor(const std::string & name) const;
+    /// Returns a const pointer on the descriptor of the output of name <name> 
+    const OutputDescriptor* GetOutputDescriptor(const std::string & name) const;
+
+    /// Sets the name of the **TYPE** of BlackBox
+    void SetTypeName( const std::string& name ) { mTypeName=name; }
+    /// Adds the string to the BlackBox's description
+    void AddToDescription( const std::string&, bool clear = false );
+    /// Adds the string to the BlackBox's author list
+    void AddToAuthor( const std::string&, bool clear = false );
+    /// Sets the Package to which the box belongs
+    void SetPackage(Package *package) { mPackage = package; }
+    /// Sets the category of box 
+    void SetCategory(Category category) { mCategory = category; }
+
+    /* 
+   virtual void InsertHTMLGraph( std::ofstream& s, int detail, int level, 
+                                 const std::string& output_dir = "" ) { }
+    */
+    /// Writes html formatted help into the output file stream. 
+    /// detail and level are used for graphical representation of 
+    /// complex black boxes (see ComplexBlackBox::InsertHTMLGraph)
+    /// output_dir is the directory in which to write auxilliary files 
+    /// (.dot/.png/.cmap)
+    virtual void InsertHtmlHelp ( std::ofstream& s, 
+                                 int detail, int level,
+                                 const std::string& output_dir = "",
+                                 bool relative_link = false );
+
+  protected:
+    /// Adds an input descriptor
+    void AddInputDescriptor( BlackBoxInputDescriptor* d ) 
+    { mInput[d->GetName()] = d; }
+    /// Adds an output descriptor
+    void AddOutputDescriptor( BlackBoxOutputDescriptor* d ) 
+    { mOutput[d->GetName()] = d; }
+
+    //  private:
+    /// The name of the type of black box
+    std::string mTypeName;
+    /// The description of the black box
+    std::string mDescription;
+    /// The author of the black box
+    std::string mAuthor;
+    /// The category of box
+    Category mCategory;
+    /// The Package to which the box belongs
+    Package *mPackage;
+    /// The inputs 
+    InputDescriptorMapType mInput;
+    /// The outputs 
+    OutputDescriptorMapType mOutput;
+    
+  };
+  // class BlackBoxDescriptor
+  //==========================================================================
+
+
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkBlackBoxInputConnector.cxx b/kernel/src/bbtkBlackBoxInputConnector.cxx
new file mode 100644 (file)
index 0000000..4129a71
--- /dev/null
@@ -0,0 +1,81 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxInputConnector.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxInputConnector : 
+ */
+#include "bbtkBlackBoxInputConnector.h"
+#include "bbtkMessageManager.h"
+
+namespace bbtk
+{
+  BlackBoxInputConnector::BlackBoxInputConnector(BlackBox* b)  
+    : mBox(b), mConnection(0), mStatus(MODIFIED)
+  {
+    bbtkDebugMessage("Core",9,"BlackBoxInputConnector::BlackBoxInputConnector()"<<std::endl);
+  }
+
+
+  BlackBoxInputConnector::~BlackBoxInputConnector() 
+  {
+    bbtkDebugMessageInc("Core",9,"BlackBoxInputConnector::~BlackBoxInputConnector()"<<std::endl);
+    if (mConnection) delete mConnection;
+    bbtkDebugDecTab("Core",9);
+  }
+  
+  void BlackBoxInputConnector::SetConnection(Connection* c) 
+  { 
+    bbtkDebugMessage("Core",9,"BlackBoxInputConnector::SetConnection("<<c<<")"<<std::endl);
+    mConnection = c; 
+  }
+  
+  void BlackBoxInputConnector::UnsetConnection(Connection* c) 
+  { 
+    bbtkDebugMessage("Core",9,"BlackBoxInputConnector::UnsetConnection("
+                    <<c<<")"<<std::endl);
+    mConnection = 0; 
+  }
+  
+  IOStatus BlackBoxInputConnector::BackwardUpdate()
+  {
+    bbtkDebugMessageInc("Process",4,"BlackBoxInputConnector::BackwardUpdate()"
+                       <<std::endl);
+
+    if (mConnection) 
+      {
+       IOStatus s = mConnection->BackwardUpdate();
+       mStatus = s;
+      }
+    else 
+      {
+       mStatus = UPTODATE;
+      }
+
+    bbtkDecTab("Process",4);
+
+    return mStatus;
+
+  }
+
+
+  //    void Modified();
+  
+}
+// namespace bbtk
+
diff --git a/kernel/src/bbtkBlackBoxInputConnector.h b/kernel/src/bbtkBlackBoxInputConnector.h
new file mode 100644 (file)
index 0000000..6575a8a
--- /dev/null
@@ -0,0 +1,75 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxInputConnector.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxInputConnector : 
+ */
+/**
+ * \class bbtk::BlackBoxInputConnector
+ * \brief 
+ */
+#ifndef __bbtkBlackBoxInputConnector_h__
+#define __bbtkBlackBoxInputConnector_h__
+
+#include "bbtkConnection.h"
+#include <vector>
+
+namespace bbtk
+{
+
+
+  class BBTK_EXPORT BlackBoxInputConnector 
+  {
+  public:
+     
+    /// Ctor
+    BlackBoxInputConnector(BlackBox* b);
+    /// Dtor
+    ~BlackBoxInputConnector();    
+    /// Sets a connection
+    void SetConnection(Connection* c);
+    /// Unsets the connection 
+    /// The parameter is USELESS today but would be useful if we allow multiple connections on inputs
+    void UnsetConnection(Connection* c);
+  
+    IOStatus BackwardUpdate();
+
+    /// Returns the connection plugged into this input (const)
+    const Connection* GetConnection() const { return mConnection; }
+    /// Returns the connection plugged into this input
+    Connection* GetConnection() { return mConnection; }
+    /// Returns true iff a connection is connected to it
+    bool IsConnected() const { return (mConnection != 0); }
+    /// Returns the status of the input (UPTODATE | MODIFIED)
+    const IOStatus& GetStatus() const { return mStatus; }
+    ///
+    BlackBox* GetBlackBox() const { return mBox; } 
+  private:
+    /// 
+    BlackBox* mBox;
+    /// The connection plugged into the input
+    Connection* mConnection;
+    /// The status of the input (UPTODATE | MODIFIED)
+    IOStatus mStatus;
+  };
+  
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkBlackBoxInputDescriptor.h b/kernel/src/bbtkBlackBoxInputDescriptor.h
new file mode 100644 (file)
index 0000000..0462c0c
--- /dev/null
@@ -0,0 +1,94 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxInputDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxInputDescriptor : abstract descriptor of an input of a black box (stores a name, a description and type)
+ */
+/**
+ * \class bbtk::BlackBoxInputDescriptor
+ * \brief Abstract descriptor of an input of a black box (stores a name, a description and type)
+ */
+
+#ifndef __bbtkBlackBoxInputDescriptor_h__
+#define __bbtkBlackBoxInputDescriptor_h__
+
+#include "bbtkSystem.h"
+#include "bbtkData.h"
+#include "bbtkRTTI.h"
+
+namespace bbtk
+{
+  
+  
+  class BBTK_EXPORT BlackBoxInputDescriptor
+  {
+  public:
+    typedef enum {
+      MANDATORY,
+      OPTIONAL
+    } OptionType;
+    
+    
+    /// Ctor with name and description
+    BlackBoxInputDescriptor( const std::string& name,
+                            const std::string& description,
+                            OptionType option = MANDATORY,
+                            bool copy_construct = true)
+      : mName(name), mDescription(description), 
+       mOption(option), mCopyConstruct(copy_construct) 
+    {}
+    
+    /// Returns the name of the input
+    const std::string& GetName() const { return mName; }
+    /// Returns the description of the input
+    const std::string& GetDescription() const { return mDescription; }
+    /// Returns the type of the input
+    virtual TypeInfo GetTypeInfo() const = 0;
+    /// Returns the name of the type of the input
+    virtual std::string GetTypeName() const = 0;
+    /// Returns the name of the type of the input
+    virtual std::string GetHumanTypeName() const = 0;
+    /// Returns true iff the type is a pointer to class 
+    virtual bool IsPointerType() const = 0;
+    /// Returns the option of the input
+    OptionType GetOption() const { return mOption; }
+    /// Returns true iff the input must be copied 
+    /// by the copy constructor of the box
+    bool GetCopyConstruct() const { return mCopyConstruct; }
+    
+  private:
+    /// Default ctor is private
+    BlackBoxInputDescriptor() : mName(""), mDescription(""), 
+                               mOption(OPTIONAL) {}
+    /// The name of the input
+    std::string mName;
+    /// The description of the input
+    std::string mDescription;
+    /// The option of the input 
+    OptionType mOption;
+    /// Does the input has to be copied by copy constructor 
+    /// default = true. Must be set to false if it is 
+    /// initialized by the user in bbUserCopyConstructor 
+    /// (typically if it is a pointer)
+    bool mCopyConstruct;
+  };
+  
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkBlackBoxOutputConnector.cxx b/kernel/src/bbtkBlackBoxOutputConnector.cxx
new file mode 100644 (file)
index 0000000..70352ff
--- /dev/null
@@ -0,0 +1,103 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxOutputConnector.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxOutputConnector : 
+ */
+
+#include "bbtkBlackBoxOutputConnector.h"
+#include "bbtkMessageManager.h"
+#include "bbtkBlackBox.h"
+//#include <algorithm>
+
+namespace bbtk
+{
+
+  BlackBoxOutputConnector::BlackBoxOutputConnector() 
+  // : mStatus(MODIFIED)
+  {
+    bbtkDebugMessage("Core",9,"BlackBoxOutputConnector::BlackBoxOutputConnector()"<<std::endl);
+  }
+
+  BlackBoxOutputConnector::~BlackBoxOutputConnector() 
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "BlackBoxOutputConnector::~BlackBoxOutputConnector()"
+                       <<std::endl);
+    std::vector<Connection*>::iterator i;
+    for (i=mConnection.begin();i!=mConnection.end();++i) 
+      {
+       delete *i;
+      }
+    bbtkDebugDecTab("Core",9);
+  }
+
+  ///
+  void BlackBoxOutputConnector::SetConnection(Connection* c)
+  {
+    bbtkDebugMessage("Core",9,"BlackBoxOutputConnector::SetConnection("
+                    <<c<<")"<<std::endl);
+    mConnection.push_back(c);
+  }
+
+
+
+  ///
+  void BlackBoxOutputConnector::UnsetConnection(Connection* c)
+  {
+    bbtkDebugMessageInc("Core",9,"BlackBoxOutputConnector::UnsetConnection("
+                    <<c<<")"<<std::endl);
+
+    std::vector<Connection*>::iterator i;
+    for (i=mConnection.begin();i!=mConnection.end();++i) 
+      {
+       if ( *i == c) break;
+      }
+    //= std::find(mConnection,c);
+    if (i==mConnection.end())
+      {
+       bbtkError("no connexion "<<c);
+      }
+    mConnection.erase(i);
+
+    bbtkDebugDecTab("Core",9);
+  }
+
+
+  
+  void BlackBoxOutputConnector::SetModifiedStatus()
+  {
+    bbtkDebugMessageInc("Process",5,
+                       "BlackBoxOutputConnector::SetModifiedStatus()"
+                       <<std::endl);
+    std::vector<Connection*>::iterator i;
+    for (i=mConnection.begin();i!=mConnection.end();++i) 
+      {
+       (*i)->SetModifiedStatus();
+      }
+    
+    bbtkDebugDecTab("Process",5);
+    
+   }
+
+
+}
+// namespace bbtk
+
diff --git a/kernel/src/bbtkBlackBoxOutputConnector.h b/kernel/src/bbtkBlackBoxOutputConnector.h
new file mode 100644 (file)
index 0000000..dab1274
--- /dev/null
@@ -0,0 +1,60 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxOutputConnector.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxOutputConnector : 
+ */
+/**
+ * \class bbtk::BlackBoxOutputConnector
+ * \brief 
+ */
+#ifndef __bbtkBlackBoxOutputConnector_h__
+#define __bbtkBlackBoxOutputConnector_h__
+
+#include "bbtkConnection.h"
+#include "bbtkMessageManager.h"
+#include <vector>
+
+namespace bbtk
+{
+
+
+  class BBTK_EXPORT BlackBoxOutputConnector 
+  {
+  public:
+     
+    BlackBoxOutputConnector();
+    ~BlackBoxOutputConnector();
+    void SetConnection(Connection* c);
+    void UnsetConnection(Connection* c);
+    //IOStatus Update();
+    void SetModifiedStatus();
+    const std::vector<Connection*>& GetConnectionVector() const { return mConnection; }
+    
+  private:
+    /// The vector of output connections
+    std::vector<Connection*> mConnection;
+    /// The status of the output 
+    //IOStatus mStatus;
+  };
+  
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkBlackBoxOutputDescriptor.h b/kernel/src/bbtkBlackBoxOutputDescriptor.h
new file mode 100644 (file)
index 0000000..eb1164f
--- /dev/null
@@ -0,0 +1,84 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkBlackBoxOutputDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::BlackBoxOutputDescriptor : abstract descriptor of an output of a black box (stores a name, a description and type)
+ */
+/**
+ * \class bbtk::BlackBoxOutputDescriptor
+ * \brief Abstract descriptor of an output of a black box (stores a name, a description and type)
+ */
+
+#ifndef __bbtkBlackBoxOutputDescriptor_h__
+#define __bbtkBlackBoxOutputDescriptor_h__
+
+
+#include "bbtkSystem.h"
+#include "bbtkData.h"
+#include "bbtkRTTI.h"
+
+namespace bbtk
+{
+  
+  
+  class BBTK_EXPORT BlackBoxOutputDescriptor
+  {
+  public:
+    /// Ctor with name and description
+    BlackBoxOutputDescriptor( const std::string& name,
+                             const std::string& description,
+                             bool copy_construct = true)
+      : mName(name), mDescription(description), 
+       mCopyConstruct(copy_construct) 
+    {}
+    
+    /// Returns the name of the output
+    const std::string& GetName() const { return mName; }
+    /// Returns the description of the output
+    const std::string& GetDescription() const { return mDescription; }
+    /// Returns the type of the output
+    virtual TypeInfo GetTypeInfo() const = 0;
+    /// Returns the name of the type of the output
+    virtual std::string GetTypeName() const = 0;
+    /// Returns the name of the type of the output
+    virtual std::string GetHumanTypeName() const = 0;
+     /// Returns true iff the type is a pointer to class 
+    virtual bool IsPointerType() const = 0;
+    /// Returns true iff the input must be copied 
+    /// by the copy constructor of the box
+    bool GetCopyConstruct() const { return mCopyConstruct; }
+    
+    
+  private:
+    /// Default ctor is private
+    BlackBoxOutputDescriptor() : mName(""), mDescription("") {}
+    /// The name of the output
+    std::string mName;
+    /// The description of the output
+    std::string mDescription;
+     /// Does the output has to be copied by copy constructor 
+    /// default = true. Must be set to false if it is 
+    /// initialized by the user in bbUserCopyConstructor 
+    /// (typically if it is a pointer)
+    bool mCopyConstruct;
+ };
+  
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkComplexBlackBox.cxx b/kernel/src/bbtkComplexBlackBox.cxx
new file mode 100644 (file)
index 0000000..2c09e31
--- /dev/null
@@ -0,0 +1,974 @@
+/*=========================================================================
+                                                                                
+Program:   bbtk
+Module:    $RCSfile: bbtkComplexBlackBox.cxx,v $
+Language:  C++
+Date:      $Date: 2008/01/22 15:02:00 $
+Version:   $Revision: 1.1 $
+                                                                                
+Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+l'Image). All rights reserved. See Doc/License.txt or
+http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the above copyright notices for more information.
+                                                                               
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief class bbtk::ComplexBlackBox : user defined complex black boxes
+ */
+#include "bbtkComplexBlackBox.h"
+#include "bbtkBlackBoxDescriptor.h"
+#include "bbtkFactory.h"
+#include "bbtkConfigurationFile.h"
+
+namespace bbtk
+{
+
+
+  //=======================================================================
+  /// Usefull constructor 
+  ComplexBlackBox::ComplexBlackBox(const std::string &name,
+                                  ComplexBlackBoxDescriptor* desc)
+    : BlackBox(name),
+      mDescriptor(desc)
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::ComplexBlackBox(\""
+                       <<name<<"\")"<<std::endl);
+    bbAllocateConnectors();
+    bbtkDebugDecTab("Core",9);
+  }
+  //=======================================================================
+
+  //=======================================================================
+  /// Constructor from an existing box (copy) with a new name 
+  ComplexBlackBox::ComplexBlackBox(ComplexBlackBox& from, 
+                                  const std::string &name)
+    : BlackBox(from,name),
+      mDescriptor(from.mDescriptor),
+     mExecutionList(from.mExecutionList)    
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::ComplexBlackBox(\""
+                       <<from.bbGetName()<<"\",\""
+                       <<name<<"\")"<<std::endl);
+
+    bbtkDebugMessageInc("Core",9,"* Cloning Black Boxes"<<std::endl);
+    BlackBoxMapType::const_iterator i;
+    for ( i = from.mBlackBoxMap.begin(); i != from.mBlackBoxMap.end(); ++i ) 
+      {
+       bbtkDebugMessageInc("Core",9,"* Cloning \""<<i->first<<"\""<<std::endl);
+       BlackBox* B = i->second->bbClone(i->second->bbGetName());
+       bbUnsafeAddBlackBox(B);
+       
+       bbtkDebugDecTab("Core",9);
+      }
+    bbtkDebugDecTab("Core",9);
+   
+    bbtkDebugMessageInc("Core",9,"* Cloning Connections"<<std::endl);
+    ConnectionListType::const_iterator j;
+    for ( j = from.mConnectionList.begin(); j != from.mConnectionList.end(); ++j ) 
+      {
+       bbtkDebugMessageInc("Core",9,"* Cloning \""<<
+                           (*j)->GetFullName()<<"\""<<std::endl);
+
+       BlackBox* bbfrom = bbGetBlackBox( (*j)->GetBlackBoxFrom()->bbGetName() );
+       BlackBox* bbto = bbGetBlackBox( (*j)->GetBlackBoxTo()->bbGetName() );
+       Connection* c = /*mDescriptor->GetFactory()->Create*/ 
+         NewConnection( bbfrom, 
+                        (*j)->GetBlackBoxFromOutput(), 
+                        bbto, 
+                        (*j)->GetBlackBoxToInput() );
+       
+       bbAddConnection(c);
+
+       bbtkDebugDecTab("Core",9);
+      }
+    bbtkDebugDecTab("Core",9);
+
+    bbAllocateConnectors();
+    bbtkDebugDecTab("Core",9);    
+  }
+  //=======================================================================
+
+  //======================================================================= 
+  ///  Destructor
+  ComplexBlackBox::~ComplexBlackBox()
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::~ComplexBlackBox() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
+    bbtkDebugMessageInc("Core",9,"* Delete Connections"<<std::endl);
+    ConnectionListType::iterator j;
+    for ( j = mConnectionList.begin(); j != mConnectionList.end(); ++j ) 
+      {
+       bbtkDebugMessageInc("Core",9,"* Delete \""<<
+                           (*j)->GetFullName()<<"\""<<std::endl);
+       delete *j;
+       bbtkDebugDecTab("Core",9);
+      }
+    bbtkDebugDecTab("Core",9);
+
+    
+    bbtkDebugMessageInc("Core",9,"* Delete Black Boxes"<<std::endl);
+    BlackBoxMapType::iterator i;
+    for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
+      {
+       bbtkDebugMessageInc("Core",9,"* Delete \""<<i->first<<"\""<<std::endl);
+       i->second->bbDelete();
+       bbtkDebugDecTab("Core",9);
+      }
+    bbtkDebugDecTab("Core",9);
+    //    bbtkDebugMessage("Core",9,"EO ComplexBlackBox::~ComplexBlackBox  ["
+    //              <<bbGetFullName()<<"]"<<std::endl);
+
+    
+    this->bbDesallocateConnectors();
+    bbtkDebugDecTab("Core",9);   
+  } 
+  //=======================================================================
+
+  //=========================================================================
+  /// Allocates the i/o connectors of the black box
+  void ComplexBlackBox::bbAllocateConnectors()
+  {  
+    bbtkDebugMessageInc("Core",8,
+                       "ComplexBlackBox::bbAllocateConnectors() ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);   
+
+    // Input connectors
+    const BlackBoxDescriptor::InputDescriptorMapType& imap 
+      = bbGetDescriptor()->GetInputDescriptorMap(); 
+    BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;      
+    for ( i = imap.begin(); i != imap.end(); ++i )                     
+      {                                                                        
+       bbtkDebugMessage("Core",8,"* Allocate \""<<i->first<<"\""<<std::endl);
+       // Redirect the connector to the internal box connector
+       // Cast the BBInputDescriptor into a ComplexBBInputDescriptor
+       ComplexBlackBoxInputDescriptor* d = 
+         (ComplexBlackBoxInputDescriptor*)i->second;
+       // Get the internal box connector
+       BlackBoxInputConnector* c = 
+         bbUnsafeGetBlackBox ( d->GetTarget() )
+         ->bbGetInputConnectorMap()[ d->GetInput() ];
+       
+       bbGetInputConnectorMap()[i->second->GetName()] = c;
+//new BlackBoxInputConnector();
+      }                                                                        
+
+    // Output connectors
+    const BlackBoxDescriptor::OutputDescriptorMapType& omap 
+      = bbGetDescriptor()->GetOutputDescriptorMap();                  
+    BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
+    for ( o = omap.begin(); o != omap.end(); ++o )
+      {                                                        
+       bbtkDebugMessage("Core",8,"* Allocate \""<<o->first<<"\""<<std::endl);
+       // Redirect the connector to the internal box connector
+       // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
+       ComplexBlackBoxOutputDescriptor* d = 
+         (ComplexBlackBoxOutputDescriptor*)o->second;
+       // Get the internal box connector
+       BlackBoxOutputConnector* c = 
+         bbUnsafeGetBlackBox ( d->GetTarget() )
+         ->bbGetOutputConnectorMap()[ d->GetOutput() ];
+
+       bbGetOutputConnectorMap()[o->second->GetName()] = c;
+       //new BlackBoxOutputConnector();
+      }
+    bbtkDebugDecTab("Core",8);  
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Desallocates the i/o connectors of the black box
+  void ComplexBlackBox::bbDesallocateConnectors()
+  {
+    bbtkDebugMessageInc("Core",8,
+                       "ComplexBlackBox::DesallocateConnectors()"
+                       <<std::endl);                                   
+
+    // The connectors have not been allocated by the complex box 
+    // but by the internal boxes. Hence **DO NOT** desallocate !
+    // just clear the maps to avoid that 
+    // BlackBox::bbDesallocateConnectors delete the connectors
+    bbGetInputConnectorMap().clear();
+    bbGetOutputConnectorMap().clear();
+
+    bbtkDebugDecTab("Core",8);  
+
+  }
+  //=========================================================================
+
+  //=======================================================================
+  BlackBox* ComplexBlackBox::bbClone(const std::string& name)
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::bbClone(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
+    ComplexBlackBox* CBB = new ComplexBlackBox(*this,name);
+    
+    bbtkDebugDecTab("Core",9);   
+
+    return CBB;
+  }
+  //=======================================================================
+
+  //=======================================================================
+  /// Main processing method of the box.
+  /// Executes the box so that its outputs are up-to-date on exit
+  void ComplexBlackBox::bbExecute(bool force)
+  {
+    bbtkDebugMessageInc("Process",1,
+                       "ComplexBlackBox::bbExecute() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+    wx::BeginBusyCursor();
+    
+    if (mExecutionList.size() != 0) 
+      {
+       
+        std::vector<std::string>::const_iterator i;
+        for (i=mExecutionList.begin(); 
+            i!=mExecutionList.end();
+            ++i) 
+         {
+           bbtkDebugMessage("Process",2," -> Executing '"<<*i<<"'"<<std::endl);
+           mBlackBoxMap[*i]->bbExecute(force);
+         }
+      }
+    else 
+      {
+       std::map<std::string, BlackBox*>::iterator i;
+       for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
+         {
+           i->second->bbExecute(force);
+         }
+      } 
+
+    wx::EndBusyCursor();
+    
+    bbtkDebugDecTab("Process",1);
+    
+  }
+  //==================================================================
+
+  //==================================================================
+  void ComplexBlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
+  {
+    bbtkDebugMessage("Process",3,
+                       "ComplexBlackBox::bbSetModifiedStatus("
+                    <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
+
+    c->GetBlackBox()->bbSetModifiedStatus(c);
+
+    bbtkDebugMessage("Process",3,
+                    "EO ComplexBlackBox::bbSetModifiedStatus("
+                    <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
+  }
+  //==================================================================
+
+  //==================================================================
+  void ComplexBlackBox::bbAddToExecutionList( const std::string& name )
+  {
+        bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::bbAddToExecutionList(\""
+                       <<name<<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+       mExecutionList.push_back( name );
+
+     bbtkDebugDecTab("Core",9);   
+
+  }
+  //==================================================================
+
+  //==================================================================
+  IOStatus ComplexBlackBox::bbBackwardUpdate(Connection* caller)
+  {
+    bbtkDebugMessageInc("Process",1,
+                       "ComplexBlackBox::bbBackwardUpdate("<<caller->GetFullName()<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+    IOStatus s = UPTODATE;
+    const BlackBoxDescriptor::OutputDescriptorMapType& omap 
+      = bbGetDescriptor()->GetOutputDescriptorMap(); 
+    BlackBoxDescriptor::OutputDescriptorMapType::const_iterator i 
+      = omap.find(caller->GetBlackBoxFromOutput());
+    if (i!=omap.end())
+      {        
+       // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
+       ComplexBlackBoxOutputDescriptor* d = 
+         (ComplexBlackBoxOutputDescriptor*)i->second;
+       // Get the internal box 
+       BlackBox* b = bbUnsafeGetBlackBox ( d->GetTarget() );
+       // Calls BackwardUpdate on it
+       bbtkDebugMessageInc("Process",2,"Internal box connected to output : "<<d->GetTarget()<<std::endl);
+       IOStatus s1 = b->bbBackwardUpdate(caller);
+       // ??? STATUS OF CBBs ???
+       // ??? Here it is only the final status of the boxes connected to the output 
+       if (s1==MODIFIED) s=MODIFIED;
+       bbtkDebugDecTab("Process",2);
+      }
+    else 
+      {
+       bbtkError("Connection '"<<caller->GetFullName()<<"' does not point to a valid output of the complex box !");
+      }
+    bbtkDebugDecTab("Process",1);
+    return s;
+  }
+  //==================================================================
+  
+  /*
+  //==================================================================
+  void ComplexBlackBox::bbForwardUpdate(Connection* caller)
+  { 
+    bbtkDebugMessageInc("Process",1,
+                       "ComplexBlackBox::bbForwardUpdate("<<caller->GetFullName()<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+    const BlackBoxDescriptor::InputDescriptorMapType& imap 
+      = bbGetDescriptor()->GetInputDescriptorMap(); 
+    BlackBoxDescriptor::InputDescriptorMapType::const_iterator i 
+      = imap.find(caller->GetBlackBoxToInput());
+    if (i!=imap.end())
+      {        
+       // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
+       ComplexBlackBoxInputDescriptor* d = 
+         (ComplexBlackBoxInputDescriptor*)i->second;
+       // Get the internal box 
+       BlackBox* b = bbUnsafeGetBlackBox ( d->GetTarget() );
+       // Calls ForwardUpdate on it
+       bbtkDebugMessage("Process",2,"-> Internal box connected to input : "<<d->GetTarget()<<std::endl);
+       b->bbForwardUpdate(caller);
+      }
+    else 
+      {
+       bbtkError("Connection '"<<caller->GetFullName()<<"' does not point to a valid input of the complex box !");
+      }
+    bbtkDebugDecTab("Process",1);
+  }
+  //==================================================================
+  */
+
+
+  //==================================================================
+  Data ComplexBlackBox::bbGetOutput( const std::string &name )
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "ComplexBlackBox::bbGetOutput(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+    ComplexBlackBoxOutputDescriptor* d = 
+      (ComplexBlackBoxOutputDescriptor*)
+      bbGetDescriptor()->GetOutputDescriptor(name);
+    
+    Data p = bbGetBlackBox(d->GetTarget())->bbGetOutput(d->GetOutput());
+
+
+    bbtkDebugDecTab("Data",7);
+    return p;
+  }
+  //==================================================================
+
+  //==================================================================
+  ///  Gets the input Data of a given name
+  Data ComplexBlackBox::bbGetInput( const std::string &name ) 
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "ComplexBlackBox::bbGetInput(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+
+    ComplexBlackBoxInputDescriptor* d = 
+      (ComplexBlackBoxInputDescriptor*)
+      bbGetDescriptor()->GetInputDescriptor(name);
+
+    Data p = bbGetBlackBox(d->GetTarget())->bbGetInput(d->GetInput());
+
+    bbtkDebugDecTab("Data",7);
+    return p;
+  }
+  //==================================================================
+
+  //==================================================================
+  ///  Sets the data of the output called <name>
+  void ComplexBlackBox::bbSetOutput( const std::string &name, Data data)
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "ComplexBlackBox::bbSetOutput(\""<<name<<"\",data) ["
+                       <<bbGetFullName()<<"]"<<std::endl); 
+
+    ComplexBlackBoxOutputDescriptor* d = 
+      (ComplexBlackBoxOutputDescriptor*)
+      bbGetDescriptor()->GetOutputDescriptor(name);
+    
+    bbGetBlackBox(d->GetTarget())->bbSetOutput(d->GetOutput(),data);
+
+    bbtkDebugDecTab("Data",7);
+  }
+  //==================================================================
+  
+  //==================================================================
+  ///  Sets the data of the input called <name>
+  void ComplexBlackBox::bbSetInput( const std::string &name, Data data,
+                                   bool setModified)
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "ComplexBlackBox::bbSetInput(\""<<name<<"\",data) ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+
+    ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
+      bbGetDescriptor()->GetInputDescriptor(name);
+
+    bbGetBlackBox(d->GetTarget())->bbSetInput(d->GetInput(),data,setModified);
+
+    bbtkDebugDecTab("Data",7);
+  }
+  //==================================================================
+
+  //==================================================================
+  ///  Sets the data of the input called <name>
+  void ComplexBlackBox::bbBruteForceSetInputPointer( const std::string &name, 
+                                                    void* data,
+                                                    bool setModified)
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "ComplexBlackBox::bbBruteForceSetInputPointer('"
+                       <<name<<"',"<<data<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+
+    ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
+      bbGetDescriptor()->GetInputDescriptor(name);
+
+    bbGetBlackBox(d->GetTarget())->bbBruteForceSetInputPointer(d->GetInput(),
+                                                              data,
+                                                              setModified);
+
+    bbtkDebugDecTab("Data",7);
+  }
+  //==================================================================
+
+  //==================================================================
+  /// Adds the black box to the complex box
+  void ComplexBlackBox::bbAddBlackBox( BlackBox* b)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "ComplexBlackBox::AddBlackBox(\""<<b->bbGetName()
+                       <<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+    
+    if ( bbUnsafeGetBlackBox(b->bbGetName()) ) 
+      {
+       bbtkError("a black box called \""<<b->bbGetName()
+                 <<"\" already exists");
+      }
+    b->bbSetParent(this);
+    mBlackBoxMap[b->bbGetName()] = b;
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //==================================================================
+
+  //==================================================================
+  /// Adds the black box to the complex box (unsafe)
+  void ComplexBlackBox::bbUnsafeAddBlackBox( BlackBox* b)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "ComplexBlackBox::UnsafeAddBlackBox(\""<<b->bbGetName()
+                       <<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+    
+    b->bbSetParent(this);
+    mBlackBoxMap[b->bbGetName()] = b;
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //==================================================================
+
+  //==================================================================
+  /// Removes the black box from the complex box
+  void ComplexBlackBox::bbRemoveBlackBox( const std::string& name )
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "ComplexBlackBox::RemoveBlackBox(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+
+    bbtkError("ComplexBlackBox::RemoveBlackBox not implemented");
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //==================================================================
+
+  //==================================================================
+  /// Adds the connection to the complex box
+  void ComplexBlackBox::bbAddConnection( Connection* c)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "ComplexBlackBox::AddConnection(\""<<"..."<<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+
+    mConnectionList.push_back(c);
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //==================================================================
+  //    void RemoveConnection( );
+
+  //==================================================================
+  /// Returns the black box with name <name>
+  BlackBox* ComplexBlackBox::bbGetBlackBox( const std::string& name )
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::GetBlackBox(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"<<std::endl);  
+
+    BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
+    if ( i == mBlackBoxMap.end() ) 
+      {
+       bbtkError("the black box \""<<name<<"\" does not exist");
+      }
+
+    bbtkDebugDecTab("Core",9);
+    return i->second;
+  }
+  //==================================================================
+
+  //==================================================================
+  /// Returns the black box with name <name> : does not throw an exception 
+  /// if it does not exist but return a null pointer
+  BlackBox* ComplexBlackBox::bbUnsafeGetBlackBox( const std::string& name )
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::UnsafeGetBlackBox(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);  
+
+    BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
+    if ( i == mBlackBoxMap.end() ) 
+      {
+       bbtkDebugDecTab("Core",9);
+       return 0;
+      }
+
+    bbtkDebugDecTab("Core",9);
+    return i->second;
+    
+  }
+  //==================================================================
+
+  //==================================================================
+  void ComplexBlackBox::bbPrintBlackBoxes()
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBox::PrintBlackBoxes() ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);  
+
+    BlackBoxMapType::iterator i;
+    for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
+      {
+       bbtkMessage("Help",1,i->second->bbGetFullName()<<std::endl);
+      }
+
+    bbtkDebugDecTab("Core",9);
+  }
+  //==================================================================
+
+
+  //=========================================================================
+  /// Virtual
+  void ComplexBlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
+  {
+    if (inputoutput)
+      {
+       fprintf(ff,"%s_IN_%p",bbGetTypeName().c_str(),this);
+      } else {
+      fprintf(ff,"%s_OUT_%p",bbGetTypeName().c_str(),this);
+    } // if inputoutput
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  BlackBox *ComplexBlackBox::bbFindBlackBox(const std::string &blackboxname)
+  {
+    BlackBox *blackbox=NULL;
+    std::string subname="";
+    std::string restname="";
+    std::string delimiters(">");
+    // Skip delimiters at beginning.
+    std::string::size_type lastPos = blackboxname.find_first_not_of(delimiters, 0);
+    // Find first "non-delimiter".
+    std::string::size_type pos     = blackboxname.find_first_of(delimiters, lastPos);
+           
+    // Found a token, add it to the vector.
+    subname = blackboxname.substr(lastPos, pos - lastPos);
+    restname = blackboxname.substr(lastPos+pos - lastPos+1, 999);
+
+    if (restname==subname)
+      {
+       restname="";
+      }
+
+    BlackBoxMapType::iterator i = mBlackBoxMap.find(subname);
+    if ( i == mBlackBoxMap.end() ) 
+      {
+       blackbox = NULL;
+      } else {
+      blackbox = i->second;
+      if (restname!="")
+       {
+         blackbox = blackbox->bbFindBlackBox(restname);
+       }
+    }
+    return blackbox;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void ComplexBlackBox::bbInsertHTMLGraph(  std::ofstream& s, 
+                                           int detail, 
+                                           int level,
+                                           bool instanceOrtype,
+                                           const std::string& output_dir,
+                                           bool relative_link )
+  {
+    
+    std::string directory(output_dir);
+
+    if (output_dir.length() == 0) 
+      {
+       // Don't pollute the file store with  "doc_tmp" directories ... 
+       std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
+       directory =  default_doc_dir + "/" + "doc_tmp";
+      }
+    
+    std::string simplefilename  (this->bbGetTypeName()+"_"+this->bbGetName());
+    std::string simplefilename_png (simplefilename+".png");
+    std::string filename           (directory+"/"+simplefilename);
+    std::string filename_png       (filename+".png");
+    std::string filename_cmap      (filename+".cmap");
+    std::string filename_dot       (filename+".dot");
+
+    std::string filename_png2  ("\""   + filename_png  + "\"");
+    std::string filename_cmap2 ("\""   + filename_cmap + "\"");
+    std::string filename_dot2  ("\""   + filename_dot  + "\"");
+    
+
+    std::string command1 ("dot -T png -o "  
+                         + filename_png2  + " " + filename_dot2);
+    std::string command1a("dot -T cmap -o " 
+                         + filename_cmap2 + " " + filename_dot2);
+
+    // 1. Generating .dot file
+    FILE *ff;
+    ff = fopen(filename_dot.c_str(),"w");
+    fprintf(ff,"digraph bbtk_graph{\n");
+    fprintf(ff,"rankdir=LR%s\n",";");
+    fprintf(ff,"node [shape=record]%s\n",";");
+
+    this->bbWriteDotFileBlackBox(ff,this,detail,level,
+                                instanceOrtype,
+                                relative_link );
+
+    fprintf(ff,"}\n");
+    fclose(ff);
+
+    // 2. Executing .dot file -> png
+    system( command1.c_str() );   
+    // 3. Executing .dot file -> cmap
+    system( command1a.c_str() );  
+    
+    // 4. HTML code insertion
+    // 4.1 image
+    (s) << "<center><img src=\"" << simplefilename_png 
+        <<   "\" border=\"0\" usemap=\"#map_"<< simplefilename 
+        <<"\" alt=\"\"></center>\n";
+
+    // 4.2 map
+    (s) << "<map name=\"map_"<< simplefilename <<"\">\n";
+    FILE *ff2;
+    char c;
+    ff2=fopen(filename_cmap.c_str(),"r");
+    while (!feof(ff2))
+      {
+       c=fgetc(ff2);
+       if (c!=-1)
+         {
+           (s) << c;
+         }
+      }
+    (s) << "</map>\n\n";
+    
+    // End
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Write Graphviz-dot description in file 
+  void ComplexBlackBox::bbWriteDotFileBlackBox(FILE *ff,
+                                              BlackBox *parentblackbox, 
+                                              int detail, int level,
+                                              bool instanceOrtype,
+                                              bool relative_link )   
+  {
+    std::string tmp1;
+    std::string valueStr("");
+    Package *package = this->bbGetDescriptor()->GetPackage(); 
+
+    if (package!=NULL)
+      {
+       if (relative_link)
+         tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL();
+       else 
+         tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocURL();
+      } 
+    else 
+      {
+       tmp1 = "Caspitas";
+      }
+
+    std::string tmp2=bbGetTypeName();
+    std::string url(tmp1 + "#" + tmp2 );       
+    fprintf( ff , "subgraph cluster_%s_%p {\n",bbGetName().c_str(),this);
+
+    if (!(   (bbGetTypeName()=="workspace") && (bbGetName()=="workspacePrototype")) )
+      {
+       fprintf( ff , "  URL = \"%s\" %s",url.c_str(),";");
+      }
+
+    std::string boxname="["+bbGetTypeName()+"]";
+    if (this!=parentblackbox)
+      {
+       if (detail==0)
+         {
+           boxname=bbGetName();
+         } else {
+         boxname = bbGetName();
+         boxname = boxname + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
+       }
+
+      }
+    fprintf( ff , "  label = \"%s\"%s\n",  boxname.c_str() ,";");
+
+
+
+    // fprintf( ff , "  style=filled%s\n",";");
+    // fprintf( ff , "  color=grey%s\n",";");
+    fprintf( ff , "  node [style=filled]%s\n",";");
+    fprintf( ff , "  fillcolor=grey%s\n",";");
+    fprintf( ff , "  edge [color=blue]%s\n",";");
+
+
+    // Labels Salida
+    std::string labelStr1;
+    std::string labelStr2;
+    labelStr1 = boxname + "\\n(output)" ; 
+    labelStr2 = " | {{ ";
+    bool tmp; 
+    tmp=false;
+    OutputConnectorMapType::iterator i;
+
+    const BlackBoxDescriptor::OutputDescriptorMapType& omap = this->bbGetDescriptor()->GetOutputDescriptorMap();
+    BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;     
+    for ( o = omap.begin();  o != omap.end(); ++o ) 
+      {
+       if (tmp==true)
+         {
+           labelStr2=labelStr2+" | ";
+         }
+       tmp=true;
+       if (instanceOrtype==true)
+         {
+           valueStr = this->bbGetOutputAsString(o->second->GetName()/*
+                                                                  ,factory*/) + " = ";
+         } 
+       labelStr2=labelStr2+"<"+o->second->GetName().c_str()+"> " + valueStr + o->second->GetName().c_str();
+      }
+
+    labelStr2 = labelStr2+ " } }";
+
+
+
+    if (detail==1)
+      {
+       labelStr1 = labelStr1 + labelStr2;
+      }
+
+    if (tmp){
+      fprintf(ff,"  " );
+      bbWriteDotInputOutputName(ff,false,detail,level);
+      fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
+    }
+
+
+    // label Entrada
+    labelStr1 = boxname + "\\n(input)" ; 
+    labelStr2 = " | {{ "; 
+    tmp=false;
+    InputConnectorMapType::iterator ii;
+
+    const BlackBoxDescriptor::InputDescriptorMapType& imap = this->bbGetDescriptor()->GetInputDescriptorMap(); 
+    BlackBoxDescriptor::InputDescriptorMapType::const_iterator iii;
+    for ( iii = imap.begin();  iii != imap.end(); ++iii ) 
+      {
+       if (tmp==true)
+         {
+           labelStr2=labelStr2+" | ";
+         }
+       tmp=true;
+       if (instanceOrtype==true)
+         {
+           valueStr = this->bbGetInputAsString(iii->second->GetName()/*,factory*/) + " = ";
+         } 
+       labelStr2=labelStr2+"<"+iii->second->GetName().c_str()+"> " + valueStr + iii->second->GetName().c_str();
+      }
+
+
+    labelStr2 = labelStr2+ " } }";
+    if (detail==1)
+      {
+       labelStr1 = labelStr1 + labelStr2;
+      }
+    if (tmp){
+      fprintf(ff,"  " );
+      bbWriteDotInputOutputName(ff,true,detail,level);
+      fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
+    }
+
+
+    // Body
+    BlackBoxMapType::iterator j;
+    for ( j = mBlackBoxMap.begin(); j != mBlackBoxMap.end(); ++j ) 
+      {
+       if (level>-1)
+         {
+           j->second->bbWriteDotFileBlackBox(ff,parentblackbox,detail,
+                                             level-1,
+                                             instanceOrtype,
+                                             relative_link);
+         }
+      }
+
+    fprintf( ff , "}\n\n");
+
+    fprintf( ff , "  edge[color=blue]%s\n",";");
+
+    if (level>-1)
+      {
+       // Relation Input  with the inside BlackBox of the this ComplexBlackbox
+       ComplexBlackBoxDescriptor::InputDescriptorMapType::iterator xx;
+       ComplexBlackBoxDescriptor::InputDescriptorMapType idmt=bbGetDescriptor()->GetInputDescriptorMap();
+       for ( xx = idmt.begin(); xx != idmt.end(); ++xx ) 
+         {
+           ComplexBlackBoxInputDescriptor *cbbid = (ComplexBlackBoxInputDescriptor*)xx->second;
+
+           fprintf(ff,"  ");
+           bbWriteDotInputOutputName(ff,true,detail,level);
+           if (detail==1)
+             {
+               fprintf(ff,":%s",cbbid->GetName().c_str() );
+             }
+           fprintf(ff,"->" );
+           BlackBox *bb = bbGetBlackBox( cbbid->GetTarget() ); 
+           bb->bbWriteDotInputOutputName(ff,true,detail,level);
+           if (detail==1)
+             {
+               fprintf(ff,":%s \n", cbbid->GetInput().c_str() );
+             }
+         }// for xx
+
+
+
+       fprintf(ff,"\n \n");
+
+
+
+       // Relation Output ComplexBlackBox
+       ComplexBlackBoxDescriptor::OutputDescriptorMapType::iterator yy;
+       ComplexBlackBoxDescriptor::OutputDescriptorMapType odmt=bbGetDescriptor()->GetOutputDescriptorMap();
+       for ( yy = odmt.begin(); yy != odmt.end(); ++yy ) 
+         {
+           ComplexBlackBoxOutputDescriptor *cbbod = (ComplexBlackBoxOutputDescriptor*)yy->second;
+           fprintf(ff,"  ");
+           BlackBox *bb = bbGetBlackBox( cbbod->GetTarget() ); 
+           bb->bbWriteDotInputOutputName(ff,false,detail,level);
+           if (detail==1)
+             {
+               fprintf(ff,":%s", cbbod->GetOutput().c_str() );
+             }
+           fprintf(ff,"->" );
+           bbWriteDotInputOutputName(ff,false,detail,level);
+           if (detail==1)
+             {
+               fprintf(ff,":%s",cbbod->GetName().c_str() );
+             }
+           fprintf(ff,"\n");
+         } // for yy
+
+      } // if level
+
+
+
+       // Relation from the out side of this ComplexBlackBox with its Inputs
+    if (this!=parentblackbox) {
+      for ( ii = bbGetInputConnectorMap().begin(); 
+           ii != bbGetInputConnectorMap().end(); ++ii ) 
+       {
+         if (ii->second)
+           {
+             Connection* con = ii->second->GetConnection();
+             if (con!=NULL){
+               BlackBox *a=con->GetBlackBoxFrom();
+               BlackBox *b=con->GetBlackBoxTo();
+               fprintf(ff,"  ");
+               a->bbWriteDotInputOutputName(ff,false,detail,level);
+               if (detail==1)
+                 {
+                   fprintf(ff,":%s",con->GetBlackBoxFromOutput().c_str());
+                 }
+               fprintf(ff,"->");
+               b->bbWriteDotInputOutputName(ff,true,detail,level);
+               if (detail==1)
+                 {
+                   fprintf(ff,":%s",con->GetBlackBoxToInput().c_str());
+                 }
+               fprintf(ff,"%s\n",";");
+             } // if con
+           } // if second
+       } // for
+    } // if parentblackbox
+
+  }
+  //=========================================================================
+
+  /*
+
+
+  //=======================================================================
+  /// Generates the list of the packages of which its depends 
+  /// (cause an internal box belongs to it)
+  void ComplexBlackBox::GetPackagesDependencies(std::vector<Package*>& deps)
+  {
+    deps.clear;
+    BlackBoxMapType::iterator i;
+    for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
+      {
+       deps.push_back(i->second->bbGetDescriptor()->GetPackage());
+      }
+
+  }
+  //=======================================================================
+  */
+}
diff --git a/kernel/src/bbtkComplexBlackBox.h b/kernel/src/bbtkComplexBlackBox.h
new file mode 100644 (file)
index 0000000..ae8a82a
--- /dev/null
@@ -0,0 +1,178 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkComplexBlackBox.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief class bbtk::ComplexBlackBox : user defined complex black boxes
+ */
+
+/**
+ *  \class bbtk::ComplexBlackBox
+ *  \brief Abstract user defined black boxes
+ */
+#ifndef __bbtkComplexBlackBox_h__
+#define __bbtkComplexBlackBox_h__
+
+#include "bbtkBlackBox.h"
+#include "bbtkComplexBlackBoxDescriptor.h"
+//#include "bbtkComplexBlackBoxInputDescriptor.h"
+//#include "bbtkComplexBlackBoxOutputDescriptor.h"
+#include <list>
+
+namespace bbtk
+{
+
+
+  //==================================================================
+  class BBTK_EXPORT ComplexBlackBox : public bbtk::BlackBox
+  {
+    friend class ComplexBlackBoxDescriptor;
+  public: 
+    //==================================================================
+    // PUBLIC PART : ACCESSIBLE TO THE END-USER
+    /// Returns the pointer on the box' descriptor
+    BlackBoxDescriptor* bbGetDescriptor() const { return mDescriptor; }
+    /// Returns a pointer on a clone of the box with name <name>
+    BlackBox* bbClone(const std::string& name);
+
+    void bbExecute(bool force = false);
+  
+    Data bbGetOutput( const std::string &label );
+    Data bbGetInput ( const std::string &label );
+    void bbSetOutput( const std::string &name, Data data);
+    void bbSetInput ( const std::string &name, Data data,
+                     bool setModified = true);
+    void bbBruteForceSetInputPointer( const std::string &name, 
+                                     void* data, 
+                                     bool setModified = true);
+
+    ~ComplexBlackBox();
+
+    BlackBox* bbGetBlackBox( const std::string& name );
+
+    const std::map<std::string, BlackBox*>& bbGetBlackBoxMap() 
+    { 
+      return mBlackBoxMap;
+    }
+
+    void bbPrintBlackBoxes();
+
+    /// Generates a png image representing the pipeline graph of the 
+    /// complex box and writes html code to insert it 
+    /// into the output file stream. 
+    /// detail : 
+    /// level : depth of nested complex boxes graph development 
+    /// (0:only this box level 
+    /// output_dir is the directory in which to write the files 
+    void bbInsertHTMLGraph(  std::ofstream& s, 
+                            int detail, 
+                            int level,
+                            bool instanceOrtype,
+                            const std::string& output_dir,
+                            bool relative_link );
+
+    /// Writes Graphviz-dot description in file.
+    /// Generates own description and recursively calls itself 
+    /// on internal boxes with level-1 
+    virtual void bbWriteDotFileBlackBox(FILE *ff,
+                                       BlackBox *parentblackbox, 
+                                       int detail, int level,
+                                       bool instanceOrtype,
+                                       bool relative_link );
+    
+    virtual void bbWriteDotInputOutputName(FILE *ff,
+                                          bool inputoutput, 
+                                          int detail, int level);
+    
+    virtual BlackBox *bbFindBlackBox(const std::string &blackboxname);
+    
+
+
+  protected:
+    //==================================================================
+    // PROTECTED PART : ACCESSIBLE TO ComplexBlackBoxDescriptor
+    ///  Constructor that takes the ComplexBlackBox name
+    ComplexBlackBox(const std::string &name, ComplexBlackBoxDescriptor* desc);
+    /// Constructor from an existing box (copy) with a new name 
+    ComplexBlackBox(ComplexBlackBox& from, const std::string &name);
+
+    
+  public:
+    IOStatus bbBackwardUpdate(Connection* caller);
+    //  void bbForwardUpdate(Connection* caller);
+    void bbSetModifiedStatus(BlackBoxInputConnector* c);
+
+  protected:
+  
+
+
+    void bbAddBlackBox( BlackBox* );
+    void bbAddToExecutionList( const std::string& name );
+    void bbUnsafeAddBlackBox( BlackBox* );
+    void bbRemoveBlackBox( const std::string& name );
+    void bbAddConnection( Connection* );
+    
+    //    void RemoveConnection( );
+
+    BlackBox* bbUnsafeGetBlackBox( const std::string& name );
+
+    /// 
+    void bbAllocateConnectors();
+    void bbDesallocateConnectors();
+
+  private:
+    //==================================================================
+    // PRIVATE PART : MEMBERS AND USEFULL INTERNAL METHODS
+
+    /// Default constructor : derived classes must use the constructor with the ComplexBlackBox's name
+    ComplexBlackBox() : BlackBox("") {}
+    
+    /// The descriptor pointer
+    ComplexBlackBoxDescriptor* mDescriptor;
+    
+    /// The type of map of black boxes
+    typedef std::map<std::string, BlackBox*> BlackBoxMapType;
+    /// The map of black boxes
+    BlackBoxMapType mBlackBoxMap;
+    
+    
+    /// The type of list of connections
+    typedef std::list<Connection*> ConnectionListType;
+    /// The list of connections
+    ConnectionListType mConnectionList;
+
+/// The execution list
+    std::vector<std::string> mExecutionList;
+    
+  };
+  // Class ComplexBlackBox
+  //===========================================================================
+
+
+
+}
+// namespace bbtk
+
+
+//#include "bbtkComplexBlackBoxMacros.h"
+
+#endif
+
diff --git a/kernel/src/bbtkComplexBlackBoxDescriptor.cxx b/kernel/src/bbtkComplexBlackBoxDescriptor.cxx
new file mode 100644 (file)
index 0000000..4d6b6e8
--- /dev/null
@@ -0,0 +1,507 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkComplexBlackBoxDescriptor.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::ComplexBlackBoxDescriptor : describes a ComplexBlackBox (constituents, connections) and is able to create an instance of it.
+ */
+#include "bbtkComplexBlackBoxDescriptor.h"
+#include "bbtkComplexBlackBox.h"
+//#include "bbtkFactory.h"
+#include "bbtkMessageManager.h"
+#include "bbtkUtilities.h"
+
+namespace bbtk
+{
+  
+
+  //=======================================================================
+  /// Default ctor
+  ComplexBlackBoxDescriptor::ComplexBlackBoxDescriptor(const std::string& name)
+    : BlackBoxDescriptor()
+  {
+    bbtkDebugMessageInc("Core",9,"ComplexBlackBoxDescriptor::ComplexBlackBoxDescriptor(\""<<name<<"\")"<<std::endl);
+    SetTypeName(name);
+    mPrototype = new ComplexBlackBox(name+std::string("Prototype"),this);
+    bbtkDebugDecTab("Core",9);
+  }
+  //=======================================================================
+
+
+
+  //=======================================================================
+  /// Default dtor
+  ComplexBlackBoxDescriptor::~ComplexBlackBoxDescriptor()
+  {
+    bbtkDebugMessageInc("Core",9,"ComplexBlackBoxDescriptor::~ComplexBlackBoxDescriptor(\""<<GetTypeName()<<"\")"<<std::endl);
+
+    delete mPrototype;
+
+    bbtkDebugDecTab("Core",9);
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /// Creates an instance of name <name> of the ComplexBlackBox of which this is the descriptor 
+  BlackBox* ComplexBlackBoxDescriptor::CreateInstance(const std::string& name)
+  {
+    //bbtkError("ComplexBlackBoxDescriptor::CreateInstance not implemented");
+    bbtkDebugMessageInc("Core",5,
+                       "ComplexBlackBoxDescriptor::CreateInstance(\""
+                       <<name<<"\") ["
+                       <<GetTypeName()<<"]"<<std::endl);
+    
+    return mPrototype->bbClone(name);
+
+    bbtkDebugDecTab("Core",5);
+  }
+  //=======================================================================
+
+
+
+  //=======================================================================
+  /// Adds a black box to the complex box
+  void ComplexBlackBoxDescriptor::Add ( const std::string& type,
+                                       const std::string& name
+                                       )
+  {
+    bbtkDebugMessageInc("Core",5,
+                       "ComplexBlackBoxDescriptor::Add(\""
+                       <<type<<"\",\""<<name<<"\") ["
+                       <<GetTypeName()<<"]"<<std::endl);
+    
+    
+    // Verify that a box with the same name does not exist already
+    if ( mPrototype->bbUnsafeGetBlackBox( name ) ) 
+      {
+       bbtkError("a black box \""<<name<<"\" already exists");
+      }
+    // ok : create new one
+    mPrototype->bbAddBlackBox ( /*mFactory->Create*/ NewBlackBox(type,name) );
+
+    bbtkDebugDecTab("Core",5);
+  }
+  //=======================================================================
+
+ //=======================================================================
+  /// Adds a black box to the execution list 
+  void ComplexBlackBoxDescriptor::AddToExecutionList ( const std::string& box)
+  {
+    bbtkDebugMessageInc("Core",5,
+                       "ComplexBlackBoxDescriptor::AddToExecutionList(\""
+                       <<box<<"\" ["
+                       <<GetTypeName()<<"]"<<std::endl);
+    // Verify that the box exists
+    BlackBox* b = mPrototype->bbUnsafeGetBlackBox( box ); 
+    if ( !b ) 
+      {
+       bbtkError("the black box \""<<box<<"\" does not exist");
+      }
+    // ok 
+    mPrototype->bbAddToExecutionList ( box  );
+
+    bbtkDebugDecTab("Core",5);
+    }
+
+
+  //=======================================================================
+  /// Connects two black boxes of the complex box
+  void ComplexBlackBoxDescriptor::Connect ( const std::string& from,
+                                           const std::string& output,
+                                           const std::string& to,
+                                           const std::string& input
+                                           )
+  {
+    bbtkDebugMessageInc("Core",5,
+                       "ComplexBlackBoxDescriptor::Connect(\""
+                       <<from<<"\",\""<<output<<"\",\""
+                       <<to<<"\",\""<<input
+                       <<"\") ["
+                       <<GetTypeName()<<"]"<<std::endl);
+  // Verify that a box with the same name does not exist already
+    BlackBox* bbfrom = mPrototype->bbGetBlackBox( from );
+    if ( !bbfrom ) 
+      {
+       bbtkError("the black box \""<<from<<"\" does not exist");
+      }
+    BlackBox* bbto = mPrototype->bbGetBlackBox( to );
+    if ( !bbto ) 
+      {
+       bbtkError("the black box \""<<to<<"\" does not exist");
+      }
+    
+    Connection* c = /*mFactory->*/ NewConnection( bbfrom, output, bbto, input );
+
+    mPrototype->bbAddConnection(c);
+
+    bbtkDebugDecTab("Core",5);
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /// Defines an input of the complex box
+  void ComplexBlackBoxDescriptor::DefineInput ( const std::string& name,
+                                               const std::string& box,
+                                               const std::string& input,
+                                               const std::string& help)
+  {
+    bbtkDebugMessageInc("Core",5,
+                       "ComplexBlackBoxDescriptor::DefineInput(\""
+                       <<name<<"\",\""<<box<<"\",\""
+                       <<input<<"\",\""<<help
+                       <<"\") ["
+                       <<GetTypeName()<<"]"<<std::endl);
+
+    BlackBox* bb = mPrototype->bbGetBlackBox( box );
+    if ( !bb ) 
+      {
+       bbtkError("the black box \""<<box<<"\" does not exist");
+      }
+
+    if (!bb->bbHasInput(input) )
+      {
+       bbtkError("the black box \""<<box<<"\" does not have input \""
+                 <<input<<"\"");
+      }
+    
+    AddInputDescriptor ( new ComplexBlackBoxInputDescriptor ( name,
+                                                             help,
+                                                             box,
+                                                             input,
+                                                             bb->bbGetInputType(input)));
+                                                            
+    
+    bbtkDebugDecTab("Core",5);
+  }
+  //=======================================================================
+
+  //=======================================================================
+  /// Defines an output of the complex box
+  void ComplexBlackBoxDescriptor::DefineOutput ( const std::string& name,
+                                                const std::string& box,
+                                                const std::string& output,
+                                                const std::string& help)
+  {
+    bbtkDebugMessageInc("Core",5,
+                       "ComplexBlackBoxDescriptor::DefineOutput(\""
+                       <<name<<"\",\""<<box<<"\",\""
+                       <<output<<"\",\""<<help
+                       <<"\") ["
+                       <<GetTypeName()<<"]"<<std::endl);
+
+    BlackBox* bb = mPrototype->bbGetBlackBox( box );
+    if ( !bb ) 
+      {
+       bbtkError("the black box \""<<box<<"\" does not exist");
+      }
+
+    if (!bb->bbHasOutput(output) )
+      {
+       bbtkError("the black box \""<<box<<"\" does not have output \""
+                 <<output<<"\"");
+      }
+    
+    AddOutputDescriptor ( new ComplexBlackBoxOutputDescriptor 
+                         ( name,
+                           help,
+                           box,
+                           output,
+                           bb->bbGetOutputType(output)));
+    
+    
+    bbtkDebugDecTab("Core",5);
+  }
+  //=======================================================================
+
+  //=======================================================================
+  void ComplexBlackBoxDescriptor::PrintBlackBoxes()
+  {
+    mPrototype->bbPrintBlackBoxes(); 
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  void ComplexBlackBoxDescriptor::InsertHTMLGraph( std::ofstream& s , 
+                                                  int detail, int level, 
+                                                  const std::string& output_dir, bool relative_link )   
+  {
+    this->mPrototype->bbInsertHTMLGraph( s, 
+                                        detail, level, 
+                                        false, 
+                                        output_dir,
+                                        relative_link );
+  }
+  //=======================================================================
+
+  //=========================================================================
+  void ComplexBlackBoxDescriptor::InsertHtmlHelp ( std::ofstream& s, 
+                                                  int detail, int level,
+                                                  const std::string& output_dir, bool relative_link)
+  {
+    bbtkDebugMessageInc("Core",9,
+                       "ComplexBlackBoxDescriptor::InsertHtmlHelp() ["
+                       <<GetTypeName()<<"]"<<std::endl);
+    
+    //-------------
+    // General info 
+    std::string name = GetTypeName();
+    Utilities::html_format(name);
+
+    //   std::ofstream* s = &s1;
+
+    (s) << "<p><hr>\n";
+    (s) << "<a name=\""<<name<<"\"></a>\n";
+    (s) << //"Top:&nbsp;
+      "<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
+    // (s) << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
+    // (s) << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
+    (s) << "<h2 class=\"section\">"<<name<<"</h2>\n";
+
+
+    std::string descr = GetDescription();
+    //Utilities::html_format(descr);
+    std::string author = GetAuthor();
+    Utilities::html_format(author);
+    
+    (s) << "<p><TABLE cellspacing=0  cellpadding=3>\n";
+    (s) << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
+      << descr << "</TD></TR>\n";
+    (s) << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
+      << author << "</TD></TR>\n";
+     
+    std::string inc = GetScriptFileName();
+    if (inc.size()>0) 
+      {
+    (s) << "<TR><TD style='vertical-align: top;'><b> Include </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
+      << inc << "</TD></TR>\n";
+       
+      }
+    
+    const ComplexBlackBox::BlackBoxMapType& B = mPrototype->bbGetBlackBoxMap();
+       
+    if (B.size()) 
+      {
+       (s) << "<TR><TD style='vertical-align: top;'><b> Dependencies </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  ";
+
+
+       std::set<BlackBoxDescriptor*> pdeps;
+       ComplexBlackBox::BlackBoxMapType::const_iterator b;
+       for ( b = B.begin(); b != B.end(); ++b ) 
+         {
+           BlackBoxDescriptor* d = b->second->bbGetDescriptor();
+           if (pdeps.find(d) != pdeps.end()) continue;
+           pdeps.insert(d);
+
+           Package* p = d->GetPackage();
+           
+           std::string name = b->second->bbGetTypeName();
+
+           std::string url;
+           if (relative_link) 
+             url = p->GetDocRelativeURL();
+           else 
+             url = p->GetDocURL();
+
+           s << "<a href=\"" <<url<<"#"<<name<<"\">" 
+             << p->GetName()<<"::"<<name<<"</a>\n";
+         }     
+       
+       (s) << "</TD></TR>\n";
+
+      }
+
+    (s) << "</TABLE>\n";
+
+   //-------------
+    // Graph
+    InsertHTMLGraph( s , detail,level, output_dir, relative_link);
+    
+    //-------------
+    // Inputs
+    std::string col("#CCCCFF");
+    
+    // (s) << "<h3 class=\"subsection\">Inputs</h3>\n";
+    (s) << "<p><TABLE border=1 cellspacing=0 cellpadding=3>\n";
+    (s) << "<TR><TD colspan=3 align=center bgcolor=\""<<col
+      <<"\">Inputs</TD></TR>\n";
+    const BlackBoxDescriptor::InputDescriptorMapType& imap = 
+      GetInputDescriptorMap();
+    
+    InputDescriptorMapType::const_iterator in;
+    
+    for ( in = imap.begin();  in != imap.end(); ++in ) 
+      {
+       std::string name(in->second->GetName());
+       Utilities::html_format(name);
+       
+       std::string type("<");
+       type += in->second->GetTypeName();    
+       type += ">";
+       Utilities::html_format(type);
+       
+       std::string descr(in->second->GetDescription());
+       //Utilities::html_format(descr);
+
+       (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
+         << "<TD style='vertical-align: top;'><I><PRE> "<<type<<" </PRE></I></TD>"
+         << "<TD style='vertical-align: top;'>"<<descr<<"</TD></TR>\n";
+       
+      }
+    // (s) << "</TABLE>\n";
+    
+    
+    //-------------
+    // Outputs
+    // (s) << "<h3 class=\"subsection\">Outputs</h3>\n";
+    // (s) << "<TABLE border=1 cellspacing=0>\n";
+    (s) << "<TR><TD colspan=3 align=center bgcolor=\""<<col
+      <<"\">Outputs</TD></TR>\n";
+    
+    const BlackBoxDescriptor::OutputDescriptorMapType& omap = 
+      GetOutputDescriptorMap();
+    
+    BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
+    
+    for ( o = omap.begin();  o != omap.end(); ++o ) 
+      {
+       std::string name(o->second->GetName());
+       Utilities::html_format(name);
+       
+       std::string type("<");
+       type += o->second->GetTypeName();    
+       type += ">";
+       Utilities::html_format(type);
+       
+       std::string descr(o->second->GetDescription());
+       //Utilities::html_format(descr);
+       
+       
+       (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
+         << "<TD style='vertical-align: top;'><I><PRE> "<<type<<" </PRE></I></TD>"
+         << "<TD style='vertical-align: top;'>"<<descr<<"</TD></TR>\n";
+       
+      }
+    (s) << "</TABLE>\n";
+
+    //------------
+    // End
+
+    bbtkDebugDecTab("Core",9);
+   }
+  //=========================================================================
+
+  //=======================================================================
+  void ComplexBlackBoxDescriptor::GetHelp(bool full) const
+  {
+    if (full) bbtkMessage("Help",1,"Complex Black Box <"<<
+                         GetPackage()->GetName()<<"::"
+                         <<GetTypeName()<<">"<<std::endl);
+    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
+    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
+    if (mInput.size()) 
+      bbtkMessage("Help",1," * Inputs : "<<std::endl);
+    else 
+      bbtkMessage("Help",1," * No inputs"<<std::endl);
+    InputDescriptorMapType::const_iterator i;
+    unsigned int namelmax = 0;
+    unsigned int typelmax = 0;
+    for ( i = mInput.begin();  i != mInput.end(); ++i ) 
+      {
+       if (i->second->GetName().size()>namelmax) 
+         namelmax = i->second->GetName().size();
+       if (i->second->GetTypeName().size()>typelmax) 
+         typelmax = i->second->GetTypeName().size();
+      }
+    OutputDescriptorMapType::const_iterator o;
+    if (full) 
+      {
+       for ( o = mOutput.begin();  o != mOutput.end(); ++o ) 
+         {
+           if (o->second->GetName().size()>namelmax) 
+             namelmax = o->second->GetName().size();
+           if (o->second->GetTypeName().size()>typelmax) 
+             typelmax = o->second->GetTypeName().size();
+         }
+      }
+    //
+
+    for ( i = mInput.begin();  i != mInput.end(); ++i ) 
+      {
+       std::string name(i->second->GetName());
+       name += "'";
+       name.append(1+namelmax-name.size(),' ');
+       std::string type(i->second->GetTypeName());
+       type += ">";
+       type.append(1+typelmax-type.size(),' ');
+       bbtkMessage("Help",1,
+                   "    '"<<name
+                   <<" <"<<type
+                   <<" : "<<i->second->GetDescription()<<std::endl);
+      }
+    if (full) 
+      {
+       if (mOutput.size()) 
+         bbtkMessage("Help",1," * Outputs : "<<std::endl);
+       else 
+         bbtkMessage("Help",1," * No outputs"<<std::endl);
+       for ( o = mOutput.begin();  o != mOutput.end(); ++o ) 
+         {
+           std::string name(o->second->GetName());
+           name += "'";
+           name.append(1+namelmax-name.size(),' ');
+           std::string type(o->second->GetTypeName());
+           type += ">";
+           type.append(1+typelmax-type.size(),' ');
+           bbtkMessage("Help",1,
+                       "    '"<<name
+                       <<" <"<<type
+                       <<" : "<<o->second->GetDescription()<<std::endl);
+         }
+      }
+    if (full) 
+      {
+       const ComplexBlackBox::BlackBoxMapType& B = mPrototype->bbGetBlackBoxMap();
+       
+       if (B.size()) 
+         bbtkMessage("Help",1," * Boxes : "<<std::endl);
+       else 
+         bbtkMessage("Help",1," * No boxes"<<std::endl);
+       
+       ComplexBlackBox::BlackBoxMapType::const_iterator b;
+       for ( b = B.begin(); b != B.end(); ++b ) 
+         {
+           bbtkMessage("Help",1,"    '"<<b->second->bbGetName()<<
+                       "' <"
+                       << b->second->bbGetDescriptor()->GetPackage()->GetName() 
+                       <<"::"
+                       <<b->second->bbGetTypeName()<<">"<<std::endl);
+         }
+      }
+
+  }   
+  //=======================================================================
+
+
+
+}
diff --git a/kernel/src/bbtkComplexBlackBoxDescriptor.h b/kernel/src/bbtkComplexBlackBoxDescriptor.h
new file mode 100644 (file)
index 0000000..cfa7945
--- /dev/null
@@ -0,0 +1,130 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkComplexBlackBoxDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::ComplexBlackBoxDescriptor : describes a ComplexBlackBox (constituents, connections) and is able to create an instance of it.
+ */
+/**
+ * \class bbtk::ComplexBlackBoxDescriptor
+ * \brief Describes a ComplexBlackBox (constituents, connections) and is able to create an instance of it.
+ */
+
+#ifndef __bbtkComplexBlackBoxDescriptor_h__
+#define __bbtkComplexBlackBoxDescriptor_h__
+
+#include "bbtkBlackBoxDescriptor.h"
+#include "bbtkComplexBlackBoxInputDescriptor.h"
+#include "bbtkComplexBlackBoxOutputDescriptor.h"
+#include "bbtkFactory.h"
+#include <fstream>
+
+namespace bbtk
+{
+
+  class ComplexBlackBox;
+  
+  //==========================================================================
+  class BBTK_EXPORT ComplexBlackBoxDescriptor : public bbtk::BlackBoxDescriptor
+  {
+  public:
+
+    /// Default ctor with name 
+    ComplexBlackBoxDescriptor(const std::string& name); //, Factory* f); 
+    /// Default dtor
+    ~ComplexBlackBoxDescriptor();
+    /// Creates an instance of name <name> of the ComplexBlackBox of which this is the descriptor 
+    virtual BlackBox* CreateInstance(const std::string& name);
+
+    /// Adds a black box to the complex box
+    void Add ( const std::string& type,
+              const std::string& name
+              ); 
+    /// Connects two black boxes of the complex box
+    void Connect ( const std::string& from,
+                  const std::string& output,
+                  const std::string& to,
+                  const std::string& input
+                  ); 
+    /// Defines an input of the complex box
+    void DefineInput ( const std::string& name,
+                      const std::string& box,
+                      const std::string& input,
+                      const std::string& help);
+    /// Defines an output of the complex box
+    void DefineOutput ( const std::string& name,
+                      const std::string& box,
+                      const std::string& output,
+                      const std::string& help);
+    /// Sets the name of the script file from which it is defined
+    void SetScriptFileName(const std::string& n) { mScriptFileName = n; }
+    /// Gets the name of the script file from which it is defined
+    std::string GetScriptFileName() const { return mScriptFileName; }
+   
+    /// 
+    void AddToExecutionList( const std::string& box );
+
+    ComplexBlackBox* GetPrototype() { return mPrototype; }
+    void PrintBlackBoxes(); 
+   
+    /// Prints help on the black box
+    void GetHelp(bool full=true) const;
+    /// Writes html formatted help into the output file stream. 
+    /// detail and level are used for graphical representation of 
+    /// complex black boxes (see ComplexBlackBox::InsertHTMLGraph)
+    /// output_dir is the directory in which to write auxilliary files 
+    /// (.dot/.png/.cmap)
+    void InsertHtmlHelp ( std::ofstream& s, 
+                         int detail, int level,
+                         const std::string& output_dir = "",
+                         bool relative_link = false);
+
+    /// Generates a png image representing the pipeline graph of the 
+    /// complex box and writes html code to insert it 
+    /// into the output file stream. 
+    /// detail : 
+    /// level : depth of nested complex boxes graph development 
+    /// (0:only this box level 
+    /// output_dir is the directory in which to write the files 
+    /// (.dot/.png/.cmap)
+    void InsertHTMLGraph( std::ofstream& s, 
+                         int detail, int level, 
+                         const std::string& output_dir = "",
+                         bool relative_link = false );
+    
+
+
+  private:
+    /// Default ctor is private (must have name and factory)
+    ComplexBlackBoxDescriptor() {}
+    /// The complex box in which boxes and connections are stored
+    ComplexBlackBox* mPrototype;
+    /// The name of the script file from which it was created
+    std::string mScriptFileName;
+    
+  };
+  // class ComplexBlackBoxDescriptor
+  //==========================================================================
+
+
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkComplexBlackBoxInputDescriptor.cxx b/kernel/src/bbtkComplexBlackBoxInputDescriptor.cxx
new file mode 100644 (file)
index 0000000..29d174b
--- /dev/null
@@ -0,0 +1,51 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkComplexBlackBoxInputDescriptor.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::ComplexBlackBoxInputDescriptor : structure containing the description of a ComplexBlackBox input (name, description, type, mapping)
+ */
+#include "bbtkComplexBlackBoxInputDescriptor.h"
+   
+
+namespace bbtk
+{
+
+  
+  ComplexBlackBoxInputDescriptor::ComplexBlackBoxInputDescriptor( const std::string& name,
+                                                                   const std::string& description,
+                                                                   const std::string& target,
+                                                                 const std::string& input,
+TypeInfo type)                 
+    : 
+    BlackBoxInputDescriptor(name,description),
+    mTarget(target),
+    mInput(input),
+    mType(type)
+  {    
+    
+    bbtkDebugMessage("Core",9,"ComplexBlackBoxInputDescriptor::ComplexBlackBoxInputDescriptor(\""<<name<<"\",\""<<description<<"\",\""<<target<<"\",\""<<input<<"\")"<<std::endl);
+  }
+  
+
+  ComplexBlackBoxInputDescriptor::~ComplexBlackBoxInputDescriptor() 
+  {
+    bbtkDebugMessage("Core",9,"ComplexBlackBoxInputDescriptor::~ComplexBlackBoxInputDescriptor(\""<<GetName()<<"\",\""<<GetDescription()<<"\",\""<<GetTarget()<<"\",\""<<GetInput()<<"\")"<<std::endl);
+  }
+  
+}
diff --git a/kernel/src/bbtkComplexBlackBoxInputDescriptor.h b/kernel/src/bbtkComplexBlackBoxInputDescriptor.h
new file mode 100644 (file)
index 0000000..1cd39a1
--- /dev/null
@@ -0,0 +1,76 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkComplexBlackBoxInputDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::ComplexBlackBoxInputDescriptor : structure containing the description of a ComplexBlackBox input (name, description, type, mapping)
+ */
+/**
+ * \class bbtk::ComplexBlackBoxInputDescriptor
+ * \brief Structure containing the description of a ComplexBlackBox input (name, description, type, mapping)
+ */
+
+#ifndef __bbtkComplexBlackBoxInputDescriptor_h__
+#define __bbtkComplexBlackBoxInputDescriptor_h__
+
+#include "bbtkBlackBoxInputDescriptor.h"
+#include "bbtkMessageManager.h"
+
+namespace bbtk
+{
+
+
+  class BBTK_EXPORT ComplexBlackBoxInputDescriptor : public bbtk::BlackBoxInputDescriptor
+  {
+  public:
+      
+    ComplexBlackBoxInputDescriptor( const std::string& name,
+                                   const std::string& description,
+                                   const std::string& target,
+                                   const std::string& input,
+                                   TypeInfo type);
+    
+    ~ComplexBlackBoxInputDescriptor();
+    
+    /// Returns the type of the input
+    TypeInfo GetTypeInfo() const { return mType; }
+    /// Returns the name of the type of the input
+    std::string GetTypeName() const { return TypeName(mType); }
+    /// Returns the name of the type of the input
+    std::string GetHumanTypeName() const { return HumanTypeName(mType); }
+    /// Returns the target black box 
+    const std::string& GetTarget() const { return mTarget; }
+    /// Returns the input 
+    const std::string& GetInput() const { return mInput; }
+    /// 
+    bool IsPointerType() const { return false; }
+    
+    
+  private:
+    /// Default ctor is private 
+    ComplexBlackBoxInputDescriptor() : BlackBoxInputDescriptor("",""),
+                                      mType(typeid(void)) {}
+    std::string mTarget;
+    std::string mInput;
+    TypeInfo mType;
+  };
+
+  
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkComplexBlackBoxOutputDescriptor.cxx b/kernel/src/bbtkComplexBlackBoxOutputDescriptor.cxx
new file mode 100644 (file)
index 0000000..7b2d71f
--- /dev/null
@@ -0,0 +1,54 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkComplexBlackBoxOutputDescriptor.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::ComplexBlackBoxOutputDescriptor : structure containing the description of a ComplexBlackBox output (name, description, type, mapping)
+ */
+#include "bbtkComplexBlackBoxOutputDescriptor.h"
+   
+
+namespace bbtk
+{
+
+
+  ComplexBlackBoxOutputDescriptor::ComplexBlackBoxOutputDescriptor( const std::string& name,
+                                                                   const std::string& description,
+                                                                   const std::string& target,
+                                                                   const std::string& output,
+                                                                   TypeInfo type)                      
+    : 
+    BlackBoxOutputDescriptor(name,description),
+    mTarget(target),
+    mOutput(output),
+    mType(type)
+  {    
+    
+    bbtkDebugMessage("Core",9,"ComplexBlackBoxOutputDescriptor::ComplexBlackBoxOutputDescriptor(\""<<name<<"\",\""<<description<<"\",\""<<target<<"\",\""<<output<<"\")"<<std::endl);
+  }
+  
+
+
+
+
+  ComplexBlackBoxOutputDescriptor::~ComplexBlackBoxOutputDescriptor() 
+  {
+    bbtkDebugMessage("Core",9,"ComplexBlackBoxOutputDescriptor::~ComplexBlackBoxOutputDescriptor(\""<<GetName()<<"\",\""<<GetDescription()<<"\",\""<<GetTarget()<<"\",\""<<GetOutput()<<"\")"<<std::endl);
+  }
+  
+}
diff --git a/kernel/src/bbtkComplexBlackBoxOutputDescriptor.h b/kernel/src/bbtkComplexBlackBoxOutputDescriptor.h
new file mode 100644 (file)
index 0000000..dff0204
--- /dev/null
@@ -0,0 +1,77 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkComplexBlackBoxOutputDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::ComplexBlackBoxOutputDescriptor : structure containing the description of a ComplexBlackBox output (name, description, type, mapping)
+ */
+/**
+ * \class bbtk::ComplexBlackBoxOutputDescriptor
+ * \brief Structure containing the description of a ComplexBlackBox output (name, description, type, mapping)
+ */
+
+#ifndef __bbtkComplexBlackBoxOutputDescriptor_h__
+#define __bbtkComplexBlackBoxOutputDescriptor_h__
+
+#include "bbtkBlackBoxOutputDescriptor.h"
+#include "bbtkMessageManager.h"
+//#include "bbtkSystem.h"
+
+namespace bbtk
+{
+
+
+  class BBTK_EXPORT ComplexBlackBoxOutputDescriptor : public bbtk::BlackBoxOutputDescriptor
+  {
+  public:
+      
+    ComplexBlackBoxOutputDescriptor( const std::string& name,
+                                    const std::string& description,
+                                    const std::string& target,
+                                    const std::string& output,
+                                    TypeInfo type);
+    
+    ~ComplexBlackBoxOutputDescriptor();
+    
+    /// Returns the type of the output
+    TypeInfo GetTypeInfo() const { return mType; }
+    /// Returns the name of the type of the output    
+    std::string GetTypeName() const { return TypeName(mType); }
+    /// Returns the name of the type of the output    
+    std::string GetHumanTypeName() const { return HumanTypeName(mType); }
+    /// 
+    bool IsPointerType() const { return false; }
+    
+
+    /// Returns the target black box 
+    const std::string& GetTarget() const { return mTarget; }
+    /// Returns the output 
+    const std::string& GetOutput() const { return mOutput; }
+        
+  private:
+    /// Default ctor is private 
+    ComplexBlackBoxOutputDescriptor() : 
+      BlackBoxOutputDescriptor("",""), mType(typeid(void))  {}
+    std::string mTarget;
+    std::string mOutput;
+    TypeInfo mType;
+  };
+
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkConfigurationFile.cxx b/kernel/src/bbtkConfigurationFile.cxx
new file mode 100644 (file)
index 0000000..b15e061
--- /dev/null
@@ -0,0 +1,420 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkConfigurationFile.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+/**
+ *\file
+ *\brief Class bbtk::ConfigurationFile
+ */
+
+#include "bbtkConfigurationFile.h"
+#include "bbtkMessageManager.h"
+//#include "xmlParser.h"
+#include <sys/stat.h> // for struct stat stFileInfo
+
+#if defined(WIN32)
+#include <direct.h> // for getcwd
+#endif
+
+namespace bbtk
+{
+/// Constructor
+ConfigurationFile::ConfigurationFile()
+{
+   char *execPath = GetExecutablePath();
+
+ #if defined(WIN32)
+   std::string slash("\\");
+ #else
+   std::string slash("/");
+ #endif
+// ==> First we look for bbtk_config.xml in "."
+
+   char buf[2048];
+   const char *currentDir = getcwd(buf, 2048);
+     
+   if( !currentDir )
+   {
+      std::cerr << "Path was too long to fit on 2048 bytes ?!?" << std::endl;
+      /// \todo : what else?
+      // How abort a constructor and warn the caller function?
+   }
+
+   std::string configXmlFullPathName = currentDir + slash + "bbtk_config.xml";
+
+   if ( FileExists( configXmlFullPathName ))
+   {
+      bbtkMessage("Config",1, "ConfigurationFile : [" << configXmlFullPathName << 
+            "] found in current directory" << std::endl); 
+      //Read(configXmlFullPathName.c_str());
+      // traiter le fichier local     
+   }
+
+// ==> Then we look for bbtk_config.xml in ".bbtk"
+   else 
+   {
+   #if defined(__GNUC__)
+      std::string str_home(getenv("HOME"));
+   #elif defined(_WIN32)
+      std::string str_home(getenv("USERPROFILE"));
+   #endif
+      configXmlFullPathName = str_home + slash + ".bbtk/bbtk_config.xml";
+      if (!FileExists( configXmlFullPathName ))
+      {         
+         // ==> Nothing found, we create bbtk_config.xml in ".bbtk"
+         InstallPath ();
+      }
+   }
+
+// In any case, deal with bbtk_config.xml!
+   Read(configXmlFullPathName.c_str());
+}
+
+/// Destructor
+ConfigurationFile::~ConfigurationFile()
+{
+}
+
+// See : http://www.techbytes.ca/techbyte103.html for more O.S.
+bool ConfigurationFile::FileExists(std::string strFilename) {
+  struct stat stFileInfo;
+  bool blnReturn;
+  int intStat;
+
+  // Attempt to get the file attributes
+  intStat = stat(strFilename.c_str(),&stFileInfo);
+  if(intStat == 0) {
+    // We were able to get the file attributes
+    // so the file obviously exists.
+    blnReturn = true;
+  } else {
+    // We were not able to get the file attributes.
+    // This may mean that we don't have permission to
+    // access the folder which contains this file. If you
+    // need to do that level of checking, lookup the
+    // return values of stat which will give you
+    // more details on why stat failed.
+    blnReturn = false;
+  }
+
+  return(blnReturn);
+}
+
+
+void ConfigurationFile::CreateConfigXML( char *rootDirectory )
+{
+   FILE *fp;
+   char configXml[250];
+   sprintf (configXml , "%s/bbtk_config.xml", rootDirectory);
+   bbtkMessage("Config",1, "in CreateConfigXML[" << configXml << "]" << std::endl);
+   fp = fopen (configXml, "w");
+   fprintf(fp, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
+   fprintf(fp, "<!DOCTYPE config SYSTEM \"/mnt/windows/bbtk/bbtk_config.xml>\n");
+   fprintf(fp, "<config>\n");
+   fprintf(fp, "   <description>  </description>\n");
+   fprintf(fp, "   <url>  http://www.creatis.insa-lyon.fr/software/bbtk  </url>\n");
+   fprintf(fp, "   <install_path> </install_path>\n");
+   fprintf(fp, "   <bbs_path>     </bbs_path>\n");
+  // fprintf(fp, "   <ext_dll_path> </ext_dll_path>\n");
+   fprintf(fp, "   <package_path> </package_path>\n");
+   fprintf(fp, "   <data_path> %s </data_path>\n", BBTK_DATA_PATH);
+   /// \todo find a decent default value !
+   ///fprintf(fp, "   <default_doc_tmp>  %s </default_doc_tmp>\n", " ");
+   // when $ will be found, default_doc_tmp value will be replaced
+   fprintf(fp, "   <default_doc_tmp>$</default_doc_tmp>\n");
+   fprintf(fp, "</config>\n");
+   fclose(fp);
+}
+
+char *ConfigurationFile::GetExecutablePath()
+{
+    /// \todo : Think to delete it!
+    char *buf = (char *)malloc(512);
+    char *slash;
+
+#if defined(WIN32)
+    GetModuleFileName(NULL, buf, 511);
+    slash = strrchr(buf, '\\');
+    if (slash)
+    {
+        *slash = 0;
+    }
+#elif defined(__GNUC__)
+    int res;
+    res = readlink("/proc/self/exe", buf, 512);
+    if (res == -1)
+        return "";
+    buf[res] = 0;
+    slash = strrchr(buf, '/');
+    if (slash)
+    {
+        *slash = 0;
+    }
+#else
+    return "";
+#endif
+
+    return buf;
+}
+
+
+
+void ConfigurationFile::InstallPath ()
+{
+
+/*--------------------------------------------------
+New policy for bbtk_config.xml :
+
+if bbtk_config.xml found in current directory (user is an aware user!)
+   use it!
+   
+else if bbtk_config.xml found in HOME/.bbtk (user already worked with it)
+   use it!
+   
+else if bbtk_config.xml.tmp found in /usr/local/bin or c:\\Program Files\\BBTK\\bin
+   copy it as .bbtk/bbtk_config.xml
+   
+else (nothing installed)
+   create a minimum version in HOME/.bbtk
+----------------------------------------------------*/
+
+
+// -----------------------------------------------------------------
+#if defined(__GNUC__)
+
+// ------------------ create some usefull strings ----------------
+// installed bbtk_path
+  char bbtk_path[100];
+  strcpy(bbtk_path, "/usr/local/bin");
+       
+// rootDirectory
+  char rootDirectory[200];
+  sprintf( rootDirectory,  "%s/.bbtk", getenv("HOME"));
+      
+// configPath
+  char configPath[200];
+  sprintf(configPath, "%s/bbtk_config.xml",rootDirectory);
+  
+// makeDir
+  char makeDir[250];
+  sprintf( makeDir, "mkdir \"%s\" ", rootDirectory);
+
+// configXmlTmp
+  char configXmlTmp[250]; 
+  sprintf(configXmlTmp, "%s/bbtk_config.xml.tmp", bbtk_path);
+
+// copyFile
+  char copyFile[250];
+
+  if (!FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found (not installed)
+  {  
+     if (!FileExists(rootDirectory)) // .bbtk not found
+     {
+       system(makeDir);  // create .bbtk
+     }
+
+     // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk
+     CreateConfigXML( rootDirectory );// create .bbtk
+  }
+  else
+  {
+     sprintf(copyFile,"cp %s  %s/bbtk_config.xml ",configXmlTmp,rootDirectory );
+     if (!FileExists(rootDirectory))
+     {
+       //std::cout << "makeDir[" << makeDir << "]" << std::endl;
+       system(makeDir);
+     }
+
+     if (!FileExists(configPath))
+     {
+       system(copyFile);
+     }
+  }
+  return;
+   
+// ------------------------------------------------------------------
+#elif defined(WIN32)
+
+
+// installed bbtk_path
+  char bbtk_path[100];
+  strcpy(bbtk_path, "\"c:\\Program Files\\BBTK\\bin\"");
+  char bbtk_path2[100];
+  strcpy(bbtk_path2, "c:\\Program Files\\BBTK\\bin");
+
+// rootDirectory
+  char rootDirectory[200];  
+  sprintf(rootDirectory, "%s\\.bbtk",getenv("USERPROFILE"));
+  //  std::cout << "[" << rootDirectory << "]" << std::endl;
+    
+// configPath
+  char configPath[200];
+  sprintf(configPath, "%s\\bbtk_config.xml",rootDirectory);
+    
+// makeDir
+  char makeDir[250];
+  sprintf( makeDir, "mkdir \"%s\" ", rootDirectory);
+
+// configXmlTmp
+  char configXmlTmp[250]; 
+  sprintf(configXmlTmp, "%s\\bbtk_config.xml.tmp", bbtk_path2);
+    
+// copyFile
+  char copyFile[250];
+  
+  if (!FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found
+  {
+     if (!FileExists(rootDirectory)) // .bbtk not found
+     {
+       system(makeDir);  // create .bbtk
+     }
+     
+     // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk
+     CreateConfigXML( rootDirectory );// create .bbtk
+     return;
+  }  
+  
+  sprintf(copyFile,"copy %s\\bbtk_config.xml.tmp \"%s\"\\bbtk_config.xml ",bbtk_path,rootDirectory );
+    
+  int attribs = GetFileAttributes (rootDirectory);
+  bbtkMessage("Config",1,std::hex << attribs << " " << FILE_ATTRIBUTE_DIRECTORY << std::endl);
+  if ( attribs != 0xFFFFFFFF){
+    if ((attribs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) /// \TODO : check !
+    {
+      if ( GetFileAttributes( configPath ) == 0xFFFFFFFF)
+      {
+         system(copyFile);  
+      } 
+    }
+  } else {
+    system(makeDir);
+    system(copyFile); 
+  }    
+  return;  
+// ------------------------------------------------------------------    
+#else
+/// \todo  ConfigurationFile::InstallPath() : exit when for not WIN32 and not__GNUC__
+
+  return;    
+#endif
+
+}
+
+void ConfigurationFile::GetTextOrClear(const XMLNode& node, std::string& var)
+{
+  if (node.nText()>0) 
+    {
+      var = node.getText();
+    }
+  else if (node.nClear()>0) 
+    {
+      var = node.getClear().lpszValue;
+    }
+  else 
+    {
+      std::string mess("Error : element <");
+      mess += node.getName();
+      mess += "> : no text nor <PRE></PRE> clear tag found";
+    }
+}
+
+
+// Gets the list of directories holding bb scripts, packages, dll, ... from the xml file
+//      bbtk_config.xml
+
+void ConfigurationFile::Read(const std::string& filename)
+{
+
+  //std::cout << "=======================in  ConfigurationFile::Read filename [" <<filename << "]" << std::endl;
+  
+  mConfig_xml_full_path = filename;
+  XMLResults* res = new XMLResults;
+  XMLNode BB = XMLNode::parseFile((XMLCSTR)filename.c_str(),(XMLCSTR)"config",res);
+
+  if ( res->error != eXMLErrorNone ) 
+    {
+      std::ostringstream str;
+      str << XMLNode::getError(res->error);
+      str << " [line " << res->nLine << ", col "<<res->nColumn<<"] ";
+      str << " file "<<filename; 
+      delete res;
+      bbtkError(str.str());
+//      throw ConfigurationException(str.str());
+    }
+  delete res;
+
+  int i,j;
+
+  // Description
+  for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"description"); i++) 
+    {
+      std::string val;
+      GetTextOrClear(BB.getChildNode((XMLCSTR)"description",&j),val);
+      mDescription += val;
+    }    
+
+  // Url
+  if( BB.nChildNode((XMLCSTR)"url") ) 
+     GetTextOrClear(BB.getChildNode((XMLCSTR)"url"),mUrl);
+
+  // Data_Path
+  if( BB.nChildNode((XMLCSTR)"data_path") ) 
+     GetTextOrClear(BB.getChildNode((XMLCSTR)"data_path"),mData_path);
+
+  // install_path
+  if( BB.nChildNode((XMLCSTR)"install_path") )
+     GetTextOrClear(BB.getChildNode((XMLCSTR)"install_path"),mInstall_path);
+
+  // always add "." (current working directory) at the begining
+
+  // bbs_paths
+  mBbs_paths.push_back("."); 
+  for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"bbs_path"); i++) 
+    {
+      std::string val;
+      GetTextOrClear(BB.getChildNode((XMLCSTR)"bbs_path",&j),val);
+      mBbs_paths.push_back(val);
+    }
+
+  // package_paths
+  mPackage_paths.push_back(".");   
+  for (i=0,j=0; i<BB.nChildNode((XMLCSTR)"package_path"); i++) 
+    {
+      std::string val;
+      GetTextOrClear(BB.getChildNode((XMLCSTR)"package_path",&j),val);
+      mPackage_paths.push_back(val);
+    }
+
+  // default_doc_tmp
+  if( BB.nChildNode((XMLCSTR)"default_doc_tmp") ) 
+     GetTextOrClear(BB.getChildNode((XMLCSTR)"default_doc_tmp"),mDefault_doc_tmp);
+
+  if ( mDefault_doc_tmp == "$") // no value found in config_xml
+  {
+     size_t pos = mConfig_xml_full_path.find("bbtk_config.xml");
+     mDefault_doc_tmp = mConfig_xml_full_path.substr (0,pos); 
+  }    
+  // file separator
+  #if defined(_WIN32)
+     mFile_separator = "\\";
+  #else
+     mFile_separator = "/";
+  #endif
+}
+
+
+} // namespace bbtk
diff --git a/kernel/src/bbtkConfigurationFile.h b/kernel/src/bbtkConfigurationFile.h
new file mode 100644 (file)
index 0000000..d264c91
--- /dev/null
@@ -0,0 +1,130 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkConfigurationFile.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+/**
+ *\file
+ *\brief Class bbtk::ConfigurationFile
+ */
+/**
+ *\class bbtk::ConfigurationFile
+ *\brief DDD
+ *
+ */
+
+#ifndef __bbtkConfigurationFile_h__
+#define __bbtkConfigurationFile_h__
+
+#include "bbtkSystem.h"
+#include <string>
+
+
+#ifdef WIN32
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#include <stdio.h>
+#include "xmlParser.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+
+
+namespace bbtk
+{
+//==========================================================================
+class BBTK_EXPORT  ConfigurationException
+{
+public:
+  ConfigurationException(const std::string& message) : mMessage(message) {}
+
+  std::string mMessage;
+};
+
+
+//==========================================================================
+class BBTK_EXPORT ConfigurationFile
+{
+public:
+
+  static ConfigurationFile const &GetInstance()
+  {
+    static ConfigurationFile f;
+    return f;
+  }
+
+  ~ConfigurationFile();
+
+private:
+  ConfigurationFile();
+  void InstallPath ();
+
+public:
+  inline const std::string& Get_description() const
+     { return mDescription;}
+  inline const std::string& Get_url() const
+     { return mUrl;}
+  inline const std::string& Get_data_path() const
+     { return mData_path;}  
+  inline const std::string& Get_file_separator() const
+     { return mFile_separator;}
+  inline const std::string& Get_install_path() const
+     { return mInstall_path;}
+  inline const std::vector<std::string>& Get_bbs_paths() const
+     { return mBbs_paths;}
+  inline const std::vector<std::string>& Get_package_paths() const
+     { return mPackage_paths;}
+  inline const std::string& Get_config_xml_full_path() const
+     { return mConfig_xml_full_path;}
+  inline const std::string& Get_default_doc_tmp() const
+     { return mDefault_doc_tmp;}
+           
+  private:
+  void Read(const std::string& fileName);
+  void GetTextOrClear(const XMLNode& node, std::string& var); 
+  char *GetExecutablePath();
+  bool FileExists(std::string strFilename);
+  void CreateConfigXML( char *rootDirectory );
+    
+// Attributes :
+  private :
+  std::string mDescription; 
+  /// Where is the file bbtk_config.xml
+  std::string mConfig_xml_full_path;  
+  /// Where the doc is
+  std::string mUrl;
+  std::string mInstall_path;
+  std::string mData_path;
+  /// / or \, depending on the OS
+  std::string mFile_separator;
+  /// Scripts  
+  std::vector<std::string> mBbs_paths; 
+  /// Package dlls    
+  std::vector<std::string> mPackage_paths;
+  /// If Packages link against extern dlls
+  std::vector<std::string> mExt_dll_paths;
+  /// Default directory for generating Graph
+  std::string mDefault_doc_tmp;       
+  };
+
+
+}// namespace bbtk
+
+
+
+#endif
+
diff --git a/kernel/src/bbtkConnection.cxx b/kernel/src/bbtkConnection.cxx
new file mode 100644 (file)
index 0000000..ff8bd77
--- /dev/null
@@ -0,0 +1,329 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkConnection.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *\file
+ *\brief Class bbtk::Connection
+ */
+
+#include "bbtkConnection.h"
+#include "bbtkFactory.h"
+#include "bbtkBlackBox.h"
+#include "bbtkMessageManager.h"
+
+namespace bbtk
+{
+  
+  //==================================================================
+  /// Ctor with the black box from and to and their input and output.
+/// Check the input and output compatibility
+  Connection::Connection(BlackBox* from, const std::string& output,
+                        BlackBox* to, const std::string& input   )
+    : mAdaptor(0),
+      mFromAny(false),
+      mToAny(false)
+  {
+    bbtkDebugMessageInc("Core",7,"Connection::Connection(\""
+                       <<from->bbGetName()<<"\",\""<<output<<"\",\""
+                       <<to->bbGetName()<<"\",\""<<input<<"\")"
+                       <<std::endl);    
+
+    mFrom = from;
+    mTo = to;
+    mInput = input;
+    mOutput = output;
+    
+
+    if (! from->bbHasOutput(output) )
+      {
+       bbtkError("The box \""<<from->bbGetTypeName()<<
+                 "\" has no output \""<<output<<"\"");
+      }
+    if (! to->bbHasInput(input) )
+      {
+       bbtkError("The box \""<<to->bbGetTypeName()<<
+                 "\" has no input \""<<input<<"\"");
+      } 
+
+    if (to->bbGetInputConnectorMap().find(input)->second->IsConnected())
+      {
+       bbtkError("The input \""<<input<<"\" of the box \""<<to->bbGetTypeName()
+                 <<"\" is already connected");
+      }
+    
+    //  std::string t1 ( from->bbGetOutputType(output).name() );
+    //   std::string t2 ( to->bbGetInputType(input).name() );
+    // if  //( t1 != t2 ) 
+    if ( from->bbGetOutputType(output) !=
+        to->bbGetInputType(input) )
+      {
+       if ( from->bbGetOutputType(output) == typeid(Data) )
+         {
+           bbtkWarning("Connection '"
+                       <<GetFullName()
+                       <<"' : '"<<from->bbGetName()<<"."<<output
+                       <<"' is of type <"
+                       <<HumanTypeName<Data>()
+                       <<"> : type compatibility with '"
+                       <<to->bbGetName()<<"."<<input
+                       <<"' will be resolved at run time"
+                       );
+           mFromAny = true;
+         }
+       else if (  to->bbGetInputType(input) == typeid(Data) )
+         {   
+           bbtkDebugMessage("Core",8," -> '"<<input<<"' type is "
+                            <<TypeName<Data>()<<" : can receive any data"
+                            <<std::endl);
+           mToAny = true;
+         }
+       else 
+         {
+           //   std::cout << "Adaptive connection "<<std::endl;
+           std::string name;
+           name = from->bbGetName() + "." + output + "-" 
+             + to->bbGetName() + "." + input; 
+           mAdaptor = NewAdaptor(from->bbGetOutputType(output),
+                                 to->bbGetInputType(input),
+                                 name);
+           if (!mAdaptor)  
+             {  
+               bbtkError("did not find any <"
+                         <<TypeName(from->bbGetOutputType(output))
+                         <<"> to <"
+                         <<TypeName(to->bbGetInputType(input))
+                         <<"> adaptor");
+             } 
+         }
+      }
+
+     // 
+    from->bbConnectOutput(output,this);
+    to->bbConnectInput(input,this);
+    
+    bbtkDebugDecTab("Core",7);
+  }
+
+  //==================================================================
+  
+  
+  //==================================================================
+  /// Dtor 
+  Connection::~Connection()
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "Connection::~Connection() ["
+                       <<GetFullName()<<"]"<<std::endl);
+
+    mFrom->bbDisconnectOutput(mOutput,this);
+    mTo->bbDisconnectInput(mInput,this);
+    if (mAdaptor) mAdaptor->bbDelete();
+
+    bbtkDebugDecTab("Core",7);
+  }
+  //==================================================================
+  
+  //==================================================================
+  /// Backward Update
+  IOStatus Connection::BackwardUpdate()
+  {
+    bbtkDebugMessageInc("Process",2,
+                       "Connection::BackwardUpdate() ["
+                       <<GetFullName()<<"]"<<std::endl);
+
+    IOStatus s = UPTODATE;
+    s = mFrom->bbBackwardUpdate(this);
+
+    TransferData();
+
+    if (mAdaptor && (s==MODIFIED)) mAdaptor->bbSetModifiedStatus();
+
+    bbtkDebugDecTab("Process",2);
+
+    return s;
+  }
+  //==================================================================
+
+  /*
+  //==================================================================
+  /// Forward Update
+  void Connection::ForwardUpdate()
+  {
+    bbtkDebugMessageInc("Process",2,
+                       "Connection::ForwardUpdate() ["
+                       <<GetFullName()<<"]"<<std::endl);
+
+  
+    TransferData();
+
+    mTo->bbForwardUpdate(this);
+
+    bbtkDebugDecTab("Process",2);
+  }
+  //==================================================================
+  */
+
+  //==================================================================
+  /// Transfers the data from the source output to the target input
+  /// doing necessary conversions (adaptation or pointer cast)
+  void Connection::TransferData()
+  {
+    bbtkDebugMessageInc("Process",3,
+                       "Connection::TransferData() ["
+                       <<GetFullName()<<"]"<<std::endl);
+    
+    
+    // If an adaptor was created we need to adapt the data
+    if (mAdaptor) 
+      {
+       mAdaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
+       mAdaptor->bbExecute();
+       // LG : Connection Update does not set mTo as modified
+       mTo->bbSetInput(mInput, mAdaptor->bbGetOutput("Out"),false);
+       
+      }
+    // If no adaptor but source type is an any and target is not an any
+    else if ( mFromAny && (! mToAny) )
+      {
+       bbtkDebugMessage("Data",3,
+                        "Connection::TransferData() ["
+                        <<GetFullName()<<"]"<<std::endl);
+       bbtkDebugMessage("Data",3,
+                        " * Source type is an "
+                        <<HumanTypeName<Data>()
+                        <<" which contains a <"
+                        <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
+                        <<">"<<std::endl);
+       bbtkDebugMessage("Data",3,
+                        " * Target type is <"
+                        <<HumanTypeName(mTo->bbGetInputType(mInput))
+                        <<">"<<std::endl);
+       
+       // 1) Test strict type matching between any content and target
+       if (mFrom->bbGetOutput(mOutput)
+           .contains( mTo->bbGetInputType(mInput) ) )
+         {
+           bbtkDebugMessage("Data",3,
+                            " -> Equal types : transfer ok"<<std::endl);
+           mTo->bbSetInput( mInput, 
+                            mFrom->bbGetOutput(mOutput),
+                            false);
+         }
+       else 
+         {
+           // 2) Look for an adaptor
+           bbtk::BlackBox* adaptor = 0;
+           try 
+             {
+               adaptor = NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
+                                    mTo->bbGetInputType(mInput),
+                                    "");
+             }
+           catch (...)
+             {
+             }
+           if (adaptor)  
+             {
+               bbtkDebugMessage("Data",3," -> Adaptor found : using it"
+                                <<std::endl);
+                 adaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
+               adaptor->bbExecute();
+               // LG : Connection Update does not set mTo as modified
+               mTo->bbSetInput(mInput, adaptor->bbGetOutput("Out"),false);
+               adaptor->bbDelete();
+             }
+           // 3) If no adaptor found but the any content is a pointer
+           //    and target type is also a pointer : we try run-time cast
+           else if ( (mFrom->bbGetOutput(mOutput).contains_pointer()) &&
+                     (mTo->bbGetDescriptor()->GetInputDescriptor(mInput)
+                      ->IsPointerType()) )
+             {
+               bbtkDebugMessage("Data",3,
+                                " -> No adaptor found but source and target types are both pointers : trying up or down cast"<<std::endl);
+               
+               void* nptr = 
+                 mFrom->bbGetOutput(mOutput)
+                 .get_pointer_to(mTo->bbGetInput(mInput).pointed_type());
+               if (!nptr)  
+                 {
+                   bbtkError("Connection '"
+                             <<GetFullName()
+                             <<"' : <"
+                             <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
+                             <<"> to <"
+                             <<HumanTypeName(mTo->bbGetInputType(mInput))
+                             <<"> : no adaptor available and run-time up and down cast failed");
+                 }
+               mTo->bbBruteForceSetInputPointer(mInput, nptr, false);
+             }
+           // 4) Nothing worked : error
+           else 
+             {
+               bbtkError("Connection '"<<GetFullName()<<"' "
+                         <<"no adaptor found to convert <"
+                         <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
+                         <<"> to <"
+                         <<HumanTypeName(mTo->bbGetInputType(mInput))<<">");
+             }
+         }
+      }
+    // EO : mFromAny && ! mToAny
+    // Default case : types are the same; we use simple get-set
+    else 
+      {
+       // LG : Connection Update does not set mTo as modified
+       mTo->bbSetInput(mInput, mFrom->bbGetOutput(mOutput),false);
+      }
+
+    bbtkDebugDecTab("Process",3);
+  }
+  //==================================================================
+  
+  //==================================================================
+  /// Modified
+  void Connection::SetModifiedStatus()
+  {
+    bbtkDebugMessageInc("Process",5,
+                       "Connection::SetModifiedStatus() ["
+                       <<GetFullName()<<"]"<<std::endl);
+    
+    if (mAdaptor) mAdaptor->bbSetModifiedStatus();
+    
+    mTo->bbSetModifiedStatus(  mTo->bbGetInputConnectorMap().find(mInput)->second );
+    
+    bbtkDebugDecTab("Process",5);
+  }
+  //==================================================================
+
+  
+  //==================================================================
+  std::string Connection::GetFullName() const {
+    if (mFrom && mTo)
+      return  mFrom->bbGetName()+"."+mOutput+"--"
+       +mTo->bbGetName()+"."+mInput;
+    return "***Invalid Connection***";
+  }
+  //==================================================================
+
+
+
+}// namespace bbtk
+
+
+
+
+
diff --git a/kernel/src/bbtkConnection.h b/kernel/src/bbtkConnection.h
new file mode 100644 (file)
index 0000000..09a5d7f
--- /dev/null
@@ -0,0 +1,130 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkConnection.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *\file
+ *\brief Class bbtk::Connection
+ */
+/**
+ *\class bbtk::Connection
+ *\brief DDD
+ *
+ */
+
+#ifndef __bbtkConnection_h__
+#define __bbtkConnection_h__
+
+#include "bbtkSystem.h"
+#include <string>
+
+namespace bbtk
+{
+  /// 
+  typedef int IOStatus;
+  /// 
+  const int MODIFIED = 0;
+  /// 
+  const int UPTODATE = 1;
+  /// 
+  const int UPDATING = 2;
+
+
+
+  class BlackBox;
+  class BlackBoxInputConnector;
+  class BlackBoxOutputConnector;
+
+
+
+  class BBTK_EXPORT Connection
+  {
+  public:
+    /// Ctor 
+    Connection(BlackBox* from, const std::string& output,
+              BlackBox* to, const std::string& input   );
+    /// Dtor
+    ~Connection();
+
+    /// Amont direction pipeline processing
+    /// 1) call bbBackwardUpdate(this) on the amont box
+    /// 2) copies the amont box output to the aval box input adapting it if needed
+    virtual IOStatus BackwardUpdate();
+
+    /// Aval direction pipeline processing :
+    /// 1) copies the amont box output to the aval box input adapting it if needed
+    /// 2) call bbForwardUpdate(this) on the aval box
+    //    virtual void ForwardUpdate();
+
+
+    virtual void SetModifiedStatus();
+    std::string GetFullName() const; 
+
+    /// Returns the initial black box of the connection
+    BlackBox* GetBlackBoxFrom() const { return mFrom; }
+    /// Returns the final black box of the connection
+    BlackBox* GetBlackBoxTo() const { return mTo; }
+    /// Returns the output of the initial black box of the connection
+    const std::string& GetBlackBoxFromOutput() const { return mOutput; }
+    /// Returns the input of the final black box of the connection
+    const std::string& GetBlackBoxToInput() const { return mInput; }
+
+    
+
+  protected:
+    /// Black box origin of the connection
+    BlackBox* mFrom;
+    /// Output of mFrom which is connected
+    std::string mOutput;
+    /// Output connector of mFrom which is connected
+    //  BlackBoxOutputConnector* mOutputConnector;
+    /// Black box destination of the connection
+    BlackBox* mTo;
+    /// Input of mTo which is connected
+    std::string mInput;
+    /// Input connector of mTo which is connected
+    //  BlackBoxInputConnector* mInputConnector;
+    /// Adaptor black box if needed
+    BlackBox* mAdaptor;
+
+    /// Is the connection input type is any<thing> ?
+    bool mFromAny;
+
+    /// Is the connection output type is any<thing> ?
+    bool mToAny;
+
+
+    /// Have to do dynamic_cast ?
+    bool mDoDynamicCast;
+
+  
+    /// Ctor with the black box from and to and their input and output
+    /// and a dummy int to differentiate from the public constructor.
+    /// Sets the members but does not test compatibility (used by bbtk::AdaptiveConnection)
+    //  Connection(BlackBox* from, const std::string& output,
+    //        BlackBox* to, const std::string& input, int   );
+    
+    void TransferData(); 
+  };
+
+
+}// namespace bbtk
+
+
+
+#endif
+
diff --git a/kernel/src/bbtkData.h b/kernel/src/bbtkData.h
new file mode 100644 (file)
index 0000000..f473a02
--- /dev/null
@@ -0,0 +1,278 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkData.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *\file
+ *\brief  Defines Data and TypeInfo 
+ * 
+ * Data is bbtk general type exchanged between black boxes (adapted from boost::any).
+ * TypeInfo is the bbtk type of object storing informations on a data type (typedef on std::type_info). 
+ */
+
+#ifndef __bbtkData_h__
+#define __bbtkData_h__
+
+//#include "bbtkSystem.h"
+//#include "bbtkMessageManager.h"
+//#include <string>
+//#include <typeinfo>
+
+//#include "bbtkany.h"
+
+//#include "bbtkReferenceCountedObject.h"
+
+#include "bbtkAny.h"
+
+namespace bbtk
+{
+  
+  typedef any<thing> Data;
+
+  /*
+
+  /// Can transport any kind of data (adaptation of boost::any)
+    class Data
+    {
+    public: // structors
+
+        Data()
+          : content(0)
+        {
+        }
+
+        template<typename ValueType>
+        Data(const ValueType & value)
+          : content(new holder<ValueType>(value))
+        {
+        }
+
+        Data(const Data & other)
+          : content(other.content ? other.content->clone() : 0)
+        {
+        }
+
+        ~Data()
+        {
+            delete content;
+        }
+
+    public: // modifiers
+
+        Data & swap(Data & rhs)
+        {
+            std::swap(content, rhs.content);
+            return *this;
+        }
+
+        template<typename ValueType>
+        Data & operator=(const ValueType & rhs)
+        {
+            Data(rhs).swap(*this);
+            return *this;
+        }
+
+        Data & operator=(const Data & rhs)
+        {
+            Data(rhs).swap(*this);
+            return *this;
+        }
+
+    public: // queries
+
+        bool empty() const
+        {
+            return !content;
+        }
+
+        const std::type_info & type() const
+        {
+            return content ? content->type() : typeid(void);
+        }
+
+#ifndef BBTK_NO_MEMBER_TEMPLATE_FRIENDS
+    private: // types
+#else
+    public: // types (public so Data_cast can be non-friend)
+#endif
+
+        class placeholder
+        {
+        public: // structors
+
+            virtual ~placeholder()
+            {
+            }
+
+        public: // queries
+
+            virtual const std::type_info & type() const = 0;
+
+            virtual placeholder * clone() const = 0;
+
+        };
+
+        template<typename ValueType>
+        class holder : public placeholder
+        {
+        public: // structors
+
+            holder(const ValueType & value)
+              : held(value)
+            {
+            }
+
+        public: // queries
+
+            virtual const std::type_info & type() const
+            {
+                return typeid(ValueType);
+            }
+
+            virtual placeholder * clone() const
+            {
+                return new holder(held);
+            }
+
+        public: // representation
+
+            ValueType held;
+
+        };
+
+#ifndef BBTK_NO_MEMBER_TEMPLATE_FRIENDS
+
+    private: // representation
+
+      //       template<typename ValueType>
+      //       friend ValueType * Data_cast(Data *);
+
+        template<typename ValueType>
+        friend ValueType * unsafe_Data_cast(Data *);
+        template<typename ValueType>
+        friend ValueType  unsafe_Data_cast(Data &);
+
+#else
+
+    public: // representation (public so Data_cast can be non-friend)
+
+#endif
+
+        placeholder * content;
+
+    };
+
+    class bad_Data_cast : public std::bad_cast
+    {
+    public:
+        virtual const char * what() const throw()
+        {
+            return "bbtk::bad_Data_cast: "
+                   "failed conversion using bbtk::Data_cast";
+        }
+    };
+  */
+  /*
+    template<typename ValueType>
+    ValueType * Data_cast(Data * operand)
+    {
+        return operand && operand->type() == typeid(ValueType)
+                    ? &static_cast<Data::holder<ValueType> *>(operand->content)->held
+                    : 0;
+    }
+
+    template<typename ValueType>
+    const ValueType * Data_cast(const Data * operand)
+    {
+        return Data_cast<ValueType>(const_cast<Data *>(operand));
+    }
+
+// Removed Data_cast
+    template<typename ValueType>
+    ValueType Data_cast(const Data & operand)
+    {
+        typedef BBTK_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
+
+#ifdef BBTK_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+        // If 'nonref' is still reference type, it means the user has not
+        // specialized 'remove_reference'.
+
+        // Please use BBTK_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
+        // to generate specialization of remove_reference for your class
+        // See type traits library documentation for details
+        BBTK_STATIC_ASSERT(!is_reference<nonref>::value);
+#endif
+
+        const nonref * result = Data_cast<nonref>(&operand);
+        if(!result)
+            bbtk::throw_exception(bad_Data_cast());
+        return *result;
+    }
+
+    template<typename ValueType>
+    ValueType Data_cast(Data & operand)
+    {
+        typedef BBTK_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
+
+#ifdef BBTK_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+        // The comment in the above version of 'Data_cast' explains when this
+        // assert is fired and what to do.
+        BBTK_STATIC_ASSERT(!is_reference<nonref>::value);
+#endif
+
+        nonref * result = Data_cast<nonref>(&operand);
+        if(!result)
+            bbtk::throw_exception(bad_Data_cast());
+        return *result;
+    }
+  */
+    // Note: The "unsafe" versions of Data_cast are not part of the
+    // public interface and may be removed at Data time. They are
+    // required where we know what type is stored in the Data and can't
+    // use typeid() comparison, e.g., when our types may travel across
+    // different shared libraries.
+    // LG : This is precisely our case !
+  /*
+    template<typename ValueType>
+    inline ValueType * unsafe_Data_cast(Data * operand)
+    {
+        return &static_cast<Data::holder<ValueType> *>(operand->content)->held;
+    }
+
+    template<typename ValueType>
+    inline const ValueType * unsafe_Data_cast(const Data * operand)
+    {
+        return unsafe_Data_cast<ValueType>(const_cast<Data *>(operand));
+    }
+
+    template<typename ValueType>
+    inline ValueType  unsafe_Data_cast(Data & operand)
+    {
+        return static_cast<Data::holder<ValueType> *>(operand.content)->held;
+    }
+
+    template<typename ValueType>
+    inline ValueType unsafe_Data_cast(const Data & operand)
+    {
+        return *unsafe_Data_cast<ValueType>(const_cast<Data *>(&operand));
+    }
+  */
+
+}// namespace bbtk
+
+#endif
+
diff --git a/kernel/src/bbtkDynamicLibraryHandling.h b/kernel/src/bbtkDynamicLibraryHandling.h
new file mode 100644 (file)
index 0000000..39f3af7
--- /dev/null
@@ -0,0 +1,73 @@
+/*=========================================================================
+                                                                                
+Program:   bbtk
+Module:    $RCSfile: bbtkDynamicLibraryHandling.h,v $
+Language:  C++
+
+Date:      $Date: 2008/01/22 15:02:00 $
+Version:   $Revision: 1.1 $
+                                                                                
+
+Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+l'Image). All rights reserved. See doc/license.txt or
+http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+/**
+ *\file
+ *\brief Dynamic library loading stuff (OS dependent)
+ */
+
+// System dependent includes for loading dynamic libraries
+#if defined(__GNUC__)
+// GCC compiler
+
+// dlopen, dlsym, etc.
+#include <dlfcn.h>
+
+// dlopen loading mode : 
+// instant/delayed symbol resolution
+#ifndef BBTK_RTLD_NOW
+#  define BBTK_RTLD_TIME RTLD_LAZY
+#else
+#  define BBTK_RTLD_TIME RTLD_NOW
+#endif
+// local/global symbol loading
+// one **MUST** use RTLD_GLOBAL in order to have 
+// the RTTI mechanism travel correctly across packages (typeid,dynamic_cast...)
+// however this can cause problems (symbol clashes) ...
+// see :
+// http://gcc.gnu.org/faq.html#dso
+// http://gcc.gnu.org/ml/gcc/2003-04/msg00256.html
+// http://gcc.gnu.org/ml/gcc-bugs/2003-10/msg02771.html
+#ifndef BBTK_RTLD_LOCAL
+#  define BBTK_RTLD_SCOPE RTLD_GLOBAL
+#else 
+#  define BBTK_RTLD_SCOPE RTLD_LOCAL
+#endif
+
+// dl handler type
+namespace bbtk 
+{
+  typedef void* DynamicLibraryHandler;
+}
+
+#elif defined(_WIN32)
+// Win32
+// HINSTANCE, LoadLibrary, etc. definition
+#include "Windows.h"
+// dl handler type
+namespace bbtk 
+{
+  typedef HINSTANCE DynamicLibraryHandler;
+}
+
+#else
+
+ERROR !! DYNAMIC LIBRARY LOADING NOT IMPLEMENTED FOR YOUR SYSTEM
+
+#endif
diff --git a/kernel/src/bbtkException.h b/kernel/src/bbtkException.h
new file mode 100644 (file)
index 0000000..9c5c6ae
--- /dev/null
@@ -0,0 +1,76 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkException.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief  class Exception:generic class for throwing any exception (header) 
+ *
+ *    Long description:
+ */
+
+/**
+ *  \class bbtk::Exception 
+ *  \brief  class Exception : generic class for throwing any exception 
+ *
+ *    Long description:
+ */
+#ifndef __bbtkException_h__
+#define __bbtkException_h__
+
+#include "bbtkSystem.h"
+#include <exception>
+
+namespace bbtk
+{
+
+  inline std::string bbGetObjectDescription() { return(""); }
+
+  class BBTK_EXPORT Exception : public std::exception
+  {
+  public:
+    Exception(const std::string& object,
+             const std::string& file,
+             const std::string& message) throw()
+      : mObject(object),
+       mFile(file),
+       mMessage(message)
+    {}
+    ~Exception() throw() {}
+    void Print() throw()
+    {
+      std::cerr << "* ERROR  : " << mMessage <<std::endl; 
+      int lev = bbtk::MessageManager::GetMessageLevel("Error");
+      if (lev > 0) {
+       std::cerr << "* OBJECT : " <<mObject<<std::endl;
+       std::cerr << "* FILE   : " <<mFile<<std::endl;
+      }
+    }
+    const std::string& GetObject() const { return mObject; }
+    const std::string& GetFile() const { return mFile; }
+    const std::string& GetMessage() const { return mMessage; }
+  private:
+    std::string mObject;
+    std::string mFile;
+    std::string mMessage;
+  };
+
+}//namespace
+
+#endif
diff --git a/kernel/src/bbtkExecuter.cxx b/kernel/src/bbtkExecuter.cxx
new file mode 100644 (file)
index 0000000..ddda38a
--- /dev/null
@@ -0,0 +1,553 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkExecuter.cxx,v $ $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *  \file 
+ *  \brief class Executer: level 0 of script execution (code)
+ */
+
+#include "bbtkExecuter.h" 
+#include "bbtkMessageManager.h"
+#include "bbtkFactory.h"
+#include "bbtkUtilities.h"
+
+#include <fstream>
+
+#ifdef _USE_WXWIDGETS_
+#include <wx/textdlg.h>
+#endif
+
+#include "bbtkWxBlackBox.h"
+
+#include "bbtkConfigurationFile.h"
+
+namespace bbtk
+{  
+/**
+ *  
+ */
+  Executer::Executer() 
+    : mPackage(0),
+      mRoot(0),
+      mNoExecMode(false),
+      mDialogMode(NoDialog)
+  {
+    //VirtualExec();
+    
+    bbtkDebugMessageInc("Core",9,"Executer::Executer()" <<std::endl);
+    Reset();
+    bbtkDebugDecTab("Core",9);
+  } 
+  
+/**
+ *  
+ */
+  Executer::~Executer()
+  {
+     bbtkDebugMessageInc("Core",9,"Executer::~Executer()" <<std::endl);
+     if (mRoot) 
+     {
+        mPackage->UnRegisterBlackBox("workspace");
+        delete mRoot;    
+     }
+     if (mPackage) 
+     {
+        GetGlobalFactory()->UnLoadPackage("user");
+     }
+     bbtkDebugDecTab("Core",9);
+  }
+  
+
+/**
+ *  
+ */
+  void Executer::Reset()
+  {
+    bbtkDebugMessageInc("Core",9,"Executer::Reset()" <<std::endl);
+
+    // The 'user' package must be closed before all other 
+    // because box destructors must not be unloaded when bb are deleted!
+    // Similarly, the 'workspace' CBB must be destroyed before 
+    // all user defined CBB otherwise any instance 
+    // of a user CBB that is in the 'workspace' would try to 
+    // access a user CBB descriptor which has been previously freed
+    if (mRoot) 
+    {
+       mPackage->UnRegisterBlackBox(mRoot->GetTypeName());
+       delete mRoot;    
+    }
+    if (mPackage) 
+    {
+       GetGlobalFactory()->UnLoadPackage("user");
+    }
+    GetGlobalFactory()->Reset();
+    // Create user package
+    mPackage = new Package("user","internal to bbi",
+                           "User defined black boxes",
+                           "",
+                           BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));
+    // Create user workspace
+    mRoot = new ComplexBlackBoxDescriptor("workspace"); //,f);
+    mRoot->AddToAuthor("bbi (internal)");
+    mRoot->AddToDescription("User's workspace");
+    mCurrent.push_back(CBBDefinition(mRoot,"user"));
+    // Register it into the user package
+    mPackage->RegisterBlackBox(mRoot);
+    // Insert the user package in the factory
+    InsertPackage(mPackage);
+
+    bbtkDebugDecTab("Core",9);
+  }
+  
+  /// changes the workspace name
+  void Executer::SetWorkspaceName( const std::string& n )
+  {
+    mPackage->ChangeBlackBoxName( mRoot->GetTypeName(), n );
+  }
+  
+
+  void Executer::Define (const std::string &name,
+                        const std::string &pack,
+                        const std::string &scriptfilename)
+  {
+    bbtkDebugMessageInc("Core",9,"Executer::Define(\""<<name<<
+                       ","<<pack<<"\")" 
+                        <<std::endl);
+
+    ComplexBlackBoxDescriptor* b = new ComplexBlackBoxDescriptor(name);
+    b->SetScriptFileName(scriptfilename);
+    mCurrent.push_back( CBBDefinition( b, pack ) );
+    
+    bbtkDebugDecTab("Core",9);
+  }
+
+  void Executer::EndDefine ()
+  {
+    bbtkDebugMessageInc("Core",9,"Executer::EndDefine(\""
+                        <<Current()->GetTypeName()<<"\")" 
+                        <<std::endl);
+    // Does current package exist ?
+    std::string pname(mCurrent.back().package);
+    Package* p;
+    try 
+      {
+       p = GetGlobalFactory()->GetPackage(pname);
+      }
+    catch (Exception e)
+      {
+       p = new Package(pname,
+                       "",
+                       "",
+                       "",
+                       BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));
+       InsertPackage(p);
+      }
+
+    p->RegisterBlackBox(Current());
+    
+    mCurrent.pop_back();
+  }
+
+
+  void Executer::Create ( const std::string& nodeType, 
+                          const std::string& nodeName)
+  {
+     Current()->Add(nodeType,nodeName);
+  }
+  
+
+  /*
+    void Executer::Remove (const std::string &nodeName)
+  { 
+    // Current()->RemoveBlackBox(nodeName);
+  }
+  */    
+
+/**
+ *  
+ */
+  void Executer::Connect (const std::string &nodeFrom, 
+                          const std::string &outputLabel, 
+                          const std::string &nodeTo, 
+                          const std::string &inputLabel)
+  {
+    Current()->Connect(nodeFrom, outputLabel, nodeTo, inputLabel); 
+  }
+   
+ /**
+ *  
+ */ 
+  void Executer::Update (const std::string &nodeName) // would 'Execute' be more meaningfull ?
+  {
+ // if in root
+     if (Current()==mRoot) 
+     {
+        if (!mNoExecMode) 
+        {
+           Current()->GetPrototype()->bbGetBlackBox(nodeName)->bbExecute(true);
+        }
+     }
+     else 
+     {
+        Current()->AddToExecutionList(nodeName) ;
+     }
+  }
+    
+/**
+ *  
+ */
+  void Executer::DefineInput ( const std::string &name,
+                               const std::string &box,
+                               const std::string &input,
+                               const std::string& help)
+  {
+    // If the input is defined in the Root box
+    if (Current()==mRoot) 
+      {
+      // If the dialog mode is set to NoDialog
+      // and the user passed the name in the Inputs map 
+      // then the associated value is set to the box.input
+      // This is the way command line parameters are passed to the Root box
+         if (mDialogMode == NoDialog) 
+         {
+         // find if name is in mInputs
+            std::map<std::string,std::string>::iterator i;
+            i = mInputs.find(name);
+            if (i!=mInputs.end()) {
+               Set(box,input,(*i).second);
+            }
+         }
+        // If the dialog mode is set to TextDialog
+        // The user is prompted for the value
+        else if (mDialogMode == TextDialog) 
+        {
+           std::cout << name << "=";
+           std::string ans;
+           std::cin >> ans;
+           Set(box,input,ans);
+        }
+       #ifdef _USE_WXWIDGETS_
+       // If the dialog mode is set to GraphicalDialog
+       // A dialog box is pop up
+       else if (mDialogMode == GraphicalDialog) 
+       {
+          std::string mess("Enter the value of '");
+          mess += name;
+          mess += "' (";
+          mess += help;
+          mess += ")";
+          std::string title(name);
+          title += " ?";
+    
+          std::string ans = wx2std ( wxGetTextFromUser( std2wx (mess), std2wx(title)));
+          Set(box,input,ans); 
+       }
+#endif
+    }
+    
+    Current()->DefineInput(name,box,input,help);
+        
+  }
+  
+ /**
+ *  
+ */ 
+   void Executer::DefineOutput ( const std::string &name,
+                                 const std::string &box,
+                                 const std::string &output,
+                                 const std::string& help)
+  {
+    Current()->DefineOutput(name,box,output,help);
+  }
+  
+  /**
+   *  
+   */ 
+  void Executer::Set (const std::string &box,
+                      const std::string &input,
+                      const std::string &value)
+  {
+    BlackBox* b = Current()->GetPrototype()->bbGetBlackBox(box);
+    // Looks for the adaptor
+
+    if ( b->bbGetInputType(input) !=  typeid(std::string) ) 
+      {
+         BlackBox* a = /*mFactory->*/
+         NewAdaptor(typeid(std::string),
+                    b->bbGetInputType(input),
+                    "tmp");
+         if (!a) 
+         {
+            bbtkError("No <"<<
+                      TypeName(b->bbGetInputType(input))
+                      <<"> to <std::string> found");
+         }
+         std::string v(value);
+         a->bbSetInput("In",v);
+         a->bbExecute();
+         b->bbSetInput(input,a->bbGetOutput("Out"));
+         a->bbDelete();
+      }
+    else 
+      {
+      std::string v(value);
+      b->bbSetInput(input,v);
+      }
+  }
+
+  
+  /**
+   *  
+   */ 
+  std::string Executer::Get(const std::string &box,
+                            const std::string &output)
+  {
+    BlackBox* b = Current()->GetPrototype()->bbGetBlackBox(box);
+    // Looks for the adaptor
+    if (b->bbGetOutputType(output) != typeid(std::string)) 
+      {
+      BlackBox* a = /*mFactory->*/
+          NewAdaptor(
+             b->bbGetOutputType(output),
+             typeid(std::string),
+             "tmp");
+      if (!a) 
+        {
+        bbtkError("No <"<<
+                   TypeName(b->bbGetOutputType(output))
+                   <<"> to <std::string> found");
+        }
+        b->bbExecute();
+
+        a->bbSetInput("In",b->bbGetOutput(output));
+        a->bbExecute();
+        std::string r = a->bbGetOutput("Out").unsafe_get<std::string>();
+       //std::string v = *((std::string*)a->bbGetOutput("Out")) ;
+       //   std::cout << a->bbGetOutput("Out").unsafe_get<std::string>() 
+       //             << std::endl;
+       //std::string v(value);
+       //b->bbSetInput(input,a->bbGetOutput("Out"));
+        a->bbDelete();
+        return r;
+      }
+    else 
+      {
+       b->bbExecute();
+       return b->bbGetOutput(output).unsafe_get<std::string>();
+       // std::string v = *((std::string*)b->bbGetOutput(output)) ;
+       // std::cout << b->bbGetOutput("Out").unsafe_get<std::string>() 
+       //   << std::endl;
+       // b->bbSetInput(input,&v);
+      }
+  }
+
+
+  void Executer::Author(const std::string &authorName)
+  {
+    Current()->AddToAuthor(authorName,Current()==mRoot);
+  }
+
+
+
+  void Executer::Description(const std::string &d)
+  {
+     Current()->AddToDescription(d,Current()==mRoot);
+  }
+
+
+  /// prints the list of the boxes of the current descriptor
+  void Executer::PrintBoxes()
+  {  
+    bbtkMessageInc("Help",1,"The black box descriptor \""
+                   <<Current()->GetTypeName()<<"\" contains : "<<std::endl);
+    Current()->PrintBlackBoxes();
+    bbtkDecTab("Help",1);
+ }
+
+
+  std::string Executer::ShowGraph(const std::string &nameblackbox, 
+                                 const std::string &detailStr, 
+                                 const std::string &levelStr,
+                                 const std::string &output_html,
+                                 const std::string &custom_header,
+                                 const std::string &custom_title,
+                                 bool system_display )
+  {
+
+    int detail =       atoi(detailStr.c_str());
+    int level  =       atoi(levelStr.c_str());
+
+    std::string filename_rootHtml (output_html) ;
+    std::string simplefilename_rootHtml ( Utilities::get_file_name(output_html));
+
+    bool relative_link = true;
+
+    // No output provided : automatic generation
+    if (output_html.length() == 0)
+      {
+       // Don't pollute the file store with  "doc_tmp" directories ...    
+       std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
+       
+       char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
+       
+       std::string directory = default_doc_dir; 
+       if (c != '/' && c !='\\') directory = directory + "/";
+       directory = directory +  "doc_tmp";    
+       
+       filename_rootHtml = directory + "/" + "User.html";
+       simplefilename_rootHtml = "User.html" ;
+
+       // Creating directory
+       std::string command0("mkdir \"" +directory + "\"");
+       system( command0.c_str() );      
+
+       relative_link = false;
+      }
+
+    // Generating documentation-help of workspace
+    mPackage->SetDocURL(filename_rootHtml);
+    mPackage->SetDocRelativeURL(simplefilename_rootHtml);
+
+    mPackage->CreateHtmlPage(filename_rootHtml,"bbi","user package",custom_header,custom_title,detail,level,relative_link);
+    
+    std::string page = filename_rootHtml;
+    /*
+    try 
+      {
+       ShowGraphTypes(nameblackbox);
+      }
+    catch (bbtk::Exception a) 
+      {
+       std::cout <<"EXC"<<std::endl;
+       page = ShowGraphInstances(nameblackbox,detail,level,system_display);
+      }
+    */
+    return page;
+  }
+
+  /// Generate a png file with the actual pipeline (Graphviz-dot needed)
+  std::string Executer::ShowGraphInstances(const std::string &nameblackbox, int detail, int level,
+                                   bool system_display)
+  {
+
+    BlackBox* blackbox=NULL;
+    if (nameblackbox==".")
+      {
+       blackbox=Current()->GetPrototype();
+      } 
+    else 
+      {
+       blackbox = Current()->GetPrototype()->bbFindBlackBox(nameblackbox);
+      }
+    
+    std::string page;
+
+    if (blackbox)
+      {      
+       // Don't pollute the file store with  "doc_tmp" directories ...    
+       std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
+       char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
+       
+       std::string directory = default_doc_dir; 
+       if (c != '/' && c !='\\') directory = directory + "/";
+
+       directory = directory +  "doc_tmp"; 
+       
+       //std::string directory("doc_tmp");
+       std::string filename(directory + "/" + "bbtk_graph_pipeline");
+       std::string filename_html(filename+".html");
+       std::string command0("mkdir \""+directory + "\"");
+
+#if defined(_WIN32)  
+       std::string command2("start ");
+#else 
+       std::string command2("gnome-open ");
+#endif
+
+       command2=command2+filename_html;
+       page = filename_html;
+       // 1. Generate Html Diagram
+       std::ofstream s;
+       s.open(filename_html.c_str());
+       if (s.good()) 
+         {
+           s << "<html><head><title>BBtk graph diagram</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"></head>\n";
+           s << "<body bgcolor=\"#FFFFFF\" text=\"#000000\"> \n\n";
+           if ( blackbox->bbGetName()=="workspacePrototype" )
+             {
+               s << "<center>Current workspace</center>";
+             } else {
+             s << "<center>" << blackbox->bbGetName()<< "</center>";
+           } 
+
+           blackbox->bbInsertHTMLGraph( s, detail, level, true, directory, false );
+           s << "</body></html>\n";      
+         }
+       s.close();
+       
+       // 2. Starting Browser
+       if (system_display) system( command2.c_str() );      
+      } 
+    else 
+      {
+       bbtkMessageInc("Help",1,"No black box: \""
+                      <<nameblackbox<<"\" " <<std::endl);
+       
+      }
+    return page;
+  }
+  
+
+void Executer::ShowRelations(const std::string &nameblackbox, const std::string &detailStr, const std::string &levelStr)
+  {
+       bool found=false;
+
+       int detail = atoi(detailStr.c_str());
+       int level  = atoi(levelStr.c_str());
+       BlackBox* blackbox=NULL;
+       if (nameblackbox.compare(".")==0)
+       {
+          blackbox=Current()->GetPrototype();
+       } else {
+          blackbox = Current()->GetPrototype()->bbFindBlackBox(nameblackbox);
+       }
+
+       if (blackbox)
+       {
+          found=true;
+          blackbox->bbShowRelations(blackbox,detail,level); //,mFactory);
+       }
+
+       if (!found) 
+       {
+          bbtkError("Blackbox Name not found.. <"  <<nameblackbox<<">");
+       }
+  }
+
+  /*
+  /// sets the level of message
+  void Executer::Message(const std::string &category, 
+                         const std::string& level)
+  {
+    int l;
+    sscanf(level.c_str(),"%d",&l);
+    bbtk::MessageManager::SetMessageLevel(category,l);
+  }
+  */
+
+
+}//namespace
diff --git a/kernel/src/bbtkExecuter.h b/kernel/src/bbtkExecuter.h
new file mode 100644 (file)
index 0000000..be6099a
--- /dev/null
@@ -0,0 +1,205 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkExecuter.h,v $ $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *  \file 
+ *  \brief class Executer: level 0 of script execution (header)
+ */
+/**
+ *  \class bbtk::Executer 
+ *  \brief class Executer: level 0 of script execution 
+ */
+  
+#ifndef __bbtkExecuter_h__
+#define __bbtkExecuter_h__
+
+#include "bbtkVirtualExec.h"
+
+#include "bbtkSystem.h"
+#include "bbtkComplexBlackBox.h"
+#include "bbtkFactory.h"
+#include <string>
+#include <deque>
+
+namespace bbtk
+{
+
+  class /*BBTK_EXPORT*/ Executer : public VirtualExec
+  {
+
+  public:
+
+  /*
+   typedef enum 
+    {
+      NoDialog,
+      TextDialog,
+      GraphicalDialog
+    }
+    DialogModeType;
+*/    
+
+    /// Constructor
+    Executer();
+
+    /// 
+    //  void SetFactory(Factory* f);
+      
+    /// Destructor
+    ~Executer();
+    
+    /// Sets the inputs of the workspace : 
+    void SetInputs(const std::map<std::string,std::string>& m) { mInputs = m; }
+
+    /// Puts the executer in "no exec" mode, 
+    /// which creates but does not execute pipelines 
+    void SetNoExecMode(bool b) { mNoExecMode = b; }
+
+    bool GetNoExecMode() const { return mNoExecMode; }
+
+    /// Sets the mode of dialog of the executer for Root inputs 
+    void SetDialogMode(DialogModeType t) { mDialogMode = t; }
+
+    /// Starts the definition of a new ComplexBlackBox in package pack
+    /// scriptfilename is the file from which the def is read
+    void Define (const std::string &name,
+                const std::string& pack,
+                const std::string &scriptfilename);
+
+    /// End the definition of a ComplexBlackBox
+    void EndDefine ();
+
+    /// Creates a new black box in current complex box
+    void Create ( const std::string& boxType, const std::string& boxName);
+
+    /// Destroys a black box
+    void Destroy (const std::string &boxName);
+
+    /// Connects the output boxOutput to the input boxInput
+    void Connect (const std::string &boxfrom,
+                 const std::string &output,
+                 const std::string &boxto,
+                 const std::string &input);
+
+    /// Updates the box 
+    /// would 'Execute' be more meaningfull ?
+    void Update (const std::string &box);
+
+    /// Defines an input of the current complex box
+    void DefineInput (const std::string &name,
+                     const std::string &box,
+                     const std::string &input,
+                     const std::string &help);
+
+    /// Defines an output of the current complex box
+    void DefineOutput (const std::string &name,
+                      const std::string &box,
+                      const std::string &output,
+                      const std::string &help);     
+  
+    /// sets the input of the box with the value
+    void Set (const std::string &box, 
+             const std::string &input, 
+             const std::string &value);
+
+    /// gets the output of the box
+    std::string Get (const std::string &box, 
+                    const std::string &output);
+
+    /// changes the workspace name
+    void SetWorkspaceName( const std::string& n );
+
+    ///Adds the authorName to the Box's author list
+    void Author(const std::string &authorName);
+
+    /// The description string which explains what does the ComplexBox
+    void Description(const std::string & d);
+
+    /// prints the list off the boxes of the current box
+    void PrintBoxes();
+
+   /// Generate a HTML with a gif file with the actual pipeline (Graphviz-dot needed). Returns the file path
+    std::string ShowGraph(const std::string &nameblackbox, 
+                         const std::string &detailStr, 
+                         const std::string &levelStr,
+                         const std::string &output_file,
+                         const std::string &custom_header,
+                         const std::string &custom_title,
+                         bool system_display = true);
+
+   /// Generate a HTML with a gif file with the actual pipeline (Graphviz-dot needed). Returns the file path
+    std::string ShowGraphInstances(const std::string &nameblackbox, int detail, int level, bool system_display=true);
+
+   /// Description of the actual pipeline
+      void ShowRelations(const std::string &nameblackbox, const std::string &detailStr, const std::string &levelStr);
+
+      void Reset();
+
+  //  static const std::string& GetObjectDescription() 
+  //  { static std::string s("Executer"); return s; }
+
+  protected:
+
+  private:
+
+    /// Gets the current working black box 
+    ComplexBlackBoxDescriptor* Current() { return mCurrent.back().box; }
+    
+    /// Returns true when we are inside a define/endefine block
+    //    bool InDefinitionBlock() { return (mCurrent.size()>1); }
+
+    //==================================================================
+    // ATTRIBUTES
+     
+    /// The factory used
+    //   Factory* mFactory;
+
+    /// The Root Package
+    Package* mPackage;
+    
+    /// The root ComplexBlackBox, in which operations are done when outside a define/endefine block
+    /// Its name in bbi is 'workspace'  
+    ComplexBlackBoxDescriptor* mRoot;
+    
+    /// Struct that stores info on user defined complex black boxes
+    struct CBBDefinition
+    {
+      ComplexBlackBoxDescriptor* box;
+      std::string package;
+      CBBDefinition(ComplexBlackBoxDescriptor* d, const std::string& p )
+        : box(d), package(p) {}
+    };
+
+    /// The stack of current working ComplexBlackBox
+    /// (is a stack for nested definitions)
+    /// only contains the root when outside a define/endefine block
+    std::deque<CBBDefinition> mCurrent;
+
+    /// flag which is true when we are inside a Define/EndDefine block
+    //    bool mDefineFlag;
+    
+    /// The input values of the Root ComplexBlackBox
+    std::map<std::string,std::string> mInputs;
+    
+    /// no exec mode flag
+    bool mNoExecMode;
+
+    /// Dialog mode
+    DialogModeType mDialogMode;
+  };
+}
+#endif
diff --git a/kernel/src/bbtkFactory.cxx b/kernel/src/bbtkFactory.cxx
new file mode 100644 (file)
index 0000000..eb0b829
--- /dev/null
@@ -0,0 +1,1041 @@
+/*=========================================================================
+                                                                                
+Program:   bbtk
+Module:    $RCSfile: bbtkFactory.cxx,v $
+Language:  C++
+
+Date:      $Date: 2008/01/22 15:02:00 $
+Version:   $Revision: 1.1 $
+                                                                                
+
+Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+l'Image). All rights reserved. See doc/license.txt or
+http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+/**
+ *\file
+ *\brief  Class bbtk::Factory : can load and unload dynamic libraries containing 
+ *        black boxes packages and create instances of the black boxes registered 
+ *       in the packages loaded.
+ */
+#include "bbtkFactory.h"
+#include "bbtkMessageManager.h"
+#include "bbtkConnection.h"
+#include "bbtkConfigurationFile.h"
+
+#include <sys/stat.h> // for struct stat stFileInfo
+
+#if defined(_WIN32)
+#include <direct.h> // for getcwd
+#endif
+
+
+// was in gdcm ...
+/*
+#ifdef _MSC_VER
+#   define getcwd _getcwd
+#endif
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#   include <direct.h>
+#else
+#   include <unistd.h>
+#endif
+
+*/
+
+
+namespace bbtk
+{
+  typedef Package* (*PackageAccessor)();
+  typedef void (*PackageDeleteFunction)();
+
+
+  //===================================================================
+  /// Default ctor
+  Factory::Factory()
+  {
+    bbtkDebugMessage("Core",7,"Factory::Factory()"<<std::endl);
+  }
+  //===================================================================
+
+  //===================================================================
+  /// Dtor
+  Factory::~Factory()
+  {
+    bbtkDebugMessageInc("Core",7,"Factory::~Factory()"<<std::endl);
+    CloseAllPackages();
+    bbtkDebugDecTab("Core",7);
+  }
+  //===================================================================
+
+
+  //===================================================================
+  void Factory::CloseAllPackages()
+  {
+    bbtkDebugMessageInc("Core",7,"Factory::CloseAllPackages()"<<std::endl);
+    while (mPackageMap.begin() != mPackageMap.end())
+      {
+        PackageMapType::iterator i = mPackageMap.begin();
+        ClosePackage(i);
+      }
+    bbtkDebugDecTab("Core",7);
+  }
+  //===================================================================
+
+  //===================================================================
+  void Factory::Reset()
+  {
+    bbtkDebugMessageInc("Core",7,"Factory::Reset()"<<std::endl);
+    CloseAllPackages();
+    bbtkDebugDecTab("Core",7);
+  }
+  //===================================================================
+
+// --> usefull in many places (at least : ConfigurationFile, Factory, Interpreter)
+// should be factorized ( "bbtk::Util class ?)
+/*
+bool Factory::FileExists(std::string strFilename)
+bool Factory::IsAtRoot(std::string cwd)
+std::string Factory::ExtractPackageName(const std::string  &name)
+std::string Factory::ExpandLibName(const std::string &name, bool verbose)
+std::string Factory::MakeLibnameFromPath(std::string path, std::string pkgname)
+bool Factory::CheckIfLibraryContainsPackage(std::string libname,std::string pkgname, bool verbose)
+*/
+
+// See : http://www.techbytes.ca/techbyte103.html for more O.S.
+bool Factory::FileExists(std::string strFilename) {
+  struct stat stFileInfo;
+  bool blnReturn;
+  int intStat;
+
+  // Attempt to get the file attributes
+  intStat = stat(strFilename.c_str(),&stFileInfo);
+  if(intStat == 0) {
+    // We were able to get the file attributes
+    // so the file obviously exists.
+    blnReturn = true;
+  } else {
+    // We were not able to get the file attributes.
+    // This may mean that we don't have permission to
+    // access the folder which contains this file. If you
+    // need to do that level of checking, lookup the
+    // return values of stat which will give you
+    // more details on why stat failed.
+    blnReturn = false;
+  }
+
+  return(blnReturn);
+}
+  
+// ===================================================================================
+
+  std::string Factory::ExtractPackageName(const std::string  &name, 
+                                         std::string& path)
+  {
+    std::string pkgname;
+    path = "";
+
+    std::string::size_type slash_position = name.find_last_of("/\\");
+    if (slash_position != std::string::npos) 
+      {
+       pkgname = name.substr(slash_position+1,std::string::npos);   
+       path = name.substr(0,slash_position); 
+       //      std::cout << "F:P='"<<path<<"'"<<std::endl;//+1,std::string::npos); 
+      } 
+    else 
+      {
+       pkgname = name;  
+      }      
+          
+    // remove {.so | dll} if any
+    std::string::size_type dot_position = pkgname.find_last_of('.');      
+    if (dot_position != std::string::npos){
+      pkgname = pkgname.substr(0,dot_position);
+    }      
+#if defined(__GNUC__)
+    
+    // GCC mechanism
+    // shared lib name = libbb<name>.so
+
+      // remove {libbb} if any
+    if (memcmp ( pkgname.c_str(), "libbb", 5) == 0) {
+      pkgname =  pkgname.substr(5, pkgname.length());
+    }
+      /*
+      /// \ \todo     what would happen if (stupid) user names his package 'libbb' ?!?
+      /// \ --> Should be forbidden!
+      */
+#elif defined(_WIN32)
+
+       // WIN 32 mechanism
+       // shared lib name = <name>.dll
+
+     // remove {bb} if any
+    if (memcmp (pkgname.c_str(), "bb", 2) == 0) {
+       pkgname =  pkgname.substr(2, pkgname.length());  
+    } 
+         
+     /*
+     /// \ \todo     what would happen if (stupid) user names his package 'bb' ?!?
+     /// \ --> Should be forbidden!
+     */
+#else
+    bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
+#endif      
+    return pkgname;
+  }
+  
+// ===================================================================================
+
+  std::string Factory::ExpandLibName(const std::string &name, bool verbose)
+  {
+     // -----   Think of expanding path name ( ./ ../ ../../ )
+
+    char buf[2048]; // for getcwd
+    char * currentDir = getcwd(buf, 2048);
+    std::string cwd(currentDir);
+    std::string libname(name);
+    
+    // tooHigh : true is user supplies a library pathname with too many "../"
+    bool tooHigh = false;
+
+    if ( name[0] == '/' ||  name[0] == '\\' )
+    {
+
+      return(libname);
+    } 
+    else if  (name[0] == '.' && (name[1] == '/' || name[1] == '\\') ) 
+    {
+      libname = cwd  + ConfigurationFile::GetInstance().Get_file_separator () + name.substr(2, name.length());
+      return(libname);  
+    } 
+    else if ( name[0] == '.' &&  name[1] == '.' && (name[2] == '/' || name[2] == '\\') ) 
+    {       
+      if ( IsAtRoot(cwd) )  // hope it gets / (for Linux),  C: D: (for Windows)
+      {  
+     // if we are already at / or c: --> hopeless  
+         if (verbose)
+           std::cout << "   File path [" <<  name << "] doesn't exist" << std::endl;
+         tooHigh = true;
+      }
+      else
+      {
+         // iterate on ../ and go up from the current working dir!
+         std::string a(name); 
+         bool alreadyProcessRoot = false;                
+         for(;;) 
+         { 
+            std::string::size_type slash_position = cwd.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ());
+            if (slash_position != std::string::npos) {
+              if (slash_position == 0)
+               slash_position = 1;  
+              cwd = cwd.substr(0,slash_position/*+1*/);
+              a =  a.substr(3, name.length());  // remove ../  
+              if (a == "" || alreadyProcessRoot)
+              {
+                if (verbose)
+                  std::cout << "   File path [" <<  name << "] doesn't exist" << std::endl;
+                tooHigh = true;
+                break;
+              }
+              libname =  cwd;
+              char c = cwd[cwd.size()-1];
+              if (c != '/' && c != '\\' )
+                libname += ConfigurationFile::GetInstance().Get_file_separator ();
+              libname += a;
+                          
+              if ( a[0] != '.' ) // if . (probabely ../), loop again
+                break;
+               
+              if (IsAtRoot(cwd))
+                alreadyProcessRoot = true;                            
+            }                  
+         } // end iterating on ../
+      }
+      if (tooHigh)
+         libname="";
+//  std::cout << "=======================================3 libname [" << libname << "]" << std::endl;
+         
+      return (libname);
+      
+    }  // -----   End of expanding path name   ( ./ ../ ../../ )
+    // avoid warnings
+    return(""); // will never get here!
+  } 
+   
+// ===================================================================================
+
+  std::string Factory::MakeLibnameFromPath(std::string path, std::string pkgname)
+  {
+    std::string libname = path;
+    char c = path[path.size()-1];    
+#if defined(__GNUC__)
+       if (c != '/')
+          libname += "/libbb";
+       libname += pkgname;
+       libname += ".so";
+         
+#elif defined(_WIN32)
+       if (c != '\\')
+          libname = path+"\\bb";
+       libname += pkgname;
+       libname += ".dll";
+#endif
+    return libname;    
+  }
+   
+// ===================================================================================
+
+
+  bool  Factory::IsAtRoot(std::string cwd)
+  {
+    if ( cwd == "/"                             // hope it gets /     (for Linux)
+        || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows)
+      return (true);
+    else
+      return(false);
+}
+// ===================================================================================
+
+  bool Factory::DoLoadPackage(std::string libname,
+                             std::string pkgname, 
+                             std::string path, 
+                             bool verbose)
+  {
+
+#if defined(__GNUC__)
+
+        void *handler;            
+        handler = dlopen(libname.c_str(), 
+                                     BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
+        if (!handler)
+        {
+          if (verbose) {
+            std::cout <<"[" <<libname<<"] can't be open" << std::endl;
+            std::cout << "   " <<dlerror() << std::endl;
+          }
+          return false; // try next path
+        }
+      
+        if (verbose)
+          std::cout <<"   -->[" <<libname<<"] found" << std::endl;
+
+      // Loads the Package accessor
+
+        std::string getpackname(pkgname);
+        getpackname += "GetPackage";
+        void *getpack = dlsym(handler, getpackname.c_str());
+        if (!getpack)
+        {
+          dlclose(handler);
+          bbtkError("GetPackage : could not load package \""<<pkgname
+                   <<"\" [symbol "<<getpackname<<"] :"<<dlerror());
+        }
+
+        // Verifies that the Package delete function is present
+        std::string delfname(pkgname);
+        delfname += "DeletePackage";
+        void *delf = dlsym(handler, delfname.c_str());
+        if (!delf)
+        {
+          dlclose(handler);
+          bbtkError("DeletePackage : could not load package \""<<pkgname
+                    <<"\" [symbol "<<delfname<<"] :"<<dlerror());
+        } 
+
+#elif defined(_WIN32)
+
+        HINSTANCE handler;
+     
+        SetErrorMode(0);
+        handler = LoadLibrary(libname.c_str());
+        if (!handler){
+          if (verbose)
+            std::cout <<"   no handler for [" <<libname<<"];" << std::endl;     
+          return false;// Problem with the found library
+        }
+        if (verbose)
+          std::cout <<"   --->[" <<libname<<"] found" << std::endl;
+
+    // Loads the Package accessor
+
+        std::string getpackname(pkgname);
+        getpackname += "GetPackage";
+        void *getpack = GetProcAddress(handler, getpackname.c_str());
+        if (!getpack)
+        {
+          FreeLibrary(handler);
+          bbtkError("[1]could not load package \""<<pkgname
+          <<"\" : "<<getpackname<<" symbol not found (is it a bbtk package lib ?)");
+          // look how to get the error message on win
+              //<<dlerror());
+
+        }
+        // Verifies that the Package delete function is present
+        std::string delfname(pkgname);
+        delfname += "DeletePackage";
+        void *delf = GetProcAddress(handler, delfname.c_str());
+        if (!delf)
+        {
+          FreeLibrary(handler);
+          bbtkError("[2]could not load package \""<<pkgname
+                     <<"\" : "<<delfname<<" symbol not found (is it a bbtk package lib ?)");
+          // look how to get the error message on win
+          //<<dlerror());
+        } 
+#else
+        bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
+#endif   
+  
+    // Stores the package
+        PackageInfoType pack;
+        pack.mDynamicLibraryHandler = handler;
+    // Invokes the accessor to the PackageUnit pointer
+        pack.mPackage = ((PackageAccessor)getpack)();
+
+        mPackageMap[pkgname] = pack;
+
+    // Test bbtk build version ok
+        if ( pack.mPackage->GetBBTKVersion() != bbtk::GetVersion() )
+        {
+          std::string v(pack.mPackage->GetBBTKVersion());
+          UnLoadPackage(pkgname);
+          bbtkError(" package build with bbtk version "
+                   << v
+                   << " whereas application build with version "
+                   << bbtk::GetVersion());
+        }
+
+       std::string separator = 
+         ConfigurationFile::GetInstance().Get_file_separator ();
+       //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
+       std::string docreldoc = separator + "packages" + separator + pkgname 
+         + separator + "bbdoc" + separator + "index.html";
+       std::string reldoc = ".." + separator + ".." + separator 
+         + ".." + docreldoc;
+       std::string doc = path + separator + ".." + separator
+         + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH) 
+         + docreldoc; 
+       std::cout << "doc='"<<doc<<"'"<<std::endl;
+       
+       pack.mPackage->SetDocURL(doc);
+       pack.mPackage->SetDocRelativeURL(reldoc);
+       
+    //===================================================================
+        bbtkMessage("Output",2,pack.mPackage->GetName()<<" "
+           <<pack.mPackage->GetVersion()
+           <<" (bbtk "
+           <<pack.mPackage->GetBBTKVersion()<<") "
+           <<pack.mPackage->GetAuthor() 
+           <<std::endl);
+        bbtkMessage("Output",2,pack.mPackage->GetDescription()<<std::endl);
+    //===================================================================
+
+        bbtkDebugDecTab("Core",7);
+        return true;
+  }
+
+ //===================================================================
+  /// \brief Loads a package.
+  ///
+  /// The name is the system-independant name of the package (the name of the instance of bbtk::Package).
+  /// Tries to open the dynamic library :
+  /// - "libbb<name>.so" for linux systems,
+  /// - "bb<name>.dll" for windows systems.
+  /// If it succeeds, then tries to load the symbols "<name>GetPackage" and "<name>DeletePackage".
+  /// "<name>GetPackage" is called to get the pointer on the bbtk::Package of the library
+  /// ("<name>DeletePackage" is not used, its presence is just checked before loading the package).
+
+  /// now, filename is only the last name (no longer the full name!)
+  /// it will be searched within *all* the paths given in bbtk_config.xml
+
+  /// verbose = true (set by "config v") displays the loading process
+  void Factory::LoadPackage( const std::string& name,
+                             bool use_configuration_file, bool verbose)
+  {
+  // Note : in the following :
+  // name : the user supplied name 
+  //      - abreviated name    e.g.       pkg   pkg.so   libbpkg   libbbpkg.so 
+  //      - relative full name e.g.       ./libbbpkg.so   ../../libbbpkg.so 
+  //      - absolute full name e.g.       /home/usrname/proj/lib/libbbpkg.so
+  //          same for Windows, with      c:, d: ...
+  //
+    bbtkDebugMessageInc("Core",7,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);    
+    bbtkMessage("Debug",1,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);    
+    bbtkMessage("Debug",1,"use_configuration_file [" 
+               << use_configuration_file << "]" << std::endl);
+  
+    std::vector<std::string> package_paths;
+    std::string libname;  // full path library name
+    std::string pkgname;  // e.g. libbb<pkgname>.so
+    
+    std::string upath;
+    pkgname = ExtractPackageName(name,upath);
+
+    bbtkMessage("Debug",1,"Package name ["<<pkgname<<"]"<<std::endl);
+    bbtkMessage("Debug",1,"Package path ["<<upath<<"]"<<std::endl);
+
+    // no loading package if already loaded
+    PackageMapType::iterator iUnload;
+    iUnload = mPackageMap.find(pkgname);
+    if (iUnload != mPackageMap.end()) 
+    {
+      bbtkMessage("Output",2,"["<<pkgname<<"] already loaded"<<std::endl);
+      return; 
+    }
+    
+   // If path provided by user will be the first scanned : 
+    // push it into vector of paths
+    if (upath.length()>0) package_paths.push_back(upath);
+
+    // Add the path of config file 
+    if (use_configuration_file)
+    {
+      std::vector<std::string>::const_iterator pi;
+      for (pi =ConfigurationFile::GetInstance().Get_package_paths().begin();
+               pi!=ConfigurationFile::GetInstance().Get_package_paths().end();
+             ++pi)
+            package_paths.push_back(*pi);
+    }
+   
+    bool ok = false; 
+    bool foundFile = false;    
+
+    std::vector<std::string>::iterator i;
+    for (i=package_paths.begin();i!=package_paths.end();++i)
+      {
+        foundFile = false;    
+            std::string path = *i;
+       
+       // we *really* want '.' to be the current working directory
+        if (path == ".") {
+          char buf[2048]; // for getcwd
+          char * currentDir = getcwd(buf, 2048);
+          std::string cwd(currentDir);        
+          path = currentDir;
+        }
+       
+        libname = MakeLibnameFromPath(path, pkgname);
+       
+            bbtkMessage("Debug",2,"-> Trying to load ["<<libname<<"]"<<std::endl);
+
+      // Check if library exists           
+        if ( !FileExists(libname) )
+        {
+        // The following is *NOT* a debug time message :
+        // It's a user intended message.
+        // Please don't remove it.
+             if (verbose)
+                std::cout <<"   [" <<libname <<"] : doesn't exist" <<std::endl;
+            continue;  // try next path
+        }
+        foundFile = true; 
+
+      // Try to Load the library
+         
+        ok = DoLoadPackage( libname, pkgname, path, verbose);
+        if (ok)
+            {
+               bbtkMessage("Debug",2,"   OK"<<std::endl);
+               break; // a package was found; we stop iterating
+            }
+    } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
+      //  }
+
+    if( !ok )  // nothing was loaded
+    {
+      if (!foundFile)
+      {
+        bbtkError("could not find package ["<<pkgname<< "]");
+      }
+      else
+      {
+#if defined(__GNUC__)
+        bbtkError("could not load package \""<< pkgname
+                  <<"\" :" << std::endl << "   " <<dlerror());
+#elif defined(_WIN32)
+        bbtkError("could not load package \""<<pkgname
+                 <<"\" : " << std::endl << "   " <<libname<<" not found");
+
+    // look how to get the error message on win
+    //<<dlerror());
+    // it is the bordel !! (the bloody fucking bordel, you mean?)
+    // look : http://msdn2.microsoft.com/en-us/library/ms680582.aspx
+#endif
+      }
+    }
+    bbtkMessage("Output",2,"[" << libname << "] loaded" << std::endl);
+
+  }
+    
+  //===================================================================
+  /// \brief UnLoads a package.
+  ///
+  /// The package must have been previously loaded by LoadPackage.
+  /// If the entry is found in the map, calls ClosePackage
+ void Factory::UnLoadPackage( const std::string& userSuppliedName )
+  { 
+    std::string path;
+    std::string name = ExtractPackageName(userSuppliedName,path);
+    bbtkDebugMessageInc("Core",7,"Factory::UnLoadPackage(\""
+                       <<name<<"\")"<<std::endl);
+  
+    PackageMapType::iterator i;
+    i = mPackageMap.find(name);
+    if (i == mPackageMap.end()) 
+    {
+      bbtkError("cannot unload package \""<<name
+                <<"\" : package not loaded !");
+    }
+    ClosePackage(i);
+    bbtkDebugDecTab("Core",7);
+  }
+  //===================================================================
+
+
+  //===================================================================
+  /// \brief Close the package referenced by the iterator 
+  ///
+  /// If it is a dynamically loaded package 
+  /// - Loads and calls the function "<name>DeletePackage" of the dynamic library (responsible for package desallocation)
+  /// - Closes the dynamic library
+  /// - Erases the package entry in the packages map
+  ///
+  /// Else simply erases the package entry in the packages map
+  void Factory::ClosePackage(PackageMapType::iterator& i) 
+  {   
+     bbtkDebugMessageInc("Core",7,"Factory::ClosePackage(\""
+                         <<i->second.mPackage->GetName()
+                        <<"\")"<<std::endl);
+
+     if (i->second.mDynamicLibraryHandler) 
+     {
+      // If it is a dynamically loaded package
+      // Loads the Package delete function
+
+        std::string delfname(i->second.mPackage->GetName());
+        delfname += "DeletePackage";
+#if defined(__GNUC__)     
+        void *delf = dlsym(i->second.mDynamicLibraryHandler, delfname.c_str());
+        if (!delf)
+        {
+           bbtkError("could not close package \""
+                     <<i->second.mPackage->GetName()
+                     <<"\" :"<<dlerror());
+        }    
+#elif defined(_WIN32)
+        void *delf = GetProcAddress(i->second.mDynamicLibraryHandler, 
+                                 delfname.c_str());
+        if (!delf)
+        {  
+           bbtkError("could not close package \""
+                <<i->second.mPackage->GetName()
+                <<"\" : "<<delfname
+                <<" symbol not found (how did you open it ???");
+               //<<"\" :"<<dlerror());
+        }    
+#endif     
+
+   // deletes the package
+   ((PackageDeleteFunction)delf)();
+
+   // closes the dl handler
+#if defined(__GNUC__)  
+    dlclose(i->second.mDynamicLibraryHandler);  
+#elif defined(_WIN32)
+
+    FreeLibrary(i->second.mDynamicLibraryHandler);
+#endif
+    }
+    else 
+    {  
+       // If it is a manually inserted package 
+       delete i->second.mPackage;
+    }
+
+    // remove the entry in the map
+    mPackageMap.erase(i);
+    bbtkDebugDecTab("Core",7);
+ }
+  //===================================================================
+
+
+
+  //===================================================================  
+  /// Displays the list of packages loaded
+  void Factory::PrintPackages(bool details, bool adaptors) const
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::PrintPackages"<<std::endl);
+
+    PackageMapType::const_iterator i;
+    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+    {
+      bbtkMessage("Help",1, i->first << std::endl);
+      if (details) {
+         i->second.mPackage->PrintBlackBoxes(false,adaptors);
+      }
+    }
+
+    bbtkDebugDecTab("Core",9);
+  }
+  //===================================================================
+
+  //===================================================================  
+  /// Displays help on a package
+  void Factory::HelpPackage(const std::string& name/* &userSuppliedName */, bool adaptors) const
+  {
+   // std::string name = ExtractPackageName(userSuppliedName);
+    bbtkDebugMessageInc("Core",9,"Factory::HelpPackage(\""<<name<<"\")"
+                        <<std::endl);
+
+    PackageMapType::const_iterator i = mPackageMap.find(name);
+    if ( i != mPackageMap.end() ) 
+      {
+      bbtkMessage("Help",1, "Package "<<i->first<<" ");
+      if (i->second.mPackage->GetVersion().length()>0)
+        bbtkMessageCont("Help",1,"v" <<i->second.mPackage->GetVersion());
+      if (i->second.mPackage->GetAuthor().length()>0)
+        bbtkMessageCont("Help",1,"- "<<i->second.mPackage->GetAuthor());
+      bbtkMessageCont("Help",1,std::endl);
+      bbtkIncTab("Help",1);
+      bbtkMessage("Help",1,i->second.mPackage->GetDescription()<<std::endl);
+      if (i->second.mPackage->GetNumberOfBlackBoxes()>0) 
+        {
+          bbtkMessage("Help",1, "Black boxes : "<<std::endl);
+          i->second.mPackage->PrintBlackBoxes(true,adaptors);
+        }
+      else 
+        {
+          bbtkMessage("Help",1, "No black boxes"<<std::endl);
+        }
+      bbtkDecTab("Help",1);
+      }
+    else 
+      {
+      bbtkDebugDecTab("Core",9);
+      bbtkError("package \""<<name<<"\" unknown");
+      }
+    
+    bbtkDebugDecTab("Core",9);
+  }
+  //===================================================================
+
+  //===================================================================
+  /// Prints help on the black box of type <name>
+  void Factory::HelpBlackBox(const std::string& name, bool full) const
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::HelpBlackBox(\""<<name<<"\")"
+                        <<std::endl);
+
+    bool found = false;
+    PackageMapType::const_iterator i;
+    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+      {
+      if (i->second.mPackage->ContainsBlackBox(name)) 
+        {
+          i->second.mPackage->HelpBlackBox(name,full);
+          found = true;
+        }
+      }
+    
+    bbtkDebugDecTab("Core",9);
+    if (!found) 
+      {
+      bbtkError("No package of the factory contains any black box <"
+                 <<name<<">");
+      }
+  }  
+  //===================================================================
+
+
+  //=================================================================== 
+  /// Inserts a package in the factory
+  void Factory::InsertPackage( Package* p )
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::InsertPackage(\""<<
+                        p->GetName()<<"\")"<<std::endl);
+
+    PackageInfoType pack;
+    pack.mDynamicLibraryHandler = 0;
+    
+    pack.mPackage = p;
+
+    mPackageMap[p->GetName()] = pack;
+    bbtkDebugDecTab("Core",9);
+  }
+  //===================================================================
+  
+  //=================================================================== 
+  /// Removes a package from the factory (and deletes it)
+  void Factory::RemovePackage( Package* p )
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::RemovePackage(\""<<
+                        p->GetName()<<"\")"<<std::endl);
+
+    PackageMapType::iterator i;
+    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+      {
+         if (i->second.mPackage == p) break;
+      };
+    
+    if (i!=mPackageMap.end())
+      {
+      ClosePackage(i);
+      }
+    else 
+      {
+      bbtkError("Factory::RemovePackage(\""<<
+                 p->GetName()<<"\") : package absent from factory");
+      }
+
+    bbtkDebugDecTab("Core",9);
+  }
+  //===================================================================
+  
+
+  //===================================================================
+  /// Creates an instance of a black box of type <type> with name <name>
+  BlackBox* Factory::NewBlackBox(const std::string& type, 
+                                 const std::string& name) const
+  {
+    bbtkDebugMessageInc("Core",7,"Factory::NewBlackBox(\""
+                        <<type<<"\",\""<<name<<"\")"<<std::endl);
+
+    BlackBox* b = 0; 
+    PackageMapType::const_iterator i;
+    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+      {
+      b = i->second.mPackage->NewBlackBox(type,name);
+      if (b) break; 
+      }
+    if (!b) 
+      {
+       bbtkError("black box type \""<<type<<"\" unknown");
+      } 
+
+    bbtkDebugDecTab("Core",7);
+    return b;
+  }
+  //===================================================================
+
+  //===================================================================
+  /// Creates an instance of a black box of type <type> with name <name>
+  BlackBox* Factory::NewAdaptor(TypeInfo typein,
+                     TypeInfo typeout,
+                     const std::string& name) const
+  {
+    bbtkDebugMessageInc("Core",8,"Factory::NewAdaptor(<"
+                        <<TypeName(typein)<<">,<"
+                        <<TypeName(typeout)<<">,\""
+                        <<name<<"\")"<<bbtkendl);
+
+
+    BlackBox* b = 0; 
+    PackageMapType::const_iterator i;
+    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+      {
+      b = i->second.mPackage->NewAdaptor(typein,typeout,name);
+      if (b) break; 
+      }
+    if (!b) 
+      {
+      bbtkError("no <"
+          <<TypeName(typein)<<"> to <"
+          <<TypeName(typeout)
+          <<"> adaptor available");
+      } 
+    
+    bbtkDebugDecTab("Core",7);
+    return b; 
+  }
+  //===================================================================
+
+  //===================================================================
+  /// Creates an instance of a connection
+  Connection* Factory::NewConnection(BlackBox* from,
+                                     const std::string& output,
+                                     BlackBox* to,
+                                     const std::string& input) const
+  {
+    bbtkDebugMessage("Core",7,"Factory::NewConnection(\""
+                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
+                      <<to->bbGetName()<<"\",\""<<input
+                      <<"\")"<<std::endl);
+    
+    return new Connection(from,output,to,input);
+    /*  
+       Connection* c;
+    // !!! WARNING : WE NEED TO TEST THE TYPE NAME EQUALITY 
+    // BECAUSE IN DIFFERENT DYN LIBS THE type_info EQUALITY CAN 
+    // BE FALSE (DIFFERENT INSTANCES !)
+  
+    std::string t1 ( from->bbGetOutputType(output).name() );
+    std::string t2 ( to->bbGetInputType(input).name() );
+
+
+    if ( t1 == t2 ) 
+       //from->bbGetOutputType(output) ==
+       // to->bbGetInputType(input) )
+      {
+         c = new Connection(from,output,to,input);
+      }
+    else 
+      {
+         //   std::cout << "Adaptive connection "<<std::endl;
+         std::string name;
+         name = from->bbGetName() + "." + output + "-" 
+                                  + to->bbGetName() + "." + input; 
+
+         BlackBox* b = 0; 
+         PackageMapType::const_iterator i;
+         for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+         {
+             b = i->second.mPackage->NewAdaptor(from->bbGetOutputType(output),
+                                                  to->bbGetInputType(input),
+                                                  name);
+             if (b) break; 
+         } 
+         if (!b)  
+         {  
+            bbtkError("did not find any <"
+                       <<TypeName(from->bbGetOutputType(output))
+                       <<"> to <"
+                       <<TypeName(to->bbGetInputType(input))
+                       <<"> adaptor");
+         } 
+         c = new AdaptiveConnection(from,output,to,input,b);
+      }
+      bbtkDebugDecTab("Core",7);
+    
+      return c;
+    */
+  }
+  //===================================================================
+
+
+
+  //===================================================================
+  const Package* Factory::GetPackage(const std::string& name) const
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
+                         <<std::endl);
+
+    PackageMapType::const_iterator i = mPackageMap.find(name);
+    if ( i != mPackageMap.end() ) 
+    {
+      bbtkDebugDecTab("Core",9); 
+      return i->second.mPackage;
+    }
+    else 
+    {
+       bbtkDebugDecTab("Core",9);
+       bbtkError("package \""<<name<<"\" unknown");
+    }
+    
+    bbtkDebugDecTab("Core",9);  
+  }
+  //===================================================================
+  
+  //===================================================================
+  Package* Factory::GetPackage(const std::string& name) 
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
+                         <<std::endl);
+
+    PackageMapType::const_iterator i = mPackageMap.find(name);
+    if ( i != mPackageMap.end() ) 
+    {
+      bbtkDebugDecTab("Core",9); 
+      return i->second.mPackage;
+    }
+    else 
+    {
+       bbtkDebugDecTab("Core",9);
+       bbtkError("package \""<<name<<"\" unknown");
+    }
+    
+    bbtkDebugDecTab("Core",9);  
+  }
+  //===================================================================
+
+  //===================================================================
+  void Factory::WriteDotFilePackagesList(FILE *ff)
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::WriteDotFilePackagesList()"
+                         <<std::endl);
+
+    fprintf( ff , "\n");
+    fprintf( ff , "subgraph cluster_FACTORY {\n");
+    fprintf( ff , "  label = \"PACKAGES\"%s\n",  ";");
+    fprintf( ff , "  style=filled%s\n",";");
+    fprintf( ff , "  color=lightgrey%s\n",";");
+    fprintf( ff , "  rankdir=TB%s\n",";");
+
+    PackageMapType::const_iterator i;
+    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+    {
+       std::string url = GetPackage(i->first)->GetDocURL();
+       fprintf(ff,"  %s [shape=ellipse, URL=\"%s\"]%s\n",
+              i->first.c_str(),
+              url.c_str(),";" );
+    }
+    fprintf( ff , "}\n\n");
+    bbtkDebugDecTab("Core",9);
+  }
+  //===================================================================
+
+
+  void Factory::ShowGraphTypes(const std::string& name) const
+  {
+    bool found = false;
+    PackageMapType::const_iterator i;
+    for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
+      {
+       if (i->second.mPackage->ContainsBlackBox(name)) 
+         {
+           std::string separator = ConfigurationFile::GetInstance().Get_file_separator ();
+           
+            // Don't pollute the file store with  "doc_tmp" directories ...    
+           std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
+           std::string directory = "\"" + default_doc_dir + separator + "doc_tmp"  +separator + "\"";
+           std::string filename2 =  default_doc_dir + separator + "doc_tmp" + separator + "tmp.html"; 
+           
+#if defined(_WIN32)  
+           std::string command("start \"Titre\" /D ");
+#else 
+           std::string command("gnome-open ");
+#endif
+           command=command + directory +" tmp.html";
+           FILE *ff;
+           ff=fopen(filename2.c_str(),"w");
+           
+           fprintf(ff,"<html><head><title>TMP</title> <script type=\"text/javascript\"> <!--\n");
+           fprintf(ff,"  window.location=\"%s#%s\";\n" , i->second.mPackage->GetDocURL().c_str(),name.c_str() );
+           fprintf(ff,"//--></script></head><body></body></html>\n");
+           
+           
+           //fprintf(ff, "<a  href=\"%s#%s\">Link</a>\n", i->second.mPackage->GetDocURL().c_str(),name.c_str() );
+           fclose(ff);
+           system( command.c_str() );      
+           found = true;
+         }
+      }
+    
+    bbtkDebugDecTab("Core",9);
+    if (!found) 
+      {
+       bbtkError("No package of the factory contains any black box <"
+                 <<name<<">");
+      }
+  }
+
+}
+  
diff --git a/kernel/src/bbtkFactory.h b/kernel/src/bbtkFactory.h
new file mode 100644 (file)
index 0000000..7a54768
--- /dev/null
@@ -0,0 +1,223 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkFactory.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *\file
+ *\brief Class bbtk::Factory : can load and unload dynamic libraries containing black boxes packages and create instances of the black boxes registered in the packages loaded.
+ */
+/**
+ *\class bbtk::Factory
+ *\brief Can load and unload dynamic libraries containing black boxes packages and create instances of the black boxes registered in the packages loaded.
+ *
+ */
+
+
+#ifndef __bbtkFactory_h__
+#define __bbtkFactory_h__
+
+//#include "bbtkBlackBox.h"
+#include "bbtkPackage.h"
+#include "bbtkDynamicLibraryHandling.h"
+
+namespace bbtk
+{
+
+
+
+  class BBTK_EXPORT Factory
+  {
+
+  public:
+
+    Factory();
+    ~Factory();
+
+    void LoadPackage( const std::string& name, 
+                      bool use_configuration_file = true, 
+                     bool verbose = false );
+    void UnLoadPackage( const std::string& name );
+    void PrintPackages(bool details = true, bool adaptors = false) const;
+    void HelpPackage(const std::string& name, bool adaptors = false) const;
+    void HelpBlackBox(const std::string& name, bool full=true) const;
+    void ShowGraphTypes(const std::string& name) const;
+    void InsertPackage( Package* );
+    void RemovePackage( Package* );
+
+    const Package* GetPackage(const std::string& name) const;
+    Package* GetPackage(const std::string& name);
+    
+    BlackBox* NewBlackBox(const std::string& type, 
+                          const std::string& name) const;
+    
+    BlackBox* NewAdaptor(TypeInfo typein,
+                         TypeInfo typeout,
+                         const std::string& name) const;
+    
+    Connection* NewConnection(BlackBox* from,
+                              const std::string& output,
+                              BlackBox* to,
+                              const std::string& input) const;
+    
+    void WriteDotFilePackagesList(FILE *ff);
+
+    void Reset();
+    
+    // usefull in many places.
+    // -> should be factorized : bbtk::Util class?    
+    bool FileExists(std::string strFilename);
+  private:
+    /// the methods for LoadPackage
+    std::string ExtractPackageName(const std::string &name, 
+                                  std::string& path);
+    std::string ExpandLibName(const std::string &name, bool v);  
+    std::string MakeLibnameFromPath(std::string path, std::string pkgname);
+    bool DoLoadPackage(std::string libname,
+                      std::string pkgname,
+                      std::string path,
+                      bool v);
+    bool IsAtRoot(std::string cwd);     
+    private:
+    /// The structure storing info on a package
+    class PackageInfoType
+    {
+    public :
+      /// Ctor
+      PackageInfoType() {}
+      /// Dtor
+      ~PackageInfoType() {}
+      /// The pointer on the package
+      Package* mPackage;
+      /// The handler of the dynamic library 
+      DynamicLibraryHandler mDynamicLibraryHandler;
+    };
+    /// The type of map of packages
+    typedef std::map< std::string, PackageInfoType > PackageMapType;
+    /// The map of packages
+    PackageMapType mPackageMap;
+
+    void CloseAllPackages();
+    void ClosePackage(PackageMapType::iterator& i);
+
+  };
+  // class Factory
+
+
+  /// SYSTEM METHOD : Global method returning the global factory object pointer
+  inline Factory*& GlobalFactoryPointer() 
+  {
+    static Factory* f = 0;
+    return f;
+  }
+
+  /// SYSTEM METHOD : Global method returning the global factory object 
+  inline Factory* GetGlobalFactory() 
+  {
+    if (!GlobalFactoryPointer()) 
+    {
+       GlobalFactoryPointer() = new Factory;
+    }
+    return GlobalFactoryPointer();
+  }
+
+  /// SYSTEM METHOD : Deletes the global factory pointer
+  inline void DeleteGlobalFactory() 
+  {
+    if (GlobalFactoryPointer()) 
+    {
+      delete GlobalFactoryPointer();
+    }
+  }
+
+  inline void LoadPackage( const std::string& name, 
+                           bool use_configuration_file = true, bool verbose = false )
+  {
+    GetGlobalFactory()->LoadPackage(name,use_configuration_file, verbose);
+  }
+
+  inline void UnLoadPackage( const std::string& name )
+  { 
+    GetGlobalFactory()->UnLoadPackage(name);
+  }
+
+  inline void PrintPackages(bool details = true, bool adaptors = false)
+  {
+    GetGlobalFactory()->PrintPackages(details,adaptors);
+  }
+
+  inline void HelpPackage(const std::string& name, bool adaptors = false) 
+  {
+    GetGlobalFactory()->HelpPackage(name,adaptors);
+  }
+  
+  inline void HelpBlackBox(const std::string& name, bool full=true) 
+  {
+    GetGlobalFactory()->HelpBlackBox(name,full);
+  }
+
+
+  inline void ShowGraphTypes(const std::string& name)
+  {
+    GetGlobalFactory()->ShowGraphTypes(name);
+  }
+
+  inline void InsertPackage( Package* p)
+  {
+    GetGlobalFactory()->InsertPackage(p);
+  }
+
+  inline void RemovePackage( Package* p)
+  {
+    GetGlobalFactory()->RemovePackage(p);
+  }
+  
+  inline const Package* GetPackage(const std::string& name) 
+  {
+    return GetGlobalFactory()->GetPackage(name);
+  }
+    
+  inline BlackBox* NewBlackBox(const std::string& type, 
+                               const std::string& name) 
+  {
+    return GetGlobalFactory()->NewBlackBox(type,name);
+  }
+    
+  inline BlackBox* NewAdaptor(TypeInfo typein,
+                              TypeInfo typeout,
+                              const std::string& name) 
+  {
+    return GetGlobalFactory()->NewAdaptor(typein,typeout,name);
+  }
+  
+  inline Connection* NewConnection(BlackBox* from,
+                                   const std::string& output,
+                                   BlackBox* to,
+                                   const std::string& input) 
+  {
+    return GetGlobalFactory()->NewConnection(from,output,to,input);
+  }
+  
+  inline void WriteDotFilePackagesList(FILE *ff)
+  {
+    GetGlobalFactory()->WriteDotFilePackagesList(ff);
+  }
+
+}// namespace bbtk
+
+
+
+#endif
+
diff --git a/kernel/src/bbtkInterpreter.cxx b/kernel/src/bbtkInterpreter.cxx
new file mode 100644 (file)
index 0000000..f500e92
--- /dev/null
@@ -0,0 +1,1586 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkInterpreter.cxx,v $ $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *  \file 
+ *  \brief class Interpreter : 
+ */
+
+#include "bbtkInterpreter.h" 
+#include "bbtkMessageManager.h"
+#include "bbtkConfigurationFile.h"
+#include "bbtkWxConsole.h"
+#include "bbtkUtilities.h"
+#include <sys/stat.h>
+#ifdef CMAKE_HAVE_TERMIOS_H
+#include <termios.h>
+#define BBTK_USE_TERMIOS_BASED_PROMPT
+#endif
+
+
+namespace bbtk
+{
+
+Interpreter* Interpreter::mGlobalInterpreter = NULL;
+
+
+
+ //=======================================================================
+ /**
+   *  
+   */
+  Interpreter::Interpreter() 
+    :
+    mCommandLine(false), verbose(false)
+  {
+    bbtk::MessageManager::RegisterMessageType("Echo","Level>0 : Prints the 'echo' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
+    bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
+
+    mGlobalInterpreter = this;
+
+    //    mFactory = new bbtk::Factory();
+    mExecuter = new bbtk::Executer();
+    //mExecuter->SetFactory(mFactory);
+
+    // Builds the commands dict
+    CommandInfoType info;
+   
+    info.keyword = "new";
+    info.argmin = 2;
+    info.argmax = 2;
+    info.code = cNew;
+    info.syntax = "new <type> <name>";
+    info.help = "Creates a new black box of type <type> with name <name>";
+    mCommandDict[info.keyword] = info;
+    
+    info.keyword = "delete";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cDelete;
+    info.syntax = "delete <box>";
+    info.help = "Deletes the black box of name <box>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "connect";
+    info.argmin = 2;
+    info.argmax = 2;
+    info.code = cConnect;
+    info.syntax = "connect <box1.output> <box2.input>";
+    info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "print";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cPrint;
+    info.syntax = "print <string>";
+    info.help = "Prints the string. Substitutes any token of the form '$box.output$' by the string adaptation of the output of the box (requires the right adaptor). No carriage return is issued at the end, use '\\n' to add carriage returns. The level of 'Echo' messages must be greater than 1 (see the command 'message').";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "exec";
+    info.argmin = 1;
+    info.argmax = 2;
+    info.code = cExec;
+    info.syntax = "exec <box | 'freeze' | 'unfreeze' >";
+    info.help = "Executes the black box of name <box> (and connected boxes if needed). If the special keyword 'freeze' is given then freezes any further execution command. 'unfreeze' reverts to normal execution mode.";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "define";
+    info.argmin = 1;
+    info.argmax = 2;
+    info.code = cDefine;
+    info.syntax = "define <type> [<package>]";
+    info.help = "Begins the definition of a new type of complex black box called <type>. If <package> if provided will create it in the given package.";
+    mCommandDict[info.keyword] = info;
+    
+    info.keyword = "endefine";
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cEndDefine;
+    info.syntax = "endefine";
+    info.help = "Ends the definition of a new type of complex black box";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "input";
+    info.argmin = 3;
+    info.argmax = 3;
+    info.code = cInput;
+    info.syntax = "input <name> <box.input> <help>";
+    info.help = "Defines the input <name> of the current working black box as being an alias for the input <input> of the black box <box>. <help> defines the help string for the newly created input";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "output";
+    info.argmin = 3;
+    info.argmax = 3;
+    info.code = cOutput;
+    info.syntax = "output <name> <box.output> <help>";
+    info.help = "Defines the output <name> of the current working black box as being an alias for the output <output> of the black box <box>. <help> defines the help string for the newly created output";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "set";
+    info.argmin = 2;
+    info.argmax = 2;
+    info.code = cSet;
+    info.syntax = "set <box.input> <value>";
+    info.help = "Sets the value of the input <input> of the black box <box> to <value>. There must exist a string to the value type adaptor";
+    mCommandDict[info.keyword] = info;
+   
+    info.keyword = "config";  // JPR
+    info.argmin = 0;
+    info.argmax = 1;
+    info.code = cConfig;
+    info.syntax = "config [<verbose>|<v>]";
+    info.help = "Prints the value of all configuration parameters";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "reset";  //EED
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cReset;
+    info.syntax = "reset";
+    info.help = "Deletes all boxes and unloads all packages (bbi is reset to its start state)";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "author";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cAuthor;
+    info.syntax = "author <string>";
+    info.help = "Adds the string <string> to the author information of the black box being defined";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "description";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cDescription;
+    info.syntax = "description <string>";
+    info.help = "Adds the string <string> to the descriptive information of the black box being defined";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "help";
+    info.argmin = 0;
+    info.argmax = 2;
+    info.code = cHelp;
+    info.syntax = "help";
+    info.syntax = "\n         (1) help \n         (2) help <command name> \n         (3) help packages [all]\n         (4) help <package name> [all]\n         (5) help <black box type> \n         (6) help <black box name>";
+    info.help = "Effect :\n         (1) Lists all available commands;\n         (2) Prints help on a particular command; \n         (3) Lists the packages loaded and their black boxes.\n             Add 'all' to list adaptors; \n         (4) Prints short help on the black boxes of a package.\n             Add 'all' to include adaptors; \n         (5) Prints full help on a black box type; \n         (6) Prints information on the inputs, outputs and connections of a black box instance.";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "message";
+    info.argmin = 0;
+    info.argmax = 2;
+    info.code = cMessage;
+    info.syntax = "message <category> <level>";
+    info.help = "Sets the level of the category of messages <category> to <level>.\n  If category='All' then sets the level for all categories. If no category nor level is passed then prints info on available categories of messages and their current level.";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "include";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cInclude;
+    info.syntax = "include <filename>";
+    info.help = "Includes the file <filename>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "quit";
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cQuit;
+    info.syntax = "quit";
+    info.help = "Quits the program (during script execution it stops the complete execution)";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "load";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cLoad;
+    info.syntax = "load <packagename>";
+    info.help = "Loads the black box package <packagename>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "unload";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cUnload;
+    info.syntax = "unload <packagename>";
+    info.help = "Unloads the black box package <packagename>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "graph";
+    info.argmin = 0;
+    info.argmax = 6;
+    info.code = cGraph;
+    info.syntax = "graph [ BlackBoxName [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]] \n         graph [ BlackBoxNameType [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]]";
+    info.help = "Shows a graphical view of a bbtk pipeline.\n- BlackBoxName : name of the box to view. Default '.' : current box.\n- BlackBoxNameType : name of the type of box to view, ex : 'workspace')";
+    mCommandDict[info.keyword] = info;
+
+    /*
+    info.keyword = "workspace";
+    info.argmin = 1;
+    info.argmax = 2;
+    info.code = cWorkspace;
+    info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
+    info.help = "Configures the workspace.\n        'freeze' allow to block execution commands while keeping definition commands active. 'unfreeze' turns back the worspace in 'normal' mode.\n      'rename' allow to set a new name to the workspace.";
+    mCommandDict[info.keyword] = info;
+    */
+
+    bbtkDebugDecTab("Interpreter",9);
+
+  } 
+  //=======================================================================
+  
+  
+  
+  //=======================================================================  
+  /**
+   *  
+   */
+  Interpreter::~Interpreter()
+  {
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::~Interpreter()" <<std::endl);
+    delete mExecuter;
+    //delete mFactory;
+
+    //    std::cout <<"EO Interpreter::~Interpreter()"<<std::endl;
+    bbtkDebugDecTab("Interpreter",9);
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /**
+   *  
+   */
+  void Interpreter::InterpretFile( const std::string& filename,  bool use_configuration_file, bool verbose)
+  {
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
+
+    bool exm = mCommandLine;
+    mCommandLine = false;
+
+    try 
+    {
+      SwitchToFile(filename, use_configuration_file, verbose);
+      bool insideComment = false; // for multiline comment
+      while (mFile.size()>0) 
+      {
+         while ((mFile.size()>0) && 
+                (!mFile.back()->eof()))
+         {
+            mLine.back()++;
+            char buf[500];
+            mFile.back()->getline(buf,500);
+      
+            std::string str(buf);
+            int size=str.length();
+            if ( str[ size-1 ]==13  )
+            {
+               str.erase(size-1,1);
+            }
+      
+            InterpretLine(str, insideComment);
+         }
+        //if (mFile.size()>0) 
+        CloseCurrentFile();
+      }
+    }
+    catch (QuitException e) 
+    {
+    }
+    catch (bbtk::Exception e) 
+    {
+      std::cerr << "* ERROR : "<<e.GetMessage()<<std::endl;
+      if (mFileName.size()) {
+         std::cerr << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
+         std::cerr << "* LINE  : "<<mLine.back()<<std::endl;
+      }    
+    }
+    catch (std::exception& e) 
+    {
+       std::cerr << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
+       if (mFileName.size()) {
+          std::cerr << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
+          std::cerr << "* LINE  : "<<mLine.back()<<std::endl;
+       }    
+    }  
+    catch (...)
+    {
+       std::cout << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
+       if (mFileName.size()) {
+          std::cout << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
+          std::cout << "* LINE  : "<<mLine.back()<<std::endl;
+      }    
+    }
+    
+    CloseAllFiles();
+    bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
+    bbtkDecTab("Interpreter",9);
+
+    mCommandLine = exm;
+  }
+  //=======================================================================
+
+
+
+  //=======================================================================  
+  /**
+   *
+   */
+void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
+{
+
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine(\""<<line<<"\")"<<std::endl);
+    bbtkMessage("Echo",2,"\""<<line<<"\""<<std::endl);
+
+    std::vector<std::string> words;
+    SplitLine(line,words);
+    
+    // Empty line
+    if (words.size()<1) 
+    {
+       bbtkDebugDecTab("Interpreter",9);
+       return;
+    }
+
+    // Single line comment : # or //
+    if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') ) 
+    {  
+       bbtkDebugDecTab("Interpreter",9);
+       bbtkMessage("Interpreter",9,"Comment"<<std::endl);
+       return;
+    }
+
+    // Multi line comment ( /* ... */ ) -delimiters on different lines !-
+    
+    if (words[0][0]=='/' && words[0][1]=='*') 
+    {  
+       bbtkDebugDecTab("Interpreter",9);
+       bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
+       insideComment = true;
+       return;
+    }
+
+    if (words[0][0]=='*' && words[0][1]=='/') 
+    {  
+       bbtkDebugDecTab("Interpreter",9);
+       bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
+       if ( !insideComment ) {
+          bbtkDebugDecTab("Interpreter",9);
+          bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);       
+       }
+       insideComment = false;
+       return;
+    }
+
+    if (insideComment) 
+    {  
+       bbtkDebugDecTab("Interpreter",9);
+       bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
+       return;
+    }
+                
+    // Command 
+    CommandInfoType command;
+    InterpretCommand(words,command);
+
+    bbtkDebugMessage("Interpreter",9,
+                     "Command '"<<command.keyword
+                      <<" code="<<command.code<<std::endl); 
+    int level=0;
+    std::string left,right,left2,right2;
+    std::string filename;
+    switch (command.code) 
+    {
+      case cNew :
+            mExecuter->Create(words[1],words[2]);
+            break;
+        
+      case cDelete :
+            // TO DO !!
+            // mExecuter->Remove(words[1]);
+            break;
+        
+      case cConnect :
+            SplitAroundFirstDot(words[1],left,right);
+            SplitAroundFirstDot(words[2],left2,right2);      
+            mExecuter->Connect(left,right,left2,right2);
+            break;
+        
+      case cDefine :
+       if (mFileName.size()>0) 
+         {
+           filename = Utilities::get_file_name(mFileName.back());
+         }
+       if (words.size()==2) 
+         {
+           mExecuter->Define(words[1],"user",filename);
+         }
+       else 
+         {
+           mExecuter->Define(words[1],words[2],filename);
+         }
+       break;
+        
+      case cEndDefine :
+            mExecuter->EndDefine();
+            break;
+        
+      case cPrint :
+            Print(words[1]);
+            break;
+        
+      case cExec :
+       if (words[1]=="freeze") mExecuter->SetNoExecMode(true);
+       else if (words[1]=="unfreeze") mExecuter->SetNoExecMode(false);
+       else mExecuter->Update(words[1]);
+       break;
+        
+      case cInput :
+            SplitAroundFirstDot(words[2],left,right);
+            mExecuter->DefineInput(words[1],left,right,words[3]);
+            break;
+        
+      case cOutput :
+            SplitAroundFirstDot(words[2],left,right);
+            mExecuter->DefineOutput(words[1],left,right,words[3]);
+            break;
+        
+      case cSet :
+            SplitAroundFirstDot(words[1],left,right);
+            mExecuter->Set(left,right,words[2]);
+            break;
+        
+      case cAuthor :
+            mExecuter->Author(words[1]);
+            break;
+        
+      case cDescription :
+            mExecuter->Description(words[1]);
+            break;
+        
+      case cHelp :
+            Help(words);
+            break;
+        
+      case cMessage : 
+            if (words.size()<3) 
+            {
+            bbtk::MessageManager::PrintInfo();
+            }
+            else 
+            {
+            sscanf(words[2].c_str(),"%d",&level);
+            bbtk::MessageManager::SetMessageLevel(words[1],level);
+            }
+            break;
+        
+      case cGraph : 
+            Graph(words);
+            break;
+        
+      case cConfig :
+            if (words.size()>1) // any param for config means verbose = true
+              verbose = true;
+            else
+              verbose = false;
+            Config(verbose);            
+            break;
+        
+      case cReset :  // EED
+            this->mExecuter->Reset();
+            break;
+        
+      case cInclude :
+            if (mCommandLine) 
+            {
+           InterpretFile(words[1], true, verbose); // true : better pass use_config_file
+            }
+            else 
+            {
+            SwitchToFile(words[1], true, verbose); // true : better pass use_config_file
+            }
+            break;
+        
+      case cLoad:
+            LoadPackage(words[1], true, verbose); // true : better pass use_config_file
+            break;
+        
+      case cUnload:
+            UnLoadPackage(words[1]);
+            break;
+        
+      case cQuit :
+            throw QuitException();
+            break;
+        
+      case cWorkspace :
+            if (words.size() == 2) 
+            {
+               if (words[1]=="freeze") mExecuter->SetNoExecMode(true);
+               else if (words[1]=="unfreeze") mExecuter->SetNoExecMode(false);
+            }
+            else 
+            {
+               mExecuter->SetWorkspaceName(words[2]);
+            }
+            break;
+        
+      default:
+            bbtkInternalError("should not reach here !!!");
+   }
+    
+   bbtkDecTab("Interpreter",9);
+}
+  //=======================================================================  
+
+
+
+  //=======================================================================
+  void SplitString ( const std::string& str, const std::string& delimiters, 
+                     std::vector<std::string>& tokens)
+  {
+    // Skip delimiters at beginning.
+    std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
+    // Find first delimiter.
+    std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
+    
+    while (std::string::npos != pos || std::string::npos != lastPos)
+      {
+        // Found a token, add it to the vector.
+        tokens.push_back(str.substr(lastPos, pos - lastPos));
+        // Skip delimiters.  Note the "not_of"
+        lastPos = str.find_first_not_of(delimiters, pos);
+        // Find next delimiter
+        pos = str.find_first_of(delimiters, lastPos);
+      }
+    
+  }
+  //=======================================================================
+
+
+
+  //=======================================================================
+  /**
+   *  
+   */
+void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
+{
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
+    std::string delimiters = "\"";
+    std::vector<std::string> quote;
+    SplitString(str,delimiters,quote);
+
+    delimiters = " \t";
+    std::vector<std::string>::iterator i;
+    for (i=quote.begin(); i!=quote.end(); ) 
+    {
+       SplitString(*i,delimiters,tokens);
+       ++i;
+       if (i!=quote.end()) 
+       {
+        //    bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
+          tokens.push_back(*i);
+          ++i;
+       }
+    }
+
+    for (i=tokens.begin(); i!=tokens.end(); ++i) 
+    {
+       bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
+    }
+    bbtkDebugMessageCont("Interpreter",9,std::endl);
+
+    bbtkDebugDecTab("Interpreter",9);    
+ }
+  //=======================================================================
+
+
+  //=======================================================================
+  // Replaces substrings "\\n" by a real carriage return "\n"
+  void SubsBackslashN ( std::string& s )
+  {
+    //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
+    std::string ss("\\n");
+    std::string::size_type pos = 0;
+    pos = s.find(ss,0);
+    char* cr = "\n";
+    while ( pos != std::string::npos )
+   {
+      //  std::cout << "*** find one "<<std::endl;
+      s.replace(pos,2,cr,1);
+      pos = s.find(ss, pos-1);
+   } 
+    //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /**
+   *  
+   */
+  void Interpreter::Print( const std::string& str)
+  {
+    if (mExecuter->GetNoExecMode()) return;
+
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
+
+
+    std::vector<std::string> chains;
+    std::string delimiters("$");
+
+    // Skip delimiters at beginning.
+    std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
+    bool is_text = true;
+    if (lastPos>0) is_text = false;
+  
+    // Find first delimiter.
+    std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
+    
+    while (std::string::npos != pos || std::string::npos != lastPos)
+    {
+       if (is_text) 
+       {
+          // Found a text token, add it to the vector.
+          chains.push_back(str.substr(lastPos, pos - lastPos));
+          // std::cout << "text='"<<chains.back()<<"'"<<std::endl;
+       }
+       else 
+       {
+       // is an output (between $$) : decode 
+         std::string tok,box,output;
+         tok = str.substr(lastPos, pos - lastPos);
+         SplitAroundFirstDot(tok,box,output);
+         chains.push_back( mExecuter->Get(box,output) );
+    //    std::cout << "outp='"<<chains.back()<<"'"<<std::endl;
+       }
+        // Skip delimiters.  Note the "not_of"
+       lastPos = str.find_first_not_of(delimiters, pos);
+        // Find next delimiter
+       pos = str.find_first_of(delimiters, lastPos);
+    //
+       is_text = !is_text;
+     }
+    //    std::cout << "nb="<<chains.size()<<std::endl;
+     std::vector<std::string>::iterator i;
+     for (i= chains.begin(); i!=chains.end(); ++i) 
+     {
+       //  bbtkMessage("Echo",1,*i);
+       SubsBackslashN(*i);
+       std::cout << *i;
+     }
+     std::cout << std::endl;
+     bbtkDebugDecTab("Interpreter",9);    
+ }
+
+  //=======================================================================
+  /**
+   *  
+   */
+
+
+// --> usefull in many places (at least : ConfigurationFile, Factory, Interpreter)
+// should be factorized ( "bbtk::Util class ?)
+/*
+bool Interpreter::FileExists(std::string strFilename)
+bool Interpreter::IsAtRoot(std::string cwd)
+std::string Interpreter::ExtractPackageName(const std::string  &name)
+std::string Interpreter::ExpandLibName(const std::string &name, bool verbose)
+std::string Interpreter::MakeLibnameFromPath(std::string path, std::string pkgname)
+*/    
+// ===================================================================================
+  
+// See : http://www.techbytes.ca/techbyte103.html for more O.S.
+bool Interpreter::FileExists(std::string strFilename) {
+  struct stat stFileInfo;
+  bool blnReturn;
+  int intStat;
+
+  // Attempt to get the file attributes
+  intStat = stat(strFilename.c_str(),&stFileInfo);
+  if(intStat == 0) {
+    // We were able to get the file attributes
+    // so the file obviously exists.
+    blnReturn = true;
+  } else {
+    // We were not able to get the file attributes.
+    // This may mean that we don't have permission to
+    // access the folder which contains this file. If you
+    // need to do that level of checking, lookup the
+    // return values of stat which will give you
+    // more details on why stat failed.
+    blnReturn = false;
+  }
+
+  return(blnReturn);
+}
+    
+// ===================================================================================
+
+  std::string Interpreter::ExtractScriptName(const std::string  &name)
+  {
+    std::string pkgname;
+   
+    std::string::size_type slash_position = name.find_last_of("/\\");
+    if (slash_position != std::string::npos) {
+      pkgname =name.substr(slash_position+1,std::string::npos);   
+    } else {
+      pkgname = name;  
+    }      
+          
+    // remove {.bbs } if any
+    std::string::size_type dot_position = pkgname.find_last_of('.');      
+    if (dot_position != std::string::npos){
+      pkgname = pkgname.substr(0,dot_position);
+    }       
+    return pkgname;
+  }
+  
+// ===================================================================================
+
+  std::string Interpreter::ExpandLibName(const std::string &name, bool verbose)
+  {
+     // -----   Think of expanding path name ( ./ ../ ../../ )
+
+    char buf[2048]; // for getcwd
+    char * currentDir = getcwd(buf, 2048);
+    std::string cwd(currentDir);
+    std::string libname(name);
+    
+    // tooHigh : true is user supplies a library pathname with too many "../"
+    bool tooHigh = false;
+
+    if ( name[0] == '/' ||  name[0] == '\\' )
+    {
+      return(libname);
+    } 
+    else if  (name[0] == '.' && (name[1] == '/' || name[1] == '\\') ) 
+    {
+      libname = cwd  + ConfigurationFile::GetInstance().Get_file_separator () + name.substr(2, name.length());
+      return(libname);      
+    } 
+    else if ( name[0] == '.' &&  name[1] == '.' && (name[2] == '/' || name[2] == '\\') ) 
+    {       
+      if ( IsAtRoot(cwd) )  // hope it gets / (for Linux),  C: D: (for Windows)
+      {  
+     // if we are already at / or c: --> hopeless  
+         if (verbose)
+           std::cout << "   File path [" <<  name << "] doesn't exist" << std::endl;
+         tooHigh = true;
+      }
+      else
+      {
+         // iterate on ../ and go up from the current working dir!
+         std::string a(name); 
+         bool alreadyProcessRoot = false;
+         for(;;) 
+         {    
+            std::string::size_type slash_position = cwd.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ());
+            if (slash_position != std::string::npos) {
+             if (slash_position == 0)
+                slash_position = 1;        
+              cwd = cwd.substr(0,slash_position/*+1*/);
+                 a = a.substr(3, name.length());  // remove ../
+              if (a == "" || alreadyProcessRoot)
+              {
+                if (verbose)
+                  std::cout << "   File path [" <<  name << "] doesn't exist" << std::endl;
+                tooHigh = true;
+                break;
+              }
+             // std::string b = cwd + a;
+              libname =  cwd;
+              char c = cwd[cwd.size()-1];
+              if (c != '/' && c != '\\' )
+                libname += ConfigurationFile::GetInstance().Get_file_separator ();
+              libname += a;           
+              if ( a[0] != '.' ) // if . (probabely ../), loop again
+                break;
+               
+              if (IsAtRoot(cwd))
+                alreadyProcessRoot = true;                            
+            }                  
+         } // end iterating on ../
+      }
+      if (tooHigh)
+         libname="";
+      return (libname);
+      
+    }  // -----   End of expanding path name   ( ./ ../ ../../ )
+    
+    // To avoid warning
+    return(""); // Will never get here!
+  } 
+
+  
+// ===================================================================================
+
+  std::string Interpreter::MakeLibnameFromPath(std::string path, std::string pkgname)
+  {
+    std::string libname = path;
+         char c = path[path.size()-1];
+         if (c != '/' && c != '\\')
+            libname +=  ConfigurationFile::GetInstance().Get_file_separator ();
+         libname += pkgname;
+         libname += ".bbs";
+    return libname;    
+  }
+  
+// ===================================================================================
+
+  bool  Interpreter::IsAtRoot(std::string cwd)
+  {
+    if ( cwd == "/"                          // hope it gets /     (for Linux)
+        || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows)
+      return (true);
+    else
+      return(false);
+}
+
+  
+// ===================================================================================
+
+
+  void Interpreter::SwitchToFile( const std::string& name,
+                                  bool use_configuration_file, bool verbose)
+  {
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
+                         <<name<<"\")"<<std::endl);
+
+    std::vector<std::string> script_paths;
+    std::string libname;  // full path library name
+    std::string pkgname;  // e.g. <scriptname>.bbs
+     
+    pkgname = ExtractScriptName(name);
+
+    if (use_configuration_file)
+    {
+      if (verbose)
+         std::cout << "look for : [" << name << "] (use_configuration_file == TRUE)"  << std::endl;
+      script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
+    }
+
+    bool fullnameGiven = false; 
+    bool foundFile     = false;
+    std::string::size_type slash_position = name.find_last_of("/\\");
+  
+    if (slash_position != std::string::npos)
+    {
+      fullnameGiven = true;     
+      libname = ExpandLibName(name, verbose);
+      if (libname != "") {
+        if (FileExists(libname))
+        {
+          foundFile = true;
+        }
+      }
+    }
+    else    // ----------------------- iterate on the paths
+    {
+      std::string path;    
+      std::vector<std::string>::iterator i;
+      for (i=script_paths.begin();i!=script_paths.end();++i)
+      {
+        path = *i;
+
+       // we *really* want '.' to be the current working directory
+        if (path == ".") {
+          char buf[2048]; // for getcwd
+          char * currentDir = getcwd(buf, 2048);
+          std::string cwd(currentDir);        
+          path = currentDir;
+        }
+
+        libname = MakeLibnameFromPath(path, pkgname);
+
+      // Check if library exists           
+        if ( !FileExists(libname) )
+        {
+          if (verbose)
+            std::cout <<"   [" <<libname <<"] : doesn't exist" <<std::endl;
+            continue;  // try next path
+        }
+        foundFile = true;
+        break; // a script was found; we stop iterating
+
+      } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
+    }
+
+    std::ifstream* s;
+
+    if (!foundFile)
+    {
+       if (fullnameGiven)
+         if(libname == "")
+            bbtkError("Path \""<<name<<"\" doesn't exist");
+         else
+            bbtkError("Script \""<<libname<<"\" not found");
+       else
+          bbtkError("No \""<<pkgname<<".bbs\" script found");
+       return;    
+    }
+
+    bbtkMessage("Interpreter",1,pkgname<<" loaded"<<std::endl);
+    
+    s = new std::ifstream;
+    s->open(libname.c_str());
+    if (!s->good()) 
+    {
+        bbtkError("Could not open file \""<<libname<<"\"");
+        return;     
+    }
+
+    if (verbose)
+       std::cout << "   -->[" << libname << "] found" << std::endl;
+
+    mFile.push_back(s);
+    mFileName.push_back(libname);
+    mLine.push_back(0);
+  }   
+   
+
+  //=======================================================================
+
+
+  //=======================================================================
+  /**
+   *  
+   */
+  void Interpreter::CloseCurrentFile()
+  {
+    bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
+                      <<std::endl);
+    
+    if (mFile.size()==0) 
+    {
+      bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
+      return;
+    }
+
+    mFile.back()->close();
+    delete mFile.back();
+    mFile.pop_back();
+    bbtkDebugMessage("Interpreter",9,
+                     " Closing file '"<<mFileName.back()<<"'"<<std::endl);
+    
+    mFileName.pop_back();
+    mLine.pop_back();
+    bbtkDebugMessage("Interpreter",9," Remains "
+                     <<mFile.size()
+                     <<" open"<<std::endl);
+    bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
+                     <<std::endl);
+  }
+  //=======================================================================
+
+ //=======================================================================
+  /**
+   *  
+   */
+  void Interpreter::CloseAllFiles()
+  {
+    bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
+                      <<std::endl);
+    
+    while (mFile.size() != 0) 
+    {
+      mFile.back()->close();
+      delete mFile.back();
+      mFile.pop_back();
+      bbtkDebugMessage("Interpreter",9,
+                      " Closing file '"<<mFileName.back()<<"'"<<std::endl);
+      mFileName.pop_back();
+      mLine.pop_back();
+    }
+    bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
+                      <<std::endl);
+  }
+  //=======================================================================
+
+
+
+  //=======================================================================
+  /**
+   *  
+   */
+  void Interpreter::InterpretCommand( const std::vector<std::string>& words,
+                                      CommandInfoType& info )
+  {
+    bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
+    
+    // searches the command keyword
+    CommandDictType::iterator c;
+    c = mCommandDict.find(words[0]);
+    if ( c == mCommandDict.end() ) {
+      bbtkError(words[0]<<" : unknown command");
+    }
+
+    // tests the number of args 
+    if ( ( words.size()-1 < c->second.argmin ) ||
+         ( words.size()-1 > c->second.argmax ) )
+    {
+       HelpCommand(words[0]);
+       bbtkError(words[0]<<" : wrong number of arguments");
+    }
+
+    info = c->second;
+    bbtkDecTab("Interpreter",9);
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /// Displays help on all the commands
+void Interpreter::Help(const std::vector<std::string>& words)
+{
+    unsigned int nbarg = words.size()-1;
+    
+    if (nbarg==0) 
+    {
+       HelpCommands();
+    }
+    else if (nbarg==1) 
+    {
+      if (words[1]=="packages") 
+      {
+         PrintPackages(true);
+         return;
+      }
+      try 
+      {
+          HelpCommand(words[1]);
+      }
+      catch (bbtk::Exception e) 
+      {
+         try 
+         {
+            HelpPackage(words[1]);
+         }
+         catch (bbtk::Exception f) 
+         {
+            try 
+            {
+               HelpBlackBox(words[1]);
+            }
+           catch (bbtk::Exception g) 
+           {
+              try
+              {
+                 this->mExecuter->ShowRelations(words[1],"0","9999");
+              }
+              catch (bbtk::Exception h){
+                bbtkError("\""<<words[1].c_str()
+                          <<"\" is not a known command, package, black box type or black box name");
+              }
+           }
+         }
+       }
+    }
+    else if (nbarg==2) 
+    {
+      if (words[2]=="all")
+      {
+         if ( words[1]=="packages" )
+         {
+            PrintPackages(true,true);
+            return;
+          }
+         try 
+         {
+            HelpPackage(words[1],true);
+         }
+         catch (bbtk::Exception f) 
+         {
+         }
+     }
+     else 
+     {
+        HelpCommand(words[0]);
+        bbtkError(words[0]<<" : syntax error");
+     }
+  }
+  else 
+  {
+     bbtkError("Should not reach here !!!");
+  }
+}
+  //=======================================================================
+
+   //===================================================================    
+  /// Displays the Configuration
+  void Interpreter::Config( bool verbose ) const
+  {
+    bbtkDebugMessageInc("Core",9,"Factory::Config"<<std::endl);
+    
+    ConfigurationFile cf = ConfigurationFile::GetInstance();
+    
+    const std::string config_xml_full_path      = cf.Get_config_xml_full_path();    
+    const std::string description               = cf.Get_description();
+    const std::string url                       = cf.Get_url();
+    const std::string data_path                 = cf.Get_data_path();
+    const std::string default_doc_tmp           = cf.Get_default_doc_tmp();    
+    const std::string file_separator            = cf.Get_file_separator();    
+    const std::vector<std::string>bbs_paths     = cf.Get_bbs_paths();
+    const std::vector<std::string>package_paths = cf.Get_package_paths();
+    
+    bbtkMessage("Help",1, "============="   << std::endl);           
+    bbtkMessage("Help",1, "Configuration"   << std::endl);
+    bbtkMessage("Help",1, "============="   << std::endl);
+    bbtkMessage("Help",1, "bbtk_config.xml   : [" << config_xml_full_path  << "]" << std::endl); 
+    bbtkMessage("Help",1, "Documentation Url : [" << url             << "]" << std::endl);
+    bbtkMessage("Help",1, "Data Path         : [" << data_path       << "]" << std::endl);
+    bbtkMessage("Help",1, "Default Doc_tmp   : [" << default_doc_tmp << "]" << std::endl);
+    bbtkMessage("Help",1, "File Separator    : [" << file_separator  << "]" << std::endl);
+
+    std::vector<std::string>::const_iterator i;
+           
+    bbtkMessage("Help",1, "BBS Paths   " << std::endl);     
+    for (i = bbs_paths.begin(); i!=bbs_paths.end(); ++i )
+    {
+      bbtkMessage("Help",1,"--- ["<<*i<<"]"<<std::endl);
+    }    
+    
+    bbtkMessage("Help",1, "PACKAGE Paths : " << std::endl);     
+    for (i = package_paths.begin(); i!=package_paths.end(); ++i )
+    {
+      bbtkMessage("Help",1,"--- ["<<*i<<"]"<<std::endl);
+    }
+
+    bbtkDebugDecTab("Core",9);
+  }  
+
+  //=======================================================================
+  /// Displays help on all the commands
+  void Interpreter::HelpCommands()
+  {
+    std::cout << "Available commands :" << std::endl;
+    CommandDictType::iterator i;
+    for ( i =  mCommandDict.begin();
+          i != mCommandDict.end();
+        ++i) {
+              std::cout << " " << i->first << std::endl;
+      //      std::cout << "   usage : " << i->second.syntax << std::endl;
+      //     std::cout << "    " << i->second.help << std::endl;
+    }
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /// Displays help on a particular commands
+  void Interpreter::HelpCommand(const std::string& s)
+  {
+    CommandDictType::iterator c;
+    c = mCommandDict.find(s);
+    if ( c == mCommandDict.end() ) {
+      bbtkError(s<<" : Unknown command");
+    }
+    //    std::cout << " " << s << " : "<<  std::endl;
+    //    CommandParamDictType::iterator i;
+    //    for ( i =  c->second.begin();
+    //      i != c->second.end();
+    //      ++i) {
+    std::cout << " usage : " << c->second.syntax << std::endl;
+    std::cout << "  " << c->second.help << std::endl;
+    
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /// Fills the vector commands with the commands which 
+  /// have the first n chars of buf for prefix
+  /// TODO : skip initial spaces in buf and also return the position of first
+  /// non blank char in buf
+  void Interpreter::FindCommandsWithPrefix( char* buf,
+                                            int n,
+                                            std::vector<std::string>& commands )
+  {
+    CommandDictType::const_iterator i;
+    for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
+    {
+      if ((i->first).find(buf,0,n) == 0) 
+        commands.push_back(i->first);
+    }
+  }
+  //=======================================================================
+
+
+  
+  //=======================================================================
+#ifdef BBTK_USE_TERMIOS_BASED_PROMPT
+  
+  inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
+  inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
+  
+  // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
+  // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
+  // E.G. STORE THIS IN bbtk_config.xml
+#define BBTK_UP_ARROW_KBCODE    0x00415B1B
+#define BBTK_DOWN_ARROW_KBCODE  0x00425B1B
+#define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
+#define BBTK_LEFT_ARROW_KBCODE  0x00445B1B
+#define BBTK_BACKSPACE_KBCODE   0x00000008
+#define BBTK_DEL_KBCODE         0x0000007F
+#define BBTK_SPACE_KBCODE       0x00000020 
+
+  //=======================================================================
+  void Interpreter::GetLineFromPrompt(std::string& s)
+  {
+    int c;
+    int ind=0;
+    
+    int MAX_LINE_SIZE = 160;
+    int MAX_HISTORY_SIZE = 100;
+    
+    char* newline = new char[MAX_LINE_SIZE];
+    memset(newline,0,MAX_LINE_SIZE);
+    char* histline = new char[MAX_LINE_SIZE];
+    memset(histline,0,MAX_LINE_SIZE);
+    
+    char* line = newline;
+    int hist = mHistory.size();
+    
+    
+    write(1,"> ",2);
+    while(1)
+    {
+       c=0;
+       read ( STDIN_FILENO, &c, 4) ;
+
+       bbtkDebugMessage("Debug",9,"[0x"<<std::hex<<c<<"]\n");
+
+       // Printable character
+       if ( (ind<MAX_LINE_SIZE-1) &&
+            ( c >= BBTK_SPACE_KBCODE ) && 
+            ( c <  BBTK_DEL_KBCODE )) 
+       {
+          PrintChar(c);
+          line[ind++]=c;
+       }
+      // CR
+       else if (c=='\n')
+       {
+       // delete the unused line
+          if (line==newline)
+              delete histline;
+          else
+              delete newline;
+   
+    // empty lines are not stored in from history
+          if (strlen(line)) 
+          {
+               // if history too long : delete oldest command
+               if (mHistory.size()>MAX_HISTORY_SIZE) 
+                 {
+                   delete mHistory.front();
+                   mHistory.pop_front();
+                 }
+               mHistory.push_back(line);
+          }
+    
+          break;
+        }
+       // Backspace
+       else if ( (ind>0) && 
+                 ((c == BBTK_BACKSPACE_KBCODE) ||
+                  (c == BBTK_DEL_KBCODE)) )
+         {
+           line[ind--]=' ';
+           BackSpace();
+         }
+       // Tab 
+       else if (c=='\t')
+         {
+           // TODO : Command completion  
+           std::vector<std::string> commands;
+           FindCommandsWithPrefix( line,ind,commands);
+           if (commands.size()==1) 
+             {
+               std::string com = *commands.begin();
+               for (; ind<com.size(); ++ind) 
+                 {
+                   PrintChar(com[ind]); 
+                   line[ind]=com[ind];
+                 }
+               PrintChar(' '); 
+               line[ind++]=' ';
+             }
+           else if (commands.size()>1) 
+             {
+               std::vector<std::string>::iterator i;
+               write(1,"\n",1);
+               for (i=commands.begin();i!=commands.end();++i) 
+                 {
+                   write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
+                   PrintChar(' ');
+                 }
+               write(STDOUT_FILENO,"\n> ",3);
+               //for (int j=0;j<ind;++j) 
+                 //{
+                   write(STDOUT_FILENO,line,ind); 
+                   //  }
+             }
+         }
+       // Arrow up : back in history
+       else if (c==BBTK_UP_ARROW_KBCODE)
+         {
+           if (hist) 
+             {
+               // erase current line
+               while (ind--) BackSpace();
+               // 
+               hist--;
+               // 
+               strcpy(histline,mHistory[hist]);
+               line = histline;
+               ind = strlen(line);
+               
+               write(STDOUT_FILENO,line,ind);
+             }
+         }
+       // Arrow down : down in history
+       else if (c==BBTK_DOWN_ARROW_KBCODE)
+         {
+           if (hist<mHistory.size()-1) 
+             {
+               // erase current line
+               while (ind--) BackSpace();
+               // 
+               hist++;
+               // 
+               strcpy(histline,mHistory[hist]);
+               line = histline;
+               ind = strlen(line);
+               
+               write(STDOUT_FILENO,line,ind);
+             }
+           // end of history : switch back to newline
+           else if (hist==mHistory.size()-1)
+             {
+               // erase current line
+               while (ind--) BackSpace();
+               // 
+               hist++;
+               // 
+               line = newline;
+               ind = strlen(line);
+               
+               write(STDOUT_FILENO,line,ind);
+             }
+         }
+       // Arrow right
+       else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
+         {
+           PrintChar(line[ind]);
+           ind++;
+         }
+       
+       // Arrow left
+       else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
+         {
+           PrintChar('\b');
+           ind--;
+           
+         }
+
+      }
+    write(STDOUT_FILENO,"\n\r",2);
+    
+    
+    s = line;
+    
+  }
+#else
+
+  //=======================================================================
+  void Interpreter::GetLineFromPrompt(std::string& s)
+  {  
+    s.clear();
+
+    putchar('>');
+    putchar(' ');
+
+    do 
+    {
+      char c = getchar();
+      if (c=='\n') 
+      {
+        putchar('\n');
+        break;
+      }
+      if (c=='\t') 
+      {
+        // putchar('T');
+        continue;
+      }
+      // putchar(c);
+      s += c;
+    } 
+    while (true);  
+    
+  }
+  //=======================================================================  
+
+#endif
+
+
+
+  //=======================================================================
+  void Interpreter::CommandLineInterpreter()
+  {
+    bbtkDebugMessageInc("Interpreter",9,
+                        "Interpreter::CommandLineInterpreter()"<<std::endl);
+    
+#ifdef BBTK_USE_TERMIOS_BASED_PROMPT  
+    // Initialise the tty in non canonical mode with no echo
+    // oter remembers the previous settings to restore them after 
+    struct termios ter,oter;
+    tcgetattr(0,&ter);
+    oter=ter;
+    ter.c_lflag &= ~ECHO;
+    ter.c_lflag &= ~ICANON;
+    ter.c_cc[VMIN]=1;
+    ter.c_cc[VTIME]=0;
+    tcsetattr(0,TCSANOW,&ter);
+#endif
+    
+    mCommandLine = true;
+    bool again = true;
+    bool insideComment = false; // for multiline comment  
+    do 
+    {
+      try 
+      {
+        std::string line;
+        GetLineFromPrompt(line);
+        InterpretLine(line, insideComment);
+      }
+      catch (QuitException e)
+      {
+        again = false;
+      }
+      catch (bbtk::Exception e) 
+      {
+        e.Print();
+      }
+        catch (std::exception& e) 
+      {
+        std::cerr << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
+      }
+      catch (...)
+      {
+        std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
+      }
+    }
+    while (again);
+  
+#ifdef BBTK_USE_TERMIOS_BASED_PROMPT
+    tcsetattr(0,TCSANOW,&oter);
+#endif
+  
+    std::cout << "Good bye !" << std::endl;
+    
+    bbtkDebugDecTab("Interpreter",9);
+  }
+  //=======================================================================
+  
+  
+  //=======================================================================
+  void Interpreter::SplitAroundFirstDot( const std::string& in,
+                                         std::string& left,
+                                         std::string& right)
+  {
+    bbtkDebugMessageInc("Interpreter",9,
+                        "Interpreter::SplitAroundFirstDot(\""
+                        <<in<<"\")"<<std::endl);
+    
+    std::string delimiter = ".";
+    std::string::size_type pos = in.find_first_of(delimiter);
+    if (std::string::npos != pos) 
+    {
+       left = in.substr(0,pos);
+       right = in.substr(pos+1,in.size());
+       bbtkDebugMessage("Interpreter",9,
+       "["<<left<<"] ["<<right<<"]"<<std::endl);
+    }
+    else 
+    {
+       bbtkError(in<<" : expected 'a.b' format but no dot found");
+    }
+    
+    bbtkDebugDecTab("Interpreter",9);
+  }
+  //=======================================================================
+  
+
+
+  //=======================================================================
+  void Interpreter::Graph(const std::vector<std::string>& words)
+  {
+    std::string page;
+    bool system_display = true;
+
+#ifdef _USE_WXWIDGETS_
+    if ( WxConsole::GetInstance() != 0 ) system_display = false; 
+#endif
+    if (words.size()==1) 
+    {
+      page = mExecuter->ShowGraph(".","0","0","","","",system_display);
+    }
+    else if (words.size()==2) 
+    {
+      page = mExecuter->ShowGraph(words[1],"0","0","","","",system_display);
+    }
+    else if (words.size()==3) 
+    {
+      page = mExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
+    }
+    else if (words.size()==4) 
+    {
+      page = mExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
+    } 
+    else if (words.size()==5) 
+    {
+      page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
+    } 
+    else if (words.size()==6) 
+    {
+      page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
+    } 
+    else if (words.size()==7) 
+    {
+      page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
+    } 
+
+#ifdef _USE_WXWIDGETS_
+    if ( WxConsole::GetInstance() != 0 )
+      WxConsole::GetInstance()->ShowHtmlPage(page);
+#endif
+  }
+  //=======================================================================
+
+
+}//namespace
+
+
diff --git a/kernel/src/bbtkInterpreter.h b/kernel/src/bbtkInterpreter.h
new file mode 100644 (file)
index 0000000..b078a58
--- /dev/null
@@ -0,0 +1,208 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkInterpreter.h,v $ $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *  \file 
+ *  \brief class Interpreter : The bbtk language interpreter
+ */
+/**
+ *  \class bbtk::Interpreter 
+ *  \brief The bbtk language interpreter
+ */
+  
+#ifndef __bbtkInterpreter_h__
+#define __bbtkInterpreter_h__
+
+
+#include "bbtkExecuter.h"
+#include <fstream>
+#include <deque>
+
+namespace bbtk
+{
+  class BBTK_EXPORT Interpreter
+  {
+
+  private:
+    
+    /// The enumeration of command codes == Command name
+    typedef enum 
+    {
+      cNew, 
+      cDelete,
+      cConnect,
+      cExec,
+      cDefine,
+      cEndDefine,
+      cInput,
+      cOutput,
+      cSet,
+      cConfig,  // JPR
+      cReset,   // EED
+      cAuthor,
+      cDescription,
+      cHelp,
+      cMessage,
+      cInclude,
+      cQuit,
+      cLoad,
+      cUnload,
+      cGraph,
+      cPrint,
+      cWorkspace // LG 
+    } CommandCodeType;
+    
+    /// The structure storing the informations on a command 
+    typedef struct 
+    {
+      std::string keyword;
+      int argmin, argmax;
+      CommandCodeType code;
+      std::string syntax;
+      std::string help;
+    } CommandInfoType;
+
+
+
+    /// The type of dictionnary of commands 
+    typedef std::map<std::string,CommandInfoType> CommandDictType;
+
+  public:
+    /// Constructor
+    Interpreter();  
+    /// Destructor
+    ~Interpreter();
+      
+   static Interpreter* mGlobalInterpreter;
+
+    /// Launches a command line interpreter (with a prompt)
+    void CommandLineInterpreter();
+    
+    /// Sets the inputs of the workspace : 
+    /// the map is passed as is to the Executer
+    void SetInputs(const std::map<std::string,std::string>& m)
+    { mExecuter->SetInputs(m); }
+    /// Puts the executer in "no exec" mode, 
+    /// which creates but does not execute pipelines.
+    void SetNoExecMode(bool b) { mExecuter->SetNoExecMode(b); }
+
+    /// 
+    typedef Executer::DialogModeType DialogModeType;
+
+    void SetDialogMode(DialogModeType t) { mExecuter->SetDialogMode(t); }
+
+    /// Runs the interpretation of a file
+    void InterpretFile( const std::string& filename, bool use_configuration_file=true, bool verbose=false);
+
+    /// Interprets a line (either from a file or typed interactively)
+    void InterpretLine( const std::string& line, bool &insideComment );
+
+    /// Reads a line from prompt
+    void GetLineFromPrompt( std::string& line );
+
+    /// Splits a line into words
+    void SplitLine ( const std::string& line,
+                     std::vector<std::string>& words );
+
+    /// Executes the right action depending on the command name  
+    void InterpretCommand( const std::vector<std::string>& words, 
+                           CommandInfoType& info );
+    
+    /// Switch to the interpretation of a file
+    void SwitchToFile( const std::string& filename, bool use_configuration_file=true, bool verbose=false );
+    
+    /// Closes the currently open file
+    void CloseCurrentFile();
+    
+    /// Closes all open files
+    void CloseAllFiles();
+
+    /// Displays help (entry point of any help)
+    void Help(const std::vector<std::string>& words);
+    
+    /// Displays help on all the commands
+    void HelpCommands();
+    
+    /// Displays help on a particular command 
+    void HelpCommand( const std::string& command );
+    
+    ///
+    void Graph(const std::vector<std::string>& words);
+    
+    ///
+    void Config(bool verbose) const; // JPR
+    /// 
+    void Print(const std::string&);
+    
+    /// Splits the string in around the first dot encountered
+    void SplitAroundFirstDot( const std::string& in,
+                              std::string& left,
+                              std::string& right);
+    ///
+    void FindCommandsWithPrefix( char* buf,
+                                int n,
+                                std::vector<std::string>& commands );
+             
+    /// Sets the bool that indicates wether we are in command line context
+    void SetCommandLine(bool v = true) { mCommandLine = v; }
+
+  private:
+  /// the methods for include bbs
+  bool FileExists(std::string strFilename);
+  std::string ExtractScriptName(const std::string &name);
+  std::string ExpandLibName(const std::string &name, bool v);  
+  std::string MakeLibnameFromPath(std::string path, std::string pkgname);
+  bool IsAtRoot(std::string cwd);       
+    
+  private:
+  
+    //==================================================================
+    // ATTRIBUTES
+    /// The factory
+    //    bbtk::Factory* mFactory;
+    /// The command executer  
+    bbtk::Executer* mExecuter;
+    /// Vector of opened files  
+    std::vector<std::ifstream*> mFile; 
+    /// Vector of names of open files  
+    std::vector<std::string> mFileName; 
+    /// Stores the current line number in each open file
+    std::vector<int> mLine; 
+    /// The dictionnary of commands
+    CommandDictType mCommandDict;
+    /// Are we in a command line context ?
+    bool mCommandLine;
+    /// The history of commands 
+    std::deque< char* > mHistory; 
+    
+    bool verbose; // true -> displays the search results (for packages)
+  };
+
+
+  // The "Quit" exception
+  struct QuitException : public bbtk::Exception
+  {
+    QuitException() : bbtk::Exception("","","") {}
+  };
+
+
+
+}
+#endif
diff --git a/kernel/src/bbtkMessageManager.cxx b/kernel/src/bbtkMessageManager.cxx
new file mode 100644 (file)
index 0000000..ff2c393
--- /dev/null
@@ -0,0 +1,173 @@
+   /*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkMessageManager.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ * \file
+ * \brief class MessageManager : Manages the messages displayed by bbtk (code)
+ */
+#include "bbtkMessageManager.h"
+
+namespace bbtk 
+{
+
+  MessageManager::MessageManager() 
+    : mMaxMessageLength(8), mAllLevel(0) 
+    
+  {
+    std::string key;
+    key ="Core";
+    mMessageLevel[key] = 0;
+    mMessageHelp[key] = "Messages generated by the core classes of the lib";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key ="Process";
+    mMessageLevel[key] = 0;
+    mMessageHelp[key] = "Messages related to box processing";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Help";
+    mMessageLevel[key] = 1;
+    mMessageHelp[key] = "Help messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Error";
+    mMessageLevel[key] = 0;
+    mMessageHelp[key] = "Error messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Warning";
+    mMessageLevel[key] = 1;
+    mMessageHelp[key] = "Warning messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Output";
+    mMessageLevel[key] = 1;
+    mMessageHelp[key] = "Output messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Debug";
+    mMessageLevel[key] = 0;
+    mMessageHelp[key] = "Debug messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Config";
+    mMessageLevel[key] = 0;
+    mMessageHelp[key] = "Configuration related messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Data";
+    mMessageLevel[key] = 0;
+    mMessageHelp[key] = "Data related messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+    key = "Wx";
+    mMessageLevel[key] = 0;
+    mMessageHelp[key] = "Widgets related messages";
+    if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
+  }
+
+
+
+
+  MessageManager::~MessageManager() 
+  {
+    //      std::cout << "~MessageManager"<<std::endl;
+  }
+  
+
+
+  MessageManager* MessageManager::GetInstance() 
+  { 
+    static MessageManager* m = 0;
+    if (!m) m = new MessageManager();
+    return m; 
+  }
+
+  void MessageManager::RegisterMessageType(std::string key, 
+                                                 std::string help,
+                                                 unsigned char default_level) 
+  {
+    GetInstance()->mMessageLevel[key] = default_level;
+    GetInstance()->mMessageHelp[key] = help;
+    if (GetInstance()->mMaxMessageLength<key.length()) 
+      GetInstance()->mMaxMessageLength = key.length();
+  }
+
+
+
+  void MessageManager::SetMessageLevel(std::string key, 
+                                             unsigned char level) 
+  {
+    std::map<std::string,int>::iterator i;
+    if (key==std::string("All")) {
+      GetInstance()->mAllLevel = level;
+      
+      for (i=GetInstance()->mMessageLevel.begin();
+          i!=GetInstance()->mMessageLevel.end();
+          ++i) 
+        (*i).second = level;
+      
+    }
+    else {
+      i = GetInstance()->mMessageLevel.find(key);
+      if (i!=GetInstance()->mMessageLevel.end()) {
+       (*i).second = level;
+      }
+      else {
+       bbtkWarning("MessageManager::SetMessageLevel : message type=<"
+                   <<key<<"> unregistered");
+      }
+    }
+  }
+
+
+
+  int MessageManager::GetMessageLevel(std::string key) 
+  {
+    int l = GetInstance()->mAllLevel;
+    std::map<std::string,int>::iterator i = 
+      GetInstance()->mMessageLevel.find(key);
+    if (i!=GetInstance()->mMessageLevel.end()) {
+      if ( (*i).second > l ) l = (*i).second;      
+    }
+    return l;
+  }
+
+
+
+  void MessageManager::PrintInfo() 
+  {
+    bbtkMessage("Help",1,"================ Messages =================" 
+               << bbtkendl);
+    bbtkMessage("Help",1, "Category");
+    for (int k=0;
+        k<(int)(GetInstance()->mMaxMessageLength-8);
+        k++) {
+      bbtkMessageCont("Help",1," "); 
+    }
+    bbtkMessageCont("Help",1,"Level  Nature" << bbtkendl);
+    std::map<std::string,int>::iterator i;
+    std::map<std::string,std::string>::iterator j;  
+    for (i=GetInstance()->mMessageLevel.begin(),
+          j=GetInstance()->mMessageHelp.begin();
+        i!=GetInstance()->mMessageLevel.end();++i,++j) {
+      bbtkMessage("Help",1, (*i).first);
+      for (int k=0;
+          k<(int)(GetInstance()->mMaxMessageLength+2-(*i).first.length());
+          k++) {
+       bbtkMessageCont("Help",1," ");
+      }
+      bbtkMessageCont("Help",1, (*i).second << "\t" 
+                     << (*j).second << bbtkendl);
+    }
+    bbtkMessage("Help",1,"===========================================" 
+               << bbtkendl);
+  }
+  
+
+}
diff --git a/kernel/src/bbtkMessageManager.h b/kernel/src/bbtkMessageManager.h
new file mode 100644 (file)
index 0000000..221c986
--- /dev/null
@@ -0,0 +1,424 @@
+
+/*! \file
+  \brief Class bbtkMessageManager and Macros for outputing messages in bbtk
+
+  There are 4 kinds of messages :
+  - Messages (normal messages)
+  - Debug messages (not compiled in release)
+  - Warnings 
+  - Errors
+  There are also "types" of messages which are strings which identify the nature of the message 
+  (for example : "Core" messages are generated by the core classes of the librairy, there can be a type of 
+  message for each type of Node, and so on...)
+  A type of message must be declared by registering it into the MessageManager. This is done by a line like :
+  bbtk::MessageManager::RegisterMessageType("Core","Messages generated by the core classes of the library",5);
+  where : 
+  -The first string is the type of the message (the keyword which will be used to generate a message of this type)
+  -The second string is help string
+  -The integer is the initial level for the messages of this type (see below).
+  
+  To generate a message of a known type then use one of the macros :
+  bbtkMessage, bbtkDebugMessage, bbtkWarning, bbtkError or their variants.
+
+  example :
+
+  bbtkMessage("Core",4,"problem with "<<GetName()<<bbtkendl);
+
+  will push the 3rd argument in std::cout if the message level of "Core" messages is greater or equal to 4.
+  which means that it generates a message of level 4 (0 : very important/always displayed ... 9 : deep debug message).
+
+  At run time, one is able to change the level of the messages displayed by using a command like :
+  
+  bbtk::MessageManager::SetMessageLevel("Core",5); 
+  
+  which tells the manager to display all Core messages of level up to 5.
+
+  Variants :
+
+  bbtk*Cont : continues a previous bbtkMessage on the same line (without rewriting the type and level)
+  bbtk*Inc / Dec : displays the message and then increments/decrement the messages tabulation 
+
+*/
+  //===========================================================
+  /**
+     \class bbtk::MessageManager
+     \brief Manages the messages displayed by bbtk
+  */
+
+
+#ifndef __bbtkMessageManager_h__
+#define __bbtkMessageManager_h__
+
+// The do { } while(0) statement in macros is made to "swallow the semicolon" 
+// see http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon
+
+#include "bbtkSystem.h"
+#include "bbtkRTTI.h"
+
+#include <string>
+#include <map>
+#include <iostream>
+#include <sstream>
+
+// Comment out these symbols to prevent compilation 
+//#define BBTK_COMPILE_MESSAGES
+//#define BBTK_COMPILE_DEBUG_MESSAGES
+//#define BBTK_COMPILE_WARNING_MESSAGES
+//#define BBTK_COMPILE_ERROR_MESSAGES
+
+
+#define bbtkOnMessageLevel(key,value)                  \
+  int __bbtkOnMessageLevelVariable =                   \
+    bbtk::MessageManager::GetMessageLevel(key);                \
+  if ( __bbtkOnMessageLevelVariable<0)                 \
+    {                                                  \
+      bbtkWarning("message type '"<<key<<"' unknown"); \
+    }                                                  \
+  else if (value<= __bbtkOnMessageLevelVariable) 
+
+#ifdef BBTK_PREPEND_MESSAGE_WITH_CODE
+#define bbtkMessageCode                                \
+  key[0] << key[1] << key[2] << value << " "
+#else 
+#define bbtkMessageCode ""
+#endif 
+
+#ifdef BBTK_PREPEND_MESSAGE_WITH_TAB
+#define bbtkMessageTab                         \
+  bbtk::MessageManager::GetTab()
+#else 
+#define bbtkMessageTab ""
+#endif
+
+#define BBTK_PREPEND_MESSAGE_WITH_SPACE
+#ifdef BBTK_PREPEND_MESSAGE_WITH_SPACE
+#define bbtkMessageSpace(value)                        \
+  bbtk::MessageManager::GetSpace(value)
+#else 
+#define bbtkMessageSpace(value) ""
+#endif
+
+//===========================================================
+#ifdef BBTK_COMPILE_MESSAGES
+
+// Macro for messages
+#define bbtkMessage(key,value,MESSAGE)                 \
+  do {                                                 \
+    bbtkOnMessageLevel(key,value)                      \
+      {                                                        \
+       std::cout << bbtkMessageCode                    \
+                 << bbtkMessageTab                     \
+                 << bbtkMessageSpace(value)            \
+                 << MESSAGE;                           \
+      }                                                        \
+  }                                                    \
+  while (0)
+
+// Macro for continuing a message (when one wants to split the macro
+// call into multiple lines)
+#define bbtkMessageCont(key,value,MESSAGE)     \
+  do                                           \
+    {                                          \
+      bbtkOnMessageLevel(key,value)            \
+       {                                       \
+         std::cout << MESSAGE;                 \
+       }                                       \
+    }                                          \
+  while (0)
+
+#define bbtkMessageInc(key,value,MESSAGE)              \
+  do                                                   \
+    {                                                  \
+      bbtkOnMessageLevel(key,value)                    \
+       {                                               \
+         std::cout << bbtkMessageCode                  \
+                   << bbtkMessageTab                   \
+                   << bbtkMessageSpace(value)          \
+                   << MESSAGE;                         \
+         bbtk::MessageManager::IncTab();               \
+       }                                               \
+    }                                                  \
+  while (0)
+
+#define bbtkMessageDec(key,value,MESSAGE)               \
+  do                                                   \
+    {                                                  \
+      bbtkOnMessageLevel(key,value)                    \
+       {                                               \
+         bbtk::MessageManager::DecTab();               \
+         std::cout << bbtkMessageCode                  \
+                   << bbtkMessageTab                   \
+                   << bbtkMessageSpace(value)          \
+                   << MESSAGE;                         \
+       }                                               \
+    }                                                  \
+  while (0)
+
+#define bbtkDecTab(key,value)                  \
+  do                                           \
+    {                                          \
+      bbtkOnMessageLevel(key,value)            \
+       {                                       \
+         bbtk::MessageManager::DecTab();       \
+       }                                       \
+    }                                          \
+  while (0)
+
+#define bbtkIncTab(key,value)                  \
+  do                                           \
+    {                                          \
+      bbtkOnMessageLevel(key,value)            \
+       {                                       \
+         bbtk::MessageManager::IncTab();       \
+       }                                       \
+    }                                          \
+  while (0)
+
+#define bbtkResetTab()                         \
+  do                                           \
+    {                                          \
+      bbtk::MessageManager::ResetTab();                \
+    }                                          \
+  while (0)
+
+#else
+#define bbtkMessage(key,value,MESSAGE)
+#define bbtkMessageInc(key,value,MESSAGE)
+#define bbtkMessageDec(key,value,MESSAGE)
+#define bbtkMessageCont(key,value,MESSAGE)
+#define bbtkDecTab(key,value)
+#define bbtkIncTab(key,value)
+#define bbtkResetTab()
+#endif
+//===========================================================
+
+
+
+//===========================================================
+#ifdef BBTK_COMPILE_DEBUG_MESSAGES
+
+// Macro for debug messages
+#define bbtkDebugMessage(key,value,MESSAGE)             \
+  do                                                   \
+    {                                                  \
+      bbtkOnMessageLevel(key,value)                    \
+       {                                               \
+         std::cout << bbtkMessageCode                  \
+                   << bbtkMessageTab                   \
+                   << bbtkMessageSpace(value)          \
+                   << MESSAGE;                         \
+       }                                               \
+    }                                                  \
+  while (0)
+
+// Macro for continuing a debug message (when one wants to split the
+// macro call into multiple lines)
+#define bbtkDebugMessageCont(key,value,MESSAGE)        \
+  do                                           \
+    {                                          \
+      bbtkOnMessageLevel(key,value)            \
+       {                                       \
+         std::cout << MESSAGE;                 \
+       }                                       \
+    }                                          \
+  while (0)
+
+#define bbtkDebugMessageInc(key,value,MESSAGE)         \
+  do                                                   \
+    {                                                  \
+      bbtkOnMessageLevel(key,value)                    \
+       {                                               \
+         std::cout << bbtkMessageCode                  \
+                   << bbtkMessageTab                   \
+                   << bbtkMessageSpace(value)          \
+                   << MESSAGE;                         \
+         bbtk::MessageManager::IncTab();               \
+       }                                               \
+    }                                                  \
+  while (0)
+
+#define bbtkDebugMessageDec(key,value,MESSAGE)         \
+  do                                                   \
+    {                                                  \
+      bbtkOnMessageLevel(key,value)                    \
+       {                                               \
+         bbtk::MessageManager::DecTab();               \
+         std::cout << bbtkMessageCode                  \
+                   << bbtkMessageTab                   \
+                   << bbtkMessageSpace(value)          \
+                   << MESSAGE;                         \
+       }                                               \
+    }                                                  \
+  while (0)
+
+#define bbtkDebugDecTab(key,value)             \
+  do                                           \
+    {                                          \
+      bbtkOnMessageLevel(key,value)            \
+       {                                       \
+         bbtk::MessageManager::DecTab();       \
+       }                                       \
+    }                                          \
+  while (0)
+
+#define bbtkDebugIncTab(key,value)             \
+    do                                         \
+      {                                                \
+       bbtkOnMessageLevel(key,value)           \
+         {                                     \
+           bbtk::MessageManager::IncTab();     \
+         }                                     \
+      }                                                \
+    while (0)
+    
+#define bbtkDebugResetTab()                    \
+    do                                         \
+      {                                                \
+       bbtk::MessageManager::ResetTab();       \
+      }                                                \
+    while (0)
+
+#else
+#define bbtkDebugMessage(key,value,MESSAGE) 
+#define bbtkDebugMessageCont(key,value,MESSAGE) 
+#define bbtkDebugMessageInc(key,value,MESSAGE)
+#define bbtkDebugMessageDec(key,value,MESSAGE) 
+#define bbtkDebugDecTab(key,value)
+#define bbtkDebugIncTab(key,value)
+#endif
+//===========================================================
+
+//===========================================================
+#ifdef BBTK_COMPILE_WARNING_MESSAGES
+#define bbtkWarning(MESSAGE)                                           \
+  do                                                                   \
+    {                                                                  \
+      int lev = bbtk::MessageManager::GetMessageLevel("Warning");      \
+      if (lev >0)                                                      \
+       {                                                               \
+         std::cerr << "!! WARNING !! " << MESSAGE << std::endl;        \
+         if (lev >1)                                                   \
+           {                                                           \
+             std::cerr << "!! WARNING !! In file '"<<__FILE__          \
+                       <<"' ; Line "<<__LINE__<<std::endl;             \
+           }                                                           \
+       }                                                               \
+    }                                                                  \
+  while (0) 
+
+#else
+#define bbtkWarning(MESSAGE) 
+#endif
+//===========================================================
+
+
+//===========================================================
+#ifdef BBTK_COMPILE_ERROR_MESSAGES
+#include "bbtkWx.h"
+#define bbtkError(MESSAGE)                             \
+  do                                                   \
+    {                                                  \
+      bbtk::wx::ResetCursor();                         \
+      std::ostringstream s;                            \
+      s << MESSAGE;                                    \
+      std::ostringstream f;                            \
+      f << __FILE__ << " (l."<<__LINE__<<")";          \
+      bbtk::Exception e( BBTK_GET_CURRENT_OBJECT_NAME, \
+                       f.str(),                        \
+                       s.str());                       \
+      throw e;                                         \
+    }                                                  \
+  while (0) 
+
+#define bbtkGlobalError(MESSAGE)                               \
+  do                                                   \
+    {                                                  \
+      std::ostringstream s;                            \
+      s << MESSAGE;                                    \
+      std::ostringstream f;                            \
+      f << __FILE__ << " (l."<<__LINE__<<")";          \
+      bbtk::Exception e( "global scope",               \
+                       f.str(),                        \
+                       s.str());                       \
+      throw e;                                         \
+    }                                                  \
+  while (0) 
+
+#define BBTK_INTERNAL_ERROR_MESSAGE \
+  "\n\n***********************************************\n**** THIS IS AN INTERNAL ERROR TO BBTK     ****\n**** Please send a full bug report to :    ****\n****  bbtk-developers@creatis.insa-lyon.fr ****\n***********************************************\n\n"
+
+#define bbtkInternalError(MESSAGE)                     \
+  do                                                   \
+    {                                                  \
+      std::ostringstream s;                            \
+      s << MESSAGE << BBTK_INTERNAL_ERROR_MESSAGE;     \
+      std::ostringstream f;                            \
+      f << __FILE__ << " (l."<<__LINE__<<")";          \
+      bbtk::Exception e( BBTK_GET_CURRENT_OBJECT_NAME, \
+                        f.str(),                       \
+                        s.str());                      \
+      throw e;                                         \
+    }                                                  \
+  while (0) 
+
+#else
+#define bbtkError(MESSAGE)
+#define bbtkGlobalError(MESSAGE)
+#define bbtkInternalError(MESSAGE)
+#endif
+//===========================================================
+
+//===========================================================
+#define bbtkendl std::endl
+//===========================================================
+
+
+namespace bbtk 
+{
+
+  class BBTK_EXPORT MessageManager
+  {
+  public:
+    ///
+    MessageManager();
+    ///
+    ~MessageManager();
+    ///
+    static MessageManager* GetInstance();
+    ///
+    static void RegisterMessageType(std::string key, 
+                                    std::string help,
+                                    unsigned char default_level = 9);
+    ///
+    static void SetMessageLevel(std::string key, unsigned char level);
+    ///
+    static int GetMessageLevel(std::string key);
+    ///  
+    static std::string& GetTab() { static std::string s; return s; }
+    ///
+    static std::string GetSpace(int n) { 
+      std::string s; s.insert(0,"                ",n); return s; }
+    ///
+    static void IncTab() { GetTab() += std::string(" "); }
+    ///
+    static void DecTab() { GetTab() = GetTab().substr(0,GetTab().length()-1); }
+    ///
+    static void ResetTab() { GetTab() = std::string(""); }
+    ///
+    static void PrintInfo();
+
+  private:
+    std::map<std::string,int> mMessageLevel;
+    std::map<std::string,std::string> mMessageHelp;  
+    unsigned int mMaxMessageLength;
+    int mAllLevel;
+  };
+  //===========================================================
+  
+}
+
+#include "bbtkException.h"
+
+#endif
diff --git a/kernel/src/bbtkPackage.cxx b/kernel/src/bbtkPackage.cxx
new file mode 100644 (file)
index 0000000..4acb0f1
--- /dev/null
@@ -0,0 +1,640 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkPackage.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *\file
+ *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
+ */
+#include "bbtkPackage.h"
+#include "bbtkMessageManager.h"
+#include "bbtkConfigurationFile.h"
+#include <fstream>
+#include <time.h>
+#include "bbtkUtilities.h"
+
+namespace bbtk
+{
+  //==========================================================================
+  /// Ctor with the name of the package
+  Package::Package(const std::string& name,
+                  const std::string& author,
+                  const std::string& description,
+                  const std::string& version,
+                  const std::string& BBTKVersion) 
+    : mName(name),
+      mAuthor(author),
+      mDescription(description),
+      mVersion(version),
+      mBBTKVersion(BBTKVersion)
+  {
+    std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
+    char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
+    std::string url = default_doc_dir; 
+    if (c != '/' && c !='\\') url = url + "/";
+    url = url +  "doc_tmp/" + name + "/index.html";    
+    
+    SetDocURL(url);
+    SetDocRelativeURL("Relative url not set");
+
+    /*
+    std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
+    relurl += "/packages/"+name+"/bbdoc/index.html";
+    std::string url = ConfigurationFile::GetInstance().Get_url()
+      + relurl; 
+    SetDocURL(url);
+    SetDocRelativeURL(relurl);   
+    */
+
+    //    std::cout  << "   url=["<<url<<"]"<<std::endl;
+    //    std::cout  << "relurl=["<<relurl<<"]"<<std::endl;
+    bbtkDebugMessage("Core",7,"Package::Package(\""<<name<<"\")"<<bbtkendl);
+  }
+  //==========================================================================
+
+
+
+  //==========================================================================
+  /// Dtor
+  Package::~Package()
+  {
+    bbtkDebugMessageInc("Core",7,"Package::~Package(\""<<mName<<"\")"<<bbtkendl);
+    BlackBoxMapType::const_iterator i;
+    for (i=mBlackBoxMap.begin();
+        i!=mBlackBoxMap.end();
+        ++i) 
+      {
+       delete i->second;
+      } 
+    // Adaptors are also stored in the black box map : hence already deleted
+    /*
+    AdaptorMapType::const_iterator j;
+    for (j=mAdaptorMap.begin();
+        j!=mAdaptorMap.end();
+        ++j) 
+      {
+       delete j->second;
+       }
+    */ 
+    bbtkDebugDecTab("Core",7);
+  }
+  //==========================================================================
+
+
+
+  //==========================================================================
+  /// Creates an instance of a black box of type <type> with name <name>
+  BlackBox* Package::NewBlackBox(const std::string& type, 
+                                   const std::string& name) const
+  {
+    bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
+    
+    BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
+    if (i == mBlackBoxMap.end())  
+      {
+       bbtkDebugDecTab("Core",8);
+       return 0;
+      }
+    BlackBox* bb =i->second->CreateInstance(name);
+    bbtkDebugDecTab("Core",8);
+    return bb;   
+
+  }
+  //==========================================================================
+
+
+
+  //==========================================================================
+  /// Creates an instance of an adaptor of input type <typein> and 
+  /// output type <typeout>  with name <name>
+  BlackBox* Package::NewAdaptor(TypeInfo typein,
+                                  TypeInfo typeout,
+                                  const std::string& name) const
+  {
+    bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<
+                       ">::NewAdaptor(<"
+                       <<TypeName(typein)<<">,<"
+                       <<TypeName(typeout)<<">,\""
+                       <<name<<"\")"<<bbtkendl);
+
+    AdaptorKey key(typein,typeout);
+    AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
+    if (i == mAdaptorMap.end())  
+      {
+       bbtkDebugDecTab("Core",8);
+       return 0;
+      }
+    BlackBox* bb =i->second->CreateInstance(name);
+    bbtkDebugDecTab("Core",8);
+    return bb;   
+
+  }
+  //==========================================================================
+
+
+
+
+  //==========================================================================
+  /// Registers a black box descriptor in the package
+  bool Package::RegisterBlackBox(BlackBoxDescriptor* d) 
+  {
+    bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
+    
+    mBlackBoxMap[d->GetTypeName()] = d;
+    d->SetPackage(this);
+    
+    // If it is a default adaptor, also register it in the adaptors map
+    if ( d->GetCategory() == BlackBoxDescriptor::DEFAULT_ADAPTOR) 
+      {
+       TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
+       TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
+       AdaptorKey key(typein,typeout);
+       AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
+       if (i == mAdaptorMap.end())  
+         {
+           bbtkDebugMessage("Core",8,"The box is an adaptor, inserting it in adaptors map ..."<<std::endl);       
+           mAdaptorMap[key] = d;
+         }
+       // If already an adaptor registered : error
+       else 
+         {
+           bbtkError("Package <"<<GetName()<<
+                     "> : trying to register black box <"
+                     <<d->GetTypeName()
+                     <<"> as default adaptor but there is already a default adaptor registered (<"
+                     <<i->second->GetTypeName()<<">)");
+         }
+       
+
+      }
+    
+    bbtkDebugDecTab("Core",8);
+   
+    return true;
+  }
+  //==========================================================================
+  
+
+  //==========================================================================
+  /// UnRegisters a black box descriptor from the package
+  void Package::UnRegisterBlackBox(const std::string& name) 
+  {
+    bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::UnRegisterBlackBox(\""<<name<<"\")"<<std::endl);
+    // Looking into the bb map
+    BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
+    if (i == mBlackBoxMap.end())  
+      {
+       bbtkDebugDecTab("Core",8);
+       bbtkError("UnRegister : The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
+      }
+    mBlackBoxMap.erase(i);
+    // Is it also in the adaptors map ?
+    /*
+    AdaptorMapType::iterator j = mAdaptorMap.find(name);
+    if (j != mAdaptorMap.end())  
+      {
+       mAdaptorMap.erase(j);
+      }
+    */    
+    bbtkDebugDecTab("Core",8);    
+  }
+  //==========================================================================
+
+  //==========================================================================
+  /// Changes the name of a black box type
+  void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
+  { 
+    bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
+    // Looking into the bb map
+    BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
+    if (i == mBlackBoxMap.end())  
+      {
+       bbtkDebugDecTab("Core",8);
+       bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
+      }
+
+    i->second->SetTypeName(newname);
+    mBlackBoxMap[newname] = i->second;
+    mBlackBoxMap.erase(i);
+
+    bbtkDebugDecTab("Core",8);    
+  }
+  //==========================================================================
+
+  /*
+
+  //==========================================================================
+  /// Registers an adaptor descriptor in the package
+  bool Package::RegisterAdaptor(BlackBoxDescriptor* d) 
+  {
+    bbtkDebugMessage("Core",8,"Package<"<<GetName()<<">::RegisterAdaptor(\""<<d->GetTypeName()<<"\")"<<std::endl);
+    
+    TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
+    TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
+    AdaptorKey key(typein,typeout);
+    
+    mAdaptorMap[key] = d;
+    return true;
+  }
+  //==========================================================================
+  */
+
+
+  //==========================================================================
+  /// Displays the list of black boxes of the package
+  void Package::PrintBlackBoxes(bool description, bool adaptors) const
+  {
+    unsigned int lmax = 0;
+    std::vector<std::string> names;
+    std::vector<std::string> categs;
+    std::vector<std::string> descrs;
+
+    BlackBoxMapType::const_iterator i;
+    for (i=mBlackBoxMap.begin();
+        i!=mBlackBoxMap.end();
+        ++i) 
+      {
+       if ( adaptors || 
+            ( i->second->GetCategory() == BlackBoxDescriptor::STANDARD) ) 
+         {
+           std::string name("  ");
+           name += i->second->GetTypeName();
+           names.push_back(name);
+
+           std::string categ;
+           if ( i->second->GetCategory() == BlackBoxDescriptor::ADAPTOR )
+             {
+               categ = std::string("[A]");
+             }
+           else if ( i->second->GetCategory() == 
+                     BlackBoxDescriptor::DEFAULT_ADAPTOR )
+             {
+               categ = std::string("[DA]");
+             }
+           categs.push_back(categ);
+
+           unsigned int l = name.size()+categ.size();
+           if (l>lmax) lmax = l;
+
+           std::string descr;
+           if (description) 
+             {
+               descr += " : ";
+               descr += i->second->GetDescription();
+             } 
+           descrs.push_back(descr);
+         }
+      } 
+    
+
+    std::string offs;
+    offs.append(lmax+3,' ');
+    std::vector<std::string>::iterator ni,ci,di;
+    for (ni = names.begin(), ci = categs.begin(), di = descrs.begin();
+        ni != names.end(); ++ni, ++ci, ++di)
+      {
+       std::string space;
+       space.append(lmax - ni->size() - ci->size(),' ');
+       bbtkMessage("Help",1,*ni << space << *ci );
+       std::string d(*di);
+       unsigned int dmax = 75 - lmax;
+       //      while (d.size() > dmax ) 
+       //  {
+       if (d.size()>dmax) 
+         bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl);
+       else 
+         bbtkMessage("Help",1,d << std::endl);
+       //    d = d.substr(dmax,d.size());
+       //  }   
+      }
+
+  }
+  //==========================================================================
+
+  //==========================================================================
+  /// Displays the list of adaptors of the package
+  void Package::PrintAdaptors(bool description) const
+  {
+    BlackBoxMapType::const_iterator i;
+    for (i=mBlackBoxMap.begin();
+        i!=mBlackBoxMap.end();
+        ++i) 
+      {
+       if ( i->second->GetCategory() != BlackBoxDescriptor::STANDARD ) 
+         {
+           bbtkMessage("Help",1,
+                       "  "<<i->second->GetTypeName());
+           if ( i->second->GetCategory() == 
+                BlackBoxDescriptor::DEFAULT_ADAPTOR )
+             {
+               bbtkMessage("Help",1,
+                           " [default]");
+             }  
+           if (description) 
+             {
+               bbtkMessage("Help",1,
+                           " : "<<i->second->GetDescription());
+               
+             } 
+           bbtkMessage("Help",1,std::endl);
+         }
+      } 
+    /*
+    AdaptorMapType::const_iterator i;
+    for (i=mAdaptorMap.begin();
+        i!=mAdaptorMap.end();
+        ++i) 
+      {
+       bbtkMessage("Help",1,
+                   "  "<<i->second->GetTypeName());
+       if (detail_level>0) 
+         {
+           bbtkMessage("Help",1,
+                       " : "<<i->second->GetDescription());
+         
+         } 
+       bbtkMessage("Help",1,std::endl);
+      }
+    */ 
+  }
+  //==========================================================================
+
+  //==========================================================================
+  /// Prints help on a black box
+  void Package::HelpBlackBox(const std::string& name, bool full) const
+  {
+    bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
+                       <<name<<"\")"<<bbtkendl);
+
+    BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
+    if (i == mBlackBoxMap.end())  
+      {
+       bbtkDebugDecTab("Core",8);
+       bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
+      }
+    //    bbtkMessage("Help",1,"["<<GetName()<<"] ");
+    i->second->GetHelp(full);
+    bbtkDebugDecTab("Core",8);
+
+  }
+  //==========================================================================
+
+
+  //==========================================================================
+  /// Returns true iff the package contains the box of name boxname
+  bool Package::ContainsBlackBox(const std::string& name) const 
+  {
+    bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
+                       <<name<<"\")"<<bbtkendl);
+    
+    BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
+    if (i == mBlackBoxMap.end())  
+      {
+       bbtkDebugDecTab("Core",8);
+       return false;
+      }
+    bbtkDebugDecTab("Core",8);
+    return true;
+  }
+  //==========================================================================
+
+
+  //==========================================================================
+  void Package::CreateHtmlPage(const std::string& filename,
+                              const std::string& caller,
+                              const std::string& source,       
+                              const std::string& custom_header,
+                              const std::string& custom_title,
+                              int detail, 
+                              int level,
+                              bool relative_link ) const
+  {
+    bbtkDebugMessageInc("Core",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
+                       <<filename<<"\")"<<bbtkendl);
+
+    //---------------------
+    // Open output file
+    std::ofstream s;
+    s.open(filename.c_str());
+    if (!s.good()) 
+      {
+       bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
+      }
+    
+    //----------------------
+    // Html head
+    std::string title = "BBTK Package "+GetName()+" "+GetVersion(); 
+
+    if (custom_title.length() != 0) title = custom_title;
+
+    s << "<html lang=\"en\">\n";
+    s << "<head>\n";
+    s << "<title>" << title << "</title>\n";
+    s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
+    s << "<meta name=\"description\" content=\""<<title<<"\">\n";
+    s << "<meta name=\"generator\" content=\"\">\n";
+    s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
+    //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
+    s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
+    s << "pre.display { font-family:inherit }\n";
+    s << "pre.format  { font-family:inherit }\n";
+    s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
+    s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
+    s << "pre.smallexample { font-size:smaller }\n";
+    s << "pre.smalllisp    { font-size:smaller }\n";
+    s << "span.sc    { font-variant:small-caps }\n";
+    s << "span.roman { font-family:serif; font-weight:normal; } \n";
+    s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
+    s << "--></style>\n";
+    s << "</head>\n";
+    //----------------------
+
+    //----------------------
+    // Html body
+    s << "<body>\n";
+    s << "<a name=\"Top\"></a>\n"; 
+    
+    //----------------------
+    // Header
+    if ( custom_header.length() != 0) 
+      {
+       if ( custom_header != "none" )
+         { 
+           std::ifstream in;
+           in.open(custom_header.c_str());    
+           if (!in.good()) 
+             {
+               bbtkError("Could not open file \""<<custom_header<<"\"");
+             }
+           char buffer[512];
+           while (!in.eof()) 
+             {
+               in.getline(buffer,512);
+               std::string line(buffer);
+               s << line;
+             }
+           in.close();
+           s << "<hr>\n";
+          
+           /*   
+           s << "<object data=\"" << custom_header 
+             << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
+             << custom_header <<" could not be embedded.</object>\n";
+           
+           s << "<hr>\n";
+           */
+         }
+      }
+
+    else 
+      {
+       s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
+       s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
+       s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
+         << GetDescription() << "</TD></TR>\n";
+       s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
+         << GetAuthor() << "</TD></TR>\n";
+       s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
+         << GetVersion() << "</TD></TR>\n";
+       s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
+         << GetBBTKVersion() << "</TD></TR>\n";
+       s << "</TABLE>\n";
+      }
+
+    //-------------------
+    // Table of contents
+    // Black boxes list
+    //  s << "<div class=\"contents\">\n";
+    s << "<p><b> Black Boxes : </b>\n";
+    s << "<ul>\n";
+
+    s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
+
+    BlackBoxMapType::const_iterator i;
+    for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) 
+      {
+       if ( i->second->GetCategory() != BlackBoxDescriptor::STANDARD) 
+         continue;
+       
+       std::string name = i->second->GetTypeName();
+       Utilities::html_format(name);
+       std::string descr = i->second->GetDescription();
+       
+        s << "<TR>";
+       s << "<TD style='vertical-align: top;'>";
+       s << "<li><a name=\"toc_"<<name
+         <<"\" href=\"#"<<name<<"\">"
+         <<name<<"</a>";
+       s << "</TD> ";
+       s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
+        s << "</TR>\n";
+      }    
+    s << "</TABLE>\n";
+    
+    
+    s << "</li></ul>\n";
+    s << "</div>\n";
+    
+    //-------------------
+    // Adaptors list
+    if (mAdaptorMap.size()>0) 
+      {
+       //  s << "<div class=\"contents\">\n";
+       s << "<p><b> Adaptors : </b>\n";
+       s << "<ul>\n";
+       
+       //    BlackBoxMapType::const_iterator i;
+       s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
+       for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i) 
+         {
+           if ( i->second->GetCategory() == BlackBoxDescriptor::STANDARD) 
+             continue;
+           
+           std::string name = i->second->GetTypeName();
+           Utilities::html_format(name);
+           std::string descr = i->second->GetDescription();
+           
+           s << "<TR>";
+           s << "<TD style='vertical-align: top;'>";
+           s << "<li><a name=\"toc_"<<name
+             <<"\" href=\"#"<<name<<"\">"
+             <<name<<"</a>";
+           s << "</TD> ";
+           s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
+           s << "</TR>\n";
+         }    
+       s << "</TABLE>\n";
+       
+       s << "</li></ul>\n";
+       s << "</div>\n";
+      }
+    
+    
+    //  s << "<div class=\"node\">\n";
+
+    //    s << "<p><hr>\n";
+    //    s << "<a name=\"Top\"></a>\n";
+    //  s << "Top:&nbsp;<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
+    // s << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
+    // s << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
+    
+    //    s << "</div>\n";
+
+    //----------------------
+    // Boxes doc
+
+    //-------------------
+    // Computes output directory from filename to pass it to 
+    // BlackBoxDescriptor::InsertHtmlHelp
+    std::string dir;
+    std::string::size_type slash_position = 
+      filename.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ());
+    if (slash_position != std::string::npos) {
+      if (slash_position == 0)
+       slash_position = 1;  
+      dir = filename.substr(0,slash_position);
+    }
+
+    for (i=mBlackBoxMap.begin();
+        i!=mBlackBoxMap.end();
+        ++i) 
+      {
+       i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
+      }    
+
+    //----------------------
+    // Footer 
+    time_t rawtime;
+    tm * ptm;
+    time ( &rawtime );
+    ptm = gmtime ( &rawtime );
+
+    s << "<p><hr>\n";
+    s << "Automatically generated by <b>"<<caller<<"</b> from <b>"
+      <<source<<"</b> on "
+      << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
+      << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
+    s << "</body></html>\n"; 
+    s.close();
+    //----------------------
+
+    // End
+    bbtkDebugDecTab("Core",9);
+  }
+  //==========================================================================
+}
+
diff --git a/kernel/src/bbtkPackage.h b/kernel/src/bbtkPackage.h
new file mode 100644 (file)
index 0000000..069d135
--- /dev/null
@@ -0,0 +1,242 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkPackage.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ * \file
+ * \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
+ */
+/**
+ * \class bbtk::Package
+ * \brief registers black boxes descriptors and is able to create instances of the black boxes registered.
+ */
+
+#ifndef __bbtkPackage_h__
+#define __bbtkPackage_h__
+
+#include "bbtkBlackBox.h"
+
+namespace bbtk
+{
+
+  class BBTK_EXPORT Package
+  {
+  public:
+    Package(const std::string& name,
+           const std::string& author,
+           const std::string& description,
+           const std::string& version,
+           const std::string& BBTKVersion);
+    ~Package();
+    /// Returns the name of the package
+    const std::string& GetName() const { return mName; }
+    /// Returns the author of the package
+    const std::string& GetAuthor() const { return mAuthor; }
+    /// Returns the description of the package
+    const std::string& GetDescription() const { return mDescription; }
+    /// Returns the version of the package
+    const std::string& GetVersion() const { return mVersion; }
+    /// Returns the version of bbtk used to build the package
+    const std::string& GetBBTKVersion() const { return mBBTKVersion; }
+  
+    bool ContainsBlackBox(const std::string& boxname) const;
+
+  
+    BlackBox* NewBlackBox(const std::string& type, 
+                            const std::string& name) const;
+  
+    BlackBox* NewAdaptor(TypeInfo typein,
+                           TypeInfo typeout,
+                           const std::string& name) const;
+
+    bool RegisterBlackBox(BlackBoxDescriptor*); 
+    void UnRegisterBlackBox(const std::string& name); 
+
+    //   bool RegisterAdaptor(BlackBoxDescriptor*); 
+
+    void PrintBlackBoxes(bool description = false, 
+                        bool adaptors = false) const;
+    void PrintAdaptors(bool description = false) const;
+    void HelpBlackBox(const std::string& name, bool full=true) const;
+    
+    void CreateHtmlPage(const std::string& filename,
+                       const std::string& caller = "?",
+                       const std::string& source = "?",
+                       const std::string& custom_header = "",
+                       const std::string& custom_title = "",
+                       int detail = 1, 
+                       int level = 0,
+                       bool relative_link = false ) const;
+
+    void  SetDocURL(std::string url){ mDocURL=url; }
+    const std::string& GetDocURL() const { return mDocURL; }
+    
+    void  SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
+    const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
+
+
+    unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
+    
+    /// Changes the name of a black box type
+    void ChangeBlackBoxName( const std::string& oldname, 
+                            const std::string& newname );
+
+  private:
+    /// The name of the package
+    std::string mName;
+    /// The author of the package
+    std::string mAuthor;
+    /// The description of the package
+    std::string mDescription;
+    /// The version of the package
+    std::string mVersion;
+    /// The version of the library bbtk used to build the package
+    std::string mBBTKVersion;
+    /// URL of the documentation of the Package (absolute path)
+    std::string mDocURL;
+    /// URL of the documentation of the Package 
+    /// (path relative to bbtk doc root)
+    std::string mDocRelativeURL;
+
+
+    /// The type of map of descriptors
+    typedef std::map< std::string, BlackBoxDescriptor*> BlackBoxMapType;
+    /// The map of black boxes descriptors
+    BlackBoxMapType mBlackBoxMap;
+
+    /// The type of key in the map of adaptor descriptors
+    class AdaptorKey 
+    {
+    public:
+      AdaptorKey( TypeInfo typein, TypeInfo typeout) 
+       : mTypeIn(typein.name()), mTypeOut(typeout.name()) {}
+      
+      bool operator< ( const AdaptorKey& k ) const
+      {
+       //      return ( ( mTypeIn.before(k.mTypeIn) ) ||
+       //               ( ( mTypeIn == k.mTypeIn ) && 
+       //                 ( mTypeOut.before(k.mTypeOut) ) ) );
+       return ( ( mTypeIn < k.mTypeIn ) ||
+                ( ( mTypeIn == k.mTypeIn ) && 
+                  ( mTypeOut < k.mTypeOut ) ) );
+      }
+      
+    private:
+      //      TypeInfo mTypeIn;
+      //      TypeInfo mTypeOut;
+      std::string mTypeIn;
+      std::string mTypeOut;
+    };
+    
+    //typedef std::string AdaptorKey;
+
+    /// The type of map of adaptor descriptors
+    typedef std::map< AdaptorKey, BlackBoxDescriptor*> AdaptorMapType;
+
+    /// The map of adaptors descriptors
+    AdaptorMapType mAdaptorMap;
+  };
+  // EO class Package
+  //====================================================================
+
+
+//====================================================================
+#if defined(_WIN32)
+  #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
+#else
+  #define BBTK_PACKAGE_EXPORT
+#endif // defined(_WIN32) 
+//====================================================================
+
+//====================================================================
+#define BBTK_DECLARE_PACKAGE(NAME)                                     \
+  extern "C"                                                           \
+  {                                                                    \
+    bbtk::Package*& NAME ## GetPackagePointer();                       \
+    BBTK_PACKAGE_EXPORT void BBTK_CDECL NAME ## DeletePackage();       \
+    BBTK_PACKAGE_EXPORT bbtk::Package* BBTK_CDECL NAME ## GetPackage();        \
+  }
+//==================================================================== 
+
+//==================================================================== 
+#define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)                \
+  extern "C"                                                           \
+  {                                                                    \
+    bbtk::Package*& NAME ## GetPackagePointer()                                \
+    {                                                                  \
+      static bbtk::Package* u = 0;                                     \
+      return u;                                                                \
+    }                                                                  \
+    BBTK_PACKAGE_EXPORT void BBTK_CDECL NAME ## DeletePackage()                \
+    {                                                                  \
+      if (NAME ## GetPackagePointer())                                 \
+       delete NAME ## GetPackagePointer();                             \
+      NAME ## GetPackagePointer() = 0;                                 \
+    }                                                                  \
+    BBTK_PACKAGE_EXPORT bbtk::Package* BBTK_CDECL NAME ## GetPackage() \
+    {                                                                  \
+      if (!NAME ## GetPackagePointer())                                        \
+       NAME ## GetPackagePointer() =                                   \
+         new bbtk::Package(#NAME,                                      \
+                           AUTHOR,     \
+                           DESCRIPTION, \
+                           VERSION,    \
+                           BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)         \
+                           );                                          \
+      return NAME ## GetPackagePointer();                              \
+    }                                                                  \
+  }
+//====================================================================  
+
+//====================================================================
+#define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                      \
+  bool bbDummy##NAME##CLASS = NAME ## GetPackage()->RegisterBlackBox(CLASS::bbDescriptor());
+  //====================================================================
+  
+//====================================================================
+#define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
+  bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage()->RegisterBlackBox(CLASS<TEMPLATE_PARAM>::bbDescriptor());
+  //====================================================================
+
+//====================================================================
+#define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)      \
+  bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage()->RegisterBlackBox(CLASS<T1,T2>::bbDescriptor()); 
+  //====================================================================
+  
+//====================================================================
+//#define BBTK_ADD_ADAPTOR_TO_PACKAGE(NAME,CLASS)                      \
+//  bool bbDummy##NAME##CLASS = NAME ## GetPackage()->RegisterBlackBox(CLASS::bbDescriptor()); \
+//  bool bbDummyAdaptor##NAME##CLASS = NAME ## GetPackage()->RegisterAdaptor(CLASS::bbDescriptor());
+//====================================================================
+
+//====================================================================
+//#define BBTK_ADD_TEMPLATE_ADAPTOR_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
+//  bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage()->RegisterBlackBox(CLASS<TEMPLATE_PARAM>::bbDescriptor()); \
+//  bool bbDummyAdaptor##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage()->RegisterAdaptor(CLASS<TEMPLATE_PARAM>::bbDescriptor());
+//====================================================================
+
+//====================================================================
+//#define BBTK_ADD_TEMPLATE2_ADAPTOR_TO_PACKAGE(NAME,CLASS,T1,T2)      \
+//  bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage()->RegisterBlackBox(CLASS<T1,T2>::bbDescriptor()); \
+//    bool bbDummyAdaptor##NAME##CLASS##T1##T2 = NAME ## GetPackage()->RegisterAdaptor(CLASS<T1,T2>::bbDescriptor());
+  //====================================================================
+
+}// namespace bbtk
+
+
+
+#endif
+
diff --git a/kernel/src/bbtkRTTI.cxx b/kernel/src/bbtkRTTI.cxx
new file mode 100644 (file)
index 0000000..81791f6
--- /dev/null
@@ -0,0 +1,80 @@
+#include "bbtkRTTI.h"
+#include "bbtkMessageManager.h"
+
+
+
+namespace bbtk
+{
+  // Adapted from https://savannah.cern.ch/support/download.php?file_id=1972
+  
+  // Something to which we can cast the void*s, to allow finding the
+  // dynamic typeid.
+  struct Dummy {
+    virtual ~Dummy() {}
+  };
+  
+
+ void*  run_time_up_or_down_cast( const std::type_info& target_type,
+                              const std::type_info& source_type,
+                              const void*  source_pointer
+                              )
+ {
+   return run_time_up_or_down_cast(target_type,
+                                  source_type,
+                                  const_cast<void*>(source_pointer));
+ }
+
+  void*   run_time_up_or_down_cast( const std::type_info& target_type,
+                              const std::type_info& source_type,
+                              void*  source_pointer
+                              )
+  {
+    bbtkDebugMessage("Data",5,
+                    "run_time_up_or_down_cast : Casting pointer to '" 
+                    << TypeName(typeid(*(Dummy*)source_pointer)) 
+                    << "' from " << TypeName(source_type) 
+                    << " to " << TypeName(target_type) << std::endl);
+
+    void* target_pointer = 0;
+#if __GNUC__ > 3 ||                                    \
+  (__GNUC__ == 3 && (__GNUC_MINOR__ > 1 ||             \
+                    (__GNUC_MINOR__ == 1 &&            \
+                     __GNUC_PATCHLEVEL__ > 0)))
+    
+    const abi::__class_type_info* targetTI = 
+      (const abi::__class_type_info *)( &(target_type));
+    
+    bbtkDebugMessage("Data",7," * source   = "<<source_pointer<<std::endl);
+
+    void* tmp = source_pointer;
+    if (source_type.__do_upcast(targetTI,&tmp)) 
+      {
+       target_pointer = tmp;
+      }
+    else 
+      {
+       bbtkDebugMessage("Data",7,
+                        " * upcast failed : trying dynamic down cast"
+                        <<std::endl);
+       const abi::__class_type_info* sourceTI = 
+         (const abi::__class_type_info *)( &(source_type));
+       
+       
+       target_pointer = abi::__dynamic_cast(source_pointer, 
+                                            sourceTI, 
+                                            targetTI, 
+                                            -1);   
+      }
+    
+    bbtkDebugMessage("Data",7," * target   = "<<target_pointer<<std::endl);
+    
+#else
+    bbtkWarning("run_time_up_or_down_cast not impl. on Win : to do");
+    // target_pointer = __RTDynamicCast(source_pointer, 0, source_type, target_type, 0);
+#endif
+    return target_pointer;
+    
+  }
+
+}
+
diff --git a/kernel/src/bbtkRTTI.h b/kernel/src/bbtkRTTI.h
new file mode 100644 (file)
index 0000000..ca7ec42
--- /dev/null
@@ -0,0 +1,187 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkRTTI.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *\file
+ *\brief RTTI tools (system dependent).
+ */
+
+#ifndef __BBTKRTTI_H_INCLUDED__
+#define __BBTKRTTI_H_INCLUDED__
+
+#include "bbtkSystem.h"
+#include <vector>
+
+//-----------------------------------------------------------------------------
+// RRTI type_info.name() demangling
+// For type_info.name() demangling (gcc >= 3.1, see http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaceabi.html)
+// Test for GCC > 3.1.0 //
+#if __GNUC__ > 3 ||                                    \
+  (__GNUC__ == 3 && (__GNUC_MINOR__ > 1 ||             \
+                    (__GNUC_MINOR__ == 1 &&            \
+                     __GNUC_PATCHLEVEL__ > 0)))
+#include <cxxabi.h>
+namespace bbtk
+{
+  inline std::string demangle_type_name(const char* name) 
+  {
+    int  status;
+    char* dem = abi::__cxa_demangle(name, 0, 0, &status);
+    std::string demangled(dem);
+    free(dem);
+    if (!status) return demangled;
+    return name;
+  }
+
+}
+
+#define BBTK_DEMANGLE_TYPE_NAME(NAME) bbtk::demangle_type_name(NAME)
+
+//==========================================================================
+#elif defined(_WIN32)
+// WIN32
+//#include "Windows.h"
+//#include "stdafx.h"
+#include <windows.h>
+#include <imagehlp.h>
+// include the right library in the linker stage
+#pragma comment( lib, "imagehlp.lib" )
+
+namespace bbtk
+{
+
+  
+  
+  
+  inline std::string demangle_type_name(const char* name) 
+  {
+    char demangled[513]; 
+    if (UnDecorateSymbolName(name, demangled, 
+                            sizeof(name), UNDNAME_COMPLETE))
+      {
+                 return name; //demangled;
+      }
+    else 
+      {
+       return name;
+      }
+  }
+}
+#define BBTK_DEMANGLE_TYPE_NAME(NAME) bbtk::demangle_type_name(NAME)
+
+#else 
+// OTHER
+#define BBTK_DEMANGLE_TYPE_NAME(NAME) NAME
+#endif 
+
+#define BBTK_GET_CURRENT_OBJECT_NAME \
+  BBTK_DEMANGLE_TYPE_NAME(typeid(*this).name())
+
+#define BBTK_GET_TYPE_NAME(A)          \
+  BBTK_DEMANGLE_TYPE_NAME(typeid(A).name())
+//-----------------------------------------------------------------------------
+
+
+namespace bbtk 
+{
+  /// Template method which returns the name of a type
+  template <class T>
+  inline std::string TypeName() 
+  { return BBTK_DEMANGLE_TYPE_NAME(typeid(T).name()); }
+  /// Template method which returns the name of the type of a variable
+  template <class T>
+  inline std::string TypeName(const T& t) 
+  { return BBTK_DEMANGLE_TYPE_NAME(typeid(t).name()); }
+  /// Specialisation of TypeName when the type passed is already a type_info :
+  /// The user does not want to know the type of the type_info class but of 
+  /// the class whose type_info is passed !
+  template <> 
+  inline std::string TypeName<std::type_info>(const std::type_info& t)
+  { return BBTK_DEMANGLE_TYPE_NAME(t.name()); }
+
+  /// Template method which returns the human readable name of a type
+  template <class T>
+  inline std::string HumanTypeName() 
+  { return TypeName<T>(); }
+  /// Template method which returns the human readable name of the type of a variable
+  template <class T>
+  inline std::string HumanTypeName(const T& t) 
+  { return TypeName(t); }
+  /// Specialisation of TypeName when the type passed is already a type_info :
+  /// The user does not want to know the type of the type_info class but of 
+  /// the class whose type_info is passed !
+  template <> 
+  inline std::string HumanTypeName<std::type_info>(const std::type_info& t)
+  { return TypeName<std::type_info>(t); }
+  /// Macro to specialise the template function TypeName for certain types 
+  /// (typically highly template types, such as STL types) 
+  /// in order to return a **really** human readable string
+#define BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(TYPE,NAME)                        \
+  template <> inline std::string HumanTypeName< TYPE >()               \
+  { return NAME; }                                                     \
+    template <> inline std::string HumanTypeName< TYPE >(const TYPE&)  \
+    { return NAME; }   
+  
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::string,"std::string");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(signed char,"char");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(signed short,"short");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(signed int,"int");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned char,"unsigned char");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned short,"unsigned short");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned int,"unsigned int");
+  
+  // Human readable strings for std::vector
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<int8_t>,
+                                      "std::vector<char>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<uint8_t>,
+                                      "std::vector<uchar>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<int16_t>,
+                                      "std::vector<short>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<uint16_t>,
+                                      "std::vector<ushort>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<int32_t>,
+                                      "std::vector<int>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<uint32_t>,
+                                      "std::vector<uint>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<long>,
+                                      "std::vector<long>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<float>,
+                                      "std::vector<float>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<double>,
+                                      "std::vector<double>");
+  BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<std::string>,
+                                      "std::vector<std::string>");
+
+
+/// The bbtk::TypeInfo type is a const ref on std::type_info (which can only be manipulated as such (because typeid returns const std::type_info& and type_info has all constructors private)) 
+  typedef const std::type_info& TypeInfo;
+
+
+  BBTK_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
+                                 const std::type_info& source_type,
+                                 void*  source_pointer
+                                 );
+ BBTK_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
+                                 const std::type_info& source_type,
+                                 const void*  source_pointer
+                                 );
+
+
+}
+
+#endif
+
diff --git a/kernel/src/bbtkSystem.h b/kernel/src/bbtkSystem.h
new file mode 100644 (file)
index 0000000..1047e7d
--- /dev/null
@@ -0,0 +1,215 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkSystem.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *\file
+ *\brief contains all the OS depending stuff
+ */
+#ifndef __bbtkSystem_h__
+#define __bbtkSystem_h__
+
+#include "bbtkConfigure.h"
+
+// We try for Visual 6..????
+//#pragma warning( disable : 4786)
+
+
+
+//-----------------------------------------------------------------------------
+//This is needed when compiling in debug mode
+#ifdef _MSC_VER
+// 'identifier' : class 'type' needs to have dll-interface to be used by
+// clients of class 'type2'
+#pragma warning ( disable : 4251 )
+// non dll-interface class 'type' used as base for dll-interface class 'type2'
+#pragma warning ( disable : 4275 )
+// 'identifier' : identifier was truncated to 'number' characters in the
+// debug information
+#pragma warning ( disable : 4786 )
+//'identifier' : decorated name length exceeded, name was truncated
+#pragma warning ( disable : 4503 )
+// C++ exception specification ignored except to indicate a 
+// function is not __declspec(nothrow)
+#pragma warning ( disable : 4290 )
+// signed/unsigned mismatch
+#pragma warning ( disable : 4018 )
+// return type for 'identifier' is '' (ie; not a UDT or reference to UDT. Will
+// produce errors if applied using infix notation
+#pragma warning ( disable : 4284 )
+// 'type' : forcing value to bool 'true' or 'false' (performance warning)
+// //#pragma warning ( disable : 4800 )
+#endif //_MSC_VER
+
+
+#include <stdio.h>  // for printf, ...
+#include <iostream> // for cout, endl, ...
+
+#ifdef _MSC_VER
+// Micro$oft related stuff
+#pragma once
+#include <conio.h>
+#include <tchar.h>
+#else
+//#include  <curses.h> // for getch
+#endif //_MSC_VER
+
+//-----------------------------------------------------------------------------
+// Micro$oft shared library related stuff
+//
+// all the classes should be defined as :
+// class BBTK_EXPORT ClassName 
+// instead of :
+// class ClassName
+
+
+#if defined(_WIN32) && defined(BUILD_SHARED_LIBS)
+  #ifdef bbtk_EXPORTS2
+    #define BBTK_EXPORT2 export
+  #else
+    #define BBTK_EXPORT2 
+  #endif
+#else
+  #define BBTK_EXPORT2
+#endif // defined(_WIN32) && defined(BUILD_SHARED_LIBS)
+
+
+
+
+#if defined(_WIN32) && defined(BUILD_SHARED_LIBS)
+//#include "WWW.h"
+  #ifdef bbtk_EXPORTS
+    #define BBTK_EXPORT __declspec( dllexport )
+  #else
+    #define BBTK_EXPORT __declspec( dllimport )
+  #endif
+  #define BBTK_CDECL __cdecl
+#else
+  #define BBTK_EXPORT
+  #define BBTK_CDECL
+#endif // defined(_WIN32) && defined(BUILD_SHARED_LIBS)
+
+
+
+#ifdef __BORLANDC__
+#include <mem.h>
+#endif //__BORLANDC__
+
+
+
+// ----------------------------------------------------------------------------
+// wx headers
+// ----------------------------------------------------------------------------
+#include "bbtkWx.h"
+
+/*
+#ifdef _USE_WXWIDGETS_
+#include "wx/wxprec.h"
+#include <wx/datetime.h>
+#ifndef WX_PRECOMP
+#   include <wx/wx.h>
+#endif //WX_PRECOMP
+
+#include <wx/log.h>
+
+#ifdef __WXGTK__
+# include <locale.h>
+#endif //__WXGTK__
+
+#endif //_USE_WXWIDGETS_
+*/
+//-----------------------------------------------------------------------------
+
+
+
+
+//-----------------------------------------------------------------------------
+// Version
+#include <string.h>
+
+namespace bbtk
+{
+#define BBTK_STRINGIFY(A) #A
+#define BBTK_STRINGIFY_SYMBOL(A) BBTK_STRINGIFY(A)
+
+  extern "C" 
+  {
+    BBTK_EXPORT inline const std::string& BBTK_CDECL GetVersion() 
+    {
+      static const std::string v(BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));
+      return v;
+    }
+  }
+
+}
+//-----------------------------------------------------------------------------
+
+
+
+
+//-----------------------------------------------------------------------------
+/*
+#ifdef _WIN32
+typedef  signed char         int8_t;
+typedef  signed short        int16_t;
+typedef  signed int          int32_t;
+typedef  unsigned char       uint8_t;
+typedef  unsigned short      uint16_t;
+typedef  unsigned int        uint32_t;
+#else 
+#include <stdint.h>
+#include <inttypes.h> 
+#endif
+*/
+
+#ifdef CMAKE_HAVE_STDINT_H
+   #include <stdint.h>
+#else
+#ifdef CMAKE_HAVE_INTTYPES_H
+   // Old system only have this
+   #include <inttypes.h>   // For uint8_t uint16_t and uint32_t
+#else
+   //#include "XXX.h"
+// Broken plateforms do not respect C99 and do not provide those typedef
+// Special case for recent Borland compiler, comes with stdint.h
+#if defined(_MSC_VER) || defined(__BORLANDC__) && (__BORLANDC__ < 0x0560)  \
+                      || defined(__MINGW32__)
+typedef  signed char         int8_t;
+typedef  signed short        int16_t;
+typedef  signed int          int32_t;
+typedef  unsigned char       uint8_t;
+typedef  unsigned short      uint16_t;
+typedef  unsigned int        uint32_t;
+
+/// \todo Find a clever way to deal with int64_t, uint64_t
+
+#else
+#error "Sorry your plateform is not supported"
+#endif // defined(_MSC_VER) || defined(__BORLANDC__) && (__BORLANDC__ < 0x0560)  || defined(__MINGW32__)
+#endif // CMAKE_HAVE_INTTYPES_H
+#endif // CMAKE_HAVE_STDINT_H
+
+// Basically for VS6 and bcc 5.5.1:
+#ifndef UINT32_MAX
+#define UINT32_MAX    (4294967295U)
+#endif
+
+
+
+//-----------------------------------------------------------------------------
+
+#endif
diff --git a/kernel/src/bbtkTypeMapping.h b/kernel/src/bbtkTypeMapping.h
new file mode 100644 (file)
index 0000000..95d706b
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef __bbtkTypeMapping_h_INCLUDED__
+#define __bbtkTypeMapping_h_INCLUDED__
+
+
+namespace bbtk 
+{
+
+/// 
+template <typename ValueType>
+class TypeMapping 
+{
+public:
+  TypeMapping() {}
+
+  template <typename T>
+  ValueType& value() 
+  {
+    return m_map[ (void*)typeid(T).name() ];
+  }
+  template <typename T>
+  ValueType& operator[]( const T& ) 
+  {
+    return m_map[ (void*)typeid(T).name() ];
+  }
+
+  ValueType& operator[]( const std::type_info& t) 
+  {
+    return m_map[ (void*)t.name() ];
+  }
+  
+  unsigned int size() const { return m_map.size(); }
+
+  typedef typename std::map<void*, ValueType>::const_iterator const_iterator;
+
+  const_iterator begin() const { return m_map.begin(); }
+  const_iterator end() const { return m_map.end(); }
+
+protected:
+  std::map<void*, ValueType> m_map;
+};
+
+
+
+}
+#endif
diff --git a/kernel/src/bbtkUserBlackBox.cxx b/kernel/src/bbtkUserBlackBox.cxx
new file mode 100644 (file)
index 0000000..4c3beab
--- /dev/null
@@ -0,0 +1,288 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBox.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief class bbtk::UserBlackBox : abstract user defined black boxes
+ */
+#include "bbtkUserBlackBox.h"
+
+namespace bbtk
+{
+  
+  //=========================================================================
+  UserBlackBox::UserBlackBox(const std::string &name, bool alloc)
+    : BlackBox(name)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "UserBlackBox::UserBlackBox(\""
+                       <<name<<"\")"<<std::endl);
+    bbtkDebugDecTab("Core",7);
+  }
+  //========================================================================= 
+  
+  //=========================================================================
+  /// Constructor from an existing box (copy) with a new name 
+  UserBlackBox::UserBlackBox(UserBlackBox& from, 
+                            const std::string &name, 
+                            bool alloc)
+    : BlackBox(from,name)
+  {
+    bbtkDebugMessageInc("Core",7,
+                       "UserBlackBox::UserBlackBox("
+                       <<from.bbGetFullName()<<",\""
+                       <<name<<"\")"<<std::endl);
+    bbtkDebugDecTab("Core",7);
+    
+  }
+  //=========================================================================
+  
+  
+  //=========================================================================
+  ///  Destructor
+  UserBlackBox::~UserBlackBox()
+  {
+    bbtkDebugMessage("Core",7,"UserBlackBox::~UserBlackBox()"
+                    <<std::endl);
+  } 
+  //=========================================================================
+  
+  
+
+  //=========================================================================
+  /// Main processing method of the box.
+  IOStatus UserBlackBox::bbBackwardUpdate( Connection* caller )
+  {
+    bbtkDebugMessageInc("Process",1,
+                       "=> UserBlackBox::bbBackwardUpdate() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
+    bbtkDebugMessage("Process",5,"Initial Status  = "<<bbGetStatus()<<std::endl);
+    bbtkDebugMessage("Process",5,"BoxProcessMode  = "<<bbGetInputBoxProcessMode()<<std::endl);
+   
+    /* 
+    if ( bbGetStatus() == UPDATING ) 
+      {
+       bbtkMessage("Warning",1,"!! WARNING !! Cyclic pipeline execution (bbBackwardUpdate ["<<bbGetFullName()<<"] reentered). This may indicate an error in pipeline conception"<<std::endl);
+       //      return UPTODATE;
+       bbSetStatus(MODIFIED);
+      }
+    */
+
+    if ( ( bbGetStatus() == MODIFIED ) ||
+        ( bbBoxProcessModeIsAlways() ) )
+      {
+       bool wasExecuting = bbGlobalGetSomeBoxExecuting();
+       bbGlobalSetSomeBoxExecuting(true);
+
+       //      bbSetStatus(UPDATING);
+
+       // Updates its inputs
+       IOStatus s = bbUpdateInputs();
+       
+       bbtkDebugMessage("Process",6,"Inputs post-update status = "<<s<<std::endl);
+       // If all inputs are in UPTODATE post-update status 
+       // and mProcessMode is not "Always"
+       // then the box is now UPTODATE
+       if ( ( s == UPTODATE ) && 
+            ( ! bbBoxProcessModeIsAlways() ) ) 
+         {
+           bbSetStatus(UPTODATE);
+         }
+       else 
+         {
+           // else it remains MODIFIED
+           bbSetStatus(MODIFIED);
+         }     
+
+       // Creates the window (WxBlackbox)
+       //      bbCreateWindow();
+
+       // Children update (WxContainerBlackBox)
+       //      bbUpdateChildren(caller);       
+
+       // User process
+       bbProcess();
+
+       // Displays the window (WxBlackbox)
+       bbShowWindow(caller);
+
+
+
+       bbGlobalSetSomeBoxExecuting(wasExecuting);
+
+
+      }
+    else 
+      {
+       bbtkDebugMessage("Process",5,"Up-to-date : nothing to do"<<std::endl);
+      }
+
+    bbtkDebugMessage("Process",5,"Final Status    = "
+                    <<bbGetStatus()<<std::endl);
+    bbtkDebugMessage("Process",1,
+                    "<= UserBlackBox::bbBackwardUpdate() ["
+                    <<bbGetFullName()<<"]"<<std::endl);
+    bbtkDebugDecTab("Process",1);
+
+    return bbGetStatus();
+
+  }
+  //=========================================================================
+  
+  /*
+  //=========================================================================
+  /// Main processing method of the box.
+  void UserBlackBox::bbForwardUpdate( Connection* caller )
+  {
+    bbtkDebugMessageInc("Process",1,
+                       "=> UserBlackBox::bbForwardUpdate() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
+    bbtkDebugMessage("Process",5,"Initial Status  = "<<bbGetStatus()<<std::endl);
+    bbtkDebugMessage("Process",5,"BoxProcessMode     = "<<bbGetInputBoxProcessMode()<<std::endl);
+    
+    if ( ( bbGetStatus() == MODIFIED ) ||
+        ( bbBoxProcessModeIsAlways() ) )
+      {
+       bool wasExecuting = bbGlobalGetSomeBoxExecuting();
+       bbGlobalSetSomeBoxExecuting(true);
+
+       // Updates its inputs ** EXCLUDING "Parent" **
+       IOStatus s = bbUpdateInputs(true);
+
+       // ??? Status management on ForwardUpdate ???
+       bbSetStatus(UPTODATE);
+
+       // Creates the window 
+       bbCreateWindow();
+
+       // Children update (WxContainer)
+       bbUpdateChildren(caller);       
+
+       // User process
+       bbProcess();
+
+       bbGlobalSetSomeBoxExecuting(wasExecuting);
+      }
+    
+    bbtkDebugMessage("Process",1,
+                    "<= UserBlackBox::bbForwardUpdate() ["
+                    <<bbGetFullName()<<"]"<<std::endl);
+
+    bbtkDebugDecTab("Process",1);
+  }
+  //=========================================================================
+  */
+  
+  
+   
+  //=========================================================================
+  Data UserBlackBox::bbGetOutput( const std::string &name )
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "UserBlackBox::bbGetOutput(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);
+    
+    Data p = ((UserBlackBoxOutputDescriptor*)bbGetDescriptor()->GetOutputDescriptor(name))->GetGetFunctor()->Get(this);
+    
+    bbtkDebugDecTab("Data",7);
+    return p;
+  }
+  //=========================================================================
+  
+  
+  //=========================================================================
+  ///  Gets the input Data of a given name
+  Data UserBlackBox::bbGetInput( const std::string &name ) 
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "UserBlackBox::bbGetInput(\""<<name<<"\") ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);  
+    
+    Data p = ((UserBlackBoxInputDescriptor*)bbGetDescriptor()->GetInputDescriptor(name))->GetGetFunctor()->Get(this);
+    
+    bbtkDebugDecTab("Data",7);
+    return p;
+  }
+  //=========================================================================
+  
+  
+  //=========================================================================
+  ///  Sets the data of the output called <name>
+  void UserBlackBox::bbSetOutput( const std::string &name, Data data)
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "UserBlackBox::bbSetOutput(\""<<name<<"\",data) ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl); 
+    
+    ((UserBlackBoxOutputDescriptor*)bbGetDescriptor()->GetOutputDescriptor(name))->GetSetFunctor()->Set(this,data);
+    
+    bbtkDebugDecTab("Data",7);
+  }  
+  //=========================================================================
+  
+  
+  //=========================================================================
+  ///  Sets the data of the input called <name>
+  void UserBlackBox::bbSetInput( const std::string &name, Data data, 
+                                bool setModified )
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "UserBlackBox::bbSetInput(\""<<name<<"\",data) ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);  
+    ((UserBlackBoxInputDescriptor*)bbGetDescriptor()->GetInputDescriptor(name))->GetSetFunctor()->Set(this,data);
+    
+    if (setModified) 
+      {
+       bbSetModifiedStatus();
+      }
+    
+    bbtkDebugDecTab("Data",7);
+  }
+  //=========================================================================
+  
+    //=========================================================================
+  ///  Sets the data of the input called <name>
+  void UserBlackBox::bbBruteForceSetInputPointer( const std::string &name, 
+                                                 void* data, 
+                                                 bool setModified )
+  {
+    bbtkDebugMessageInc("Data",7,
+                       "UserBlackBox::bbBruteForceSetInputPointer(\""
+                       <<name<<"\",data) ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);  
+    ((UserBlackBoxInputDescriptor*)bbGetDescriptor()->GetInputDescriptor(name))->GetSetFunctor()->BruteForceSetPointer(this,data);
+    
+    if (setModified) 
+      {
+       bbSetModifiedStatus();
+      }
+    
+    bbtkDebugDecTab("Data",7);
+  }
+  //=========================================================================
+  
+}
+// EO namespace bbtk
diff --git a/kernel/src/bbtkUserBlackBox.h b/kernel/src/bbtkUserBlackBox.h
new file mode 100644 (file)
index 0000000..a716cc6
--- /dev/null
@@ -0,0 +1,148 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBox.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief class bbtk::UserBlackBox : Ancestor of all user defined (concrete) black boxes
+ */
+
+/**
+ *  \class bbtk::UserBlackBox
+ *  \brief Ancestor of all user defined (concrete) black boxes.
+ */
+#ifndef __bbtkUserBlackBox_h__
+#define __bbtkUserBlackBox_h__
+
+#include "bbtkBlackBox.h"
+#include "bbtkUserBlackBoxDescriptor.h"
+
+namespace bbtk
+{
+
+  //==================================================================
+  class BBTK_EXPORT UserBlackBox : public bbtk::BlackBox
+  {
+    //==================================================================
+  public: 
+    //==================================================================
+    /// Gets the output Data of a given label
+    Data bbGetOutput( const std::string &label );
+    ///  Gets the input Data of a given label
+    Data bbGetInput( const std::string &label );
+    ///  Sets the data of the output called <name>
+    void bbSetOutput( const std::string &name, Data data);
+    ///  Sets the data of the input called <name>
+    void bbSetInput( const std::string &name, Data data, 
+                    bool setModified = true);
+    ///  Sets the data of the input called <name>
+    void bbBruteForceSetInputPointer( const std::string &name, 
+                                     void* data, 
+                                     bool setModified = true);
+    //==================================================================
+
+    //==================================================================
+    ///  Destructor
+    virtual ~UserBlackBox();
+    //==================================================================
+
+    //==================================================================
+  protected:
+    //==================================================================
+    ///  Constructor with the UserBlackBox's instance name
+    UserBlackBox(const std::string &name, bool alloc = true);
+    /// Constructor from an existing box (copy) with a new instance name 
+    UserBlackBox(UserBlackBox& from, const std::string &name, 
+                bool alloc = true);
+    //==================================================================
+
+  public:
+    //==================================================================   
+    /// Recursive pipeline processing in backward direction 
+    /// (recursion is in backward direction however execution always goes forward).
+    /// 
+    /// \returns The final status of the box (UPTODATE or MODIFIED)
+    ///
+    /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
+    /// then : 
+    /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on amont boxes)
+    /// - calls bbCreateWidget
+    /// - calls bbProcess which is the user callback which does the actual processing
+    /// - calls bbUpdateChildren
+    /// - calls bbShowWidget which shows the widget associated to the box (if any)
+    IOStatus bbBackwardUpdate(Connection* caller);
+    //==================================================================
+
+    //==================================================================
+    /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
+    /// 
+    /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
+    /// then : 
+    /// - calls bbCreateWidget
+    /// - calls bbProcess which is the user callback which does the actual processing
+    /// - calls bbUpdateChildren which recursively calls bbForwardUpdate on connections attached the "Child" output
+    // void bbForwardUpdate(Connection* caller);
+    //==================================================================
+  protected:
+    //==================================================================
+    /// User callback which computes the outputs as a function of the inputs. 
+    /// It is assumed to be deterministic and thus is only called is the inputs have changed 
+    /// (i.e. if the black box is marked as modified)
+    virtual void bbProcess() 
+    {
+      bbtkWarning("UserBlackBox::bbProcess() not overloaded for box '"
+                 <<bbGetFullName()
+                 <<"' : the box does nothing. Is it a bug or a feature ?"
+                 <<std::endl);
+    }
+    //==================================================================
+
+    //==================================================================
+    /// User callback called in the box contructor
+    virtual void bbUserConstructor() {}
+    /// User callback called in the box copy constructor
+    virtual void bbUserCopyConstructor() {}
+    /// User callback called in the box destructor
+    virtual void bbUserDestructor() {}
+    //==================================================================    
+
+     //==================================================================
+  private:
+    //================================================================== 
+    /// Default constructor is private : 
+    /// derived classes must use the constructor with the UserBlackBox's name
+    UserBlackBox() : BlackBox("") {}
+    //================================================================== 
+
+
+  };
+  // Class UserBlackBox
+  //===========================================================================
+
+
+
+}
+// namespace bbtk
+
+
+#include "bbtkUserBlackBoxMacros.h"
+
+#endif
+
diff --git a/kernel/src/bbtkUserBlackBoxDescriptor.h b/kernel/src/bbtkUserBlackBoxDescriptor.h
new file mode 100644 (file)
index 0000000..7f42a75
--- /dev/null
@@ -0,0 +1,62 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBoxDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::UserBlackBoxDescriptor : structure containing the description of a UserBlackBox input (name, description, type, functor)
+ */
+/**
+ * \class bbtk::UserBlackBoxDescriptor
+ * \brief Structure containing the description of a UserBlackBox input (name, description, type, functor)
+ */
+#ifndef __bbtkUserBlackBoxDescriptor_h__
+#define __bbtkUserBlackBoxDescriptor_h__
+
+#include "bbtkBlackBoxDescriptor.h"
+#include "bbtkUserBlackBoxInputDescriptor.h"
+#include "bbtkUserBlackBoxOutputDescriptor.h"
+
+namespace bbtk
+{
+
+
+  class BBTK_EXPORT UserBlackBoxDescriptor : public bbtk::BlackBoxDescriptor
+  {
+  public:
+    UserBlackBoxDescriptor() 
+    {  
+      AddInputDescriptor(new bbtk::UserBlackBoxInputDescriptor("BoxProcessMode",
+                                                              "Set the process mode of the box (Pipeline | Always | Reactive)", 
+                                                              new bbtk::UserBlackBoxTGetFunctor<BlackBox,std::string,std::string>(&BlackBox::bbGetInputBoxProcessMode), 
+                                                              new bbtk::UserBlackBoxTSetFunctor<BlackBox,std::string,std::string>(&BlackBox::bbSetInputBoxProcessMode) ) );
+      AddInputDescriptor(new bbtk::UserBlackBoxInputDescriptor("BoxExecute",
+                                                              "Any change signal received by this input executes the box", 
+                                                              new bbtk::UserBlackBoxTGetFunctor<BlackBox,Void,Void>(&BlackBox::bbGetInputBoxExecute), 
+                                                              new bbtk::UserBlackBoxTSetFunctor<BlackBox,Void,Void>(&BlackBox::bbSetInputBoxExecute) ) );
+      
+      AddOutputDescriptor(new bbtk::UserBlackBoxOutputDescriptor("BoxChange",
+                                                                "Propagates modification of the box", 
+                                                                new bbtk::UserBlackBoxTGetFunctor<BlackBox,Void,Void>(&BlackBox::bbGetOutputBoxChange), 
+                                                                new bbtk::UserBlackBoxTSetFunctor<BlackBox,Void,Void>(&BlackBox::bbSetOutputBoxChange) ) );
+    }
+  };
+    
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkUserBlackBoxGetSetFunctor.h b/kernel/src/bbtkUserBlackBoxGetSetFunctor.h
new file mode 100644 (file)
index 0000000..8573cc6
--- /dev/null
@@ -0,0 +1,268 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBoxGetSetFunctor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief Class bbtk::UserBlackBoxGetFunctor / Class bbtk::UserBlackBoxSetFunctor : abstract functors of the Get and Set accessors of the inputs and outputs of a UserBlackBox ; Concrete derivatives.
+ */
+
+/**
+ *  \class bbtk::UserBlackBoxGetFunctor
+ *  \brief Abstract functor of the Get accessors of the inputs and outputs of a UserBlackBox
+ *  \class bbtk::UserBlackBoxSetFunctor
+ *  \brief Abstract functor of the Set accessors of the inputs and outputs of a UserBlackBox
+ * \class bbtk::UserBlackBoxTGetFunctor
+ * \brief Template for concrete functors of the Get accessors of the inputs and outputs of a UserBlackBox (inherits from bbtk::UserBlackBoxGetFunctor).
+ * \class bbtk::UserBlackBoxTSetFunctor
+ * \brief Template for concrete functors of the Set accessors of the inputs and outputs of a UserBlackBox (inherits from bbtk::UserBlackBoxSetFunctor).
+ */
+#ifndef __bbtkUserBlackBoxGetSetFunctor_h__
+#define __bbtkUserBlackBoxGetSetFunctor_h__
+
+#include "bbtkData.h"
+#include "bbtkMessageManager.h"
+
+namespace bbtk
+{
+
+   // Forward declaration
+  class UserBlackBox;
+
+
+  //===========================================================================
+  class BBTK_EXPORT UserBlackBoxGetFunctor
+  {
+  public:
+    /// Default constructor
+    UserBlackBoxGetFunctor() {}
+    /// Abstract method which applies the "Get" function of UserBlackBox o
+    virtual Data Get(UserBlackBox* o) = 0;
+    /// 
+    virtual TypeInfo GetTypeInfo() const = 0;
+    /// 
+    virtual std::string GetTypeName() const = 0;
+    /// 
+    virtual std::string GetHumanTypeName() const = 0;
+    /// 
+    virtual bool IsPointerType() const = 0;
+
+  };
+  //===========================================================================
+
+
+  //===========================================================================
+  class UserBlackBoxSetFunctor
+  {
+  public:
+    /// Default constructor
+    UserBlackBoxSetFunctor() {}
+    /// Abstract method which applies the "Set" function of UserBlackBox o
+    virtual void Set(UserBlackBox* o, const Data&) = 0;
+    /// 
+    virtual TypeInfo GetTypeInfo() const = 0;
+    /// 
+    virtual std::string GetTypeName() const = 0;
+    /// 
+    virtual std::string GetHumanTypeName() const = 0;
+    /// 
+    virtual bool IsPointerType() const = 0;
+    /// Abstract method which applies the "Set" function of UserBlackBox o
+    /// using brute force cast to the typed pointer required by the "Set" fun.
+    /// Only works if the param type of the "Set" function is a pointer 
+    /// (see template specialization below).
+    /// !!! Use with care !!!
+    virtual void BruteForceSetPointer(UserBlackBox* o, void* p) = 0;
+
+  };
+  //===========================================================================
+
+
+
+  //===========================================================================
+  template <class UBB, class T, class TRETURN> 
+  class UserBlackBoxTGetFunctor : public bbtk::UserBlackBoxGetFunctor
+  {
+  public:
+    /// Type of pointer on a UBB::Get method  
+    typedef TRETURN (UBB::*GetMethodPointerType)(void); //const
+
+    /// Construction with the pointer on the Get method
+    UserBlackBoxTGetFunctor(GetMethodPointerType g) :
+      mGetMethodPointer(g)
+      {
+       bbtkDebugMessage("Data",9,"UserBlackBoxTGetFunctor<"<<
+                        TypeName<UBB>()<<","<<
+                        TypeName<T>()<<","<<
+                        TypeName<TRETURN>()<<
+                        ">::UserBlackBoxTGetFunctor()"<<std::endl);
+      }
+      
+    /// Concrete application of the Get method of object o
+    Data Get(UserBlackBox* o) 
+    {
+      bbtkDebugMessage("Data",9,"UserBlackBoxTGetFunctor<"<<
+                      TypeName<UBB>()<<","<<
+                      TypeName<T>()<<","<<
+                      TypeName<TRETURN>()<<
+                      ">::Get()"<<std::endl);
+      return (((UBB*)o)->*mGetMethodPointer)();
+    }
+    /// 
+    TypeInfo GetTypeInfo() const { return typeid(T); }
+    std::string GetTypeName() const { return TypeName<T>(); }
+    std::string GetHumanTypeName() const { return HumanTypeName<T>(); }
+    /// 
+    virtual bool IsPointerType() const 
+    {
+#ifdef _USE_BOOST_
+       return boost::is_pointer<T>::value;
+#else
+       return false;
+#endif
+    }
+
+  private:
+    ///  Pointer on the Get method  
+    GetMethodPointerType mGetMethodPointer;
+  };
+  //===========================================================================
+
+
+
+  //===========================================================================
+  template <class UBB, class T, class TACCESS> 
+  class UserBlackBoxTSetFunctor : public UserBlackBoxSetFunctor
+  {
+  public:
+    /// Type of pointer on a UBB::Set method  
+    typedef void (UBB::*SetMethodPointerType)(TACCESS);
+
+    /// Construction with the pointer on the Set method
+    UserBlackBoxTSetFunctor(SetMethodPointerType s) :
+      mSetMethodPointer(s) 
+      {
+       bbtkDebugMessage("Data",9,"UserBlackBoxTSetFunctor<"<<
+                       TypeName<UBB>()<<","<<
+                       TypeName<T>()<<","<<
+                       TypeName<TACCESS>()<<
+                        ">::UserBlackBoxTSetFunctor()"<<std::endl);
+      }
+      
+    /// Concrete application of the Set method of object o
+    void Set(UserBlackBox* o, const Data& d)
+    { 
+      bbtkDebugMessage("Data",9,"UserBlackBoxTSetfunctor<"<<
+                       TypeName<UBB>()<<","<<
+                       TypeName<T>()<<","<<
+                       TypeName<TACCESS>()<<
+                      ">::Set()"<<std::endl);
+      //      (((UBB*)o)->*mSetMethodPointer)(*(T*)d);
+      //      bbtkAssert( bbtkEqualTypes( d.type(), typeid(T) ) );
+      T t = d.unsafe_get<T>();
+      (((UBB*)o)->*mSetMethodPointer)(t);
+      //      bbtkDebugMessage("Core",9,"SetOK"<<std::endl);
+    }
+
+    /// 
+    TypeInfo GetTypeInfo() const { return typeid(T); }
+    std::string GetTypeName() const { return TypeName<T>(); }
+    std::string GetHumanTypeName() const { return HumanTypeName<T>(); }
+    virtual bool IsPointerType() const { return false; }
+    virtual void BruteForceSetPointer(UserBlackBox* b, void* p) 
+    {
+      bbtkInternalError("UserBlackBoxTSetFunctor<"
+                       <<TypeName<UBB>()<<","
+                       <<TypeName<T>()<<","
+                       <<TypeName<TACCESS>()
+                       <<">::BruteForceSetPointer("
+                       <<b<<","<<p<<")"
+                       <<" called whereas type '"
+                       <<TypeName<T>()
+                       <<"' is not a pointer type"); 
+    }
+  private:
+    ///  Pointer on the Set method  
+    SetMethodPointerType mSetMethodPointer;
+  };
+  //===========================================================================
+
+
+
+  //===========================================================================
+  /// Template specialization of UserBlackBoxTSetFunctor for pointer types
+  template <class UBB, class T, class TACCESS> 
+  class UserBlackBoxTSetFunctor<UBB,T*,TACCESS*> 
+    : public UserBlackBoxSetFunctor
+  {
+  public:
+    /// Type of pointer on a UBB::Set method  
+    typedef void (UBB::*SetMethodPointerType)(TACCESS*);
+
+    /// Construction with the pointer on the Set method
+    UserBlackBoxTSetFunctor(SetMethodPointerType s) :
+      mSetMethodPointer(s) 
+    {
+      bbtkDebugMessage("Data",9,"UserBlackBoxTSetFunctor<"<<
+                      TypeName<UBB>()<<","<<
+                      TypeName<T*>()<<","<<
+                      TypeName<TACCESS*>()<<
+                      ">::UserBlackBoxTSetFunctor()"<<std::endl);
+    }
+    
+    /// Concrete application of the Set method of object o
+    void Set(UserBlackBox* o, const Data& d)
+    { 
+      bbtkDebugMessage("Data",9,"UserBlackBoxTSetfunctor<"<<
+                      TypeName<UBB>()<<","<<
+                      TypeName<T*>()<<","<<
+                      TypeName<TACCESS*>()<<
+                      ">::Set()"<<std::endl);
+      
+      (((UBB*)o)->*mSetMethodPointer)(d.unsafe_get<T*>());
+
+    }
+
+    /// 
+    TypeInfo GetTypeInfo() const { return typeid(T*); }
+    std::string GetTypeName() const { return TypeName<T*>(); }
+    std::string GetHumanTypeName() const { return HumanTypeName<T*>(); }
+    virtual bool IsPointerType() const { return true; }
+
+    virtual void BruteForceSetPointer(UserBlackBox* o, void* p) 
+    {  
+      bbtkDebugMessage("Data",9,"UserBlackBoxTSetFunctor<"
+                      <<TypeName<UBB>()<<","
+                      <<TypeName<T*>()<<","
+                      <<TypeName<TACCESS*>()
+                      <<">::BruteForceSetPointer() (pointer specialization)");
+
+      (((UBB*)o)->*mSetMethodPointer)((T*)p);
+
+    }
+  private:
+    ///  Pointer on the Set method  
+    SetMethodPointerType mSetMethodPointer;
+  };
+  //===========================================================================
+
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkUserBlackBoxInputDescriptor.cxx b/kernel/src/bbtkUserBlackBoxInputDescriptor.cxx
new file mode 100644 (file)
index 0000000..297b612
--- /dev/null
@@ -0,0 +1,57 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBoxInputDescriptor.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::UserBlackBoxInputDescriptor : structure containing the description of a UserBlackBox input (name, description, type, functor)
+ */
+#include "bbtkUserBlackBoxInputDescriptor.h"
+
+
+namespace bbtk
+{
+  
+  UserBlackBoxInputDescriptor::UserBlackBoxInputDescriptor( const std::string& name,
+                                                           const std::string& description,
+                                                           UserBlackBoxGetFunctor* getfunctor,
+                                                           UserBlackBoxSetFunctor* setfunctor,
+                                                           bool copy_construct) 
+    : 
+    BlackBoxInputDescriptor(name,description,MANDATORY,copy_construct),
+    mGetFunctor(getfunctor),
+    mSetFunctor(setfunctor)
+  {  
+    bbtkDebugMessage("Core",9,
+                    "UserBlackBoxInputDescriptor::"
+                    <<"UserBlackBoxInputDescriptor(\""
+                    <<name<<"\",\""<<description<<"\","
+                    <<getfunctor<<","<<setfunctor<<","
+                    <<copy_construct<<")"<<std::endl);
+  }
+
+
+
+  UserBlackBoxInputDescriptor::~UserBlackBoxInputDescriptor()
+  {
+    bbtkDebugMessage("Core",9,
+                    "UserBlackBoxInputDescriptor::"
+                    <<"~UserBlackBoxInputDescriptor(\""
+                    <<GetName()<<"\",\""<<GetDescription()<<"\","
+                    <<mGetFunctor<<","<<mSetFunctor<<")"<<std::endl);
+  } 
+}
diff --git a/kernel/src/bbtkUserBlackBoxInputDescriptor.h b/kernel/src/bbtkUserBlackBoxInputDescriptor.h
new file mode 100644 (file)
index 0000000..a5cce85
--- /dev/null
@@ -0,0 +1,80 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBoxInputDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::UserBlackBoxInputDescriptor : structure containing the description of a UserBlackBox input (name, description, type, functor)
+ */
+/**
+ * \class bbtk::UserBlackBoxInputDescriptor
+ * \brief Structure containing the description of a UserBlackBox input (name, description, type, functor)
+ */
+#ifndef __bbtkUserBlackBoxInputDescriptor_h__
+#define __bbtkUserBlackBoxInputDescriptor_h__
+
+#include "bbtkBlackBoxInputDescriptor.h"
+#include "bbtkUserBlackBoxGetSetFunctor.h"
+#include <typeinfo>
+
+namespace bbtk
+{
+
+
+  class BBTK_EXPORT UserBlackBoxInputDescriptor : public bbtk::BlackBoxInputDescriptor
+  {
+  public:
+    //typedef enum {
+    //  MANDATORY,
+    //  OPTIONAL
+    //} InputType;
+
+      
+    UserBlackBoxInputDescriptor( const std::string& name,
+                                const std::string& description,
+                                UserBlackBoxGetFunctor* getfunctor,
+                                UserBlackBoxSetFunctor* setfunctor,
+                                bool copy_construct = true);
+
+    ~UserBlackBoxInputDescriptor();  
+    /// Returns the type of the input
+    TypeInfo GetTypeInfo() const { return mGetFunctor->GetTypeInfo(); }
+    /// Returns the name of the type of the input
+    std::string GetTypeName() const { return mGetFunctor->GetTypeName(); }
+    /// Returns the name of the type of the input
+    std::string GetHumanTypeName() const { return mGetFunctor->GetHumanTypeName(); }    
+    /// Returns true iff the type is a pointer to class 
+    virtual bool IsPointerType() const { return mGetFunctor->IsPointerType(); }    
+    /// Returns the functor on the Get method
+    UserBlackBoxGetFunctor* GetGetFunctor() { return mGetFunctor; }
+    /// Returns the functor on the Set method
+    UserBlackBoxSetFunctor* GetSetFunctor() { return mSetFunctor; }
+    
+    
+  private:
+    /// Default ctor is private 
+    UserBlackBoxInputDescriptor() : BlackBoxInputDescriptor("","") {}
+    /// The functor on the Get method
+    UserBlackBoxGetFunctor* mGetFunctor;
+    /// The functor on the Set method
+    UserBlackBoxSetFunctor* mSetFunctor;
+  };
+  
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkUserBlackBoxMacros.h b/kernel/src/bbtkUserBlackBoxMacros.h
new file mode 100644 (file)
index 0000000..fb09f34
--- /dev/null
@@ -0,0 +1,677 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBoxMacros.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief Defines macros for the creation of new user black boxes
+ */
+#ifndef __bbtkUserBlackBoxMacros_h__
+#define __bbtkUserBlackBoxMacros_h__
+
+//============================================================================
+/// Declares the standard interface of a UserBlackBox 
+/// (ctor, New, descriptor related methods)
+#define BBTK_USER_BLACK_BOX_INTERFACE(CLASS,PARENT)                    \
+  private:                                                             \
+  inline static void bbCreateDescriptorIfNeeded();                     \
+  protected:                                                           \
+  CLASS(const std::string& name, bool allocate_connectors = true);     \
+  CLASS(CLASS& from, const std::string& name,                          \
+       bool allocate_connectors = true);                               \
+  ~CLASS();                                                            \
+  public: \
+  inline static CLASS* bbNew(const std::string& name)                  \
+  {                                                                    \
+    bbtkDebugMessageInc("Core",9,#CLASS<<"::bbNew(\""<<name<<"\")"<<std::endl); \
+    bbCreateDescriptorIfNeeded();                                      \
+    CLASS* c = new CLASS(name);                                                \
+    bbtkDebugDecTab("Core",9);                                         \
+    return c;                                                          \
+  }                                                                    \
+  inline bbtk::BlackBox* bbClone(const std::string& name)              \
+  {                                                                    \
+    bbtkDebugMessageInc("Core",9,#CLASS<<"::bbClone(\""<<name<<"\")"<<std::endl); \
+    bbCreateDescriptorIfNeeded();                                      \
+    CLASS* c = new CLASS(*this,name);                                  \
+    bbtkDebugDecTab("Core",9);                                         \
+    return c;                                                          \
+  }                                                                    \
+  bbtk::BlackBoxDescriptor* bbGetDescriptor() const                    \
+  {                                                                    \
+    return (bbtk::BlackBoxDescriptor*)bbDescriptor();                  \
+  }                                                                    \
+  static bbtk::BlackBoxDescriptor* bbDescriptor()                      \
+  {                                                                    \
+    bbCreateDescriptorIfNeeded();                                      \
+    return bbDescriptorPointer();                                      \
+  }                                                                    \
+  private:                                                             \
+  CLASS() : PARENT("") {}                                              \
+  static bbtk::BlackBoxDescriptor*& bbDescriptorPointer()              \
+  {                                                                    \
+    static bbtk::BlackBoxDescriptor* d = 0;                            \
+    return d;                                                          \
+  }                                                                    
+//============================================================================
+
+
+//============================================================================
+/// Defines the bbProcess method
+#define BBTK_PROCESS(CALLBACK)                                         \
+  public:                                                              \
+  inline void bbProcess()                                              \
+  {                                                                    \
+    bbtkDebugMessageInc("Process",1,"=> "<<bbGetTypeName()<<"::bbProcess() [" \
+                       <<bbGetFullName()<<"]"<<std::endl);             \
+    CALLBACK();                                                                \
+    bbtkDebugMessageDec("Process",1,"<= "<<bbGetTypeName()<<"::bbProcess() [" \
+                       <<bbGetFullName()<<"]"<<std::endl);             \
+  }
+//============================================================================
+
+
+//============================================================================
+/// Declares a new UserBlackBox input (to be put in the class interface)
+#define BBTK_DECLARE_INPUT(NAME,TYPE)                                  \
+  protected:                                                           \
+  TYPE bbmInput##NAME;                                                 \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return bbmInput##NAME; }                                           \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { bbmInput##NAME = d;                                                        \
+    /*bbSetModifiedStatus();*/ }                               
+//============================================================================
+
+//============================================================================
+/// Declares a new UserBlackBox output (to be put in the class interface)
+#define BBTK_DECLARE_OUTPUT(NAME,TYPE)                                 \
+  protected:                                                           \
+  TYPE bbmOutput##NAME;                                                        \
+  public:                                                              \
+  TYPE bbGetOutput##NAME ()                                            \
+  { return bbmOutput##NAME; }                                          \
+  void  bbSetOutput##NAME (TYPE d)                                     \
+  { bbmOutput##NAME = d; }                                     
+//============================================================================
+
+//============================================================================
+/// Declares an inherited UserBlackBox input (to be put in the class interface)
+#define BBTK_DECLARE_INHERITED_INPUT(NAME,TYPE,GETMETHOD,SETMETHOD)    \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return GETMETHOD(); }                                              \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { SETMETHOD(d);                                                      \
+    /*bbSetModifiedStatus();*/ }                       
+//============================================================================
+
+
+//============================================================================
+/// Declares an inherited UserBlackBox output (to be put in the class interface)
+#define BBTK_DECLARE_INHERITED_OUTPUT(NAME,TYPE,GETMETHOD,SETMETHOD)   \
+  public:                                                              \
+  TYPE bbGetOutput##NAME () const                                      \
+  { return GETMETHOD(); }                                              \
+  void bbSetOutput##NAME (TYPE d)                                      \
+  { SETMETHOD(d); }                                                    
+//============================================================================
+
+
+
+//============================================================================
+#define BBTK_BEGIN_BLACK_BOX_CONSTRUCTOR(CLASS,ALLOC)                  \
+  bbtkDebugMessageInc("Core",7,#CLASS<<"::"<<#CLASS                    \
+                     <<"(\""<<bbGetName()<<"\")"<<std::endl);          \
+  if (ALLOC) bbAllocateConnectors();                                   
+//============================================================================
+
+//============================================================================
+#define BBTK_BEGIN_BLACK_BOX_COPY_CONSTRUCTOR(CLASS,FROM,ALLOC)                \
+  bbtkDebugMessageInc("Core",7,#CLASS<<"::"<<#CLASS                    \
+                     <<"("<<FROM.bbGetFullName()<<",\""                \
+                     <<bbGetName()<<"\")"<<std::endl);                 \
+  if (ALLOC)                                                           \
+    {                                                                  \
+      bbAllocateConnectors();                                          \
+      bbCopyIOValues(FROM);                                            \
+   }
+//============================================================================
+
+
+//============================================================================
+#define BBTK_END_BLACK_BOX_CONSTRUCTOR         \
+  bbtkDebugDecTab("Core",7)
+//============================================================================
+
+//============================================================================
+#define BBTK_BEGIN_BLACK_BOX_DESTRUCTOR(CLASS)                         \
+  bbtkDebugMessageInc("Core",7,#CLASS <<"::~"<< #CLASS                 \
+                     <<"() ["<<this->bbGetFullName()<<"]"<<std::endl);
+//============================================================================
+
+
+
+
+//============================================================================
+#define BBTK_END_BLACK_BOX_DESTRUCTOR          \
+  bbtkDebugDecTab("Core",7)
+//============================================================================
+
+
+//============================================================================
+/// UserBlackBox std implementation of ctor and dtor
+#define BBTK_USER_BLACK_BOX_IMPLEMENTATION(CLASS,PARENT)               \
+  CLASS::CLASS(const std::string& name, bool allocate_connectors)      \
+    : PARENT(name,false)                                               \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_CONSTRUCTOR(CLASS,allocate_connectors);       \
+    CLASS::bbUserConstructor();                                                \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }                                                                    \
+  CLASS::CLASS(CLASS& from,                                            \
+              const std::string& name, bool allocate_connectors)       \
+    : PARENT(from,name,false)                                          \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_COPY_CONSTRUCTOR(CLASS,from,allocate_connectors); \
+    CLASS::bbUserCopyConstructor();                                    \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }                                                                    \
+  CLASS::~CLASS()                                                      \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_DESTRUCTOR(CLASS);                            \
+    CLASS::bbUserDestructor();                                         \
+    BBTK_END_BLACK_BOX_DESTRUCTOR;                                     \
+  }                                                                    
+//============================================================================
+
+
+//============================================================================
+/// Begins the UserBlackBox description block
+#define BBTK_BEGIN_DESCRIBE_BLACK_BOX(CLASS,PARENT)                    \
+  class /*BBTK_EXPORT*/ CLASS ## Descriptor : public PARENT ## Descriptor \
+  {                                                                    \
+  public:                                                              \
+    bbtk::BlackBox::Pointer CreateInstance(const std::string& name)    \
+    {                                                                  \
+      return CLASS::bbNew(name);                                       \
+    }                                                                  \
+    CLASS ## Descriptor()                                              \
+      {                                                                        \
+       bbtkDebugMessageInc("Core",9,#CLASS<<"Descriptor::"<<#CLASS     \
+                           <<"Descriptor()"<<std::endl)
+//============================================================================
+
+//============================================================================
+/// Ends the UserBlackBox description block
+#define BBTK_END_DESCRIBE_BLACK_BOX(CLASS)                             \
+  bbtkDecTab("Core",9);                                                        \
+  }                                                                    \
+  };                                                                   \
+  void CLASS::bbCreateDescriptorIfNeeded()                             \
+  {                                                                    \
+    if ( !bbDescriptorPointer() )                                      \
+      bbDescriptorPointer() = new CLASS ## Descriptor;                 \
+  }
+//============================================================================
+
+
+//============================================================================
+/// Declares the name of a UserBlackBox (to be put inside the UBB description block)
+#define BBTK_NAME(NAME) SetTypeName(NAME)
+//============================================================================
+
+//============================================================================
+/// Declares the author of a UserBlackBox (to be put inside the UBB description block)
+#define BBTK_AUTHOR(AUTHOR) AddToAuthor(AUTHOR)
+//============================================================================
+
+//============================================================================
+/// Declares the description of a UserBlackBox (to be put inside the UBB description block)
+#define BBTK_DESCRIPTION(DESCR) AddToDescription(DESCR)
+//============================================================================
+
+//============================================================================
+/// Declares the category of a UserBlackBox (to be put inside the UBB description block)
+//#define BBTK_CATEGORY(CATEGORY) SetCategory(CATEGORY)
+//============================================================================
+
+//============================================================================
+/// Declares that the UserBlackBox is an adaptor (to be put inside the UBB description block)
+#define BBTK_ADAPTOR() SetCategory(bbtk::BlackBoxDescriptor::ADAPTOR)
+//============================================================================
+
+//============================================================================
+/// Declares that the UserBlackBox is the default adaptor of the package (to be put inside the UBB description block)
+#define BBTK_DEFAULT_ADAPTOR() SetCategory(bbtk::BlackBoxDescriptor::DEFAULT_ADAPTOR)
+//============================================================================
+
+//============================================================================
+/// Describes a UserBlackBox input (to be put inside the UBB description block)
+#define BBTK_INPUT(CLASS,NAME,DESCR,TYPE)                              \
+  AddInputDescriptor(new bbtk::UserBlackBoxInputDescriptor             \
+                    (#NAME,DESCR,                                      \
+                     new bbtk::UserBlackBoxTGetFunctor<CLASS,TYPE,TYPE > \
+                     (&CLASS::bbGetInput##NAME),                       \
+                     new bbtk::UserBlackBoxTSetFunctor<CLASS,TYPE,TYPE > \
+                     (&CLASS::bbSetInput##NAME) ) )
+//============================================================================
+
+//============================================================================
+/// Describes a UserBlackBox output (to be put inside the UBB description block)
+#define BBTK_OUTPUT(CLASS,NAME,DESCR,TYPE)                             \
+  AddOutputDescriptor(new bbtk::UserBlackBoxOutputDescriptor           \
+                     (#NAME,DESCR,                                     \
+                      new bbtk::UserBlackBoxTGetFunctor<CLASS,TYPE,TYPE > \
+                      (&CLASS::bbGetOutput##NAME),                     \
+                      new bbtk::UserBlackBoxTSetFunctor<CLASS,TYPE,TYPE > \
+                      (&CLASS::bbSetOutput##NAME) ) )
+//============================================================================
+
+//============================================================================
+/// Describes a UserBlackBox input (to be put inside the UBB description block)
+#define BBTK_INPUT_NOCOPY(CLASS,NAME,DESCR,TYPE)                       \
+  AddInputDescriptor(new bbtk::UserBlackBoxInputDescriptor             \
+                    (#NAME,DESCR,                                      \
+                     new bbtk::UserBlackBoxTGetFunctor<CLASS,TYPE,TYPE > \
+                     (&CLASS::bbGetInput##NAME),                       \
+                     new bbtk::UserBlackBoxTSetFunctor<CLASS,TYPE,TYPE > \
+                     (&CLASS::bbSetInput##NAME),                       \
+                     false) )
+//============================================================================
+
+//============================================================================
+/// Describes a UserBlackBox output (to be put inside the UBB description block)
+#define BBTK_OUTPUT_NOCOPY(CLASS,NAME,DESCR,TYPE)                      \
+  AddOutputDescriptor(new bbtk::UserBlackBoxOutputDescriptor           \
+                     (#NAME,DESCR,                                     \
+                      new bbtk::UserBlackBoxTGetFunctor<CLASS,TYPE,TYPE > \
+                      (&CLASS::bbGetOutput##NAME),                     \
+                      new bbtk::UserBlackBoxTSetFunctor<CLASS,TYPE,TYPE > \
+                      (&CLASS::bbSetOutput##NAME),\
+                      false) )
+//============================================================================
+
+
+
+
+
+
+
+
+
+
+//============================================================================
+//============================================================================
+// Template user black boxes macros
+//============================================================================
+//============================================================================
+
+//============================================================================
+/// Begins a template UserBlackBox of template param T description block
+#define BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX(CLASS)  \
+  template <class T>                                   \
+  class /*BBTK_EXPORT*/ CLASS ## Descriptor : public bbtk::BlackBoxDescriptor \
+  {                                                                    \
+  public:                                                              \
+    bbtk::BlackBox::Pointer CreateInstance(const std::string& name)    \
+    {                                                                  \
+      return CLASS<T>::bbNew(name);                                    \
+    }                                                                  \
+    CLASS ## Descriptor()                                              \
+      {                                                                        \
+       bbtkDebugMessageInc("Core",9,#CLASS<<"Descriptor::"<<#CLASS     \
+                           <<"Descriptor()"<<std::endl)
+//============================================================================
+
+//============================================================================
+/// Ends a template UserBlackBox of template param T description block
+#define BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX(CLASS)    \
+  bbtkDecTab("Core",9);                                                        \
+  }                                                                    \
+  };                                                                   \
+  template <class T>                                   \
+  void CLASS<T>::bbCreateDescriptorIfNeeded()          \
+  {                                                                    \
+    if ( !bbDescriptorPointer() )                                      \
+      bbDescriptorPointer() = new CLASS ## Descriptor<T>;      \
+  }
+//============================================================================
+
+//============================================================================
+/// Describes a template UserBlackBox input (to be put inside the template UBB description block)
+#define BBTK_TEMPLATE_INPUT(CLASS,NAME,DESCR,TYPE)                     \
+  AddInputDescriptor(new bbtk::UserBlackBoxInputDescriptor             \
+                    (#NAME,DESCR,                                      \
+                     new bbtk::UserBlackBoxTGetFunctor<CLASS<T>,TYPE,TYPE > \
+                     (&CLASS<T>::bbGetInput##NAME),                    \
+                     new bbtk::UserBlackBoxTSetFunctor<CLASS<T>,TYPE,TYPE > \
+                     (&CLASS<T>::bbSetInput##NAME) ) )
+//============================================================================
+
+//============================================================================
+/// Describes a template UserBlackBox output (to be put inside the template UBB description block)
+#define BBTK_TEMPLATE_OUTPUT(CLASS,NAME,DESCR,TYPE)                    \
+  AddOutputDescriptor(new bbtk::UserBlackBoxOutputDescriptor           \
+                     (#NAME,DESCR,                                     \
+                      new bbtk::UserBlackBoxTGetFunctor<CLASS<T>,TYPE,TYPE > \
+                      (&CLASS<T>::bbGetOutput##NAME),                  \
+                      new bbtk::UserBlackBoxTSetFunctor<CLASS<T>,TYPE,TYPE > \
+                      (&CLASS<T>::bbSetOutput##NAME) ) )
+//============================================================================
+
+//============================================================================
+/// Template UserBlackBox std implementation of ctor and dtor
+#define BBTK_USER_BLACK_BOX_TEMPLATE_IMPLEMENTATION(CLASS,PARENT)      \
+  template <class T>                                                   \
+  CLASS<T>::CLASS(const std::string& name, bool alloc)                 \
+    : PARENT(name,false)                                               \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_CONSTRUCTOR(CLASS<T>,alloc);                  \
+    CLASS<T>::bbUserConstructor();                             \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }                            \
+  template <class T>                                                   \
+  CLASS<T>::CLASS(CLASS<T>& from,                                              \
+              const std::string& name, bool allocate_connectors)       \
+    : PARENT(from,name,false)                                          \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_COPY_CONSTRUCTOR(CLASS<T>,from,allocate_connectors); \
+    CLASS<T>::bbUserCopyConstructor();                                 \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }            \
+  template <class T>                                                   \
+  CLASS<T>::~CLASS()                                                   \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_DESTRUCTOR(CLASS<T>);                         \
+    CLASS<T>::bbUserDestructor();                                      \
+    BBTK_END_BLACK_BOX_DESTRUCTOR;                                     \
+  }                                                                    
+//============================================================================
+
+//============================================================================
+// Two template params user black boxes macros
+
+/// Begins a template UserBlackBox description block of template param T1 and T2 
+#define BBTK_BEGIN_DESCRIBE_TEMPLATE2_BLACK_BOX(CLASS)         \
+  template <class T1, class T2>                                                \
+  class /*BBTK_EXPORT*/ CLASS ## Descriptor : public bbtk::BlackBoxDescriptor \
+  {                                                                    \
+  public:                                                              \
+    bbtk::BlackBox::Pointer CreateInstance(const std::string& name)    \
+    {                                                                  \
+      return CLASS<T1,T2>::bbNew(name);                                        \
+    }                                                                  \
+    CLASS ## Descriptor()                                              \
+      {                                                                        \
+      bbtkDebugMessageInc("Core",9,#CLASS<<"Descriptor::"<<#CLASS      \
+                         <<"Descriptor()"<<std::endl)
+//============================================================================
+
+//============================================================================
+/// Ends a template UserBlackBox description block of template param T1 and T2
+#define BBTK_END_DESCRIBE_TEMPLATE2_BLACK_BOX(CLASS)           \
+  bbtkDecTab("Core",9);                                                        \
+  }                                                                    \
+  };                                                                   \
+  template <class T1, class T2>                                                \
+  void CLASS<T1,T2>::bbCreateDescriptorIfNeeded()                      \
+  {                                                                    \
+    if ( !bbDescriptorPointer() )                                      \
+      bbDescriptorPointer() = new CLASS ## Descriptor<T1,T2>;          \
+  }
+//============================================================================
+
+//============================================================================
+// Two template params user black boxes macros
+
+/// Begins a template UserBlackBox description block of template param T1 and T2 
+#define BBTK_BEGIN_DESCRIBE_TEMPLATE2_WITH_TYPES_BLACK_BOX(CLASS,TYPE1,TYPE2)          \
+  template <TYPE1 T1, TYPE2 T2>                                                \
+  class /*BBTK_EXPORT*/ CLASS ## Descriptor : public bbtk::BlackBoxDescriptor \
+  {                                                                    \
+  public:                                                              \
+    bbtk::BlackBox::Pointer CreateInstance(const std::string& name)    \
+    {                                                                  \
+      return new CLASS<T1,T2>(name);                                   \
+    }                                                                  \
+    CLASS ## Descriptor()                                              \
+      {                                                                        \
+      bbtkDebugMessageInc("Core",9,#CLASS<<"Descriptor::"<<#CLASS      \
+                         <<"Descriptor()"<<std::endl)
+//============================================================================
+
+//============================================================================
+/// Ends a template UserBlackBox description block of template param T1 and T2
+#define BBTK_END_DESCRIBE_TEMPLATE2_WITH_TYPES_BLACK_BOX(CLASS,TYPE1,TYPE2)    \
+  bbtkDecTab("Core",9);                                                        \
+  }                                                                    \
+  };                                                                   \
+  template <TYPE1 T1, TYPE2 T2>                                                \
+  void CLASS<T1,T2>::bbCreateDescriptorIfNeeded()                      \
+  {                                                                    \
+    if ( !bbDescriptorPointer() )                                      \
+      bbDescriptorPointer() = new CLASS ## Descriptor<T1,T2>;          \
+  }
+//============================================================================
+
+
+
+//============================================================================
+/// Describes a 2 template params UserBlackBox input (to be put inside the UBB description block)
+#define BBTK_TEMPLATE2_INPUT(CLASS,NAME,DESCR,TYPE)                    \
+  AddInputDescriptor(new bbtk::UserBlackBoxInputDescriptor             \
+                    (#NAME,DESCR,                                      \
+                     new bbtk::UserBlackBoxTGetFunctor<CLASS<T1,T2>,TYPE,TYPE >        \
+                     (&CLASS<T1,T2>::bbGetInput##NAME),                \
+                     new bbtk::UserBlackBoxTSetFunctor<CLASS<T1,T2>,TYPE,TYPE >        \
+                     (&CLASS<T1,T2>::bbSetInput##NAME) ) )
+//============================================================================
+
+//============================================================================
+/// Describes a 2 template params UserBlackBox output (to be put inside the UBB description block)
+#define BBTK_TEMPLATE2_OUTPUT(CLASS,NAME,DESCR,TYPE)                   \
+  AddOutputDescriptor(new bbtk::UserBlackBoxOutputDescriptor           \
+                     (#NAME,DESCR,                                     \
+                      new bbtk::UserBlackBoxTGetFunctor<CLASS<T1,T2>,TYPE,TYPE > \
+                      (&CLASS<T1,T2>::bbGetOutput##NAME),              \
+                      new bbtk::UserBlackBoxTSetFunctor<CLASS<T1,T2>,TYPE,TYPE > \
+                      (&CLASS<T1,T2>::bbSetOutput##NAME) ) )
+//============================================================================
+
+//============================================================================
+/// Template UserBlackBox std implementation of ctor and dtor
+#define BBTK_USER_BLACK_BOX_TEMPLATE2_IMPLEMENTATION(CLASS,PARENT)     \
+  template <class T1, class T2>                                                \
+  CLASS<T1,T2>::CLASS(const std::string& name, bool alloc)             \
+    : PARENT(name,false)                                               \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_CONSTRUCTOR(CLASS,alloc);                     \
+    CLASS<T1,T2>::bbUserConstructor();                                 \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }                                                                    \
+  template <class T1, class T2>                                                        \
+  CLASS<T1,T2>::CLASS(CLASS<T1,T2>& from,                                              \
+              const std::string& name, bool allocate_connectors)       \
+    : PARENT(from,name,false)                                          \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_COPY_CONSTRUCTOR(CLASS,from,allocate_connectors); \
+    CLASS<T1,T2>::bbUserCopyConstructor();                             \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }                                                                    \
+  template <class T1, class T2>                                                \
+  CLASS<T1,T2>::~CLASS()                                               \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_DESTRUCTOR(CLASS);                            \
+    CLASS<T1,T2>::bbUserDestructor();                                  \
+    BBTK_END_BLACK_BOX_DESTRUCTOR;                                     \
+  }                                                                    
+//============================================================================
+
+
+//============================================================================
+/// Template UserBlackBox std implementation of ctor and dtor
+#define BBTK_USER_BLACK_BOX_TEMPLATE2_WITH_TYPES_IMPLEMENTATION(CLASS,PARENT,TYPE1,TYPE2) \
+  template <TYPE1 T1, TYPE2 T2>                                                \
+  CLASS<T1,T2>::CLASS(const std::string& name, bool alloc)             \
+    : PARENT(name,false)                                               \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_CONSTRUCTOR(CLASS,alloc);                     \
+    this->bbUserConstructor();                                         \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }                                                                    \
+  template <TYPE1 T1, TYPE2 T2>                                                \
+  CLASS<T1,T2>::CLASS(CLASS<T1,T2>& from,                              \
+                     const std::string& name, bool allocate_connectors) \
+    : PARENT(from,name,false)                                          \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_COPY_CONSTRUCTOR(CLASS,from,allocate_connectors); \
+    this->bbUserCopyConstructor();                                     \
+    BBTK_END_BLACK_BOX_CONSTRUCTOR;                                    \
+  }                                                                    \
+  template <TYPE1 T1, TYPE2 T2>                                                \
+  CLASS<T1,T2>::~CLASS()                                               \
+  {                                                                    \
+    BBTK_BEGIN_BLACK_BOX_DESTRUCTOR(CLASS);                            \
+    this->bbUserDestructor();                                          \
+    BBTK_END_BLACK_BOX_DESTRUCTOR;                                     \
+  }                                                                    
+//============================================================================
+
+
+
+
+
+//===========================================================================
+//============================================================================
+// ITK Specific macros
+//===========================================================================
+//===========================================================================
+
+
+//===========================================================================
+/// Declares an itk-inherited UserBlackBox input 
+#define BBTK_DECLARE_ITK_INPUT(PARENT,NAME,TYPE)                       \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return PARENT::GetInput(); }                                       \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { PARENT::SetInput(d);                                               \
+    /*bbSetModifiedStatus();*/ }                                                      
+//===========================================================================
+
+//===========================================================================
+#define BBTK_DECLARE_ITK_OUTPUT(PARENT,NAME,TYPE)                      \
+  public:                                                              \
+  TYPE bbGetOutput##NAME ()                                            \
+  { return PARENT::GetOutput(); }                                      \
+  void bbSetOutput##NAME (TYPE d)                                      \
+  { /*PARENT::GetOutput() = d;*/ }                                     
+//===========================================================================
+
+//===========================================================================
+/// Declares an UserBlackBox input corresponding to an inherited itk parameter
+/// which was declared by itkSetMacro/itkGetMacro
+/// The NAME **MUST** be the same than the itk parameter name
+#define BBTK_DECLARE_ITK_PARAM(PARENT,NAME,TYPE)                       \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return PARENT::Get##NAME(); }                                      \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { PARENT::Set##NAME(d);                                              \
+    /*bbSetModifiedStatus();*/ }
+//===========================================================================
+
+
+
+
+//===========================================================================
+//============================================================================
+// VTK Specific macros
+//===========================================================================
+//===========================================================================
+
+
+//===========================================================================
+
+// EED sept 04                                                  \
+//  { return GetInput(); /*PARENT::GetInput();*/ }             \
+//  { PARENT::SetInput( /*(vtkDataObject*)*/ d);                               \
+
+
+
+/// Declares a vtkImageAlgorithm-inherited UserBlackBox input 
+#define BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT(PARENT,NAME,TYPE)                       \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return GetImageDataInput(0); /*PARENT::GetInput();*/ }             \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { PARENT::SetInput( (vtkDataObject*) d);                             \
+    /*bbSetModifiedStatus();*/ }                                                      
+//===========================================================================
+/// Declares a vtkPolyDataAlgorithm-inherited UserBlackBox input 
+#define BBTK_DECLARE_VTK_POLY_DATA_ALGORITHM_INPUT(PARENT,NAME,TYPE)   \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return GetPolyDataInput(0); /*PARENT::GetInput();*/ }              \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { PARENT::SetInput( (vtkDataObject*) d);                             \
+    /*bbSetModifiedStatus();*/ }                                                      
+//===========================================================================
+
+//===========================================================================
+/// Declares a vtkImageAlgorithm-inherited UserBlackBox output 
+#define BBTK_DECLARE_VTK_OUTPUT(PARENT,NAME,TYPE)                      \
+  public:                                                              \
+  TYPE bbGetOutput##NAME ()                                            \
+  { return PARENT::GetOutput(); }                                      \
+  void bbSetOutput##NAME (TYPE d)                                      \
+  { /*PARENT::GetOutput() = d;*/ }                                     
+//===========================================================================
+
+//===========================================================================
+/// Declares a vtkAlgorithm-inherited UserBlackBox input 
+#define BBTK_DECLARE_VTK_INPUT(PARENT,NAME,TYPE)                       \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return dynamic_cast<TYPE>(PARENT::GetInput()); }                   \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { PARENT::SetInput( (vtkDataObject*) d); /*PARENT::GetOutput() = d;*/ }
+
+//===========================================================================
+
+//===========================================================================
+/// Declares an UserBlackBox input corresponding to an inherited vtk parameter
+/// which was declared by vtkSetMacro/vtkGetMacro
+/// The NAME **MUST** be the same than the vtk parameter name
+#define BBTK_DECLARE_VTK_PARAM(PARENT,NAME,TYPE)                       \
+  public:                                                              \
+  TYPE bbGetInput##NAME ()                                             \
+  { return PARENT::Get##NAME(); }                                      \
+  void bbSetInput##NAME (TYPE d)                                       \
+  { PARENT::Set##NAME(d);                                              \
+    /*bbSetModifiedStatus();*/ }
+//===========================================================================
+
+
+
+//===========================================================================
+/// EOF
+//===========================================================================
+#endif
diff --git a/kernel/src/bbtkUserBlackBoxOutputDescriptor.cxx b/kernel/src/bbtkUserBlackBoxOutputDescriptor.cxx
new file mode 100644 (file)
index 0000000..7b46e64
--- /dev/null
@@ -0,0 +1,54 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBoxOutputDescriptor.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::UserBlackBoxOutputDescriptor : structure containing the description of a UserBlackBox output (name, description, type, functor)
+ */
+#include "bbtkUserBlackBoxOutputDescriptor.h"
+   
+
+namespace bbtk
+{
+
+
+  UserBlackBoxOutputDescriptor::UserBlackBoxOutputDescriptor( const std::string& name,
+                                                             const std::string& description,
+                                                             UserBlackBoxGetFunctor* getfunctor,
+                                                             UserBlackBoxSetFunctor* setfunctor,
+                                                             bool copy_construct ) 
+    : 
+    BlackBoxOutputDescriptor(name,description,copy_construct),
+    mGetFunctor(getfunctor),
+    mSetFunctor(setfunctor)
+  {    
+    
+    bbtkDebugMessage("Core",9,
+                    "UserBlackBoxOutputDescriptor::UserBlackBoxOutputDescriptor(\""
+                    <<name<<"\",\""<<description
+                    <<"\""<<getfunctor<<","<<setfunctor
+                    <<","<<copy_construct<<")"<<std::endl);
+  }
+  
+
+  UserBlackBoxOutputDescriptor::~UserBlackBoxOutputDescriptor() 
+  {
+    bbtkDebugMessage("Core",9,"UserBlackBoxOutputDescriptor::~UserBlackBoxOutputDescriptor(\""<<GetName()<<"\",\""<<GetDescription()<<"\""<<mGetFunctor<<","<<mSetFunctor<<")"<<std::endl);
+  }
+  
+}
diff --git a/kernel/src/bbtkUserBlackBoxOutputDescriptor.h b/kernel/src/bbtkUserBlackBoxOutputDescriptor.h
new file mode 100644 (file)
index 0000000..794587c
--- /dev/null
@@ -0,0 +1,75 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUserBlackBoxOutputDescriptor.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+/**
+ *  \file 
+ *  \brief Class bbtk::UserBlackBoxOutputDescriptor : structure containing the description of a UserBlackBox output (name, description, type, functor)
+ */
+/**
+ * \class bbtk::UserBlackBoxOutputDescriptor
+ * \brief Structure containing the description of a UserBlackBox output (name, description, type, functor)
+ */
+
+#ifndef __bbtkUserBlackBoxOutputDescriptor_h__
+#define __bbtkUserBlackBoxOutputDescriptor_h__
+
+#include "bbtkBlackBoxOutputDescriptor.h"
+#include "bbtkUserBlackBoxGetSetFunctor.h"
+#include "bbtkMessageManager.h"
+
+namespace bbtk
+{
+
+
+  class BBTK_EXPORT UserBlackBoxOutputDescriptor : public bbtk::BlackBoxOutputDescriptor
+  {
+  public:
+      
+    UserBlackBoxOutputDescriptor( const std::string& name,
+                                 const std::string& description,
+                                 UserBlackBoxGetFunctor* getfunctor,
+                                 UserBlackBoxSetFunctor* setfunctor,
+                                 bool copy_construct = true);
+    ~UserBlackBoxOutputDescriptor();
+    
+    /// Returns the type of the input
+    TypeInfo GetTypeInfo() const { return mGetFunctor->GetTypeInfo(); }
+    /// Returns the name of the type of the input
+    std::string GetTypeName() const { return mGetFunctor->GetTypeName(); }
+   /// Returns the name of the type of the input
+    std::string GetHumanTypeName() const { return mGetFunctor->GetHumanTypeName(); }
+    /// Returns true iff the type is a pointer to class 
+    virtual bool IsPointerType() const { return mGetFunctor->IsPointerType(); }   /// Returns the functor on the Get method
+    UserBlackBoxGetFunctor* GetGetFunctor() { return mGetFunctor; }
+    /// Returns the functor on the Set method
+    UserBlackBoxSetFunctor* GetSetFunctor() { return mSetFunctor; }
+    
+    
+  private:
+    /// Default ctor is private 
+    UserBlackBoxOutputDescriptor() : BlackBoxOutputDescriptor("","") {}
+    /// The functor on the Get method
+    UserBlackBoxGetFunctor* mGetFunctor;
+    /// The functor on the Set method
+    UserBlackBoxSetFunctor* mSetFunctor;
+  };
+
+  
+}
+// namespace bbtk
+#endif
diff --git a/kernel/src/bbtkUtilities.cxx b/kernel/src/bbtkUtilities.cxx
new file mode 100644 (file)
index 0000000..6ebbe61
--- /dev/null
@@ -0,0 +1,30 @@
+#include "bbtkUtilities.h"
+
+namespace bbtk
+{
+  /*
+  //========================================================================
+    /// Usefull functions for html generation
+    static void replace( std::string& str,
+                        const std::string& from, const std::string& to )
+    {
+      using std::string;
+      string::size_type pos = str.find( from );
+      while ( pos != string::npos )
+       {
+         //    std::cout << "'" << str << "' -> '";
+         str.replace( pos, from.size(), to );
+         pos = str.find( from, pos+from.size()-1 );
+         //    std::cout << str << "'"<< std::endl;
+       } 
+    }
+  //==========================================================================
+  inline void html_format(std::string& str)
+  {
+    replace( str, "&", "&amp;" );
+    replace( str, "<", "&lt;"# );
+    replace( str, ">", "&gt;" );
+  }
+  */
+}
diff --git a/kernel/src/bbtkUtilities.h b/kernel/src/bbtkUtilities.h
new file mode 100644 (file)
index 0000000..b83193f
--- /dev/null
@@ -0,0 +1,87 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUtilities.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See doc/license.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+
+/**
+ *  \file 
+ *  \brief struct bbtk::Utilities : various usefull methods 
+ */
+
+/**
+ * \class bbtk::Utilities
+ * \brief various usefull methods 
+ */
+#ifndef __bbtkUtilities_h_INCLUDED__
+#define __bbtkUtilities_h_INCLUDED__
+
+#include "bbtkSystem.h"
+#include <string>
+
+namespace bbtk
+{
+  /// Holds various usefull methods 
+  struct BBTK_EXPORT Utilities
+  {    
+    static inline std::string get_file_name(const std::string& s) 
+    { 
+      std::string::size_type slash_position = s.find_last_of("/\\");
+      if (slash_position != std::string::npos) 
+      {
+        return  s.substr(slash_position+1,std::string::npos);   
+      }
+      else 
+      {
+        return s;
+      }      
+    }
+
+
+  //========================================================================
+    // Usefull functions for html generation
+   
+    //========================================================================
+    static inline void replace( std::string& str,
+                                const std::string& from, 
+                                const std::string& to )
+    {
+      using std::string;
+      string::size_type pos = str.find( from );
+      while ( pos != string::npos )
+      {
+        str.replace( pos, from.size(), to );
+        pos = str.find( from, pos+from.size()-1 );
+      } 
+    }
+    //========================================================================
+
+    //========================================================================
+    static inline void html_format(std::string& str)
+    {
+      replace( str, "&", "&amp;" );
+      replace( str, "<", "&lt;" );
+      replace( str, ">", "&gt;" );
+    }
+    //========================================================================
+
+  };
+
+} // namespace bbtk
+#endif //#ifndef __bbtkUtilities_h_INCLUDED__
+//EOF
diff --git a/kernel/src/bbtkVirtualExec.h b/kernel/src/bbtkVirtualExec.h
new file mode 100644 (file)
index 0000000..9a15909
--- /dev/null
@@ -0,0 +1,202 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkVirtualExec.h,v $ $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *  \file 
+ *  \brief class VirtualExec: level 0 of script execution (header)
+ */
+/**
+ *  \class bbtk::VirtualExec 
+ *  \brief class VirtualExec: level 0 of script execution 
+ */
+  
+#ifndef __bbtkVirtualExec_h__
+#define __bbtkVirtualExec_h__
+
+#include "bbtkSystem.h"
+#include "bbtkComplexBlackBox.h"
+#include "bbtkFactory.h"
+#include <string>
+#include <deque>
+
+namespace bbtk
+{
+
+  class /*BBTK_EXPORT*/ VirtualExec   // All methods are pure virtual
+  {
+
+  public:
+    typedef enum 
+    {
+       NoDialog,
+       TextDialog,
+       GraphicalDialog
+    }
+    DialogModeType;
+    
+/*
+    /// Constructor
+    VirtualExec();
+
+    /// 
+    //  void SetFactory(Factory* f);
+      
+    /// Destructor
+    virtual ~VirtualExec() = 0;
+*/    
+    /// Sets the inputs of the workspace : 
+    virtual void SetInputs(const std::map<std::string,std::string>& m) = 0;
+
+    /// Puts the executer in "no exec" mode, 
+    /// which creates but does not execute pipelines 
+    virtual void SetNoExecMode(bool b) = 0;
+
+    virtual bool GetNoExecMode() const = 0;
+
+    /// Sets the mode of dialog of the executer for Root inputs 
+    virtual void SetDialogMode(DialogModeType t) = 0;
+
+    /// Starts the definition of a new ComplexBlackBox in package pack
+    /// scriptfilename is the file from which the def is read
+    virtual void Define (const std::string &name,
+                const std::string& pack,
+                const std::string &scriptfilename) = 0;
+
+    /// End the definition of a ComplexBlackBox
+    virtual void EndDefine () = 0;
+
+    /// Creates a new black box in current complex box
+    virtual void Create ( const std::string& boxType, const std::string&
+    boxName) = 0;
+
+    /// Destroys a black box
+    //virtual void Destroy (const std::string &boxName) = 0;
+
+    /// Connects the output boxOutput to the input boxInput
+    virtual void Connect (const std::string &boxfrom,
+                 const std::string &output,
+                 const std::string &boxto,
+                 const std::string &input) = 0;
+
+    /// Updates the box 
+    /// would 'Execute' be more meaningfull ?
+    virtual void Update (const std::string &box) = 0;
+
+    /// Defines an input of the current complex box
+    virtual void DefineInput (const std::string &name,
+                     const std::string &box,
+                     const std::string &input,
+                     const std::string &help) = 0;
+
+    /// Defines an output of the current complex box
+    virtual void DefineOutput (const std::string &name,
+                      const std::string &box,
+                      const std::string &output,
+                      const std::string &help) = 0;     
+  
+    /// sets the input of the box with the value
+    virtual void Set (const std::string &box, 
+             const std::string &input, 
+             const std::string &value) = 0;
+
+   /// gets the output of the box
+    virtual std::string Get (const std::string &box, 
+                    const std::string &output) = 0;
+
+    /// changes the workspace name
+    virtual void SetWorkspaceName( const std::string& n ) = 0;
+
+    ///Adds the authorName to the Box's author list
+    virtual void Author(const std::string &authorName) = 0;
+
+    /// The description string which explains what does the ComplexBox
+    virtual void Description(const std::string & d) = 0;
+
+    /// prints the list off the boxes of the current box
+    virtual void PrintBoxes() = 0;
+
+   /// Generate a HTML with a gif file with the actual pipeline (Graphviz-dot needed). Returns the file path
+    virtual std::string ShowGraph(const std::string &nameblackbox, 
+                         const std::string &detailStr, 
+                         const std::string &levelStr,
+                         const std::string &output_file,
+                         const std::string &custom_header,
+                         const std::string &custom_title,
+                         bool system_display = true) = 0;
+
+       /// Generate a HTML with a gif file with the actual pipeline (Graphviz-dot needed). Returns the file path
+    virtual std::string ShowGraphInstances(const std::string &nameblackbox, int detail, int level, bool system_display=true) = 0;
+
+/// Description of the actual pipeline
+       virtual void ShowRelations(const std::string &nameblackbox, const std::string &detailStr, const std::string &levelStr) = 0;
+
+       virtual void Reset() = 0;
+/*
+  //  static const std::string& GetObjectDescription() = 0;
+  //  { static std::string s("VirtualExec"); return s; }
+*/
+  protected:
+
+  private:
+
+    /// Gets the current working black box 
+    virtual ComplexBlackBoxDescriptor* Current() = 0;
+    
+    /// Returns true when we are inside a define/endefine block
+    //    virtual bool InDefinitionBlock() = 0;
+
+    //==================================================================
+    // ATTRIBUTES
+     
+    /// The factory used
+    //   Factory* mFactory;
+
+    /// The Root Package
+    Package* mPackage;
+    
+    /// The root ComplexBlackBox, in which operations are done when outside a define/endefine block
+    /// Its name in bbi is 'workspace'  
+    ComplexBlackBoxDescriptor* mRoot;
+    
+    /// Struct that stores info on user defined complex black boxes
+    struct CBBDefinition
+    {
+      ComplexBlackBoxDescriptor* box;
+      std::string package;
+      CBBDefinition(ComplexBlackBoxDescriptor* d, const std::string& p )
+        : box(d), package(p) {}
+    };
+
+    /// The stack of current working ComplexBlackBox
+    /// (is a stack for nested definitions)
+    /// only contains the root when outside a define/endefine block
+    std::deque<CBBDefinition> mCurrent;
+
+    /// flag which is true when we are inside a Define/EndDefine block
+    //    bool mDefineFlag;
+    
+    /// The input values of the Root ComplexBlackBox
+    std::map<std::string,std::string> mInputs;
+    
+    /// no exec mode flag
+    bool mNoExecMode;
+
+    /// Dialog mode
+    DialogModeType mDialogMode;
+  };
+}
+#endif
diff --git a/kernel/src/bbtkWx.cxx b/kernel/src/bbtkWx.cxx
new file mode 100644 (file)
index 0000000..0c6b568
--- /dev/null
@@ -0,0 +1,27 @@
+#ifdef _USE_WXWIDGETS_
+
+#include "bbtkWx.h"
+#include "bbtkMessageManager.h"
+
+namespace bbtk
+{
+  void wx::ResetCursor() 
+  {
+    bbtkDebugMessage("Wx",9,"wx::ResetCursor()"<<std::endl);
+    while (wxIsBusy()) ::wxEndBusyCursor();
+  }
+  void wx::BeginBusyCursor() 
+  {
+    bbtkDebugMessage("Wx",9,"wx::BeginBusyCursor()"<<std::endl);
+    ::wxBeginBusyCursor();
+  }
+  void wx::EndBusyCursor()
+  {
+    bbtkDebugMessage("Wx",9,"wx::EndBusyCursor()"<<std::endl);
+    ::wxEndBusyCursor();
+  }
+  
+
+}
+
+#endif
diff --git a/kernel/src/bbtkWx.h b/kernel/src/bbtkWx.h
new file mode 100644 (file)
index 0000000..c03b4d5
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef __bbtkWx_h_INCLUDED__
+#define __bbtkWx_h_INCLUDED__
+
+
+/*
+#ifdef wxUSE_STD_IOSTREAM
+#undef wxUSE_STD_IOSTREAM
+#endif
+#define wxUSE_STD_IOSTREAM 0
+*/
+
+// Wx headers
+#ifdef _USE_WXWIDGETS_
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+#include <wx/datetime.h>
+
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#ifdef __WXGTK__
+# include <locale.h>
+#endif //__WXGTK__
+// EO Wx headers
+
+#include "bbtkSystem.h"
+
+namespace bbtk
+{
+  //==================================================================
+  /// Global wx handlers (cursor...)
+
+  struct BBTK_EXPORT wx
+   {     public:
+                         static void ResetCursor();
+                         static void BeginBusyCursor(); 
+                         static void EndBusyCursor();
+                         static int mBeginBusyCallsCount;
+               }; // struct wx
+//==================================================================
+
+
+  //==================================================================
+  /// Conversion std::string to wxString 
+  inline wxString std2wx(const std::string& s){
+    wxString wx;
+    const char* my_string=s.c_str();
+    wxMBConvUTF8 *wxconv= new wxMBConvUTF8();
+    wx=wxString(wxconv->cMB2WC(my_string),wxConvUTF8);
+    delete wxconv;
+    // test if conversion works of not. In case it fails convert from Ascii
+    if(wx.length()==0)
+      wx=wxString(wxString::FromAscii(s.c_str()));
+    return wx;
+  }
+  //==================================================================
+
+  //==================================================================
+  /// Conversion wxString to std::string
+  inline std::string wx2std(const wxString& s){
+    std::string s2;
+    if(s.wxString::IsAscii()) {
+      s2=s.wxString::ToAscii();
+    } else {
+      const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(s);
+      const char *tmp_str = (const char*) tmp_buf;
+      s2=std::string(tmp_str, strlen(tmp_str));
+    }
+    return s2;
+  }
+  //==================================================================
+
+
+  
+} // namespace bbtk
+  
+
+
+#else // _USE_WXWIDGETS
+
+
+namespace bbtk
+{
+
+   struct BBTK_EXPORT wx
+       {
+               static void ResetCursor() {}
+               static void BeginBusyCursor() {}
+               static void EndBusyCursor() {}
+       }; // struct wx
+
+} // namespace bbtk
+  
+
+
+#endif // EO _USE_WXWIDGETS
+#endif // EO __bbtkWx_h_INCLUDED__
diff --git a/kernel/src/bbtkWxBlackBox.cxx b/kernel/src/bbtkWxBlackBox.cxx
new file mode 100644 (file)
index 0000000..66cdb78
--- /dev/null
@@ -0,0 +1,677 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkWxBlackBox.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+#ifdef _USE_WXWIDGETS_
+
+
+
+/**
+ *  \file 
+ *  \brief 
+ */
+#include "bbtkWxBlackBox.h"
+//#include "bbtkWxContainerBlackBox.h"
+#include <wx/dialog.h>
+
+//#include "bbtkData.h"
+//#include "bbtkFactory.h"
+
+
+
+namespace bbtk
+{
+
+  //=========================================================================
+  wxWindow* WxBlackBox::bbGlobalGetTopWindow() 
+  {
+    return bbmgTopWindow;
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBox::bbGlobalSetTopWindow(wxWindow* w) 
+  {
+    if ( bbmgTopWindow ) 
+      {
+       bbtkGlobalError("WxBlackBox::bbGlobalSetTopWindow : top window already set !");
+      } 
+    bbmgTopWindow = w;
+  }
+  //=========================================================================
+   
+
+  //=========================================================================
+  void WxBlackBox::bbGlobalDecNbWindowsAlive()
+  { 
+    bbmgNbWindowsAlive--; 
+    /*
+    if ( (bbmgNbWindowsAlive==0) && 
+        bbmgTopWindow && (!bbmgTopWindow->IsShown()))
+      {
+       bbmgTopWindow->Close();
+      }
+    */
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBox::bbGlobalDecNbWindowsShown()
+  { 
+    bbmgNbWindowsShown--; 
+    if ( (bbmgNbWindowsShown==0) && 
+        bbmgTopWindow && (!bbmgTopWindow->IsShown()))
+      {
+       bbmgTopWindow->Close();
+      }
+  }
+  //=========================================================================
+
+  //=========================================================================
+  // Static members 
+  wxWindow* WxBlackBox::bbmgTopWindow =0;
+  int WxBlackBox::bbmgNbWindowsAlive = 0;
+  int WxBlackBox::bbmgNbWindowsShown = 0;
+  //=========================================================================
+
+
+
+
+
+  //=========================================================================
+  // WxBlackBoxWindow
+  //=========================================================================
+
+
+
+  //=========================================================================
+  WxBlackBoxWindow::WxBlackBoxWindow(WxBlackBox* box)
+    : mBox(box), mShown(false)
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWindow::WxBlackBoxWindow("<<
+                    mBox->bbGetFullName()<<")"<<std::endl);
+    mBox->bbSetWindow(this);
+    WxBlackBox::bbGlobalIncNbWindowsAlive();
+    bbtkDebugMessage("Wx",9," -> Number of windows alive = "
+                    <<WxBlackBox::bbGlobalGetNbWindowsAlive()<<std::endl);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxWindow::~WxBlackBoxWindow()
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWindow::~WxBlackBoxWindow() ["<<
+                    mBox->bbGetFullName()<<"]"<<std::endl);
+    bbHide();
+    mBox->bbSetWindow(0);
+    WxBlackBox::bbGlobalDecNbWindowsAlive();
+    bbtkDebugMessage("Wx",9," -> Number of windows alive = "
+                    <<WxBlackBox::bbGlobalGetNbWindowsAlive()<<std::endl);
+     
+
+  }
+  //========================================================================= 
+
+  //=========================================================================
+  void WxBlackBoxWindow::bbShow()
+  {
+    if (bbIsShown()) return;
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWindow::bbShow() ["<<
+                    mBox->bbGetFullName()<<"]"<<std::endl);
+    WxBlackBox::bbGlobalIncNbWindowsShown();
+    mShown = true;
+    bbtkDebugMessage("Wx",9," -> Number of windows shown = "
+                    <<WxBlackBox::bbGlobalGetNbWindowsShown()<<std::endl);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBoxWindow::bbHide()
+  {
+    if (!bbIsShown()) return;
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWindow::bbHide() ["<<
+                    mBox->bbGetFullName()<<"]"<<std::endl);
+    WxBlackBox::bbGlobalDecNbWindowsShown();
+    mShown = false;
+    bbtkDebugMessage("Wx",9," -> Number of windows shown = "
+                    <<WxBlackBox::bbGlobalGetNbWindowsShown()<<std::endl);
+  }
+  //=========================================================================
+
+
+
+  //=========================================================================
+  // WxBlackBoxDialog
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxDialog::WxBlackBoxDialog(WxBlackBox* box,
+                                    wxWindow *parent,
+                                    wxString title,
+                                    wxSize size)
+    :
+    WxBlackBoxWindow(box),
+    wxDialog( parent, 
+               -1, 
+               title,
+               wxDefaultPosition,
+               size,
+               wxRESIZE_BORDER | 
+               wxSYSTEM_MENU  |
+               wxCLOSE_BOX |
+               wxMAXIMIZE_BOX | 
+               wxMINIMIZE_BOX | 
+               wxCAPTION  
+               )
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxDialog::WxBlackBoxDialog("<<
+                    bbGetBlackBox()->bbGetFullName()<<","<<parent<<","
+                    <<title<<",size)"<<std::endl);
+    // Insert the widget into the window
+    wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
+    wxWindow* widget = bbGetBlackBox()->bbGetOutputWidget();
+    widget->Reparent(this);
+    sizer->Add( widget, 1, wxALL|wxEXPAND, 2);
+    //SetAutoLayout(true);
+    SetSizer(sizer);
+    Layout();
+  }
+  //=========================================================================
+  
+  //=========================================================================
+  void WxBlackBoxDialog::bbShow()
+  { 
+    bbtkDebugMessage("Wx",5,"WxBlackBoxDialog::bbShow() ["
+                    <<bbGetBlackBox()->bbGetFullName()<<"]"<<std::endl);
+    WxBlackBoxWindow::bbShow();
+    SetReturnCode( wxDialog::ShowModal() ); 
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBoxDialog::bbHide()
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxDialog::bbHide() ["<<
+                    bbGetBlackBox()->bbGetFullName()<<"]"<<std::endl);
+    WxBlackBoxWindow::bbHide();
+    Hide();
+  }
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxDialog::~WxBlackBoxDialog()
+  {
+  }
+  //=========================================================================
+
+
+
+
+
+  //=========================================================================
+  // WxBlackBoxFrame
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxFrame::WxBlackBoxFrame(WxBlackBox* box,
+                                  wxWindow *parent,
+                                  wxString title,
+                                  wxSize size)
+    : WxBlackBoxWindow(box),
+      wxFrame( parent, 
+              -1, 
+              title,
+              wxDefaultPosition,
+              size,
+              wxRESIZE_BORDER | 
+              wxSYSTEM_MENU  |
+              wxCLOSE_BOX |
+              wxMAXIMIZE_BOX | 
+              wxMINIMIZE_BOX | 
+              wxCAPTION  
+              )
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxFrame::WxBlackBoxFrame("<<
+                    bbGetBlackBox()->bbGetFullName()<<","<<parent<<","
+                    <<title<<",size)"<<std::endl);
+    // Insert the widget into the window
+    wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
+    wxWindow* widget = bbGetBlackBox()->bbGetOutputWidget();
+    wxFrame* frame = (wxFrame*)this;
+    widget->Reparent(frame);
+    sizer->Add( widget, 1, wxALL|wxGROW, 2);
+    //  frame->SetAutoLayout(true);
+    frame->SetSizer(sizer);
+    //frame->Fit();
+    frame->Layout();
+  }
+  //=========================================================================
+  
+  //=========================================================================
+  WxBlackBoxFrame::~WxBlackBoxFrame()
+  {
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBoxFrame::bbShow() 
+  { 
+    bbtkDebugMessage("Wx",5,"WxBlackBoxFrame::bbShow("
+                    <<bbGetBlackBox()->bbGetFullName()<<")"<<std::endl);
+    WxBlackBoxWindow::bbShow();
+    wxFrame::Show(); 
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBoxFrame::bbHide()
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxFrame::bbHide() ["<<
+                    bbGetBlackBox()->bbGetFullName()<<"]"<<std::endl);
+    WxBlackBoxWindow::bbHide();
+    Hide();
+  }
+  //=========================================================================
+
+
+
+  //=========================================================================
+  // WxBlackBoxDialogWrapper
+  //=========================================================================
+  /*
+  //=========================================================================
+  WxBlackBoxDialogWrapper::WxBlackBoxDialogWrapper(WxBlackBox* box,
+                                                  wxDialog *wrapped) 
+    : WxBlackBoxWindow(box),
+      mWrapped(wrapped) 
+  {
+    bbtkDebugMessage("Wx",9,
+                    "WxBlackBoxDialogWrapper::WxBlackBoxDialogWrapper("
+                    <<bbGetBlackBox()->bbGetFullName()<<","<<wrapped
+                    <<")"<<std::endl);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxDialogWrapper::~WxBlackBoxDialogWrapper()
+  {
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBoxDialogWrapper::bbShow() 
+  {  
+    bbtkDebugMessage("Wx",5,"WxBlackBoxDialogWrapper::bbShow("
+                    <<bbGetBlackBox()->bbGetFullName()<<")"<<std::endl);
+    WxBlackBoxWindow::bbShow();
+    int i = mWrapped->ShowModal();
+    // For Windows :
+    mWrapped->SetReturnCode( i ); 
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBoxDialogWrapper::bbHide()
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxDialogWrapper::bbHide() ["<<
+                    bbGetBlackBox()->bbGetFullName()<<"]"<<std::endl);
+    WxBlackBoxWindow::bbHide();
+    mWrapped->Hide();
+  }
+  //=========================================================================
+
+  */
+
+  /*    
+  //=========================================================================
+  // WxBlackBoxWidget
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxWidget::WxBlackBoxWidget( WxBlackBox* box)
+  : mBox(box)
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWidget::WxBlackBoxWidget("<<box->bbGetFullName()<<")"<<std::endl);
+    mBox->bbSetWidget(this);
+  }
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxWidget::~WxBlackBoxWidget()
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWidget::~WxBlackBoxWidget("<<mBox->bbGetFullName()<<")"<<std::endl);
+    mBox->bbSetWidget(0);
+    //bbtkDebugMessage("Wx",9,"EO WxBlackBoxWidget::~WxBlackBoxWidget("<<mBox->bbGetFullName()<<")"<<std::endl);
+  }
+  //=========================================================================
+  */
+
+
+
+  //=========================================================================
+  // WxBlackBoxWidgetEventHandler
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxWidgetEventHandler::WxBlackBoxWidgetEventHandler( WxBlackBox* box, 
+                                                             wxWindow *widget )
+    :
+    mBox(box),
+    mWindow(widget)
+                                                           //    mDead(false)
+  { 
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWidgetEventHandler::WxBlackBoxWidgetEventHandler("<<mBox->bbGetFullName()<<")"<<std::endl);
+
+    mBox->bbSetWidgetEventHandler(this);
+
+    Connect (  mWindow->GetId(),
+              wxEVT_DESTROY,
+              (wxObjectEventFunction) 
+              (void (wxEvtHandler::*)(wxWindowDestroyEvent& c))
+               &WxBlackBoxWidgetEventHandler::OnWindowDestroy );
+    
+    mWindow->PushEventHandler(this);
+    
+  }
+  //=========================================================================
+
+  //=========================================================================
+  WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler()
+  {
+    bbtkDebugMessage("Wx",9,
+                    "WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler("
+                    <<mBox->bbGetFullName()<<")"<<std::endl);
+     mBox->bbSetWidgetEventHandler(0);   
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBoxWidgetEventHandler::OnWindowDestroy(wxWindowDestroyEvent&)
+  {
+    bbtkDebugMessage("Wx",9,"WxBlackBoxWidgetEventHandler::OnWindowDestroy() ["
+                    <<mBox->bbGetFullName()<<"]"<<std::endl);
+    mBox->bbSetOutputWidget(0);
+    mBox->bbSetModifiedStatus();
+    //mDead = true;
+    //delete this;
+  }
+  //=========================================================================
+
+
+
+
+
+
+
+  /*
+  //=========================================================================
+  wxWindow* WxParentToChildData::GetWindowInWhichToInsert( const BlackBox* b)
+    const
+  {
+    bbtkDebugMessageInc("Core",9,"WxParentToChildData::GetWindowInWhichToInsert("<<b->bbGetFullName()<<")"<<std::endl);
+    
+    BlackBox::InputConnectorMapType::const_iterator i = b->bbGetInputConnectorMap().find("WinParent");
+    if (i==b->bbGetInputConnectorMap().end())
+      {
+       bbtkError("WxParentToChildData::GetWindowInWhichToInsert : the box "
+                 <<b->bbGetFullName()
+                 <<" does not have any 'Parent' input ?!?");
+      }
+    Connection* c = i->second->GetConnection();
+    if (!c) 
+      {
+       bbtkDebugMessage("Core",9,
+                        "-> The input 'Parent' of the box "
+                        <<b->bbGetFullName()
+                        <<" is not connected."<<std::endl);
+       return 0;
+      }
+    
+    std::map< Connection*, wxWindow *>::const_iterator j 
+      = mConnectionToWindowMap.find(c);
+
+    if (j==mConnectionToWindowMap.end())
+      {
+       bbtkError("WxParentToChildData::GetWindowInWhichToInsert("
+                 <<b->bbGetFullName()
+                 <<") no window provided by parent ?!?");
+      }
+
+    bbtkDebugDecTab("Core",9);
+    return j->second;
+  }
+  //=========================================================================
+  */
+  
+  //=========================================================================
+  // WxBlackBox
+  //=========================================================================
+
+  //=========================================================================
+  //=========================================================================
+  //=========================================================================
+  //=========================================================================
+  BBTK_USER_BLACK_BOX_IMPLEMENTATION(WxBlackBox,UserBlackBox);
+  //=========================================================================
+  
+  //=========================================================================
+  void WxBlackBox::bbUserConstructor()
+  {
+    bbtkDebugMessage("Core",9,"WxBlackBox::bbUserConstructor()"<<std::endl);
+    bbInitAttributes();
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void WxBlackBox::bbUserCopyConstructor()
+  {
+    bbtkDebugMessage("Core",9,"WxBlackBox::bbUserCopyConstructor()"
+                    <<std::endl);
+    bbInitAttributes();
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  void WxBlackBox::bbUserDestructor()
+  {
+    bbtkDebugMessage("Core",9,"WxBlackBox::bbUserDestructor()"<<std::endl);
+    if (bbGetWindow()) {
+      delete bbGetWindow();
+      //      bbSetWindow(0);
+    }
+    bbtkDebugMessage("Core",9,"EO WxBlackBox::bbUserDestructor()"<<std::endl);
+  }
+  //=========================================================================
+  
+
+  /*
+  //=========================================================================
+  WxBlackBox::Widget*  WxBlackBox::bbGetWidget()
+  { 
+    if (bbGetOutputWidget() && bbGetOutputWidget()->IsDead()) 
+      {
+       bbtkDebugMessage("Wx",9,"WxBlackBox::bbGetWidget() ["<<
+                        bbGetFullName()<<"] : Widget is dead : deleting it"
+                        <<std::endl);
+       delete bbGetOutputWidget();
+       bbSetOutputWidget(0);
+      }
+    return bbGetOutputWidget();
+  }
+  //=========================================================================
+  */
+
+
+  //=========================================================================
+  /**
+   * \brief Initialize the attributes of the class
+   *
+   */
+  void WxBlackBox::bbInitAttributes()
+  {
+    bbmWindow = 0;
+    //    bbmWidget = 0;
+    //    bbSetInputWinParent(0);
+    bbSetInputWinTitle("...");
+    bbSetInputWinWidth(800);
+    bbSetInputWinHeight(800);
+    bbSetInputWinDialog(false);
+    bbSetOutputWidget(0);
+
+    bbSetWidgetEventHandler(0);
+  }
+  //=========================================================================
+
+
+
+  //==================================================================
+  /// Specific methods for window creation during pipeline execution
+  /// Shows the window associated to the box 
+  /// (called after bbProcess during bbExecute)
+  void WxBlackBox::bbShowWindow(Connection* caller)
+  {
+    bbtkDebugMessageInc("Process",1,"=> WxBlackBox::bbShowWindow() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    // If Event Handler for the widget does not exist or is obsolete : create it 
+    if (bbGetOutputWidget()!=0)
+      {
+       if (bbGetWidgetEventHandler()==0)
+         {
+           bbtkDebugMessage("Process",3,
+                            "-> No widget event handler : creating one"
+                            <<std::endl);
+           new WxBlackBoxWidgetEventHandler(this,bbGetOutputWidget());
+         }
+       else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
+                 ( bbGetOutputWidget() ) )
+         {
+           bbtkDebugMessage("Process",3,
+                            "-> Obsolete widget event handler : re-creating one"
+                            <<std::endl);
+           delete bbGetWidgetEventHandler();
+           new WxBlackBoxWidgetEventHandler(this,bbGetOutputWidget());
+         }
+      }
+
+    // If the output 'Widget' is connected then it's gonna 
+    // be captured by its parent window : nothing to do 
+    if ( (*bbGetOutputConnectorMap().find("Widget")).second
+        ->GetConnectionVector().size() != 0 ) 
+      {
+       
+       bbtkDebugMessage("Process",2,
+                        "-> Output 'Widget' connected : nothing to do"
+                        <<std::endl);
+       bbtkDebugDecTab("Process",1);
+       return;
+      }
+
+
+    Window* show = 0;
+    // If the window already exists : no need creating it
+    if (bbGetWindow()!=0)
+      {
+       bbtkDebugMessage("Process",2,
+                        "-> Window already exists"
+                        <<std::endl);
+       show = bbGetWindow();
+      }
+    // Else if the widget exists : create window 
+    else if (bbGetOutputWidget()!=0) 
+      {
+       bbtkDebugMessage("Process",2,
+                        "-> Widget exists : creating the window"
+                        <<std::endl);
+
+
+       // Input WinDialog set to true : creating a Dialog
+       if (bbGetInputWinDialog()) 
+         {
+           bbtkDebugMessage("Process",2,
+                            "   Input WinDialog set to true : creating a Dialog"
+                            <<std::endl);
+           show = (Window*) new WxBlackBoxDialog( this,
+                                                  bbGlobalGetTopWindow(), 
+                                                  std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
+                                                  wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
+         }
+       // Input WinDialog set to false : creating a Frame
+       else 
+         {
+           bbtkDebugMessage("Process",2,
+                            "   Input WinDialog set to false : creating a Frame"
+                            <<std::endl);
+           show = (Window*) new WxBlackBoxFrame( this,
+                                                 bbGlobalGetTopWindow(), 
+                                                 std2wx( bbGetInputWinTitle()  + " - bbtk (c) CREATIS LRMN"),
+                                                 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
+         }
+
+      }
+    // No window nor widget : error
+    else
+      {
+       bbtkError("WxBlackBox::bbShowWindow() ["
+                 <<bbGetFullName()
+                 <<"] : No widget. Did you set the box output 'Widget' in the processing method of the box ?");
+      }
+    
+    // Show the window
+    if (true) //!show->IsShown())
+      {
+       show->bbShow(); 
+      }
+    else 
+      {
+       bbtkDebugMessage("Process",2,"-> Already shown : nothing to do"<<std::endl);
+      }
+  
+
+    bbtkDebugMessage("Process",1,"<= WxBlackBox::bbShowWindow() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    bbtkDebugDecTab("Process",1);
+  }
+  //==================================================================
+
+
+
+
+  //==================================================================
+   void WxBlackBox::bbHideWindow()
+  {
+    bbtkDebugMessageInc("Process",1,"=> WxBlackBox::bbHideWindow() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+    if (bbGetWindow()!=0) bbGetWindow()->bbHide();
+
+    bbtkDebugMessageDec("Process",1,"<= WxBlackBox::bbHideWindow() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+  }
+  //==================================================================
+
+
+
+
+}//namespace bbtk
+
+
+#endif
+
diff --git a/kernel/src/bbtkWxBlackBox.h b/kernel/src/bbtkWxBlackBox.h
new file mode 100644 (file)
index 0000000..5ff5d66
--- /dev/null
@@ -0,0 +1,345 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkWxBlackBox.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*//**
+ * \brief Short description in one line
+ * 
+ * Long description which 
+ * can span multiple lines
+ */
+/**
+ * \file 
+ * \brief 
+ */
+/**
+ * \class bbtk::
+ * \brief 
+ */
+
+
+#ifdef _USE_WXWIDGETS_
+
+
+#ifndef __bbtkWxBlackBox_h__
+#define __bbtkWxBlackBox_h__
+
+
+#include "bbtkWx.h"
+#include "bbtkUserBlackBox.h"
+
+
+namespace bbtk
+{
+
+
+
+
+  //==================================================================
+  // Forward declaration of the class of window associated to a WxBlackBox
+  class WxBlackBoxWindow;
+  //==================================================================
+
+  //==================================================================
+  // Forward declaration of the widget event handler class
+  class WxBlackBoxWidgetEventHandler;
+  //==================================================================
+
+
+  //==================================================================
+  /// Widget black boxes
+  class BBTK_EXPORT WxBlackBox : public bbtk::UserBlackBox  
+  {
+    BBTK_USER_BLACK_BOX_INTERFACE(WxBlackBox,bbtk::UserBlackBox);
+    //   BBTK_DECLARE_INPUT(WinParent,WxParentToChildData*);
+    BBTK_DECLARE_INPUT(WinTitle,std::string);
+    BBTK_DECLARE_INPUT(WinWidth,int);
+    BBTK_DECLARE_INPUT(WinHeight,int);
+    BBTK_DECLARE_INPUT(WinDialog,bool);
+    BBTK_DECLARE_INPUT(WinHide,Void);
+    BBTK_DECLARE_OUTPUT(Widget, wxWindow*);//WxBlackBoxWidget*);
+    BBTK_PROCESS(Process);
+
+  public:
+    typedef WxBlackBoxWindow Window;
+    
+    /// Returns the window associated to the box
+    /// If 0 returned = no window
+    Window* bbGetWindow() { return bbmWindow; }
+
+    /// Returns the Parent Window that must be used to create the widget 
+    wxWindow* bbGetWxParent() { return bbGlobalGetTopWindow(); }
+
+
+    /// Returns the global parent of all bbtk windows
+    static wxWindow* bbGlobalGetTopWindow();
+    /// Sets the global parent of all bbtk windows
+    static void bbGlobalSetTopWindow(wxWindow*);
+
+    static void bbGlobalIncNbWindowsAlive() { bbmgNbWindowsAlive++; }
+    static void bbGlobalDecNbWindowsAlive();
+    static int  bbGlobalGetNbWindowsAlive() { return bbmgNbWindowsAlive; }
+    static bool bbGlobalIsSomeWindowAlive() { return (bbmgNbWindowsAlive>0);}
+
+    static void bbGlobalDecNbWindowsShown();
+    static void bbGlobalIncNbWindowsShown() { bbmgNbWindowsShown++; }
+    static int  bbGlobalGetNbWindowsShown() { return bbmgNbWindowsShown; }
+    static bool bbGlobalIsSomeWindowShown() { return (bbmgNbWindowsShown>0);}
+
+
+  private:
+    static wxWindow* bbmgTopWindow;
+    static int bbmgNbWindowsAlive;
+    static int bbmgNbWindowsShown;
+
+  protected:
+    
+  
+    //==================================================================
+    /// User callback called in the box contructor
+    virtual void bbUserConstructor();
+    /// User callback called in the box copy constructor
+    virtual void bbUserCopyConstructor();
+    /// User callback called in the box destructor
+    virtual void bbUserDestructor();
+    //==================================================================    
+
+    /*
+
+    //==================================================================    
+    /// User callback for creating the window associated to the box
+    /// Can be overloaded in order to impose your own window to show,
+    /// Typically if your widget is already a dialog that cannot 
+    /// be inserted into a parent.
+    /// WARNING : If you use it then your widget will not be inserted 
+    /// in the parent window, if any 
+    /// (i.e. even if the Parent-Child connection is set)
+    virtual Window* bbUserCreateWindow()
+    {
+      return 0;
+    }
+    //==================================================================    
+
+    //==================================================================    
+    /// User callback for creating the widget associated to the box
+    /// Must be defined if bbUserCreateWindow is not 
+    virtual Widget* bbUserCreateWidget(wxWindow *parent) 
+    {
+      bbtkError(bbGetTypeName()<<" is a WxBlackBox whose bbUserCreateWindow and bbUserCreateWidget methods are both undefined : cannot work !!");
+      return 0;
+    }
+    //==================================================================    
+    */
+
+    //==================================================================
+    /// Specific methods for windows creation during pipeline execution
+    //void bbCreateWindow();
+    void bbShowWindow(Connection* caller);
+    void bbHideWindow();
+    //==================================================================
+
+    void Process() { } 
+
+  private:
+    /// friendship
+    friend class WxBlackBoxWindow;
+    friend class WxBlackBoxWidgetEventHandler;
+
+    /// Sets the window
+    inline void bbSetWindow(Window* w) { bbmWindow=w; }
+
+    /// Sets the Widget Event Handler
+    inline void bbSetWidgetEventHandler(WxBlackBoxWidgetEventHandler* w) 
+    { bbmWidgetEventHandler = w; }
+    /// Gets the Widget Event Handler
+    inline WxBlackBoxWidgetEventHandler* bbGetWidgetEventHandler()
+    { return bbmWidgetEventHandler; }
+
+
+    /// The WxBlackBoxWindow associated to the box
+    Window* bbmWindow;
+    /// The WxBlackBoxWidgetEventHandler associated to the box
+    WxBlackBoxWidgetEventHandler* bbmWidgetEventHandler;
+
+
+    void bbInitAttributes();
+
+
+  };
+  //=================================================================
+
+  //=================================================================
+  // UserBlackBox description
+  BBTK_BEGIN_DESCRIBE_BLACK_BOX(WxBlackBox,bbtk::UserBlackBox);
+  BBTK_NAME("WxBlackBox");
+  //  BBTK_INPUT_NOCOPY(WxBlackBox,WinParent,"Parent widget box",
+  //               WxParentToChildData*);
+  BBTK_INPUT(WxBlackBox,WinTitle,
+            "Title of the window (only used if the box is the top window of a Parent-Child hierarchy)",
+            std::string);
+  BBTK_INPUT(WxBlackBox,WinWidth,
+            "Width of the window (only used if the box is the top window of a Parent-Child hierarchy)",int);
+  BBTK_INPUT(WxBlackBox,WinHeight,
+            "Height of the window (only used if the box is the top window of a Parent-Child hierarchy)",int);
+  BBTK_INPUT(WxBlackBox,WinDialog,
+            "Set to 'true' to have a dialog window, i.e. which is modal (steals the focus until closed) (only used if the box is the top window of a Parent-Child hierarchy)",bool);
+  BBTK_INPUT(WxBlackBox,WinHide,
+            "Any signal received hides the window (only active if the box is the top window of a Parent-Child hierarchy)",Void);
+  BBTK_OUTPUT(WxBlackBox,Widget,"Output widget",wxWindow*);
+  BBTK_END_DESCRIBE_BLACK_BOX(WxBlackBox);
+  //=================================================================
+
+
+
+
+
+
+
+
+
+  //==================================================================
+  // The base of the hierarchy of windows associated to a WxBlackBox
+  class BBTK_EXPORT WxBlackBoxWindow //: public wxWindow
+  {
+  public:
+    WxBlackBoxWindow(WxBlackBox* box);
+    virtual ~WxBlackBoxWindow();
+    virtual void bbShow();
+    virtual void bbHide();
+    bool bbIsShown() { return mShown; }
+    virtual WxBlackBox* bbGetBlackBox() { return mBox; }
+    virtual wxDialog* bbGetDialog() { return 0; } 
+    virtual wxFrame* bbGetFrame() { return 0; } 
+  private:
+    WxBlackBox* mBox;
+    bool mShown;
+  };
+  //==================================================================
+
+  //==================================================================
+  // Dialog window which is modal
+  class BBTK_EXPORT  WxBlackBoxDialog : public wxDialog, public WxBlackBoxWindow
+  {
+  public:
+    WxBlackBoxDialog(WxBlackBox* box, 
+                    wxWindow *parent, wxString title, wxSize size);
+    ~WxBlackBoxDialog();
+    void bbShow();  
+    void bbHide();
+    wxDialog* bbGetDialog() { return this; } 
+  };
+  //==================================================================
+
+  //==================================================================
+  // Frame window which is not modal
+  class BBTK_EXPORT  WxBlackBoxFrame : public wxFrame, public WxBlackBoxWindow
+  {
+  public:
+    WxBlackBoxFrame(WxBlackBox* box,
+                   wxWindow *parent, wxString title, wxSize size);
+    ~WxBlackBoxFrame();
+    void bbShow();
+    void bbHide();
+    wxFrame* bbGetFrame() { return this; } 
+  };
+  //==================================================================
+
+
+  /*
+ //=================================================================
+  /// Class from which a user defined widget associated to a WxBlackBox 
+  /// should inherit
+  class BBTK_EXPORT  WxBlackBoxWidget
+  {
+  public:
+    /// Ctor with the WxBlackBox which created it 
+    WxBlackBoxWidget( WxBlackBox* box);
+    /// Dtor
+    virtual ~WxBlackBoxWidget();
+
+    /// Returns the WxBlackBox which created it
+    WxBlackBox* GetBlackBox() { return mBox; }
+    /// Returns the WxBlackBox which created it (const)
+    const WxBlackBox* GetBlackBox() const { return mBox; }
+
+    /// Returns the wxWindow associated to the widget
+    virtual wxWindow* GetWxWindow() { return 0; }
+
+    virtual bool IsDead() { return false; }
+
+  private:
+    WxBlackBox* mBox;
+  };  
+  //=================================================================
+  */
+
+  //=================================================================
+  // Handles the destroy events of a widget associated to a WxBlackBox 
+  // in order to signal the widget death to its associated box
+  class BBTK_EXPORT WxBlackBoxWidgetEventHandler : public wxEvtHandler
+  {
+  public:
+    /// Ctor with the box and widget 
+    WxBlackBoxWidgetEventHandler( WxBlackBox* box, wxWindow *widget );
+    /// Dtor
+    ~WxBlackBoxWidgetEventHandler();
+    /// Returns true iff is the handler for that window  
+    bool IsHandlerOf( wxWindow* w ) { return mWindow == w; }
+    // wxWindow* GetWxWindow() { return mWindow; }
+    /// Method processing the destroy event of the widget
+    void OnWindowDestroy(wxWindowDestroyEvent&);
+    //
+    //bool IsDead() { return mDead; }
+
+  private:
+    WxBlackBox* mBox;
+    wxWindow* mWindow;
+    //bool mDead;
+  };  
+  //=================================================================
+
+  /*
+  //=================================================================
+  /// A WxBlackBoxWidget which is a wxPanel also
+  class BBTK_EXPORT  WxBlackBoxWidgetPanel :     
+                               public wxPanel,
+                               public WxBlackBoxWidget
+//                             public WxBlackBoxWidget,
+//                             public wxPanel
+  {
+  public:
+    /// Ctor with the parent and the WxBlackBox which created it 
+    WxBlackBoxWidgetPanel(WxBlackBox* box,  wxWindow *parent)
+      :
+      wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL),
+      WxBlackBoxWidget(box)
+    {}
+    
+    /// Returns the top panel of the widget    
+    wxWindow* GetWxWindow() { return (wxWindow*)(wxPanel*)(this); }
+    /// Returns the top panel of the widget    
+    wxPanel* GetPanel() { return (wxPanel*)(this); }
+
+  };  
+  //=================================================================
+  */
+
+
+} //namespace bbtk
+
+#endif  //__bbtkWxBlackBox_h__
+
+#endif  //_USE_WXWIDGETS_
diff --git a/kernel/src/bbtkWxBrowser.cxx b/kernel/src/bbtkWxBrowser.cxx
new file mode 100644 (file)
index 0000000..996e8a5
--- /dev/null
@@ -0,0 +1,197 @@
+#ifdef _USE_WXWIDGETS_
+
+#include "bbtkWxBrowser.h"
+#include "bbtkWxBlackBox.h"
+
+
+namespace bbtk
+{  
+
+
+  void WxHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& e)
+  {
+    //    std::cout  << "WxHtmlWindow::OnLink"<<std::endl;
+    //    std::cout  << e.GetHref()<<std::endl;
+    LoadPage(e.GetHref());
+    if ( ! GetOpenedAnchor().IsEmpty() )
+      { 
+       //      std::cout << "#" << GetOpenedAnchor() << std::endl;
+       LoadPage(_T("#"+GetOpenedAnchor()));
+      }
+    mBrowser->UpdateURL();
+
+
+  }
+
+
+  enum 
+    {
+      bwd_id,
+      fwd_id,
+      url_id,
+      html_id
+    };
+
+  
+  BEGIN_EVENT_TABLE(WxBrowser, wxPanel)
+    EVT_BUTTON(bwd_id, WxBrowser::OnBackButton )
+    EVT_BUTTON(fwd_id, WxBrowser::OnForwardButton )
+    EVT_TEXT_ENTER(url_id, WxBrowser::OnURLEnter )
+     EVT_HTML_LINK_CLICKED(html_id, WxBrowser::OnLinkClicked)
+  END_EVENT_TABLE()
+    
+    WxBrowser::WxBrowser ( wxWindow *parent, wxSize size )
+      : 
+    wxPanel ( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
+
+  {
+    wxPanel* panel = this;
+
+    wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
+    
+
+    wxBoxSizer *bsizer = new wxBoxSizer(wxHORIZONTAL);
+    
+    sizer->Add ( bsizer, 0, wxGROW );
+    
+    
+    mwxBackButton = new wxButton( panel, bwd_id,_T("<"),wxDefaultPosition,
+                                 wxDefaultSize,wxBU_EXACTFIT);
+    bsizer->Add ( mwxBackButton, 0, wxALIGN_CENTRE | 
+                 wxLEFT | wxTOP | wxBOTTOM , 10 );
+
+    mwxForwardButton = new wxButton( panel, fwd_id,_T(">"),wxDefaultPosition,
+                                    wxDefaultSize,wxBU_EXACTFIT);
+    bsizer->Add ( mwxForwardButton, 0, wxALIGN_CENTRE | 
+                 wxTOP | wxBOTTOM , 10);
+
+  
+    mwxURL = new wxTextCtrl(panel,url_id,_T(""),
+                           wxDefaultPosition,
+                           wxDefaultSize,
+                           wxTE_PROCESS_ENTER);
+    mwxURL->SetLabel(_T("URL"));
+    bsizer->Add(mwxURL, 1, wxGROW | wxALL, 10);
+
+
+    mwxHtmlWindow = new WxHtmlWindow(parent,html_id,this,size);
+
+    /*
+
+-1, 
+                                    wxDefaultPosition, 
+                                    size,
+                                    wxHW_SCROLLBAR_AUTO, 
+                                    "bbtk::WxBrowser");
+    */
+    mwxHtmlWindow->SetBorders(5);
+    //  mwxHtmlWindow->FitInside();
+    wxStaticBoxSizer* hw = 
+      new wxStaticBoxSizer( new wxStaticBox( this, -1, _T(""),
+                                            wxDefaultPosition, 
+                                            size ),
+                           wxVERTICAL );
+    hw->Add ( mwxHtmlWindow, 1, wxGROW  );
+    //sizer->Add ( mwxHtmlWindow, 1, wxGROW  );
+
+    sizer->Add ( hw, 1, wxGROW ); // | wxLEFT | wxRIGHT | wxBOTTOM, 10 );
+    
+
+    panel      -> SetSizer(sizer);
+    panel      -> SetAutoLayout(true);
+    panel      -> Layout();
+
+    /*
+    Connect( mwxBackButton->GetId(), 
+            wxEVT_COMMAND_BUTTON_CLICKED , 
+            (wxObjectEventFunction) 
+            (void (wxPanel::*)(wxEvent&))
+            &WxBrowser::OnBackButton ); 
+    Connect( mwxForwardButton->GetId(), 
+            wxEVT_COMMAND_BUTTON_CLICKED , 
+            (wxObjectEventFunction) 
+            (void (wxPanel::*)(wxEvent&))
+            &WxBrowser::OnForwardButton ); 
+    
+    std::cout << "e="<<wxEVT_COMMAND_HTML_LINK_CLICKED<<std::endl;
+
+    Connect( wxID_ANY, //mwxHtmlWindow->GetId(), 
+            wxEVT_COMMAND_HTML_LINK_CLICKED , 
+            wxHtmlLinkEventHandler( 
+                                   //(wxObjectEventFunction) 
+                                   //       (void (wxPanel::*)(wxEvent&))&
+                                   WxBrowser::OnLinkClicked ) ); 
+    Connect( mwxHtmlWindow->GetId(), 
+            wxEVT_COMMAND_HTML_CELL_HOVER,
+            //(wxObjectEventFunction) 
+            wxHtmlCellEventHandler(
+                                                           //       (void (wxPanel::*)(wxHtmlCellEvent&))&
+                                   WxBrowser::OnCell ) ); 
+    */
+  }
+
+  bool WxBrowser::GoTo(std::string& file)
+  { 
+    //  std::cout << "goto"<<std::endl;
+    bool r = mwxHtmlWindow->LoadPage(std2wx(file));
+    UpdateURL();
+    return r;
+  }
+  
+  void WxBrowser::OnBackButton(wxCommandEvent& )
+  {
+    //    std::cout << "back"<<std::endl;
+    mwxHtmlWindow->HistoryBack();
+    UpdateURL();
+  }
+  
+  void WxBrowser::OnForwardButton(wxCommandEvent& )
+  {
+    //    std::cout << "forward"<<std::endl;
+    mwxHtmlWindow->HistoryForward();
+    UpdateURL();
+  }
+
+  void WxBrowser::OnURLEnter( wxCommandEvent&)
+  { 
+    //std::cout  << "OnURL"<<std::endl;
+    mwxHtmlWindow->LoadPage(mwxURL->GetValue());
+  }
+
+  
+  void WxBrowser::OnLinkClicked(wxHtmlLinkEvent& e)
+  {
+    std::cout  << "WxBrowser::OnLinkClicked"<<std::endl;
+    std::cout  << e.GetLinkInfo().GetHref()<<std::endl;
+    mwxHtmlWindow->LoadPage(e.GetLinkInfo().GetHref());
+       UpdateURL();
+  }
+  /*
+  void WxBrowser::OnCell(wxHtmlCellEvent& )
+  {
+    std::cout  << "OnCell"<<std::endl;
+  }
+  */
+  void WxBrowser::UpdateURL()
+  {
+
+    wxString s = mwxHtmlWindow->GetOpenedPage();
+    if (!mwxHtmlWindow->GetOpenedAnchor().IsEmpty())
+    {
+           s += _T("#") + mwxHtmlWindow->GetOpenedAnchor();
+    }
+    mwxURL->Clear();
+    mwxURL->AppendText(s);
+  }
+  void WxBrowser::SetSize( wxSize s)
+  {
+    //    wxPanel::SetSize(s);
+    mwxHtmlWindow->SetSize(s);
+    Fit();
+  }
+
+}
+
+#endif
diff --git a/kernel/src/bbtkWxBrowser.h b/kernel/src/bbtkWxBrowser.h
new file mode 100644 (file)
index 0000000..8efe171
--- /dev/null
@@ -0,0 +1,68 @@
+#ifdef _USE_WXWIDGETS_
+
+
+#ifndef __bbtkWxBrowser_h_INCLUDED__
+#define __bbtkWxBrowser_h_INCLUDED__
+
+#include "bbtkWx.h"
+//#include <wx/notebook.h>
+#include <wx/html/htmlwin.h>
+
+namespace bbtk
+{
+
+  class WxBrowser;
+
+  class WxHtmlWindow : public virtual wxHtmlWindow
+  {
+  public:
+    WxHtmlWindow( wxWindow *parent, int id, WxBrowser* browser, wxSize size) 
+      : wxHtmlWindow(parent, id, 
+                    wxDefaultPosition, 
+                    size,
+                    wxHW_SCROLLBAR_AUTO, 
+                 _T("bbtk::WxBrowser")),
+             mBrowser(browser)
+    {
+     
+    }
+    //    wxHtmlOpeningStatus OnOpeningURL(wxHtmlURLType type,const wxString& url, wxString *redirect);
+    virtual void OnLinkClicked(const wxHtmlLinkInfo& link);
+
+  private: 
+    WxBrowser* mBrowser;
+
+
+  };
+
+  class WxBrowser : public wxPanel
+  {
+  public:
+    WxBrowser ( wxWindow *parent, wxSize size );
+    bool GoTo(std::string&);
+
+    void OnBackButton(wxCommandEvent& );
+    void OnForwardButton(wxCommandEvent& );
+       void OnLinkClicked(wxHtmlLinkEvent& );
+    void OnURLEnter( wxCommandEvent&);
+    void UpdateURL();
+    //  void OnCell(wxHtmlCellEvent& );
+
+    void SetSize( wxSize );
+
+  private:
+    WxHtmlWindow* mwxHtmlWindow;
+    wxTextCtrl* mwxURL;
+    wxButton* mwxBackButton;
+    wxButton* mwxForwardButton;
+   // any class wishing to process wxWidgets events must use this macro
+    DECLARE_EVENT_TABLE()  
+  };
+
+}
+#endif
+
+#endif
diff --git a/kernel/src/bbtkWxConsole.cxx b/kernel/src/bbtkWxConsole.cxx
new file mode 100644 (file)
index 0000000..6a2a7d8
--- /dev/null
@@ -0,0 +1,420 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkWxConsole.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*//**
+ * \brief Short description in one line
+ * 
+ * Long description which 
+ * can span multiple lines
+ */
+/**
+ * \file 
+ * \brief 
+ */
+/**
+ * \class bbtk::
+ * \brief 
+ */
+
+
+#ifdef _USE_WXWIDGETS_
+
+#include <iostream>    
+#include "bbtkWxConsole.h"
+#include "bbtkWxBlackBox.h"
+
+namespace bbtk
+{
+
+  WxConsole* WxConsole::mInstance = 0;
+// On Windows when compiling a dll, wx prevents the compilation
+// of the class wxStreamToTextRedirector (why ? it is a nightmare...)
+// The blocking symbol is wxHAS_TEXT_WINDOW_STREAM.
+// Note also that wxStreamToTextRedirector use the fact that wx is 
+// compiled with the option WX_USE_STD_STREAMS in which case 
+// wxTextCtrl inherits from std::streambuf and the redirection 
+// can be done simply by setting the std::cout buffer to the 
+// one of the wxTextCtrl. 
+// So on windows, we have to redirect manually std::cout to mwxTextHistory.  
+// Finally, on all systems we made our redirection class to redirect both to
+// the WxConsole and to printf in order to get a console trace when 
+// the appli crashes (we could also imagine to log in a file...)
+// This is why we finally wrote our own redirection which is crossplatform
+// (drawback : not optimal on Unix platform; we could think of 
+// a particular implementation...).
+
+  //================================================================
+  /// Redirects std::cout to a wxTextCtrl and optionally to printf also
+  class WxTextCtrlStreamRedirector   : public std::streambuf
+  {      
+    
+  public:
+    
+    WxTextCtrlStreamRedirector(std::ostream& redirect,
+                                wxTextCtrl *text, 
+                                const wxColour& colour = *wxBLACK,
+                                bool doprintf=true,
+                                int bufferSize=1000)
+      : mText(text),
+       mPrintf(doprintf),
+       m_ostr(redirect),
+       mColour(colour)
+    {
+      if (bufferSize)
+        {
+         char *ptr = new char[bufferSize];
+         setp(ptr, ptr + bufferSize);
+        }
+      else
+       setp(0, 0);
+      
+      m_sbufOld = m_ostr.rdbuf();
+      m_ostr.rdbuf(this);
+    }
+    
+    ~WxTextCtrlStreamRedirector()
+    {
+      sync();
+      delete[] pbase();
+      m_ostr.rdbuf(m_sbufOld);
+    }
+  
+   virtual void writeString(const std::string &str) 
+    {
+      const wxTextAttr& style = mText->GetDefaultStyle();
+      mText->SetDefaultStyle(mColour);
+      mText->AppendText(std2wx(str));
+      mText->SetDefaultStyle(style);
+     
+      if (mPrintf) 
+       {
+         printf("%s",str.c_str());
+       }
+    }
+    
+  
+  private:
+    wxTextCtrl* mText;
+    // 
+    bool mPrintf;
+    // the stream we're redirecting
+    std::ostream&   m_ostr;
+    // the old streambuf (before we changed it)
+    std::streambuf *m_sbufOld;
+    //
+    wxColour mColour;
+    
+  private:
+    int        overflow(int c)
+    {
+      sync();
+      
+      if (c != EOF)
+        {
+         if (pbase() == epptr())
+            {
+             std::string temp;
+             temp += char(c);
+             writeString(temp);
+            }
+         else
+           sputc(c);
+        }
+      
+      return 0;
+    }
+    
+    int        sync()
+    {
+      if (pbase() != pptr())
+        {
+         int len = int(pptr() - pbase());
+         std::string temp(pbase(), len);
+         writeString(temp);
+         setp(pbase(), epptr());
+        }
+      return 0;
+    }
+  };
+  //================================================================
+
+  
+  
+  //================================================================
+  WxConsole::WxConsole( wxWindow *parent, wxString title, wxSize size)
+    : wxFrame((wxFrame *)parent, -1, title, wxDefaultPosition, size)
+  {    
+    mInstance = this;
+    mInterpreter = new bbtk::Interpreter();
+    mInterpreter->SetCommandLine(true);
+    //==============
+    // Menu
+    wxInitAllImageHandlers();
+    
+    wxMenu *menuFile = new wxMenu;
+    menuFile->Append( ID_Menu_Quit, _T("&Quit") );
+    
+    wxMenu *menuAbout = new wxMenu;
+    menuAbout->Append( ID_Menu_About, _T("&About...") );
+    
+    wxMenuBar *menuBar = new wxMenuBar;
+    menuBar->Append( menuFile, _T("&File") );
+    menuBar->Append( menuAbout, _T("About") );
+    
+    SetMenuBar( menuBar );
+    
+    CreateStatusBar();
+    SetStatusText( _T("Welcome to bbi !") );
+    
+    //==============
+    // Notebook
+    
+    //    wxFlexGridSizer *sizer = new wxFlexGridSizer(1);
+    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
+    
+    mwxNotebook = new wxNotebook(this, -1, 
+                                wxDefaultPosition, wxDefaultSize, 0);
+    mwxPageCommand = new wxPanel(mwxNotebook,-1);    
+    mwxNotebook->AddPage( mwxPageCommand, _T("Command"));
+
+    mwxPageHelp = new wxPanel(mwxNotebook,-1);    
+    mwxNotebook->AddPage( mwxPageHelp, _T("Help"));
+    
+    sizer->Add ( mwxNotebook, 1, wxGROW | wxALIGN_BOTTOM );
+    
+    wxBoxSizer *cmdsizer = new wxBoxSizer(wxVERTICAL);
+    
+    mwxPageCommand->SetAutoLayout(true);    
+    mwxPageCommand->SetSizer(cmdsizer);
+    cmdsizer->Fit(mwxPageCommand);
+    cmdsizer->SetSizeHints(mwxPageCommand);
+
+    wxBoxSizer *helpsizer = new wxBoxSizer(wxVERTICAL);
+    
+    mwxPageHelp->SetAutoLayout(true);    
+    mwxPageHelp->SetSizer(helpsizer);
+    helpsizer->Fit(mwxPageHelp);
+    helpsizer->SetSizeHints(mwxPageHelp);
+   
+    mwxHtmlWindow = new WxBrowser(mwxPageHelp,
+                                 wxSize(1200,0));
+
+    //    mwxHtmlWindow->SetSize(wxSize(800,1000));
+    helpsizer->Add (mwxHtmlWindow,  wxALL | wxGROW );
+  
+    //==============
+    // Command page 
+
+    mwxTextHistory = 
+      new wxTextCtrl(mwxPageCommand,0,_T(""),wxDefaultPosition,
+                    wxDefaultSize, //HistorySize,
+                    wxTE_READONLY |
+                    wxTE_MULTILINE );
+    wxFont* FixedFont = new wxFont(10,
+                                  wxFONTFAMILY_MODERN,
+                                  wxFONTSTYLE_NORMAL,
+                                  wxFONTWEIGHT_NORMAL,
+                                  false);
+
+   mwxTextHistoryAttr = new wxTextAttr;
+   mwxTextHistoryAttr->SetFont(*FixedFont);
+   mwxTextCommand = 
+     new wxTextCtrl(mwxPageCommand,0,_T(""),wxDefaultPosition,
+                   wxDefaultSize,//CommandSize,
+                   
+                   wxTE_PROCESS_ENTER
+                       | 
+                   wxTE_PROCESS_TAB | wxWANTS_CHARS 
+//                     |  wxTAB_TRAVERSAL
+                   );
+   
+
+    mwxTextCommandAttr = new wxTextAttr;   
+    mwxTextCommandAttr->SetFont(*FixedFont);
+    mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
+    mwxTextCommand->SetFocus();
+
+     
+    
+    cmdsizer->Add ( mwxTextHistory, 1, wxALL | wxGROW, 10);
+  
+    cmdsizer->Add ( mwxTextCommand, 0, wxLEFT | wxRIGHT | wxBOTTOM 
+                   | wxGROW, 10 );
+
+    //  cmdsizer->AddGrowableCol(0);
+    //  cmdsizer->AddGrowableRow(0);
+    // cmdsizer->AddGrowableRow(1);
+    //  cmdsizer->SetFlexibleDirection(wxBOTH);
+
+    //=============================
+    // Events connection
+    // COMMAND
+    // ENTER
+    Connect( mwxTextCommand->GetId(),
+            wxEVT_COMMAND_TEXT_ENTER,
+            (wxObjectEventFunction)& WxConsole::OnCommandEnter );
+    Connect( mwxTextCommand->GetId(),
+            wxEVT_CHAR,
+            //wxEVT_COMMAND_TEXT_UPDATED,
+            (wxObjectEventFunction)& WxConsole::OnCommandChar );
+    // MENU
+    //    Connect ( 
+
+    // Redirection of std::cout to mwxTextHistory and printf
+    mRedirect_cout = 
+      new WxTextCtrlStreamRedirector(std::cout,mwxTextHistory,*wxBLACK,true);
+    mRedirect_cerr = 
+      new WxTextCtrlStreamRedirector(std::cerr,mwxTextHistory,*wxGREEN,true); 
+        
+    // Sets the console as the parent window of all bbtk windows
+    WxBlackBox::bbGlobalSetTopWindow(this);
+
+
+    // Layout
+    SetSizer(sizer);
+    SetAutoLayout(true);
+    Layout();
+
+  }
+  //================================================================
+
+ //================================================================
+  WxConsole::~WxConsole()
+  {
+    delete mRedirect_cout;
+    delete mRedirect_cerr;
+  }
+  //================================================================
+
+  //================================================================
+  void WxConsole::OnCommandEnter(wxCommandEvent& event)
+  {
+    wxString line(mwxTextCommand->GetValue());
+    wxString s = _T("> ") + line + _T("\n");
+    mwxTextHistoryAttr->SetTextColour(*wxRED);
+    mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
+    mwxTextHistory->AppendText(s);
+    // send to standard console also 
+    printf("%s",wx2std(s).c_str());
+    mwxTextCommand->Clear();
+    mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
+    mwxTextHistoryAttr->SetTextColour(*wxBLACK);
+    mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
+
+    try 
+    {
+      bool insideComment = false;
+          mInterpreter->InterpretLine( wx2std(line), insideComment );
+    }
+    catch (bbtk::QuitException)
+    {
+          Close(true); 
+    }
+    catch (bbtk::Exception e) 
+    {
+          e.Print();
+    }
+    catch (std::exception& e) 
+    {
+          std::cout << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
+    }
+    catch (...)
+    {
+          std::cout << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
+                         << std::endl;
+    }
+  }
+  //================================================================
+
+
+  //================================================================
+  void WxConsole::OnMenuQuit(wxCommandEvent& WXUNUSED(event))
+  {
+    Close(true);
+  }
+  //================================================================
+
+
+  //================================================================
+  void WxConsole::OnMenuAbout(wxCommandEvent& WXUNUSED(event))
+  {
+    
+    wxMessageBox(_T("  bbi\nThe Black Box Toolkit interpreter\n(c) CREATIS-LRMN 2007"),
+                _T("About ..."), wxOK | wxICON_INFORMATION, 
+                this);
+  }
+  //================================================================
+
+  //================================================================
+  void WxConsole::OnCommandChar(wxCommandEvent& event)
+  {
+    std::cout << "c";
+    /*
+    // Command completion  
+    std::vector<std::string> commands;
+    wxString sline( wx2std ( mwxTextCommand->GetValue() ) );
+    int ind = sline.size();
+    mInterpreter->FindCommandsWithPrefix( sline.c_str(),ind,commands);
+    if (commands.size()==1) 
+      {
+       std::string com = *commands.begin();
+       for (; ind<com.size(); ++ind) 
+         {
+           mwxTextCommand->TextAppend( std2wx ( com[ind]) ); 
+         }
+        mwxTextCommand->TextAppend(_T(" "));
+      }
+    else if (commands.size()>1) 
+      {
+       std::vector<std::string>::iterator i;
+       write(1,"\n",1);
+       for (i=commands.begin();i!=commands.end();++i) 
+         {
+           write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
+           PrintChar(' ');
+         }
+       write(STDOUT_FILENO,"\n> ",3);
+       //for (int j=0;j<ind;++j) 
+       //{
+       write(STDOUT_FILENO,line,ind); 
+       //  }
+      }
+    */
+  }
+  //================================================================
+
+  void WxConsole::ShowHtmlPage(std::string& page)
+  {
+    //  std::cout << "WxConsole::ShowHtmlPage('"<<page<<"')"<<std::endl;
+    if (!mwxHtmlWindow->GoTo(page)) 
+      {
+       //      std::cout << "ERROR html"<<std::endl;
+      }
+  } 
+
+  //================================================================  
+  BEGIN_EVENT_TABLE(WxConsole, wxFrame)
+    EVT_MENU(WxConsole::ID_Menu_Quit, WxConsole::OnMenuQuit)
+    EVT_MENU(WxConsole::ID_Menu_About, WxConsole::OnMenuAbout)
+    END_EVENT_TABLE()
+  //================================================================
+
+} // namespace bbtk
+
+
+#endif //_USE_WXWIDGETS_
diff --git a/kernel/src/bbtkWxConsole.h b/kernel/src/bbtkWxConsole.h
new file mode 100644 (file)
index 0000000..5de4ea9
--- /dev/null
@@ -0,0 +1,116 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkWxConsole.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*//**
+ * \brief Short description in one line
+ * 
+ * Long description which 
+ * can span multiple lines
+ */
+/**
+ * \file 
+ * \brief 
+ */
+/**
+ * \class bbtk::
+ * \brief 
+ */
+
+
+#ifdef _USE_WXWIDGETS_
+
+       
+#ifndef __bbtkWxConsole_h__
+#define __bbtkWxConsole_h__
+
+
+#include "bbtkWx.h"
+#include <wx/notebook.h>
+#include <wx/html/htmlwin.h>
+
+
+#include "bbtkInterpreter.h"
+#include "bbtkWxBrowser.h"
+
+namespace bbtk
+{
+
+  class WxTextCtrlStreamRedirector;
+
+  /// A console in which user can enter commands
+  class BBTK_EXPORT WxConsole : public wxFrame
+  {
+  public:
+    WxConsole( wxWindow *parent, wxString title, wxSize size);
+    ~WxConsole();
+
+    static WxConsole* GetInstance() { return mInstance; }
+
+    /// Sets the inputs of the workspace : 
+    /// the map is passed as is to the Executer
+    void SetInputs(const std::map<std::string,std::string>& m)
+    { mInterpreter->SetInputs(m); }
+    
+    /// Puts the executer in "no exec" mode, 
+    /// which creates but does not execute pipelines.
+    void SetNoExecMode(bool b) { mInterpreter->SetNoExecMode(b); }
+
+    void SetDialogMode(Interpreter::DialogModeType t) { mInterpreter->SetDialogMode(t); }
+    
+    /// Runs the interpretation of a file
+    void InterpretFile( const std::string& filename, bool use_configuration_file = true) 
+    { mInterpreter->InterpretFile(filename,use_configuration_file, false); }
+
+    void OnMenuQuit(wxCommandEvent& event);
+    void OnMenuAbout(wxCommandEvent& event);
+    void OnCommandEnter(wxCommandEvent& event);
+    void OnCommandChar(wxCommandEvent& event);
+
+    void ShowHtmlPage(std::string&);
+
+  private:
+    Interpreter* mInterpreter;
+    wxTextCtrl* mwxTextHistory;
+    wxTextCtrl* mwxTextCommand;
+    wxTextAttr* mwxTextHistoryAttr;
+    wxTextAttr* mwxTextCommandAttr;
+    wxNotebook* mwxNotebook;
+    wxPanel *mwxPageCommand, *mwxPageHelp;
+    WxTextCtrlStreamRedirector* mRedirect_cout;
+    WxTextCtrlStreamRedirector* mRedirect_cerr;
+
+    WxBrowser* mwxHtmlWindow;
+
+    static WxConsole* mInstance;
+  public:
+         
+     enum
+    {
+      ID_Menu_Quit = 1,
+      ID_Menu_About,
+    };
+    
+    DECLARE_EVENT_TABLE()
+       
+  };
+
+  
+} // namespace bbtk
+
+
+#endif // __bbtkWxConsole_h__
+
+#endif //_USE_WXWIDGETS_
diff --git a/kernel/src/cmake/bbtkConfigure.h.in b/kernel/src/cmake/bbtkConfigure.h.in
new file mode 100644 (file)
index 0000000..d9654e4
--- /dev/null
@@ -0,0 +1,92 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkConfigure.h.in,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+#ifndef __bbtkConfigure_h
+#define __bbtkConfigure_h
+
+/* This header is configured by BBTK's build process.  */
+
+/*--------------------------------------------------------------------------*/
+/* Platform Features                                                        */
+
+/* Byte order.  */
+#cmakedefine BBTK_WORDS_BIGENDIAN
+
+/* Allow access to UINT32_MAX , cf bbtkCommon.h */
+#define __STDC_LIMIT_MACROS
+
+
+/* Hardcode the path to BBTK_DATA_ROOT */
+#define BBTK_DATA_ROOT "@BBTK_DATA_ROOT@"
+
+/* Usefull in particular for loadshared where the full path
+ * to the lib is needed */
+#define BBTK_EXECUTABLE_OUTPUT_PATH "@EXECUTABLE_OUTPUT_PATH@"
+#define BBTK_LIBRARY_OUTPUT_PATH    "@LIBRARY_OUTPUT_PATH@"
+#define BBTK_DATA_PATH    "@BBTK_DATA_ROOT@"
+
+/* For older gcc / broken plateform */
+#cmakedefine BBTK_NO_ANSI_STRING_STREAM
+
+/* I guess something important */
+#cmakedefine CMAKE_HAVE_STDINT_H
+#cmakedefine CMAKE_HAVE_INTTYPES_H
+#cmakedefine CMAKE_HAVE_TERMIOS_H
+/* This variable allows you to have helpful debug statement */
+/* That are in between #ifdef / endif in the bbtk code */
+/* That means if BBTK_DEBUG is OFF there shouldn't be any 'cout' at all ! */
+/* only cerr, for instance 'invalid file' will be allowed */
+#cmakedefine BBTK_DEBUG
+
+/* Whether we are building shared libraries.  */
+/* This was important as long as BBTK is LGPL */
+#cmakedefine BUILD_SHARED_LIBS
+
+/* BBTK uses __FUNCTION__ which is not ANSI C, but C99 */
+#cmakedefine BBTK_COMPILER_HAS_FUNCTION
+
+#define BBTK_SIZEOF_LONG @BBTK_SIZEOF_LONG@
+
+/* Special time structure support */
+#cmakedefine CMAKE_HAVE_SYS_TIMES_H
+#cmakedefine CMAKE_HAVE_SYS_TIMEB_H
+
+/* GetMacAddress require a lot of include file to access low level API */
+#cmakedefine CMAKE_HAVE_UNISTD_H
+#cmakedefine CMAKE_HAVE_STDLIB_H
+#cmakedefine CMAKE_HAVE_SYS_IOCTL_H
+#cmakedefine CMAKE_HAVE_SYS_SOCKET_H
+#cmakedefine CMAKE_HAVE_SYS_SOCKIO_H
+#cmakedefine CMAKE_HAVE_NET_IF_H
+#cmakedefine CMAKE_HAVE_NETINET_IN_H
+#cmakedefine CMAKE_HAVE_NET_IF_DL_H
+#cmakedefine CMAKE_HAVE_NET_IF_ARP_H
+#cmakedefine HAVE_SA_LEN
+
+/*--------------------------------------------------------------------------*/
+/* BBTK Versioning                                                          */
+
+/* Version number.  */
+#define BBTK_MAJOR_VERSION @BBTK_MAJOR_VERSION@
+#define BBTK_MINOR_VERSION @BBTK_MINOR_VERSION@
+#define BBTK_BUILD_VERSION @BBTK_BUILD_VERSION@
+#define BBTK_VERSION "@BBTK_VERSION@"
+
+
+#endif
diff --git a/kernel/src/cmake/bbtkTestFUNCTION.cxx b/kernel/src/cmake/bbtkTestFUNCTION.cxx
new file mode 100644 (file)
index 0000000..d0da1a9
--- /dev/null
@@ -0,0 +1,38 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbtkTestFUNCTION.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+// Minimal test for existence of __FUNCTION__ pseudo-macro
+#include <string.h>
+
+int TestFUNCTION()
+{
+#ifdef __BORLANDC__
+  #ifndef __FUNCTION__
+    #define __FUNCTION__ __FUNC__
+  #endif
+#endif
+  const char *f = __FUNCTION__;
+  int r = strcmp( "TestFUNCTION", f);
+  return r;
+}
+int main()
+{
+  return TestFUNCTION();
+}
+
diff --git a/kernel/src/cmake/bbtkTestIstringStream.cxx b/kernel/src/cmake/bbtkTestIstringStream.cxx
new file mode 100644 (file)
index 0000000..a135281
--- /dev/null
@@ -0,0 +1,32 @@
+/*=========================================================================
+                                                                                
+  Program:   gdcm
+  Module:    $RCSfile: bbtkTestIstringStream.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+#include <sstream>
+
+int main()
+{
+  std::istringstream os;
+  int vm;
+  std::string s = "5";
+  os.str(s);
+
+  os >> vm;
+
+  return vm;
+}
+
diff --git a/kernel/src/xmlParser.cpp b/kernel/src/xmlParser.cpp
new file mode 100644 (file)
index 0000000..3685776
--- /dev/null
@@ -0,0 +1,2594 @@
+/**
+ ****************************************************************************
+ * <P> XML.c - implementation file for basic XML parser written in ANSI C++
+ * for portability. It works by using recursion and a node tree for breaking
+ * down the elements of an XML document.  </P>
+ *
+ * @version     V2.23
+ * @author      Frank Vanden Berghen
+ *
+ * NOTE:
+ *
+ *   If you add "#define STRICT_PARSING", on the first line of this file
+ *   the parser will see the following XML-stream:
+ *      <a><b>some text</b><b>other text    </a>
+ *   as an error. Otherwise, this tring will be equivalent to:
+ *      <a><b>some text</b><b>other text</b></a>
+ *
+ * NOTE:
+ *
+ *   If you add "#define APPROXIMATE_PARSING" on the first line of this file
+ *   the parser will see the following XML-stream:
+ *     <data name="n1">
+ *     <data name="n2">
+ *     <data name="n3" />
+ *   as equivalent to the following XML-stream:
+ *     <data name="n1" />
+ *     <data name="n2" />
+ *     <data name="n3" />
+ *   This can be useful for badly-formed XML-streams but prevent the use
+ *   of the following XML-stream (problem is: tags at contiguous levels
+ *   have the same names):
+ *     <data name="n1">
+ *        <data name="n2">
+ *            <data name="n3" />
+ *        </data>
+ *     </data>
+ *
+ * NOTE:
+ *
+ *   If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this file
+ *   the "openFileHelper" function will always display error messages inside the
+ *   console instead of inside a message-box-window. Message-box-windows are
+ *   available on windows 9x/NT/2000/XP/Vista only.
+ *
+ * BSD license:
+ * Copyright (c) 2002, Frank Vanden Berghen
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Frank Vanden Berghen nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************
+ */
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#include "xmlParser.h"
+#ifdef _XMLWINDOWS
+//#ifdef _DEBUG
+//#define _CRTDBG_MAP_ALLOC
+//#include <crtdbg.h>
+//#endif
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h> // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files
+                     // to have "MessageBoxA" to display error messages for openFilHelper
+#endif
+
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+XMLCSTR XMLNode::getVersion() { return _T("v2.23"); }
+void free_XMLDLL(void *t){free(t);}
+
+static char strictUTF8Parsing=1, guessUnicodeChars=1, dropWhiteSpace=1;
+
+inline int mmin( const int t1, const int t2 ) { return t1 < t2 ? t1 : t2; }
+
+// You can modify the initialization of the variable "XMLClearTags" below
+// to change the clearTags that are currently recognized by the library.
+// The number on the second columns is the length of the string inside the
+// first column. The "<!DOCTYPE" declaration must be the second in the list.
+static ALLXMLClearTag XMLClearTags[] =
+{
+    {    _T("<![CDATA["),9,  _T("]]>")      },
+    {    _T("<!DOCTYPE"),9,  _T(">")        },
+    {    _T("<PRE>")    ,5,  _T("</PRE>")   },
+    {    _T("<Script>") ,8,  _T("</Script>")},
+    {    _T("<!--")     ,4,  _T("-->")      },
+    {    NULL           ,0,  NULL           }
+};
+ALLXMLClearTag* XMLNode::getClearTagTable() { return XMLClearTags; }
+
+// You can modify the initialization of the variable "XMLEntities" below
+// to change the character entities that are currently recognized by the library.
+// The number on the second columns is the length of the string inside the
+// first column. Additionally, the syntaxes "&#xA0;" and "&#160;" are recognized.
+typedef struct { XMLCSTR s; int l; XMLCHAR c;} XMLCharacterEntity;
+static XMLCharacterEntity XMLEntities[] =
+{
+    { _T("&amp;" ), 5, _T('&' )},
+    { _T("&lt;"  ), 4, _T('<' )},
+    { _T("&gt;"  ), 4, _T('>' )},
+    { _T("&quot;"), 6, _T('\"')},
+    { _T("&apos;"), 6, _T('\'')},
+    { NULL        , 0, '\0'    }
+};
+
+// When rendering the XMLNode to a string (using the "createXMLString" function),
+// you can ask for a beautiful formatting. This formatting is using the
+// following indentation character:
+#define INDENTCHAR _T('\t')
+
+// The following function parses the XML errors into a user friendly string.
+// You can edit this to change the output language of the library to something else.
+XMLCSTR XMLNode::getError(XMLError xerror)
+{
+    switch (xerror)
+    {
+    case eXMLErrorNone:                  return _T("No error");
+    case eXMLErrorMissingEndTag:         return _T("Warning: Unmatched end tag");
+    case eXMLErrorEmpty:                 return _T("Error: No XML data");
+    case eXMLErrorFirstNotStartTag:      return _T("Error: First token not start tag");
+    case eXMLErrorMissingTagName:        return _T("Error: Missing start tag name");
+    case eXMLErrorMissingEndTagName:     return _T("Error: Missing end tag name");
+    case eXMLErrorNoMatchingQuote:       return _T("Error: Unmatched quote");
+    case eXMLErrorUnmatchedEndTag:       return _T("Error: Unmatched end tag");
+    case eXMLErrorUnmatchedEndClearTag:  return _T("Error: Unmatched clear tag end");
+    case eXMLErrorUnexpectedToken:       return _T("Error: Unexpected token found");
+    case eXMLErrorInvalidTag:            return _T("Error: Invalid tag found");
+    case eXMLErrorNoElements:            return _T("Error: No elements found");
+    case eXMLErrorFileNotFound:          return _T("Error: File not found");
+    case eXMLErrorFirstTagNotFound:      return _T("Error: First Tag not found");
+    case eXMLErrorUnknownCharacterEntity:return _T("Error: Unknown character entity");
+    case eXMLErrorCharConversionError:   return _T("Error: unable to convert between UNICODE and MultiByte chars");
+    case eXMLErrorCannotOpenWriteFile:   return _T("Error: unable to open file for writing");
+    case eXMLErrorCannotWriteFile:       return _T("Error: cannot write into file");
+
+    case eXMLErrorBase64DataSizeIsNotMultipleOf4: return _T("Warning: Base64-string length is not a multiple of 4");
+    case eXMLErrorBase64DecodeTruncatedData:      return _T("Warning: Base64-string is truncated");
+    case eXMLErrorBase64DecodeIllegalCharacter:   return _T("Error: Base64-string contains an illegal character");
+    case eXMLErrorBase64DecodeBufferTooSmall:     return _T("Error: Base64 decode output buffer is too small");
+    };
+    return _T("Unknown");
+}
+
+// Here is an abstraction layer to access some common string manipulation functions.
+// The abstraction layer is currently working for gcc, Microsoft Visual Studio 6.0,
+// Microsoft Visual Studio .NET, CC (sun compiler) and Borland C++.
+// If you plan to "port" the library to a new system/compiler, all you have to do is
+// to edit the following lines.
+#ifdef XML_NO_WIDE_CHAR
+char myIsTextUnicode(const void *b, int len) { return FALSE; }
+#else
+    #if defined (UNDER_CE) || !defined(WIN32)
+    char myIsTextUnicode(const void *b, int len) // inspired by the Wine API: RtlIsTextUnicode
+    {
+#ifdef sun
+        // for SPARC processors: wchar_t* buffers must always be alligned, otherwise it's a char* buffer.
+        if ((((unsigned long)b)%sizeof(wchar_t))!=0) return FALSE;
+#endif
+        const wchar_t *s=(const wchar_t*)b;
+
+        // buffer too small:
+        if (len<(int)sizeof(wchar_t)) return FALSE;
+
+        // odd length test
+        if (len&1) return FALSE;
+
+        /* only checks the first 256 characters */
+        len=mmin(256,len/sizeof(wchar_t));
+
+        // Check for the special byte order:
+        if (*s == 0xFFFE) return FALSE;     // IS_TEXT_UNICODE_REVERSE_SIGNATURE;
+        if (*s == 0xFEFF) return TRUE;      // IS_TEXT_UNICODE_SIGNATURE
+
+        // checks for ASCII characters in the UNICODE stream
+        int i,stats=0;
+        for (i=0; i<len; i++) if (s[i]<=(unsigned short)255) stats++;
+        if (stats>len/2) return TRUE;
+
+        // Check for UNICODE NULL chars
+        for (i=0; i<len; i++) if (!s[i]) return TRUE;
+
+        return FALSE;
+    }
+    #else
+    char myIsTextUnicode(const void *b,int l) { return (char)IsTextUnicode((CONST LPVOID)b,l,NULL); };
+    #endif
+#endif
+
+#ifdef _XMLWINDOWS
+// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET,
+    #ifdef _XMLUNICODE
+        wchar_t *myMultiByteToWideChar(const char *s,int l)
+        {
+            int i;
+            if (strictUTF8Parsing)  i=(int)MultiByteToWideChar(CP_UTF8,0             ,s,l,NULL,0);
+            else                    i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,l,NULL,0);
+            if (i<0) return NULL;
+            wchar_t *d=(wchar_t *)malloc((i+1)*sizeof(XMLCHAR));
+            if (strictUTF8Parsing)  i=(int)MultiByteToWideChar(CP_UTF8,0             ,s,l,d,i);
+            else                    i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,l,d,i);
+            d[i]=0;
+            return d;
+        }
+    #else
+        char *myWideCharToMultiByte(const wchar_t *s,int l)
+        {
+            UINT codePage=CP_ACP; if (strictUTF8Parsing) codePage=CP_UTF8;
+            int i=(int)WideCharToMultiByte(codePage,  // code page
+                0,                       // performance and mapping flags
+                s,                       // wide-character string
+                l,                       // number of chars in string
+                NULL,                       // buffer for new string
+                0,                       // size of buffer
+                NULL,                    // default for unmappable chars
+                NULL                     // set when default char used
+                );
+            if (i<0) return NULL;
+            char *d=(char*)malloc(i+1);
+            WideCharToMultiByte(codePage,  // code page
+                0,                       // performance and mapping flags
+                s,                       // wide-character string
+                l,                       // number of chars in string
+                d,                       // buffer for new string
+                i,                       // size of buffer
+                NULL,                    // default for unmappable chars
+                NULL                     // set when default char used
+                );
+            d[i]=0;
+            return d;
+        }
+    #endif
+    #ifdef __BORLANDC__
+    int _strnicmp(char *c1, char *c2, int l){ return strnicmp(c1,c2,l);}
+    #endif
+#else
+// for gcc and CC
+    #ifdef XML_NO_WIDE_CHAR
+        char *myWideCharToMultiByte(const wchar_t *s, int l) { return NULL; }
+    #else
+        char *myWideCharToMultiByte(const wchar_t *s, int l)
+        {
+            const wchar_t *ss=s;
+            int i=(int)wcsrtombs(NULL,&ss,0,NULL);
+            if (i<0) return NULL;
+            char *d=(char *)malloc(i+1);
+            wcsrtombs(d,&s,i,NULL);
+            d[i]=0;
+            return d;
+        }
+    #endif
+    #ifdef _XMLUNICODE
+        wchar_t *myMultiByteToWideChar(const char *s, int l)
+        {
+            const char *ss=s;
+            int i=(int)mbsrtowcs(NULL,&ss,0,NULL);
+            if (i<0) return NULL;
+            wchar_t *d=(wchar_t *)malloc((i+1)*sizeof(wchar_t));
+            mbsrtowcs(d,&s,l,NULL);
+            d[i]=0;
+            return d;
+        }
+        int _tcslen(XMLCSTR c)   { return wcslen(c); }
+        #ifdef sun
+        // for CC
+           #include <widec.h>
+           int _tcsnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncasecmp(c1,c2,l);}
+           int _tcsicmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1,c2); }
+        #else
+        // for gcc
+           int _tcsnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncasecmp(c1,c2,l);}
+           int _tcsicmp(XMLCSTR c1, XMLCSTR c2) { return wcscasecmp(c1,c2); }
+        #endif
+        XMLSTR _tcsstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)wcsstr(c1,c2); }
+        XMLSTR _tcscpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)wcscpy(c1,c2); }
+        FILE *_tfopen(XMLCSTR filename,XMLCSTR mode)
+        {
+            char *filenameAscii=myWideCharToMultiByte(filename,0);
+            FILE *f;
+            if (mode[0]==_T('r')) f=fopen(filenameAscii,"rb");
+            else                  f=fopen(filenameAscii,"wb");
+            free(filenameAscii);
+            return f;
+        }
+    #else
+        FILE *_tfopen(XMLCSTR filename,XMLCSTR mode) { return fopen(filename,mode); }
+        int _tcslen(XMLCSTR c)   { return strlen(c); }
+        int _tcsnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncasecmp(c1,c2,l);}
+        int _tcsicmp(XMLCSTR c1, XMLCSTR c2) { return strcasecmp(c1,c2); }
+        XMLSTR _tcsstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)strstr(c1,c2); }
+        XMLSTR _tcscpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)strcpy(c1,c2); }
+    #endif
+    int _strnicmp(const char *c1,const char *c2, int l) { return strncasecmp(c1,c2,l);}
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+//      Here start the core implementation of the XMLParser library    //
+/////////////////////////////////////////////////////////////////////////
+
+// You should normally not change anything below this point.
+// For your own information, I suggest that you read the openFileHelper below:
+XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag)
+{
+    // guess the value of the global parameter "strictUTF8Parsing"
+    // (the guess is based on the first 200 bytes of the file).
+    FILE *f=_tfopen(filename,_T("rb"));
+    if (f)
+    {
+        char bb[205];
+        int l=(int)fread(bb,1,200,f);
+        setGlobalOptions(guessUnicodeChars,guessUTF8ParsingParameterValue(bb,l),dropWhiteSpace);
+        fclose(f);
+    }
+
+    // parse the file
+    XMLResults pResults;
+    XMLNode xnode=XMLNode::parseFile(filename,tag,&pResults);
+
+    // display error message (if any)
+    if (pResults.error != eXMLErrorNone)
+    {
+        // create message
+        char message[2000],*s1=(char*)"",*s3=(char*)""; XMLCSTR s2=_T("");
+        if (pResults.error==eXMLErrorFirstTagNotFound) { s1=(char*)"First Tag should be '"; s2=tag; s3=(char*)"'.\n"; }
+        sprintf(message,
+#ifdef _XMLUNICODE
+            "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s"
+#else
+            "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s"
+#endif
+            ,filename,XMLNode::getError(pResults.error),pResults.nLine,pResults.nColumn,s1,s2,s3);
+
+        // display message
+#if defined(WIN32) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_)
+        MessageBoxA(NULL,message,"XML Parsing error",MB_OK|MB_ICONERROR|MB_TOPMOST);
+#else
+        printf("%s",message);
+#endif
+        exit(255);
+    }
+    return xnode;
+}
+
+#ifndef _XMLUNICODE
+// If "strictUTF8Parsing=0" then we assume that all characters have the same length of 1 byte.
+// If "strictUTF8Parsing=1" then the characters have different lengths (from 1 byte to 4 bytes).
+// This table is used as lookup-table to know the length of a character (in byte) based on the
+// content of the first byte of the character.
+// (note: if you modify this, you must always have XML_utf8ByteTable[0]=0 ).
+static const char XML_utf8ByteTable[256] =
+{
+    //  0 1 2 3 4 5 6 7 8 9 a b c d e f
+    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70End of ASCII range
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80 0x80 to 0xc1 invalid
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0
+    1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 0xc2 to 0xdf 2 byte
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0
+    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,// 0xe0 0xe0 to 0xef 3 byte
+    4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+static const char XML_asciiByteTable[256] =
+{
+    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+};
+static const char *XML_ByteTable=(const char *)XML_utf8ByteTable; // the default is "strictUTF8Parsing=1"
+#endif
+
+XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, char nFormat) const
+{
+    int i;
+    XMLSTR t=createXMLString(nFormat,&i);
+    FILE *f=_tfopen(filename,_T("wb"));
+    if (!f) return eXMLErrorCannotOpenWriteFile;
+#ifdef _XMLUNICODE
+    unsigned char h[2]={ 0xFF, 0xFE };
+    if (!fwrite(h,2,1,f)) return eXMLErrorCannotWriteFile;
+    if (!isDeclaration())
+    {
+        if (!fwrite(_T("<?xml version=\"1.0\" encoding=\"utf-16\"?>\n"),sizeof(wchar_t)*40,1,f))
+            return eXMLErrorCannotWriteFile;
+    }
+#else
+    if (!isDeclaration())
+    {
+        if ((!encoding)||(XML_ByteTable==XML_utf8ByteTable))
+        {
+            // header so that windows recognize the file as UTF-8:
+            unsigned char h[3]={0xEF,0xBB,0xBF};
+            if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile;
+            if (!fwrite("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",39,1,f)) return eXMLErrorCannotWriteFile;
+        }
+        else
+            if (fprintf(f,"<?xml version=\"1.0\" encoding=\"%s\"?>\n",encoding)<0) return eXMLErrorCannotWriteFile;
+    } else
+    {
+        if (XML_ByteTable==XML_utf8ByteTable) // test if strictUTF8Parsing==1"
+        {
+            unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile;
+        }
+    }
+#endif
+    if (!fwrite(t,sizeof(XMLCHAR)*i,1,f)) return eXMLErrorCannotWriteFile;
+    if (fclose(f)!=0) return eXMLErrorCannotWriteFile;
+    free(t);
+    return eXMLErrorNone;
+}
+
+// Duplicate a given string.
+XMLSTR stringDup(XMLCSTR lpszData, int cbData)
+{
+    if (lpszData==NULL) return NULL;
+
+    XMLSTR lpszNew;
+    if (cbData==0) cbData=(int)_tcslen(lpszData);
+    lpszNew = (XMLSTR)malloc((cbData+1) * sizeof(XMLCHAR));
+    if (lpszNew)
+    {
+        memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR));
+        lpszNew[cbData] = (XMLCHAR)NULL;
+    }
+    return lpszNew;
+}
+
+XMLNode XMLNode::emptyXMLNode;
+XMLClear XMLNode::emptyXMLClear={ NULL, NULL, NULL};
+XMLAttribute XMLNode::emptyXMLAttribute={ NULL, NULL};
+
+// Enumeration used to decipher what type a token is
+typedef enum XMLTokenTypeTag
+{
+    eTokenText = 0,
+    eTokenQuotedText,
+    eTokenTagStart,         /* "<"            */
+    eTokenTagEnd,           /* "</"           */
+    eTokenCloseTag,         /* ">"            */
+    eTokenEquals,           /* "="            */
+    eTokenDeclaration,      /* "<?"           */
+    eTokenShortHandClose,   /* "/>"           */
+    eTokenClear,
+    eTokenError
+} XMLTokenType;
+
+// Main structure used for parsing XML
+typedef struct XML
+{
+    XMLCSTR                lpXML;
+    XMLCSTR                lpszText;
+    int                    nIndex,nIndexMissigEndTag;
+    enum XMLError          error;
+    XMLCSTR                lpEndTag;
+    int                    cbEndTag;
+    XMLCSTR                lpNewElement;
+    int                    cbNewElement;
+    int                    nFirst;
+} XML;
+
+typedef struct
+{
+    ALLXMLClearTag *pClr;
+    XMLCSTR     pStr;
+} NextToken;
+
+// Enumeration used when parsing attributes
+typedef enum Attrib
+{
+    eAttribName = 0,
+    eAttribEquals,
+    eAttribValue
+} Attrib;
+
+// Enumeration used when parsing elements to dictate whether we are currently
+// inside a tag
+typedef enum Status
+{
+    eInsideTag = 0,
+    eOutsideTag
+} Status;
+
+// private (used while rendering):
+XMLSTR toXMLString(XMLSTR dest,XMLCSTR source)
+{
+    XMLSTR dd=dest;
+    XMLCHAR ch;
+    XMLCharacterEntity *entity;
+    while ((ch=*source))
+    {
+        entity=XMLEntities;
+        do
+        {
+            if (ch==entity->c) {_tcscpy(dest,entity->s); dest+=entity->l; source++; goto out_of_loop1; }
+            entity++;
+        } while(entity->s);
+#ifdef _XMLUNICODE
+        *(dest++)=*(source++);
+#else
+        switch(XML_ByteTable[(unsigned char)ch])
+        {
+        case 4: *(dest++)=*(source++);
+        case 3: *(dest++)=*(source++);
+        case 2: *(dest++)=*(source++);
+        case 1: *(dest++)=*(source++);
+        }
+#endif
+out_of_loop1:
+        ;
+    }
+    *dest=0;
+    return dd;
+}
+
+// private (used while rendering):
+int lengthXMLString(XMLCSTR source)
+{
+    int r=0;
+    XMLCharacterEntity *entity;
+    XMLCHAR ch;
+    while ((ch=*source))
+    {
+        entity=XMLEntities;
+        do
+        {
+            if (ch==entity->c) { r+=entity->l; source++; goto out_of_loop1; }
+            entity++;
+        } while(entity->s);
+#ifdef _XMLUNICODE
+        r++; source++;
+#else
+        ch=XML_ByteTable[(unsigned char)ch]; r+=ch; source+=ch;
+#endif
+out_of_loop1:
+        ;
+    }
+    return r;
+}
+
+XMLSTR toXMLString(XMLCSTR source)
+{
+    XMLSTR dest=(XMLSTR)malloc((lengthXMLString(source)+1)*sizeof(XMLCHAR));
+    return toXMLString(dest,source);
+}
+
+XMLSTR toXMLStringFast(XMLSTR *dest,int *destSz, XMLCSTR source)
+{
+    int l=lengthXMLString(source)+1;
+    if (l>*destSz) { *destSz=l; *dest=(XMLSTR)realloc(*dest,l*sizeof(XMLCHAR)); }
+    return toXMLString(*dest,source);
+}
+
+// private:
+XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML)
+{
+    // This function is the opposite of the function "toXMLString". It decodes the escape
+    // sequences &amp;, &quot;, &apos;, &lt;, &gt; and replace them by the characters
+    // &,",',<,>. This function is used internally by the XML Parser. All the calls to
+    // the XML library will always gives you back "decoded" strings.
+    //
+    // in: string (s) and length (lo) of string
+    // out:  new allocated string converted from xml
+    if (!s) return NULL;
+
+    int ll=0,j;
+    XMLSTR d;
+    XMLCSTR ss=s;
+    XMLCharacterEntity *entity;
+    while ((lo>0)&&(*s))
+    {
+        if (*s==_T('&'))
+        {
+            if ((lo>2)&&(s[1]==_T('#')))
+            {
+                s+=2; lo-=2;
+                if ((*s==_T('X'))||(*s==_T('x'))) { s++; lo--; }
+                while ((*s)&&(*s!=_T(';'))&&((lo--)>0)) s++;
+                if (*s!=_T(';'))
+                {
+                    pXML->error=eXMLErrorUnknownCharacterEntity;
+                    return NULL;
+                }
+                s++; lo--;
+            } else
+            {
+                entity=XMLEntities;
+                do
+                {
+                    if ((lo>=entity->l)&&(_tcsnicmp(s,entity->s,entity->l)==0)) { s+=entity->l; lo-=entity->l; break; }
+                    entity++;
+                } while(entity->s);
+                if (!entity->s)
+                {
+                    pXML->error=eXMLErrorUnknownCharacterEntity;
+                    return NULL;
+                }
+            }
+        } else
+        {
+#ifdef _XMLUNICODE
+            s++; lo--;
+#else
+            j=XML_ByteTable[(unsigned char)*s]; s+=j; lo-=j; ll+=j-1;
+#endif
+        }
+        ll++;
+    }
+
+    d=(XMLSTR)malloc((ll+1)*sizeof(XMLCHAR));
+    s=d;
+    while (ll-->0)
+    {
+        if (*ss==_T('&'))
+        {
+            if (ss[1]==_T('#'))
+            {
+                ss+=2; j=0;
+                if ((*ss==_T('X'))||(*ss==_T('x')))
+                {
+                    ss++;
+                    while (*ss!=_T(';'))
+                    {
+                        if ((*ss>=_T('0'))&&(*ss<=_T('9'))) j=(j<<4)+*ss-_T('0');
+                        else if ((*ss>=_T('A'))&&(*ss<=_T('F'))) j=(j<<4)+*ss-_T('A')+10;
+                        else if ((*ss>=_T('a'))&&(*ss<=_T('f'))) j=(j<<4)+*ss-_T('a')+10;
+                        else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;}
+                        ss++;
+                    }
+                } else
+                {
+                    while (*ss!=_T(';'))
+                    {
+                        if ((*ss>=_T('0'))&&(*ss<=_T('9'))) j=(j*10)+*ss-_T('0');
+                        else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;}
+                        ss++;
+                    }
+                }
+                (*d++)=(XMLCHAR)j; ss++;
+            } else
+            {
+                entity=XMLEntities;
+                do
+                {
+                    if (_tcsnicmp(ss,entity->s,entity->l)==0) { *(d++)=entity->c; ss+=entity->l; break; }
+                    entity++;
+                } while(entity->s);
+            }
+        } else
+        {
+#ifdef _XMLUNICODE
+            *(d++)=*(ss++);
+#else
+            switch(XML_ByteTable[(unsigned char)*ss])
+            {
+            case 4: *(d++)=*(ss++); ll--;
+            case 3: *(d++)=*(ss++); ll--;
+            case 2: *(d++)=*(ss++); ll--;
+            case 1: *(d++)=*(ss++);
+            }
+#endif
+        }
+    }
+    *d=0;
+    return (XMLSTR)s;
+}
+
+#define XML_isSPACECHAR(ch) ((ch==_T('\n'))||(ch==_T(' '))||(ch== _T('\t'))||(ch==_T('\r')))
+
+// private:
+char myTagCompare(XMLCSTR cclose, XMLCSTR copen)
+// !!!! WARNING strange convention&:
+// return 0 if equals
+// return 1 if different
+{
+    if (!cclose) return 1;
+    int l=(int)_tcslen(cclose);
+    if (_tcsnicmp(cclose, copen, l)!=0) return 1;
+    const XMLCHAR c=copen[l];
+    if (XML_isSPACECHAR(c)||
+        (c==_T('/' ))||
+        (c==_T('<' ))||
+        (c==_T('>' ))||
+        (c==_T('=' ))) return 0;
+    return 1;
+}
+
+// Obtain the next character from the string.
+static inline XMLCHAR getNextChar(XML *pXML)
+{
+    XMLCHAR ch = pXML->lpXML[pXML->nIndex];
+#ifdef _XMLUNICODE
+    if (ch!=0) pXML->nIndex++;
+#else
+    pXML->nIndex+=XML_ByteTable[(unsigned char)ch];
+#endif
+    return ch;
+}
+
+// Find the next token in a string.
+// pcbToken contains the number of characters that have been read.
+static NextToken GetNextToken(XML *pXML, int *pcbToken, enum XMLTokenTypeTag *pType)
+{
+    NextToken        result;
+    XMLCHAR            ch;
+    XMLCHAR            chTemp;
+    int              indexStart,nFoundMatch,nIsText=FALSE;
+    result.pClr=NULL; // prevent warning
+
+    // Find next non-white space character
+    do { indexStart=pXML->nIndex; ch=getNextChar(pXML); } while XML_isSPACECHAR(ch);
+
+    if (ch)
+    {
+        // Cache the current string pointer
+        result.pStr = &pXML->lpXML[indexStart];
+
+        // First check whether the token is in the clear tag list (meaning it
+        // does not need formatting).
+        ALLXMLClearTag *ctag=XMLClearTags;
+        do
+        {
+            if (_tcsnicmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)==0)
+            {
+                result.pClr=ctag;
+                pXML->nIndex+=ctag->openTagLen-1;
+                *pType=eTokenClear;
+                return result;
+            }
+            ctag++;
+        } while(ctag->lpszOpen);
+
+        // If we didn't find a clear tag then check for standard tokens
+        switch(ch)
+        {
+        // Check for quotes
+        case _T('\''):
+        case _T('\"'):
+            // Type of token
+            *pType = eTokenQuotedText;
+            chTemp = ch;
+
+            // Set the size
+            nFoundMatch = FALSE;
+
+            // Search through the string to find a matching quote
+            while((ch = getNextChar(pXML)))
+            {
+                if (ch==chTemp) { nFoundMatch = TRUE; break; }
+                if (ch==_T('<')) break;
+            }
+
+            // If we failed to find a matching quote
+            if (nFoundMatch == FALSE)
+            {
+                pXML->nIndex=indexStart+1;
+                nIsText=TRUE;
+                break;
+            }
+
+//  4.02.2002
+//            if (FindNonWhiteSpace(pXML)) pXML->nIndex--;
+
+            break;
+
+        // Equals (used with attribute values)
+        case _T('='):
+            *pType = eTokenEquals;
+            break;
+
+        // Close tag
+        case _T('>'):
+            *pType = eTokenCloseTag;
+            break;
+
+        // Check for tag start and tag end
+        case _T('<'):
+
+            // Peek at the next character to see if we have an end tag '</',
+            // or an xml declaration '<?'
+            chTemp = pXML->lpXML[pXML->nIndex];
+
+            // If we have a tag end...
+            if (chTemp == _T('/'))
+            {
+                // Set the type and ensure we point at the next character
+                getNextChar(pXML);
+                *pType = eTokenTagEnd;
+            }
+
+            // If we have an XML declaration tag
+            else if (chTemp == _T('?'))
+            {
+
+                // Set the type and ensure we point at the next character
+                getNextChar(pXML);
+                *pType = eTokenDeclaration;
+            }
+
+            // Otherwise we must have a start tag
+            else
+            {
+                *pType = eTokenTagStart;
+            }
+            break;
+
+        // Check to see if we have a short hand type end tag ('/>').
+        case _T('/'):
+
+            // Peek at the next character to see if we have a short end tag '/>'
+            chTemp = pXML->lpXML[pXML->nIndex];
+
+            // If we have a short hand end tag...
+            if (chTemp == _T('>'))
+            {
+                // Set the type and ensure we point at the next character
+                getNextChar(pXML);
+                *pType = eTokenShortHandClose;
+                break;
+            }
+
+            // If we haven't found a short hand closing tag then drop into the
+            // text process
+
+        // Other characters
+        default:
+            nIsText = TRUE;
+        }
+
+        // If this is a TEXT node
+        if (nIsText)
+        {
+            // Indicate we are dealing with text
+            *pType = eTokenText;
+            while((ch = getNextChar(pXML)))
+            {
+                if XML_isSPACECHAR(ch)
+                {
+                    indexStart++; break;
+
+                } else if (ch==_T('/'))
+                {
+                    // If we find a slash then this maybe text or a short hand end tag
+                    // Peek at the next character to see it we have short hand end tag
+                    ch=pXML->lpXML[pXML->nIndex];
+                    // If we found a short hand end tag then we need to exit the loop
+                    if (ch==_T('>')) { pXML->nIndex--; break; }
+
+                } else if ((ch==_T('<'))||(ch==_T('>'))||(ch==_T('=')))
+                {
+                    pXML->nIndex--; break;
+                }
+            }
+        }
+        *pcbToken = pXML->nIndex-indexStart;
+    } else
+    {
+        // If we failed to obtain a valid character
+        *pcbToken = 0;
+        *pType = eTokenError;
+        result.pStr=NULL;
+    }
+
+    return result;
+}
+
+XMLCSTR XMLNode::updateName_WOSD(XMLCSTR lpszName)
+{
+    if (d->lpszName&&(lpszName!=d->lpszName)) free((void*)d->lpszName);
+    d->lpszName=lpszName;
+    return lpszName;
+}
+
+// private:
+XMLNode::XMLNode(struct XMLNodeDataTag *p){ d=p; (p->ref_count)++; }
+XMLNode::XMLNode(XMLNodeData *pParent, XMLCSTR lpszName, char isDeclaration)
+{
+    d=(XMLNodeData*)malloc(sizeof(XMLNodeData));
+    d->ref_count=1;
+
+    d->lpszName=NULL;
+    d->nChild= 0;
+    d->nText = 0;
+    d->nClear = 0;
+    d->nAttribute = 0;
+
+    d->isDeclaration = isDeclaration;
+
+    d->pParent = pParent;
+    d->pChild= NULL;
+    d->pText= NULL;
+    d->pClear= NULL;
+    d->pAttribute= NULL;
+    d->pOrder= NULL;
+
+    updateName_WOSD(lpszName);
+}
+
+XMLNode XMLNode::createXMLTopNode_WOSD(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,lpszName,isDeclaration); }
+XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,stringDup(lpszName),isDeclaration); }
+
+#define MEMORYINCREASE 50
+
+static inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem)
+{
+    if (p==NULL) { if (memInc) return malloc(memInc*sizeofElem); return malloc(sizeofElem); }
+    if ((memInc==0)||((newsize%memInc)==0)) p=realloc(p,(newsize+memInc)*sizeofElem);
+//    if (!p)
+//    {
+//        printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220);
+//    }
+    return p;
+}
+
+// private:
+int XMLNode::findPosition(XMLNodeData *d, int index, XMLElementType xtype)
+{
+    if (index<0) return -1;
+    int i=0,j=(int)((index<<2)+xtype),*o=d->pOrder; while (o[i]!=j) i++; return i;
+}
+
+// private:
+// update "order" information when deleting a content of a XMLNode
+int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index)
+{
+    int n=d->nChild+d->nText+d->nClear, *o=d->pOrder,i=findPosition(d,index,t);
+    memmove(o+i, o+i+1, (n-i)*sizeof(int));
+    for (;i<n;i++)
+        if ((o[i]&3)==(int)t) o[i]-=4;
+    // We should normally do:
+    // d->pOrder=(int)realloc(d->pOrder,n*sizeof(int));
+    // but we skip reallocation because it's too time consuming.
+    // Anyway, at the end, it will be free'd completely at once.
+    return i;
+}
+
+void *XMLNode::addToOrder(int memoryIncrease,int *_pos, int nc, void *p, int size, XMLElementType xtype)
+{
+    //  in: *_pos is the position inside d->pOrder ("-1" means "EndOf")
+    // out: *_pos is the index inside p
+    p=myRealloc(p,(nc+1),memoryIncrease,size);
+    int n=d->nChild+d->nText+d->nClear;
+    d->pOrder=(int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,sizeof(int));
+    int pos=*_pos,*o=d->pOrder;
+
+    if ((pos<0)||(pos>=n)) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; }
+
+    int i=pos;
+    memmove(o+i+1, o+i, (n-i)*sizeof(int));
+
+    while ((pos<n)&&((o[pos]&3)!=(int)xtype)) pos++;
+    if (pos==n) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; }
+
+    o[i]=o[pos];
+    for (i=pos+1;i<=n;i++) if ((o[i]&3)==(int)xtype) o[i]+=4;
+
+    *_pos=pos=o[pos]>>2;
+    memmove(((char*)p)+(pos+1)*size,((char*)p)+pos*size,(nc-pos)*size);
+
+    return p;
+}
+
+// Add a child node to the given element.
+XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLCSTR lpszName, char isDeclaration, int pos)
+{
+    if (!lpszName) return emptyXMLNode;
+    d->pChild=(XMLNode*)addToOrder(memoryIncrease,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild);
+    d->pChild[pos].d=NULL;
+    d->pChild[pos]=XMLNode(d,lpszName,isDeclaration);
+    d->nChild++;
+    return d->pChild[pos];
+}
+
+// Add an attribute to an element.
+XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease,XMLCSTR lpszName, XMLCSTR lpszValuev)
+{
+    if (!lpszName) return &emptyXMLAttribute;
+    int nc=d->nAttribute;
+    d->pAttribute=(XMLAttribute*)myRealloc(d->pAttribute,(nc+1),memoryIncrease,sizeof(XMLAttribute));
+    XMLAttribute *pAttr=d->pAttribute+nc;
+    pAttr->lpszName = lpszName;
+    pAttr->lpszValue = lpszValuev;
+    d->nAttribute++;
+    return pAttr;
+}
+
+// Add text to the element.
+XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLCSTR lpszValue, int pos)
+{
+    if (!lpszValue) return NULL;
+    d->pText=(XMLCSTR*)addToOrder(memoryIncrease,&pos,d->nText,d->pText,sizeof(XMLSTR),eNodeText);
+    d->pText[pos]=lpszValue;
+    d->nText++;
+    return lpszValue;
+}
+
+// Add clear (unformatted) text to the element.
+XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos)
+{
+    if (!lpszValue) return &emptyXMLClear;
+    d->pClear=(XMLClear *)addToOrder(memoryIncrease,&pos,d->nClear,d->pClear,sizeof(XMLClear),eNodeClear);
+    XMLClear *pNewClear=d->pClear+pos;
+    pNewClear->lpszValue = lpszValue;
+    if (!lpszOpen) lpszOpen=getClearTagTable()->lpszOpen;
+    if (!lpszClose) lpszOpen=getClearTagTable()->lpszClose;
+    pNewClear->lpszOpenTag = lpszOpen;
+    pNewClear->lpszCloseTag = lpszClose;
+    d->nClear++;
+    return pNewClear;
+}
+
+// private:
+// Parse a clear (unformatted) type node.
+char XMLNode::parseClearTag(void *px, ALLXMLClearTag *pClear)
+{
+    XML *pXML=(XML *)px;
+    int cbTemp=0;
+    XMLCSTR lpszTemp=NULL;
+    XMLCSTR lpXML=&pXML->lpXML[pXML->nIndex];
+    static XMLCSTR docTypeEnd=_T("]>");
+
+    // Find the closing tag
+    // Seems the <!DOCTYPE need a better treatment so lets handle it
+    if (pClear->lpszOpen==XMLClearTags[1].lpszOpen)
+    {
+        XMLCSTR pCh=lpXML;
+        while (*pCh)
+        {
+            if (*pCh==_T('<')) { pClear->lpszClose=docTypeEnd; lpszTemp=_tcsstr(lpXML,docTypeEnd); break; }
+            else if (*pCh==_T('>')) { lpszTemp=pCh; break; }
+#ifdef _XMLUNICODE
+            pCh++;
+#else
+            pCh+=XML_ByteTable[(unsigned char)(*pCh)];
+#endif
+        }
+    } else lpszTemp=_tcsstr(lpXML, pClear->lpszClose);
+
+    if (lpszTemp)
+    {
+        // Cache the size and increment the index
+        cbTemp = (int)(lpszTemp - lpXML);
+
+        pXML->nIndex += cbTemp+(int)_tcslen(pClear->lpszClose);
+
+        // Add the clear node to the current element
+        addClear_priv(MEMORYINCREASE,stringDup(lpXML,cbTemp), pClear->lpszOpen, pClear->lpszClose,-1);
+        return 0;
+    }
+
+    // If we failed to find the end tag
+    pXML->error = eXMLErrorUnmatchedEndClearTag;
+    return 1;
+}
+
+void XMLNode::exactMemory(XMLNodeData *d)
+{
+    if (d->pOrder)     d->pOrder=(int*)realloc(d->pOrder,(d->nChild+d->nText+d->nClear)*sizeof(int));
+    if (d->pChild)     d->pChild=(XMLNode*)realloc(d->pChild,d->nChild*sizeof(XMLNode));
+    if (d->pAttribute) d->pAttribute=(XMLAttribute*)realloc(d->pAttribute,d->nAttribute*sizeof(XMLAttribute));
+    if (d->pText)      d->pText=(XMLCSTR*)realloc(d->pText,d->nText*sizeof(XMLSTR));
+    if (d->pClear)     d->pClear=(XMLClear *)realloc(d->pClear,d->nClear*sizeof(XMLClear));
+}
+
+char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr)
+{
+    XML *pXML=(XML *)pa;
+    XMLCSTR lpszText=pXML->lpszText;
+    if (!lpszText) return 0;
+    if (dropWhiteSpace) while (XML_isSPACECHAR(*lpszText)&&(lpszText!=tokenPStr)) lpszText++;
+    int cbText = (int)(tokenPStr - lpszText);
+    if (!cbText) { pXML->lpszText=NULL; return 0; }
+    if (dropWhiteSpace) { cbText--; while ((cbText)&&XML_isSPACECHAR(lpszText[cbText])) cbText--; cbText++; }
+    if (!cbText) { pXML->lpszText=NULL; return 0; }
+    lpszText=fromXMLString(lpszText,cbText,pXML);
+    if (!lpszText) return 1;
+    addText_priv(MEMORYINCREASE,lpszText,-1);
+    pXML->lpszText=NULL;
+    return 0;
+}
+// private:
+// Recursively parse an XML element.
+int XMLNode::ParseXMLElement(void *pa)
+{
+    XML *pXML=(XML *)pa;
+    int cbToken;
+    enum XMLTokenTypeTag type;
+    NextToken token;
+    XMLCSTR lpszTemp=NULL;
+    int cbTemp=0;
+    char nDeclaration;
+    XMLNode pNew;
+    enum Status status; // inside or outside a tag
+    enum Attrib attrib = eAttribName;
+
+    assert(pXML);
+
+    // If this is the first call to the function
+    if (pXML->nFirst)
+    {
+        // Assume we are outside of a tag definition
+        pXML->nFirst = FALSE;
+        status = eOutsideTag;
+    } else
+    {
+        // If this is not the first call then we should only be called when inside a tag.
+        status = eInsideTag;
+    }
+
+    // Iterate through the tokens in the document
+    for(;;)
+    {
+        // Obtain the next token
+        token = GetNextToken(pXML, &cbToken, &type);
+
+        if (type != eTokenError)
+        {
+            // Check the current status
+            switch(status)
+            {
+
+            // If we are outside of a tag definition
+            case eOutsideTag:
+
+                // Check what type of token we obtained
+                switch(type)
+                {
+                // If we have found text or quoted text
+                case eTokenText:
+                case eTokenCloseTag:          /* '>'         */
+                case eTokenShortHandClose:    /* '/>'        */
+                case eTokenQuotedText:
+                case eTokenEquals:
+                    break;
+
+                // If we found a start tag '<' and declarations '<?'
+                case eTokenTagStart:
+                case eTokenDeclaration:
+
+                    // Cache whether this new element is a declaration or not
+                    nDeclaration = (type == eTokenDeclaration);
+
+                    // If we have node text then add this to the element
+                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
+
+                    // Find the name of the tag
+                    token = GetNextToken(pXML, &cbToken, &type);
+
+                    // Return an error if we couldn't obtain the next token or
+                    // it wasnt text
+                    if (type != eTokenText)
+                    {
+                        pXML->error = eXMLErrorMissingTagName;
+                        return FALSE;
+                    }
+
+                    // If we found a new element which is the same as this
+                    // element then we need to pass this back to the caller..
+
+#ifdef APPROXIMATE_PARSING
+                    if (d->lpszName &&
+                        myTagCompare(d->lpszName, token.pStr) == 0)
+                    {
+                        // Indicate to the caller that it needs to create a
+                        // new element.
+                        pXML->lpNewElement = token.pStr;
+                        pXML->cbNewElement = cbToken;
+                        return TRUE;
+                    } else
+#endif
+                    {
+                        // If the name of the new element differs from the name of
+                        // the current element we need to add the new element to
+                        // the current one and recurse
+                        pNew = addChild_priv(MEMORYINCREASE,stringDup(token.pStr,cbToken), nDeclaration,-1);
+
+                        while (!pNew.isEmpty())
+                        {
+                            // Callself to process the new node.  If we return
+                            // FALSE this means we dont have any more
+                            // processing to do...
+
+                            if (!pNew.ParseXMLElement(pXML)) return FALSE;
+                            else
+                            {
+                                // If the call to recurse this function
+                                // evented in a end tag specified in XML then
+                                // we need to unwind the calls to this
+                                // function until we find the appropriate node
+                                // (the element name and end tag name must
+                                // match)
+                                if (pXML->cbEndTag)
+                                {
+                                    // If we are back at the root node then we
+                                    // have an unmatched end tag
+                                    if (!d->lpszName)
+                                    {
+                                        pXML->error=eXMLErrorUnmatchedEndTag;
+                                        return FALSE;
+                                    }
+
+                                    // If the end tag matches the name of this
+                                    // element then we only need to unwind
+                                    // once more...
+
+                                    if (myTagCompare(d->lpszName, pXML->lpEndTag)==0)
+                                    {
+                                        pXML->cbEndTag = 0;
+                                    }
+
+                                    return TRUE;
+                                } else
+                                    if (pXML->cbNewElement)
+                                    {
+                                        // If the call indicated a new element is to
+                                        // be created on THIS element.
+
+                                        // If the name of this element matches the
+                                        // name of the element we need to create
+                                        // then we need to return to the caller
+                                        // and let it process the element.
+
+                                        if (myTagCompare(d->lpszName, pXML->lpNewElement)==0)
+                                        {
+                                            return TRUE;
+                                        }
+
+                                        // Add the new element and recurse
+                                        pNew = addChild_priv(MEMORYINCREASE,stringDup(pXML->lpNewElement,pXML->cbNewElement),0,-1);
+                                        pXML->cbNewElement = 0;
+                                    }
+                                    else
+                                    {
+                                        // If we didn't have a new element to create
+                                        pNew = emptyXMLNode;
+
+                                    }
+                            }
+                        }
+                    }
+                    break;
+
+                // If we found an end tag
+                case eTokenTagEnd:
+
+                    // If we have node text then add this to the element
+                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
+
+                    // Find the name of the end tag
+                    token = GetNextToken(pXML, &cbTemp, &type);
+
+                    // The end tag should be text
+                    if (type != eTokenText)
+                    {
+                        pXML->error = eXMLErrorMissingEndTagName;
+                        return FALSE;
+                    }
+                    lpszTemp = token.pStr;
+
+                    // After the end tag we should find a closing tag
+                    token = GetNextToken(pXML, &cbToken, &type);
+                    if (type != eTokenCloseTag)
+                    {
+                        pXML->error = eXMLErrorMissingEndTagName;
+                        return FALSE;
+                    }
+                    pXML->lpszText=pXML->lpXML+pXML->nIndex;
+
+                    // We need to return to the previous caller.  If the name
+                    // of the tag cannot be found we need to keep returning to
+                    // caller until we find a match
+                    if (myTagCompare(d->lpszName, lpszTemp) != 0)
+#ifdef STRICT_PARSING
+                    {
+                        pXML->error=eXMLErrorUnmatchedEndTag;
+                        pXML->nIndexMissigEndTag=pXML->nIndex;
+                        return FALSE;
+                    }
+#else
+                    {
+                        pXML->error=eXMLErrorMissingEndTag;
+                        pXML->nIndexMissigEndTag=pXML->nIndex;
+                        pXML->lpEndTag = lpszTemp;
+                        pXML->cbEndTag = cbTemp;
+                    }
+#endif
+
+                    // Return to the caller
+                    exactMemory(d);
+                    return TRUE;
+
+                // If we found a clear (unformatted) token
+                case eTokenClear:
+                    // If we have node text then add this to the element
+                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
+                    if (parseClearTag(pXML, token.pClr)) return FALSE;
+                    pXML->lpszText=pXML->lpXML+pXML->nIndex;
+                    break;
+
+                default:
+                    break;
+                }
+                break;
+
+            // If we are inside a tag definition we need to search for attributes
+            case eInsideTag:
+
+                // Check what part of the attribute (name, equals, value) we
+                // are looking for.
+                switch(attrib)
+                {
+                // If we are looking for a new attribute
+                case eAttribName:
+
+                    // Check what the current token type is
+                    switch(type)
+                    {
+                    // If the current type is text...
+                    // Eg.  'attribute'
+                    case eTokenText:
+                        // Cache the token then indicate that we are next to
+                        // look for the equals
+                        lpszTemp = token.pStr;
+                        cbTemp = cbToken;
+                        attrib = eAttribEquals;
+                        break;
+
+                    // If we found a closing tag...
+                    // Eg.  '>'
+                    case eTokenCloseTag:
+                        // We are now outside the tag
+                        status = eOutsideTag;
+                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
+                        break;
+
+                    // If we found a short hand '/>' closing tag then we can
+                    // return to the caller
+                    case eTokenShortHandClose:
+                        exactMemory(d);
+                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
+                        return TRUE;
+
+                    // Errors...
+                    case eTokenQuotedText:    /* '"SomeText"'   */
+                    case eTokenTagStart:      /* '<'            */
+                    case eTokenTagEnd:        /* '</'           */
+                    case eTokenEquals:        /* '='            */
+                    case eTokenDeclaration:   /* '<?'           */
+                    case eTokenClear:
+                        pXML->error = eXMLErrorUnexpectedToken;
+                        return FALSE;
+                    default: break;
+                    }
+                    break;
+
+                // If we are looking for an equals
+                case eAttribEquals:
+                    // Check what the current token type is
+                    switch(type)
+                    {
+                    // If the current type is text...
+                    // Eg.  'Attribute AnotherAttribute'
+                    case eTokenText:
+                        // Add the unvalued attribute to the list
+                        addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
+                        // Cache the token then indicate.  We are next to
+                        // look for the equals attribute
+                        lpszTemp = token.pStr;
+                        cbTemp = cbToken;
+                        break;
+
+                    // If we found a closing tag 'Attribute >' or a short hand
+                    // closing tag 'Attribute />'
+                    case eTokenShortHandClose:
+                    case eTokenCloseTag:
+                        // If we are a declaration element '<?' then we need
+                        // to remove extra closing '?' if it exists
+                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
+
+                        if (d->isDeclaration &&
+                            (lpszTemp[cbTemp-1]) == _T('?'))
+                        {
+                            cbTemp--;
+                        }
+
+                        if (cbTemp)
+                        {
+                            // Add the unvalued attribute to the list
+                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
+                        }
+
+                        // If this is the end of the tag then return to the caller
+                        if (type == eTokenShortHandClose)
+                        {
+                            exactMemory(d);
+                            return TRUE;
+                        }
+
+                        // We are now outside the tag
+                        status = eOutsideTag;
+                        break;
+
+                    // If we found the equals token...
+                    // Eg.  'Attribute ='
+                    case eTokenEquals:
+                        // Indicate that we next need to search for the value
+                        // for the attribute
+                        attrib = eAttribValue;
+                        break;
+
+                    // Errors...
+                    case eTokenQuotedText:    /* 'Attribute "InvalidAttr"'*/
+                    case eTokenTagStart:      /* 'Attribute <'            */
+                    case eTokenTagEnd:        /* 'Attribute </'           */
+                    case eTokenDeclaration:   /* 'Attribute <?'           */
+                    case eTokenClear:
+                        pXML->error = eXMLErrorUnexpectedToken;
+                        return FALSE;
+                    default: break;
+                    }
+                    break;
+
+                // If we are looking for an attribute value
+                case eAttribValue:
+                    // Check what the current token type is
+                    switch(type)
+                    {
+                    // If the current type is text or quoted text...
+                    // Eg.  'Attribute = "Value"' or 'Attribute = Value' or
+                    // 'Attribute = 'Value''.
+                    case eTokenText:
+                    case eTokenQuotedText:
+                        // If we are a declaration element '<?' then we need
+                        // to remove extra closing '?' if it exists
+                        if (d->isDeclaration &&
+                            (token.pStr[cbToken-1]) == _T('?'))
+                        {
+                            cbToken--;
+                        }
+
+                        if (cbTemp)
+                        {
+                            // Add the valued attribute to the list
+                            if (type==eTokenQuotedText) { token.pStr++; cbToken-=2; }
+                            XMLCSTR attrVal=token.pStr;
+                            if (attrVal)
+                            {
+                                attrVal=fromXMLString(attrVal,cbToken,pXML);
+                                if (!attrVal) return FALSE;
+                            }
+                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp),attrVal);
+                        }
+
+                        // Indicate we are searching for a new attribute
+                        attrib = eAttribName;
+                        break;
+
+                    // Errors...
+                    case eTokenTagStart:        /* 'Attr = <'          */
+                    case eTokenTagEnd:          /* 'Attr = </'         */
+                    case eTokenCloseTag:        /* 'Attr = >'          */
+                    case eTokenShortHandClose:  /* "Attr = />"         */
+                    case eTokenEquals:          /* 'Attr = ='          */
+                    case eTokenDeclaration:     /* 'Attr = <?'         */
+                    case eTokenClear:
+                        pXML->error = eXMLErrorUnexpectedToken;
+                        return FALSE;
+                        break;
+                    default: break;
+                    }
+                }
+            }
+        }
+        // If we failed to obtain the next token
+        else
+        {
+            if ((!d->isDeclaration)&&(d->pParent))
+            {
+#ifdef STRICT_PARSING
+                pXML->error=eXMLErrorUnmatchedEndTag;
+#else
+                pXML->error=eXMLErrorMissingEndTag;
+#endif
+                pXML->nIndexMissigEndTag=pXML->nIndex;
+            }
+            return FALSE;
+        }
+    }
+}
+
+// Count the number of lines and columns in an XML string.
+static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, XMLResults *pResults)
+{
+    XMLCHAR ch;
+    assert(lpXML);
+    assert(pResults);
+
+    struct XML xml={ lpXML,lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
+
+    pResults->nLine = 1;
+    pResults->nColumn = 1;
+    while (xml.nIndex<nUpto)
+    {
+        ch = getNextChar(&xml);
+        if (ch != _T('\n')) pResults->nColumn++;
+        else
+        {
+            pResults->nLine++;
+            pResults->nColumn=1;
+        }
+    }
+}
+
+// Parse XML and return the root element.
+XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults)
+{
+    if (!lpszXML)
+    {
+        if (pResults)
+        {
+            pResults->error=eXMLErrorNoElements;
+            pResults->nLine=0;
+            pResults->nColumn=0;
+        }
+        return emptyXMLNode;
+    }
+
+    XMLNode xnode(NULL,NULL,FALSE);
+    struct XML xml={ lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
+
+    // Create header element
+    xnode.ParseXMLElement(&xml);
+    enum XMLError error = xml.error;
+    if ((xnode.nChildNode()==1)&&(xnode.nElement()==1)) xnode=xnode.getChildNode(); // skip the empty node
+
+    // If no error occurred
+    if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag))
+    {
+        XMLCSTR name=xnode.getName();
+        if (tag&&_tcslen(tag)&&((!name)||(_tcsicmp(xnode.getName(),tag))))
+        {
+            XMLNode nodeTmp;
+            int i=0;
+            while (i<xnode.nChildNode())
+            {
+                nodeTmp=xnode.getChildNode(i);
+                if (_tcsicmp(nodeTmp.getName(),tag)==0) break;
+                if (nodeTmp.isDeclaration()) { xnode=nodeTmp; i=0; } else i++;
+            }
+            if (i>=xnode.nChildNode())
+            {
+                if (pResults)
+                {
+                    pResults->error=eXMLErrorFirstTagNotFound;
+                    pResults->nLine=0;
+                    pResults->nColumn=0;
+                }
+                return emptyXMLNode;
+            }
+            xnode=nodeTmp;
+        }
+    } else
+    {
+        // Cleanup: this will destroy all the nodes
+        xnode = emptyXMLNode;
+    }
+
+
+    // If we have been given somewhere to place results
+    if (pResults)
+    {
+        pResults->error = error;
+
+        // If we have an error
+        if (error!=eXMLErrorNone)
+        {
+            if (error==eXMLErrorMissingEndTag) xml.nIndex=xml.nIndexMissigEndTag;
+            // Find which line and column it starts on.
+            CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults);
+        }
+    }
+    return xnode;
+}
+
+XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults)
+{
+    if (pResults) { pResults->nLine=0; pResults->nColumn=0; }
+    FILE *f=_tfopen(filename,_T("rb"));
+    if (f==NULL) { if (pResults) pResults->error=eXMLErrorFileNotFound; return emptyXMLNode; }
+    fseek(f,0,SEEK_END);
+    int l=ftell(f),headerSz=0;
+    if (!l) { if (pResults) pResults->error=eXMLErrorEmpty; return emptyXMLNode; }
+    fseek(f,0,SEEK_SET);
+    unsigned char *buf=(unsigned char*)malloc(l+1);
+    fread(buf,l,1,f);
+    fclose(f);
+    buf[l]=0;
+#ifdef _XMLUNICODE
+    if (guessUnicodeChars)
+    {
+        if (!myIsTextUnicode(buf,l))
+        {
+            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;
+            XMLSTR b2=myMultiByteToWideChar((const char*)(buf+headerSz),l-headerSz);
+            free(buf); buf=(unsigned char*)b2; headerSz=0;
+        } else
+        {
+            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
+            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
+        }
+    }
+#else
+    if (guessUnicodeChars)
+    {
+        if (myIsTextUnicode(buf,l))
+        {
+            l/=sizeof(wchar_t);
+            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
+            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
+            char *b2=myWideCharToMultiByte((const wchar_t*)(buf+headerSz),l-headerSz);
+            free(buf); buf=(unsigned char*)b2; headerSz=0;
+        } else
+        {
+            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;
+        }
+    }
+#endif
+
+    if (!buf) { if (pResults) pResults->error=eXMLErrorCharConversionError; return emptyXMLNode; }
+    XMLNode x=parseString((XMLSTR)(buf+headerSz),tag,pResults);
+    free(buf);
+    return x;
+}
+
+static inline void charmemset(XMLSTR dest,XMLCHAR c,int l) { while (l--) *(dest++)=c; }
+// private:
+// Creates an user friendly XML string from a given element with
+// appropriate white space and carriage returns.
+//
+// This recurses through all subnodes then adds contents of the nodes to the
+// string.
+int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat)
+{
+    int nResult = 0;
+    int cb;
+    int cbElement;
+    int nChildFormat=-1;
+    int nElementI=pEntry->nChild+pEntry->nText+pEntry->nClear;
+    int i,j;
+
+    assert(pEntry);
+
+#define LENSTR(lpsz) (lpsz ? _tcslen(lpsz) : 0)
+
+    // If the element has no name then assume this is the head node.
+    cbElement = (int)LENSTR(pEntry->lpszName);
+
+    if (cbElement)
+    {
+        // "<elementname "
+        cb = nFormat == -1 ? 0 : nFormat;
+
+        if (lpszMarker)
+        {
+            if (cb) charmemset(lpszMarker, INDENTCHAR, sizeof(XMLCHAR)*cb);
+            nResult = cb;
+            lpszMarker[nResult++]=_T('<');
+            if (pEntry->isDeclaration) lpszMarker[nResult++]=_T('?');
+            _tcscpy(&lpszMarker[nResult], pEntry->lpszName);
+            nResult+=cbElement;
+            lpszMarker[nResult++]=_T(' ');
+
+        } else
+        {
+            nResult+=cbElement+2+cb;
+            if (pEntry->isDeclaration) nResult++;
+        }
+
+        // Enumerate attributes and add them to the string
+        XMLAttribute *pAttr=pEntry->pAttribute;
+        for (i=0; i<pEntry->nAttribute; i++)
+        {
+            // "Attrib
+            cb = (int)LENSTR(pAttr->lpszName);
+            if (cb)
+            {
+                if (lpszMarker) _tcscpy(&lpszMarker[nResult], pAttr->lpszName);
+                nResult += cb;
+                // "Attrib=Value "
+                if (pAttr->lpszValue)
+                {
+                    cb=(int)lengthXMLString(pAttr->lpszValue);
+                    if (lpszMarker)
+                    {
+                        lpszMarker[nResult]=_T('=');
+                        lpszMarker[nResult+1]=_T('"');
+                        if (cb) toXMLString(&lpszMarker[nResult+2],pAttr->lpszValue);
+                        lpszMarker[nResult+cb+2]=_T('"');
+                    }
+                    nResult+=cb+3;
+                }
+                if (lpszMarker) lpszMarker[nResult] = _T(' ');
+                nResult++;
+            }
+            pAttr++;
+        }
+
+        if (pEntry->isDeclaration)
+        {
+            if (lpszMarker)
+            {
+                lpszMarker[nResult-1]=_T('?');
+                lpszMarker[nResult]=_T('>');
+            }
+            nResult++;
+            if (nFormat!=-1)
+            {
+                if (lpszMarker) lpszMarker[nResult]=_T('\n');
+                nResult++;
+            }
+        } else
+            // If there are child nodes we need to terminate the start tag
+            if (nElementI)
+            {
+                if (lpszMarker) lpszMarker[nResult-1]=_T('>');
+                if (nFormat!=-1)
+                {
+                    if (lpszMarker) lpszMarker[nResult]=_T('\n');
+                    nResult++;
+                }
+            } else nResult--;
+    }
+
+    // Calculate the child format for when we recurse.  This is used to
+    // determine the number of spaces used for prefixes.
+    if (nFormat!=-1)
+    {
+        if (cbElement&&(!pEntry->isDeclaration)) nChildFormat=nFormat+1;
+        else nChildFormat=nFormat;
+    }
+
+    // Enumerate through remaining children
+    for (i=0; i<nElementI; i++)
+    {
+        j=pEntry->pOrder[i];
+        switch((XMLElementType)(j&3))
+        {
+        // Text nodes
+        case eNodeText:
+            {
+                // "Text"
+                XMLCSTR pChild=pEntry->pText[j>>2];
+                cb = (int)lengthXMLString(pChild);
+                if (cb)
+                {
+                    if (nFormat!=-1)
+                    {
+                        if (lpszMarker)
+                        {
+                            charmemset(&lpszMarker[nResult],INDENTCHAR,sizeof(XMLCHAR)*(nFormat + 1));
+                            toXMLString(&lpszMarker[nResult+nFormat+1],pChild);
+                            lpszMarker[nResult+nFormat+1+cb]=_T('\n');
+                        }
+                        nResult+=cb+nFormat+2;
+                    } else
+                    {
+                        if (lpszMarker) toXMLString(&lpszMarker[nResult], pChild);
+                        nResult += cb;
+                    }
+                }
+                break;
+            }
+
+        // Clear type nodes
+        case eNodeClear:
+            {
+                XMLClear *pChild=pEntry->pClear+(j>>2);
+                // "OpenTag"
+                cb = (int)LENSTR(pChild->lpszOpenTag);
+                if (cb)
+                {
+                    if (nFormat!=-1)
+                    {
+                        if (lpszMarker)
+                        {
+                            charmemset(&lpszMarker[nResult], INDENTCHAR, sizeof(XMLCHAR)*(nFormat + 1));
+                            _tcscpy(&lpszMarker[nResult+nFormat+1], pChild->lpszOpenTag);
+                        }
+                        nResult+=cb+nFormat+1;
+                    }
+                    else
+                    {
+                        if (lpszMarker)_tcscpy(&lpszMarker[nResult], pChild->lpszOpenTag);
+                        nResult += cb;
+                    }
+                }
+
+                // "OpenTag Value"
+                cb = (int)LENSTR(pChild->lpszValue);
+                if (cb)
+                {
+                    if (lpszMarker) _tcscpy(&lpszMarker[nResult], pChild->lpszValue);
+                    nResult += cb;
+                }
+
+                // "OpenTag Value CloseTag"
+                cb = (int)LENSTR(pChild->lpszCloseTag);
+                if (cb)
+                {
+                    if (lpszMarker) _tcscpy(&lpszMarker[nResult], pChild->lpszCloseTag);
+                    nResult += cb;
+                }
+
+                if (nFormat!=-1)
+                {
+                    if (lpszMarker) lpszMarker[nResult] = _T('\n');
+                    nResult++;
+                }
+                break;
+            }
+
+        // Element nodes
+        case eNodeChild:
+            {
+                // Recursively add child nodes
+                nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, lpszMarker ? lpszMarker + nResult : 0, nChildFormat);
+                break;
+            }
+        default: break;
+        }
+    }
+
+    if ((cbElement)&&(!pEntry->isDeclaration))
+    {
+        // If we have child entries we need to use long XML notation for
+        // closing the element - "<elementname>blah blah blah</elementname>"
+        if (nElementI)
+        {
+            // "</elementname>\0"
+            if (lpszMarker)
+            {
+                if (nFormat != -1)
+                {
+                    if (nFormat)
+                    {
+                        charmemset(&lpszMarker[nResult], INDENTCHAR,sizeof(XMLCHAR)*nFormat);
+                        nResult+=nFormat;
+                    }
+                }
+
+                _tcscpy(&lpszMarker[nResult], _T("</"));
+                nResult += 2;
+                _tcscpy(&lpszMarker[nResult], pEntry->lpszName);
+                nResult += cbElement;
+
+                if (nFormat == -1)
+                {
+                    _tcscpy(&lpszMarker[nResult], _T(">"));
+                    nResult++;
+                } else
+                {
+                    _tcscpy(&lpszMarker[nResult], _T(">\n"));
+                    nResult+=2;
+                }
+            } else
+            {
+                if (nFormat != -1) nResult+=cbElement+4+nFormat;
+                else nResult+=cbElement+3;
+            }
+        } else
+        {
+            // If there are no children we can use shorthand XML notation -
+            // "<elementname/>"
+            // "/>\0"
+            if (lpszMarker)
+            {
+                if (nFormat == -1)
+                {
+                    _tcscpy(&lpszMarker[nResult], _T("/>"));
+                    nResult += 2;
+                }
+                else
+                {
+                    _tcscpy(&lpszMarker[nResult], _T("/>\n"));
+                    nResult += 3;
+                }
+            }
+            else
+            {
+                nResult += nFormat == -1 ? 2 : 3;
+            }
+        }
+    }
+
+    return nResult;
+}
+
+#undef LENSTR
+
+// Create an XML string
+// @param       int nFormat             - 0 if no formatting is required
+//                                        otherwise nonzero for formatted text
+//                                        with carriage returns and indentation.
+// @param       int *pnSize             - [out] pointer to the size of the
+//                                        returned string not including the
+//                                        NULL terminator.
+// @return      XMLSTR                  - Allocated XML string, you must free
+//                                        this with free().
+XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const
+{
+    if (!d) { if (pnSize) *pnSize=0; return NULL; }
+
+    XMLSTR lpszResult = NULL;
+    int cbStr;
+
+    // Recursively Calculate the size of the XML string
+    if (!dropWhiteSpace) nFormat=0;
+    nFormat = nFormat ? 0 : -1;
+    cbStr = CreateXMLStringR(d, 0, nFormat);
+    assert(cbStr);
+    // Alllocate memory for the XML string + the NULL terminator and
+    // create the recursively XML string.
+    lpszResult=(XMLSTR)malloc((cbStr+1)*sizeof(XMLCHAR));
+    CreateXMLStringR(d, lpszResult, nFormat);
+    if (pnSize) *pnSize = cbStr;
+    return lpszResult;
+}
+
+XMLNode::~XMLNode() { deleteNodeContent(); }
+
+int XMLNode::detachFromParent(XMLNodeData *d)
+{
+    XMLNode *pa=d->pParent->pChild;
+    int i=0;
+    while (((void*)(pa[i].d))!=((void*)d)) i++;
+    d->pParent->nChild--;
+    if (d->pParent->nChild) memmove(pa+i,pa+i+1,(d->pParent->nChild-i)*sizeof(XMLNode));
+    else { free(pa); d->pParent->pChild=NULL; }
+    return removeOrderElement(d->pParent,eNodeChild,i);
+}
+
+void XMLNode::deleteNodeContent(char force)
+{
+    if (!d) return;
+    (d->ref_count) --;
+    if ((d->ref_count==0)||force)
+    {
+        int i;
+        if (d->pParent) detachFromParent(d);
+        for(i=0; i<d->nChild; i++) { d->pChild[i].d->pParent=NULL; d->pChild[i].deleteNodeContent(force); }
+        free(d->pChild);
+        for(i=0; i<d->nText; i++) free((void*)d->pText[i]);
+        free(d->pText);
+        for(i=0; i<d->nClear; i++) free((void*)d->pClear[i].lpszValue);
+        free(d->pClear);
+        for(i=0; i<d->nAttribute; i++)
+        {
+            free((void*)d->pAttribute[i].lpszName);
+            if (d->pAttribute[i].lpszValue) free((void*)d->pAttribute[i].lpszValue);
+        }
+        free(d->pAttribute);
+        free(d->pOrder);
+        free((void*)d->lpszName);
+        free(d);
+        d=NULL;
+    }
+}
+
+XMLNode XMLNode::addChild(XMLNode childNode, int pos)
+{
+    XMLNodeData *dc=childNode.d;
+    if ((!dc)||(!d)) return childNode;
+    if (dc->pParent) { if ((detachFromParent(dc)<=pos)&&(dc->pParent==d)) pos--; } else dc->ref_count++;
+    dc->pParent=d;
+//     int nc=d->nChild;
+//     d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode));
+    d->pChild=(XMLNode*)addToOrder(0,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild);
+    d->pChild[pos].d=dc;
+    d->nChild++;
+    return childNode;
+}
+
+void XMLNode::deleteAttribute(int i)
+{
+    if ((!d)||(i<0)||(i>=d->nAttribute)) return;
+    d->nAttribute--;
+    XMLAttribute *p=d->pAttribute+i;
+    free((void*)p->lpszName);
+    if (p->lpszValue) free((void*)p->lpszValue);
+    if (d->nAttribute) memmove(p,p+1,(d->nAttribute-i)*sizeof(XMLAttribute)); else { free(p); d->pAttribute=NULL; }
+}
+
+void XMLNode::deleteAttribute(XMLAttribute *a){ if (a) deleteAttribute(a->lpszName); }
+void XMLNode::deleteAttribute(XMLCSTR lpszName)
+{
+    int j=0;
+    getAttribute(lpszName,&j);
+    if (j) deleteAttribute(j-1);
+}
+
+XMLAttribute *XMLNode::updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,int i)
+{
+    if (!d) return NULL;
+    if (i>=d->nAttribute)
+    {
+        if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue);
+        return NULL;
+    }
+    XMLAttribute *p=d->pAttribute+i;
+    if (p->lpszValue&&p->lpszValue!=lpszNewValue) free((void*)p->lpszValue);
+    p->lpszValue=lpszNewValue;
+    if (lpszNewName&&p->lpszName!=lpszNewName) { free((void*)p->lpszName); p->lpszName=lpszNewName; };
+    return p;
+}
+
+XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
+{
+    if (oldAttribute) return updateAttribute_WOSD(newAttribute->lpszValue,newAttribute->lpszName,oldAttribute->lpszName);
+    return addAttribute_WOSD(newAttribute->lpszName,newAttribute->lpszValue);
+}
+
+XMLAttribute *XMLNode::updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName)
+{
+    int j=0;
+    getAttribute(lpszOldName,&j);
+    if (j) return updateAttribute_WOSD(lpszNewValue,lpszNewName,j-1);
+    else
+    {
+        if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue);
+        else             return addAttribute_WOSD(stringDup(lpszOldName),lpszNewValue);
+    }
+}
+
+int XMLNode::indexText(XMLCSTR lpszValue) const
+{
+    if (!d) return -1;
+    int i,l=d->nText;
+    if (!lpszValue) { if (l) return 0; return -1; }
+    XMLCSTR *p=d->pText;
+    for (i=0; i<l; i++) if (lpszValue==p[i]) return i;
+    return -1;
+}
+
+void XMLNode::deleteText(int i)
+{
+    if ((!d)||(i<0)||(i>=d->nText)) return;
+    d->nText--;
+    XMLCSTR *p=d->pText+i;
+    free((void*)*p);
+    if (d->nText) memmove(p,p+1,(d->nText-i)*sizeof(XMLCSTR)); else { free(p); d->pText=NULL; }
+    removeOrderElement(d,eNodeText,i);
+}
+
+void XMLNode::deleteText(XMLCSTR lpszValue) { deleteText(indexText(lpszValue)); }
+
+XMLCSTR XMLNode::updateText_WOSD(XMLCSTR lpszNewValue, int i)
+{
+    if (!d) return NULL;
+    if (i>=d->nText) return addText_WOSD(lpszNewValue);
+    XMLCSTR *p=d->pText+i;
+    if (*p!=lpszNewValue) { free((void*)*p); *p=lpszNewValue; }
+    return lpszNewValue;
+}
+
+XMLCSTR XMLNode::updateText_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+{
+    if (!d) return NULL;
+    int i=indexText(lpszOldValue);
+    if (i>=0) return updateText_WOSD(lpszNewValue,i);
+    return addText_WOSD(lpszNewValue);
+}
+
+void XMLNode::deleteClear(int i)
+{
+    if ((!d)||(i<0)||(i>=d->nClear)) return;
+    d->nClear--;
+    XMLClear *p=d->pClear+i;
+    free((void*)p->lpszValue);
+    if (d->nClear) memmove(p,p+1,(d->nText-i)*sizeof(XMLClear)); else { free(p); d->pClear=NULL; }
+    removeOrderElement(d,eNodeClear,i);
+}
+
+int XMLNode::indexClear(XMLCSTR lpszValue) const
+{
+    if (!d) return -1;
+    int i,l=d->nClear;
+    if (!lpszValue) { if (l) return 0; return -1; }
+    XMLClear *p=d->pClear;
+    for (i=0; i<l; i++) if (lpszValue==p[i].lpszValue) return i;
+    return -1;
+}
+
+void XMLNode::deleteClear(XMLCSTR lpszValue) { deleteClear(indexClear(lpszValue)); }
+void XMLNode::deleteClear(XMLClear *a) { if (a) deleteClear(a->lpszValue); }
+
+XMLClear *XMLNode::updateClear_WOSD(XMLCSTR lpszNewContent, int i)
+{
+    if (!d) return NULL;
+    if (i>=d->nClear)
+    {
+        return addClear_WOSD(XMLClearTags[0].lpszOpen,lpszNewContent,XMLClearTags[0].lpszClose);
+    }
+    XMLClear *p=d->pClear+i;
+    if (lpszNewContent!=p->lpszValue) { free((void*)p->lpszValue); p->lpszValue=lpszNewContent; }
+    return p;
+}
+
+XMLClear *XMLNode::updateClear_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+{
+    if (!d) return NULL;
+    int i=indexClear(lpszOldValue);
+    if (i>=0) return updateClear_WOSD(lpszNewValue,i);
+    return addClear_WOSD(lpszNewValue,XMLClearTags[0].lpszOpen,XMLClearTags[0].lpszClose);
+}
+
+XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP,XMLClear *oldP)
+{
+    if (oldP) return updateClear_WOSD(newP->lpszValue,oldP->lpszValue);
+    return NULL;
+}
+
+XMLNode& XMLNode::operator=( const XMLNode& A )
+{
+    // shallow copy
+    if (this != &A)
+    {
+        deleteNodeContent();
+        d=A.d;
+        if (d) (d->ref_count) ++ ;
+    }
+    return *this;
+}
+
+XMLNode::XMLNode(const XMLNode &A)
+{
+    // shallow copy
+    d=A.d;
+    if (d) (d->ref_count)++ ;
+}
+
+int XMLNode::nChildNode(XMLCSTR name) const
+{
+    if (!d) return 0;
+    int i,j=0,n=d->nChild;
+    XMLNode *pc=d->pChild;
+    for (i=0; i<n; i++)
+    {
+        if (_tcsicmp(pc->d->lpszName, name)==0) j++;
+        pc++;
+    }
+    return j;
+}
+
+XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const
+{
+    if (!d) return emptyXMLNode;
+    int i=0,n=d->nChild;
+    if (j) i=*j;
+    XMLNode *pc=d->pChild+i;
+    for (; i<n; i++)
+    {
+        if (_tcsicmp(pc->d->lpszName, name)==0)
+        {
+            if (j) *j=i+1;
+            return *pc;
+        }
+        pc++;
+    }
+    return emptyXMLNode;
+}
+
+XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const
+{
+    if (!d) return emptyXMLNode;
+    int i=0;
+    while (j-->0) getChildNode(name,&i);
+    return getChildNode(name,&i);
+}
+
+int XMLNode::positionOfText     (int i) const { if (i>=d->nText ) i=d->nText-1;  return findPosition(d,i,eNodeText ); }
+int XMLNode::positionOfClear    (int i) const { if (i>=d->nClear) i=d->nClear-1; return findPosition(d,i,eNodeClear); }
+int XMLNode::positionOfChildNode(int i) const { if (i>=d->nChild) i=d->nChild-1; return findPosition(d,i,eNodeChild); }
+int XMLNode::positionOfText (XMLCSTR lpszValue) const { return positionOfText (indexText (lpszValue)); }
+int XMLNode::positionOfClear(XMLCSTR lpszValue) const { return positionOfClear(indexClear(lpszValue)); }
+int XMLNode::positionOfClear(XMLClear *a) const { if (a) return positionOfClear(a->lpszValue); return positionOfClear(); }
+int XMLNode::positionOfChildNode(XMLNode x)  const
+{
+    if ((!d)||(!x.d)) return -1;
+    XMLNodeData *dd=x.d;
+    XMLNode *pc=d->pChild;
+    int i=d->nChild;
+    while (i--) if (pc[i].d==dd) return findPosition(d,i,eNodeChild);
+    return -1;
+}
+int XMLNode::positionOfChildNode(XMLCSTR name, int count) const
+{
+    if (!name) return positionOfChildNode(count);
+    int j=0;
+    do { getChildNode(name,&j); if (j<0) return -1; } while (count--);
+    return findPosition(d,j-1,eNodeChild);
+}
+
+XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name,XMLCSTR attributeName,XMLCSTR attributeValue, int *k) const
+{
+     int i=0,j;
+     if (k) i=*k;
+     XMLNode x;
+     XMLCSTR t;
+     do
+     {
+         x=getChildNode(name,&i);
+         if (!x.isEmpty())
+         {
+             if (attributeValue)
+             {
+                 j=0;
+                 do
+                 {
+                     t=x.getAttribute(attributeName,&j);
+                     if (t&&(_tcsicmp(attributeValue,t)==0)) { if (k) *k=i+1; return x; }
+                 } while (t);
+             } else
+             {
+                 if (x.isAttributeSet(attributeName)) { if (k) *k=i+1; return x; }
+             }
+         }
+     } while (!x.isEmpty());
+     return emptyXMLNode;
+}
+
+// Find an attribute on an node.
+XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const
+{
+    if (!d) return NULL;
+    int i=0,n=d->nAttribute;
+    if (j) i=*j;
+    XMLAttribute *pAttr=d->pAttribute+i;
+    for (; i<n; i++)
+    {
+        if (_tcsicmp(pAttr->lpszName, lpszAttrib)==0)
+        {
+            if (j) *j=i+1;
+            return pAttr->lpszValue;
+        }
+        pAttr++;
+    }
+    return NULL;
+}
+
+char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const
+{
+    if (!d) return FALSE;
+    int i,n=d->nAttribute;
+    XMLAttribute *pAttr=d->pAttribute;
+    for (i=0; i<n; i++)
+    {
+        if (_tcsicmp(pAttr->lpszName, lpszAttrib)==0)
+        {
+            return TRUE;
+        }
+        pAttr++;
+    }
+    return FALSE;
+}
+
+XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const
+{
+    if (!d) return NULL;
+    int i=0;
+    while (j-->0) getAttribute(name,&i);
+    return getAttribute(name,&i);
+}
+
+XMLNodeContents XMLNode::enumContents(int i) const
+{
+    XMLNodeContents c;
+    if (!d) { c.type=eNodeNULL; return c; }
+    if (i<d->nAttribute)
+    {
+        c.type=eNodeAttribute;
+        c.attrib=d->pAttribute[i];
+        return c;
+    }
+    i-=d->nAttribute;
+    c.type=(XMLElementType)(d->pOrder[i]&3);
+    i=(d->pOrder[i])>>2;
+    switch (c.type)
+    {
+    case eNodeChild:     c.child = d->pChild[i];      break;
+    case eNodeText:      c.text  = d->pText[i];       break;
+    case eNodeClear:     c.clear = d->pClear[i];      break;
+    default: break;
+    }
+    return c;
+}
+
+XMLCSTR XMLNode::getName() const { if (!d) return NULL; return d->lpszName;   }
+int XMLNode::nText()       const { if (!d) return 0;    return d->nText;      }
+int XMLNode::nChildNode()  const { if (!d) return 0;    return d->nChild;     }
+int XMLNode::nAttribute()  const { if (!d) return 0;    return d->nAttribute; }
+int XMLNode::nClear()      const { if (!d) return 0;    return d->nClear;     }
+int XMLNode::nElement()    const { if (!d) return 0;    return d->nAttribute+d->nChild+d->nText+d->nClear; }
+XMLClear     XMLNode::getClear         (int i) const { if ((!d)||(i>=d->nClear    )) return emptyXMLClear;     return d->pClear[i];     }
+XMLAttribute XMLNode::getAttribute     (int i) const { if ((!d)||(i>=d->nAttribute)) return emptyXMLAttribute; return d->pAttribute[i]; }
+XMLCSTR      XMLNode::getAttributeName (int i) const { if ((!d)||(i>=d->nAttribute)) return NULL;              return d->pAttribute[i].lpszName;  }
+XMLCSTR      XMLNode::getAttributeValue(int i) const { if ((!d)||(i>=d->nAttribute)) return NULL;              return d->pAttribute[i].lpszValue; }
+XMLCSTR      XMLNode::getText          (int i) const { if ((!d)||(i>=d->nText     )) return NULL;              return d->pText[i];      }
+XMLNode      XMLNode::getChildNode     (int i) const { if ((!d)||(i>=d->nChild    )) return emptyXMLNode;      return d->pChild[i];     }
+XMLNode      XMLNode::getParentNode    (     ) const { if ((!d)||(!d->pParent     )) return emptyXMLNode;      return XMLNode(d->pParent); }
+char         XMLNode::isDeclaration    (     ) const { if (!d) return 0;             return d->isDeclaration; }
+char         XMLNode::isEmpty          (     ) const { return (d==NULL); }
+
+XMLNode       XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, int pos)
+              { return addChild_priv(0,stringDup(lpszName),isDeclaration,pos); }
+XMLNode       XMLNode::addChild_WOSD(XMLCSTR lpszName, char isDeclaration, int pos)
+              { return addChild_priv(0,lpszName,isDeclaration,pos); }
+XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue)
+              { return addAttribute_priv(0,stringDup(lpszName),stringDup(lpszValue)); }
+XMLAttribute *XMLNode::addAttribute_WOSD(XMLCSTR lpszName, XMLCSTR lpszValuev)
+              { return addAttribute_priv(0,lpszName,lpszValuev); }
+XMLCSTR       XMLNode::addText(XMLCSTR lpszValue, int pos)
+              { return addText_priv(0,stringDup(lpszValue),pos); }
+XMLCSTR       XMLNode::addText_WOSD(XMLCSTR lpszValue, int pos)
+              { return addText_priv(0,lpszValue,pos); }
+XMLClear     *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos)
+              { return addClear_priv(0,stringDup(lpszValue),lpszOpen,lpszClose,pos); }
+XMLClear     *XMLNode::addClear_WOSD(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos)
+              { return addClear_priv(0,lpszValue,lpszOpen,lpszClose,pos); }
+XMLCSTR       XMLNode::updateName(XMLCSTR lpszName)
+              { return updateName_WOSD(stringDup(lpszName)); }
+XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
+              { return updateAttribute_WOSD(stringDup(newAttribute->lpszValue),stringDup(newAttribute->lpszName),oldAttribute->lpszName); }
+XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,int i)
+              { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),i); }
+XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName)
+              { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),lpszOldName); }
+XMLCSTR       XMLNode::updateText(XMLCSTR lpszNewValue, int i)
+              { return updateText_WOSD(stringDup(lpszNewValue),i); }
+XMLCSTR       XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+              { return updateText_WOSD(stringDup(lpszNewValue),lpszOldValue); }
+XMLClear     *XMLNode::updateClear(XMLCSTR lpszNewContent, int i)
+              { return updateClear_WOSD(stringDup(lpszNewContent),i); }
+XMLClear     *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+              { return updateClear_WOSD(stringDup(lpszNewValue),lpszOldValue); }
+XMLClear     *XMLNode::updateClear(XMLClear *newP,XMLClear *oldP)
+              { return updateClear_WOSD(stringDup(newP->lpszValue),oldP->lpszValue); }
+
+void XMLNode::setGlobalOptions(char _guessUnicodeChars, char _strictUTF8Parsing, char _dropWhiteSpace)
+{
+    guessUnicodeChars=_guessUnicodeChars; dropWhiteSpace=_dropWhiteSpace; strictUTF8Parsing=_strictUTF8Parsing;
+#ifndef _XMLUNICODE
+    if (_strictUTF8Parsing) XML_ByteTable=XML_utf8ByteTable; else XML_ByteTable=XML_asciiByteTable;
+#endif
+}
+
+char XMLNode::guessUTF8ParsingParameterValue(void *buf,int l, char useXMLEncodingAttribute)
+{
+#ifdef _XMLUNICODE
+    return 0;
+#else
+    if (l<25) return 0;
+    if (myIsTextUnicode(buf,l)) return 0;
+    unsigned char *b=(unsigned char*)buf;
+    if ((b[0]==0xef)&&(b[1]==0xbb)&&(b[2]==0xbf)) return 1;
+
+    // Match utf-8 model ?
+    int i=0;
+    while (i<l)
+        switch (XML_utf8ByteTable[b[i]])
+        {
+        case 4: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) return 0; // 10bbbbbb ?
+        case 3: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) return 0; // 10bbbbbb ?
+        case 2: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) return 0; // 10bbbbbb ?
+        case 1: i++; break;
+        case 0: i=l;
+        }
+    if (!useXMLEncodingAttribute) return 1;
+    // if encoding is specified and different from utf-8 than it's non-utf8
+    // otherwise it's utf-8
+    char bb[201];
+    l=mmin(l,200);
+    memcpy(bb,buf,l); // copy buf into bb to be able to do "bb[l]=0"
+    bb[l]=0;
+    b=(unsigned char*)strstr(bb,"encoding");
+    if (!b) return 1;
+    b+=8; while XML_isSPACECHAR(*b) b++; if (*b!='=') return 1;
+    b++;  while XML_isSPACECHAR(*b) b++; if ((*b!='\'')&&(*b!='"')) return 1;
+    b++;  while XML_isSPACECHAR(*b) b++; if ((_strnicmp((char*)b,"utf-8",5)==0)||
+                                             (_strnicmp((char*)b,"utf8",4)==0)) return 1;
+    return 0;
+#endif
+}
+#undef XML_isSPACECHAR
+
+//////////////////////////////////////////////////////////
+//      Here starts the base64 conversion functions.    //
+//////////////////////////////////////////////////////////
+
+static const char base64Fillchar = _T('='); // used to mark partial words at the end
+
+// this lookup table defines the base64 encoding
+XMLCSTR base64EncodeTable=_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
+
+// Decode Table gives the index of any valid base64 character in the Base64 table]
+// 96: '='  -   97: space char   -   98: illegal char   -   99: end of string
+const unsigned char base64DecodeTable[] = {
+    99,98,98,98,98,98,98,98,98,97,  97,98,98,97,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //00 -29
+    98,98,97,98,98,98,98,98,98,98,  98,98,98,62,98,98,98,63,52,53,  54,55,56,57,58,59,60,61,98,98,  //30 -59
+    98,96,98,98,98, 0, 1, 2, 3, 4,   5, 6, 7, 8, 9,10,11,12,13,14,  15,16,17,18,19,20,21,22,23,24,  //60 -89
+    25,98,98,98,98,98,98,26,27,28,  29,30,31,32,33,34,35,36,37,38,  39,40,41,42,43,44,45,46,47,48,  //90 -119
+    49,50,51,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //120 -149
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //150 -179
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //180 -209
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //210 -239
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98                                               //240 -255
+};
+
+XMLParserBase64Tool::~XMLParserBase64Tool(){ freeBuffer(); }
+
+void XMLParserBase64Tool::freeBuffer(){ if (buf) free(buf); buf=NULL; buflen=0; }
+
+int XMLParserBase64Tool::encodeLength(int inlen, char formatted)
+{
+    unsigned int i=((inlen-1)/3*4+4+1);
+    if (formatted) i+=inlen/54;
+    return i;
+}
+
+XMLSTR XMLParserBase64Tool::encode(unsigned char *inbuf, unsigned int inlen, char formatted)
+{
+    int i=encodeLength(inlen,formatted),k=17,eLen=inlen/3,j;
+    alloc(i*sizeof(XMLCHAR));
+    XMLSTR curr=(XMLSTR)buf;
+    for(i=0;i<eLen;i++)
+    {
+        // Copy next three bytes into lower 24 bits of int, paying attention to sign.
+        j=(inbuf[0]<<16)|(inbuf[1]<<8)|inbuf[2]; inbuf+=3;
+        // Encode the int into four chars
+        *(curr++)=base64EncodeTable[ j>>18      ];
+        *(curr++)=base64EncodeTable[(j>>12)&0x3f];
+        *(curr++)=base64EncodeTable[(j>> 6)&0x3f];
+        *(curr++)=base64EncodeTable[(j    )&0x3f];
+        if (formatted) { if (!k) { *(curr++)=_T('\n'); k=18; } k--; }
+    }
+    eLen=inlen-eLen*3; // 0 - 2.
+    if (eLen==1)
+    {
+        *(curr++)=base64EncodeTable[ inbuf[0]>>2      ];
+        *(curr++)=base64EncodeTable[(inbuf[0]<<4)&0x3F];
+        *(curr++)=base64Fillchar;
+        *(curr++)=base64Fillchar;
+    } else if (eLen==2)
+    {
+        j=(inbuf[0]<<8)|inbuf[1];
+        *(curr++)=base64EncodeTable[ j>>10      ];
+        *(curr++)=base64EncodeTable[(j>> 4)&0x3f];
+        *(curr++)=base64EncodeTable[(j<< 2)&0x3f];
+        *(curr++)=base64Fillchar;
+    }
+    *(curr++)=0;
+    return (XMLSTR)buf;
+}
+
+unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data,XMLError *xe)
+{
+     if (xe) *xe=eXMLErrorNone;
+    int size=0;
+    unsigned char c;
+    //skip any extra characters (e.g. newlines or spaces)
+    while (*data)
+    {
+#ifdef _XMLUNICODE
+        if (*data>255) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+#endif
+        c=base64DecodeTable[(unsigned char)(*data)];
+        if (c<97) size++;
+        else if (c==98) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+        data++;
+    }
+    if (xe&&(size%4!=0)) *xe=eXMLErrorBase64DataSizeIsNotMultipleOf4;
+    if (size==0) return 0;
+    do { data--; size--; } while(*data==base64Fillchar); size++;
+    return (unsigned int)((size*3)/4);
+}
+
+unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, int len, XMLError *xe)
+{
+    if (xe) *xe=eXMLErrorNone;
+    int i=0,p=0;
+    unsigned char d,c;
+    for(;;)
+    {
+
+#ifdef _XMLUNICODE
+#define BASE64DECODE_READ_NEXT_CHAR(c)                                              \
+        do {                                                                        \
+            if (data[i]>255){ c=98; break; }                                        \
+            c=base64DecodeTable[(unsigned char)data[i++]];                       \
+        }while (c==97);                                                             \
+        if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+#else
+#define BASE64DECODE_READ_NEXT_CHAR(c)                                           \
+        do { c=base64DecodeTable[(unsigned char)data[i++]]; }while (c==97);   \
+        if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+#endif
+
+        BASE64DECODE_READ_NEXT_CHAR(c)
+        if (c==99) { return 2; }
+        if (c==96)
+        {
+            if (p==(int)len) return 2;
+            if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
+            return 1;
+        }
+
+        BASE64DECODE_READ_NEXT_CHAR(d)
+        if ((d==99)||(d==96)) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        if (p==(int)len) {      if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; return 0; }
+        buf[p++]=(c<<2)|((d>>4)&0x3);
+
+        BASE64DECODE_READ_NEXT_CHAR(c)
+        if (c==99) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        if (p==(int)len)
+        {
+            if (c==96) return 2;
+            if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
+            return 0;
+        }
+        if (c==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        buf[p++]=((d<<4)&0xf0)|((c>>2)&0xf);
+
+        BASE64DECODE_READ_NEXT_CHAR(d)
+        if (d==99 ) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        if (p==(int)len)
+        {
+            if (d==96) return 2;
+            if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
+            return 0;
+        }
+        if (d==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        buf[p++]=((c<<6)&0xc0)|d;
+    }
+}
+#undef BASE64DECODE_READ_NEXT_CHAR
+
+void XMLParserBase64Tool::alloc(int newsize)
+{
+    if ((!buf)&&(newsize)) { buf=malloc(newsize); buflen=newsize; return; }
+    if (newsize>buflen) { buf=realloc(buf,newsize); buflen=newsize; }
+}
+
+unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, XMLError *xe)
+{
+    if (xe) *xe=eXMLErrorNone;
+    unsigned int len=decodeSize(data,xe);
+    if (outlen) *outlen=len;
+    if (!len) return NULL;
+    alloc(len+1);
+    if(!decode(data,(unsigned char*)buf,len,xe)){ return NULL; }
+    return (unsigned char*)buf;
+}
+
diff --git a/kernel/src/xmlParser.h b/kernel/src/xmlParser.h
new file mode 100644 (file)
index 0000000..ac98af7
--- /dev/null
@@ -0,0 +1,548 @@
+/**
+ ****************************************************************************
+ * <P> XML.c - implementation file for basic XML parser written in ANSI C++
+ * for portability. It works by using recursion and a node tree for breaking
+ * down the elements of an XML document.  </P>
+ *
+ * @version     V2.23
+ * @author      Frank Vanden Berghen
+ *
+ * BSD license:
+ * Copyright (c) 2002, Frank Vanden Berghen
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Frank Vanden Berghen nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************
+ */
+#ifndef __INCLUDE_XML_NODE__
+#define __INCLUDE_XML_NODE__
+
+#include <stdlib.h>
+
+#ifdef _UNICODE
+// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
+// This is useful when you get error messages like:
+//    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
+// The _XMLUNICODE preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
+// must be defined) or utf8-mode(the pre-processor variable must be undefined).
+#define _XMLUNICODE
+#endif /* _UNICODE */
+
+#if defined(WIN32) || defined(UNDER_CE)
+// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET)
+#define _XMLWINDOWS
+// LG 
+#define _USE_XMLPARSER_DLL
+#define _DLL_EXPORTS_
+#endif /* _XMLWINDOWS */
+
+#ifdef DLLENTRY
+#undef  DLLENTRY
+#endif /* DLLENTRY */
+
+//#define _USE_XMLPARSER_DLL
+
+#ifdef _USE_XMLPARSER_DLL
+ #ifdef _DLL_EXPORTS_
+   #define DLLENTRY __declspec(dllexport)
+ #else
+   #define DLLENTRY __declspec(dllimport)
+ #endif /* _DLL_EXPORTS_ */ 
+#else
+  #define DLLENTRY
+#endif /* _USE_XMLPARSER_DLL */
+
+// EED  ......OOJJOOO.......
+//#define DLLENTRY __declspec(dllexport)
+
+
+// uncomment the next line if you want no support for wchar_t* (no need for the <wchar.h> or <tchar.h> libraries anymore to compile)
+//
+// --> Very strange compile errors under LINUX when commented out! JPRx
+// --> More oddities under Windows when uncommented.
+// ==> I try a '#if'
+//
+#if defined(WIN32)
+#else
+  #define XML_NO_WIDE_CHAR
+#endif /* WIN32 */
+
+#ifdef XML_NO_WIDE_CHAR
+#undef _XMLWINDOWS
+#undef _XMLUNICODE
+#endif /* XML_NO_WIDE_CHAR */ 
+
+#ifdef _XMLWINDOWS
+#include <tchar.h>
+#else
+#define DLLENTRY
+#ifndef XML_NO_WIDE_CHAR
+#include <wchar.h> // to have 'wcsrtombs' for ANSI version
+                   // to have 'mbsrtowcs' for UNICODE version
+#endif /* XML_NO_WIDE_CHAR */
+#endif /* _XMLWINDOWS */
+
+// Some common types for char set portable code
+#ifdef _XMLUNICODE
+    #ifndef _T
+        #define _T(c) L ## c
+    #endif
+    #define XMLCSTR const wchar_t *
+    #define XMLSTR  wchar_t *
+    #define XMLCHAR wchar_t
+#else
+    #ifndef _T
+        #define _T(c) c
+    #endif /* -T */
+    #define XMLCSTR const char *
+    #define XMLSTR  char *
+    #define XMLCHAR char
+#endif /* _XMLUNICODE */
+
+#ifndef FALSE
+    #define FALSE 0
+#endif /* FALSE */
+#ifndef TRUE
+    #define TRUE 1
+#endif /* TRUE */
+
+
+// Enumeration for XML parse errors.
+typedef enum XMLError
+{
+    eXMLErrorNone = 0,
+    eXMLErrorMissingEndTag,
+    eXMLErrorEmpty,
+    eXMLErrorFirstNotStartTag,
+    eXMLErrorMissingTagName,
+    eXMLErrorMissingEndTagName,
+    eXMLErrorNoMatchingQuote,
+    eXMLErrorUnmatchedEndTag,
+    eXMLErrorUnmatchedEndClearTag,
+    eXMLErrorUnexpectedToken,
+    eXMLErrorInvalidTag,
+    eXMLErrorNoElements,
+    eXMLErrorFileNotFound,
+    eXMLErrorFirstTagNotFound,
+    eXMLErrorUnknownCharacterEntity,
+    eXMLErrorCharConversionError,
+    eXMLErrorCannotOpenWriteFile,
+    eXMLErrorCannotWriteFile,
+
+    eXMLErrorBase64DataSizeIsNotMultipleOf4,
+    eXMLErrorBase64DecodeIllegalCharacter,
+    eXMLErrorBase64DecodeTruncatedData,
+    eXMLErrorBase64DecodeBufferTooSmall
+} XMLError;
+
+// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
+typedef enum XMLElementType
+{
+    eNodeChild=0,
+    eNodeAttribute=1,
+    eNodeText=2,
+    eNodeClear=3,
+    eNodeNULL=4
+} XMLElementType;
+
+// Structure used to obtain error details if the parse fails.
+typedef struct XMLResults
+{
+    enum XMLError error;
+    int  nLine,nColumn;
+} XMLResults;
+
+// Structure for XML clear (unformatted) node (usually comments)
+typedef struct {
+    XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag;
+} XMLClear;
+
+// Structure for XML attribute.
+typedef struct {
+    XMLCSTR lpszName; XMLCSTR lpszValue;
+} XMLAttribute;
+
+// Structure for XML clear tags.
+typedef struct {
+    XMLCSTR lpszOpen; int openTagLen; XMLCSTR lpszClose;
+} ALLXMLClearTag;
+
+struct XMLNodeContents;
+
+typedef struct DLLENTRY XMLNode
+{
+  private:
+
+    struct XMLNodeDataTag;
+
+    // protected constructors: use one of these four methods to get your first instance of XMLNode:
+    //  - parseString
+    //  - parseFile
+    //  - openFileHelper
+    //  - createXMLTopNode
+    XMLNode(struct XMLNodeDataTag *pParent, XMLCSTR lpszName, char isDeclaration);
+    XMLNode(struct XMLNodeDataTag *p);
+
+  public:
+
+    // You can create your first instance of XMLNode with these 4 functions:
+    // (see complete explanation of parameters below)
+
+    static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);
+    static XMLNode parseString   (XMLCSTR  lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
+    static XMLNode parseFile     (XMLCSTR     filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
+    static XMLNode openFileHelper(XMLCSTR     filename, XMLCSTR tag=NULL                           );
+
+    // The tag parameter should be the name of the first tag inside the XML file.
+    // If the tag parameter is omitted, the 3 functions return a node that represents
+    // the head of the xml document including the declaration term (<? ... ?>).
+
+    // The "openFileHelper" reports to the screen all the warnings & errors that occurred during
+    // parsing of the XML file. Since each application has its own way to report and deal with errors,
+    // you should rather use the "parseFile" function to parse XML files and program yourself thereafter
+    // an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
+    // mechanism included inside the "openFileHelper" function).
+
+    // If the XML document is corrupted:
+    //   * The "openFileHelper" method will:
+    //         - display an error message on the console (or inside a messageBox for windows).
+    //         - stop execution (exit).
+    //     I suggest that you write your own "openFileHelper" method tailored to your needs.
+    //   * The 2 other methods will initialize the "pResults" variable with some information that
+    //     can be used to trace the error.
+    //   * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as
+    //     explained inside the note at the beginning of the "xmlParser.cpp" file.
+    // You can have a user-friendly explanation of the parsing error with this function:
+    static XMLCSTR getError(XMLError error);
+    static XMLCSTR getVersion();
+    static ALLXMLClearTag* getClearTagTable();
+
+    XMLCSTR getName() const;                                         // name of the node
+    XMLCSTR getText(int i=0) const;                                  // return ith text field
+    int nText() const;                                               // nbr of text field
+    XMLNode getParentNode() const;                                   // return the parent node
+    XMLNode getChildNode(int i=0) const;                             // return ith child node
+    XMLNode getChildNode(XMLCSTR name, int i)  const;                // return ith child node with specific name
+                                                                     //     (return an empty node if failing)
+    XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;           // return next child node with specific name
+                                                                     //     (return an empty node if failing)
+    XMLNode getChildNodeWithAttribute(XMLCSTR tagName,               // return child node with specific name/attribute
+                                      XMLCSTR attributeName,         //     (return an empty node if failing)
+                                      XMLCSTR attributeValue=NULL,   //
+                                      int *i=NULL)  const;           //
+    int nChildNode(XMLCSTR name) const;                              // return the number of child node with specific name
+    int nChildNode() const;                                          // nbr of child node
+    XMLAttribute getAttribute(int i=0) const;                        // return ith attribute
+    XMLCSTR      getAttributeName(int i=0) const;                    // return ith attribute name
+    XMLCSTR      getAttributeValue(int i=0) const;                   // return ith attribute value
+    char  isAttributeSet(XMLCSTR name) const;                        // test if an attribute with a specific name is given
+    XMLCSTR getAttribute(XMLCSTR name, int i) const;                 // return ith attribute content with specific name
+                                                                     //     (return a NULL if failing)
+    XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;           // return next attribute content with specific name
+                                                                     //     (return a NULL if failing)
+    int nAttribute() const;                                          // nbr of attribute
+    XMLClear getClear(int i=0) const;                                // return ith clear field (comments)
+    int nClear() const;                                              // nbr of clear field
+    XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;   // create XML string starting from current XMLNode
+                                                                     // if nFormat==0, no formatting is required
+                                                                     // otherwise this returns an user friendly XML string from a
+                                                                     // given element with appropriate white spaces and carriage returns.
+                                                                     // if pnSize is given it returns the size in character of the string.
+    XMLError writeToFile(XMLCSTR filename, const char *encoding=NULL, char nFormat=1) const;
+                                                                     // save the content of an xmlNode inside a file.
+                                                                     // the nFormat parameter has the same meaning as in the
+                                                                     // createXMLString function. If "strictUTF8Parsing=1", the
+                                                                     // the encoding parameter is ignored and always set to
+                                                                     // "utf-8". If "_XMLUNICODE=1", the encoding parameter is
+                                                                     // ignored and always set to "utf-16".
+    XMLNodeContents enumContents(int i) const;                       // enumerate all the different contents (attribute,child,text,
+                                                                     //     clear) of the current XMLNode. The order is reflecting
+                                                                     //     the order of the original file/string.
+                                                                     //     NOTE: 0 <= i < nElement();
+    int nElement() const;                                            // nbr of different contents for current node
+    char isEmpty() const;                                            // is this node Empty?
+    char isDeclaration() const;                                      // is this node a declaration <? .... ?>
+
+// to allow shallow/fast copy:
+    ~XMLNode();
+    XMLNode(const XMLNode &A);
+    XMLNode& operator=( const XMLNode& A );
+
+    XMLNode(): d(NULL){};
+    static XMLNode emptyXMLNode;
+    static XMLClear emptyXMLClear;
+    static XMLAttribute emptyXMLAttribute;
+
+    // The following functions allows you to create from scratch (or update) a XMLNode structure
+    // Start by creating your top node with the "createXMLTopNode" function and then add new nodes with the "addChild" function.
+    // The parameter 'pos' gives the position where the childNode, the text or the XMLClearTag will be inserted.
+    // The default value (pos=-1) inserts at the end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end).
+    // REMARK: 0 <= pos < nChild()+nText()+nClear()
+    XMLNode       addChild(XMLCSTR lpszName, char isDeclaration=FALSE, int pos=-1);
+    XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);
+    XMLCSTR       addText(XMLCSTR lpszValue, int pos=-1);
+    XMLClear     *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, int pos=-1);
+                                                                    // default values: lpszOpen=XMLNode::getClearTagTable()->lpszOpen;
+                                                                    //                 lpszClose=XMLNode::getClearTagTable()->lpszClose;
+    XMLNode       addChild(XMLNode nodeToAdd, int pos=-1);          // If the "nodeToAdd" has some parents, it will be detached
+                                                                    // from it's parents before being attached to the current XMLNode
+    // Some update functions:
+    XMLCSTR       updateName(XMLCSTR lpszName);                                                    // change node's name
+    XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);         // if the attribute to update is missing, a new one will be added
+    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);         // if the attribute to update is missing, a new one will be added
+    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);  // set lpszNewName=NULL if you don't want to change the name of the attribute
+                                                                                                   // if the attribute to update is missing, a new one will be added
+    XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                       // if the text to update is missing, a new one will be added
+    XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                          // if the text to update is missing, a new one will be added
+    XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                    // if the clearTag to update is missing, a new one will be added
+    XMLClear     *updateClear(XMLClear *newP,XMLClear *oldP);                                      // if the clearTag to update is missing, a new one will be added
+    XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                         // if the clearTag to update is missing, a new one will be added
+
+    // Some deletion functions:
+    void deleteNodeContent(char force=0);  // delete the content of this XMLNode and the subtree.
+                                           // if force=0, while (references to this node still exist), no memory free occurs
+                                           // if force=1, always delete the content of this XMLNode and the subtree and free associated memory
+    void deleteAttribute(XMLCSTR lpszName);
+    void deleteAttribute(int i=0);
+    void deleteAttribute(XMLAttribute *anAttribute);
+    void deleteText(int i=0);
+    void deleteText(XMLCSTR lpszValue);
+    void deleteClear(int i=0);
+    void deleteClear(XMLClear *p);
+    void deleteClear(XMLCSTR lpszValue);
+
+    // The strings given as parameters for the following add and update methods (all these methods have
+    // a name with the postfix "_WOSD" that means "WithOut String Duplication" ) will be free'd by the
+    // XMLNode class. For example, it means that this is incorrect:
+    //    xNode.addText_WOSD("foo");
+    //    xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
+    // In opposition, this is correct:
+    //    xNode.addText("foo");
+    //    xNode.addText_WOSD(stringDup("foo"));
+    //    xNode.updateAttribute("#newcolor" ,NULL,"color");
+    //    xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
+    // Typically, you will never do:
+    //    char *b=(char*)malloc(...);
+    //    xNode.addText(b);
+    //    free(b);
+    // ... but rather:
+    //    char *b=(char*)malloc(...);
+    //    xNode.addText_WOSD(b);
+    //    ('free(b)' is performed by the XMLNode class)
+
+    static XMLNode createXMLTopNode_WOSD(XMLCSTR lpszName, char isDeclaration=FALSE);
+    XMLNode        addChild_WOSD(XMLCSTR lpszName, char isDeclaration=FALSE, int pos=-1);
+    XMLAttribute  *addAttribute_WOSD(XMLCSTR lpszName, XMLCSTR lpszValue);
+    XMLCSTR        addText_WOSD(XMLCSTR lpszValue, int pos=-1);
+    XMLClear      *addClear_WOSD(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, int pos=-1);
+
+    XMLCSTR        updateName_WOSD(XMLCSTR lpszName);
+    XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);
+    XMLAttribute  *updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);
+    XMLAttribute  *updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);
+    XMLCSTR        updateText_WOSD(XMLCSTR lpszNewValue, int i=0);
+    XMLCSTR        updateText_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);
+    XMLClear      *updateClear_WOSD(XMLCSTR lpszNewContent, int i=0);
+    XMLClear      *updateClear_WOSD(XMLClear *newP,XMLClear *oldP);
+    XMLClear      *updateClear_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);
+
+    // These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
+    // middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
+    // methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
+    int positionOfText(int i=0) const;
+    int positionOfText(XMLCSTR lpszValue) const;
+    int positionOfClear(int i=0) const;
+    int positionOfClear(XMLCSTR lpszValue) const;
+    int positionOfClear(XMLClear *a) const;
+    int positionOfChildNode(int i=0) const;
+    int positionOfChildNode(XMLNode x) const;
+    int positionOfChildNode(XMLCSTR name, int i=0) const; // return the position of the ith childNode with the specified name
+                                                          // if (name==NULL) return the position of the ith childNode
+
+    // The setGlobalOptions function allows you to change two global parameters that affect string&file
+    // parsing. First of all, you most-probably will never have to change these 2 global parameters.
+    // About the "guessUnicodeChars" parameter:
+    //     If "guessUnicodeChars=1" and if this library is compiled in UNICODE mode, then the
+    //     "parseFile" and "openFileHelper" functions will test if the file contains ASCII
+    //     characters. If this is the case, then the file will be loaded and converted in memory to
+    //     UNICODE before being parsed. If "guessUnicodeChars=0", no conversion will
+    //     be performed.
+    //
+    //     If "guessUnicodeChars=1" and if this library is compiled in ASCII/UTF8 mode, then the
+    //     "parseFile" and "openFileHelper" functions will test if the file contains UNICODE
+    //     characters. If this is the case, then the file will be loaded and converted in memory to
+    //     ASCII/UTF8 before being parsed. If "guessUnicodeChars=0", no conversion will
+    //     be performed
+    //
+    //     Sometime, it's useful to set "guessUnicodeChars=0" to disable any conversion
+    //     because the test to detect the file-type (ASCII/UTF8 or UNICODE) may fail (rarely).
+    //
+    // About the "strictUTF8Parsing" parameter:
+    //     If "strictUTF8Parsing=0" then we assume that all characters have the same length of 1 byte.
+    //     If "strictUTF8Parsing=1" then the characters have different lengths (from 1 byte to 4 bytes)
+    //     depending on the content of the first byte of the character.
+    // About the "dropWhiteSpace" parameter:
+    //
+
+    static void setGlobalOptions(char guessUnicodeChars=1, char strictUTF8Parsing=1, char dropWhiteSpace=1);
+
+    // The next function try to guess if the character encoding is UTF-8. You most-probably will never
+    // have to use this function. It then returns the appropriate value of the global parameter
+    // "strictUTF8Parsing" described above. The guess is based on the content of a buffer of length
+    // "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
+    // file to be parsed. The "openFileHelper" function is using this function to automatically compute
+    // the value of the "strictUTF8Parsing" global parameter. There are several heuristics used to do the
+    // guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
+    // forbids to use this attribute to do the guess but you can still use it if you set
+    // "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
+
+    static char guessUTF8ParsingParameterValue(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
+
+  private:
+
+// these are functions and structures used internally by the XMLNode class (don't bother about them):
+
+      typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
+      {
+          XMLCSTR                lpszName;        // Element name (=NULL if root)
+          int                    nChild,          // Number of child nodes
+                                 nText,           // Number of text fields
+                                 nClear,          // Number of Clear fields (comments)
+                                 nAttribute;      // Number of attributes
+          char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
+          struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
+          XMLNode                *pChild;         // Array of child nodes
+          XMLCSTR                *pText;          // Array of text fields
+          XMLClear               *pClear;         // Array of clear fields
+          XMLAttribute           *pAttribute;     // Array of attributes
+          int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
+          int                    ref_count;       // for garbage collection (smart pointers)
+      } XMLNodeData;
+      XMLNodeData *d;
+
+      char parseClearTag(void *px, ALLXMLClearTag *pa);
+      char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
+      int ParseXMLElement(void *pXML);
+      void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
+      int indexText(XMLCSTR lpszValue) const;
+      int indexClear(XMLCSTR lpszValue) const;
+      XMLNode addChild_priv(int,XMLCSTR,char,int);
+      XMLAttribute *addAttribute_priv(int,XMLCSTR,XMLCSTR);
+      XMLCSTR addText_priv(int,XMLCSTR,int);
+      XMLClear *addClear_priv(int,XMLCSTR,XMLCSTR,XMLCSTR,int);
+      static inline int findPosition(XMLNodeData *d, int index, XMLElementType xtype);
+      static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
+      static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
+      static void exactMemory(XMLNodeData *d);
+      static int detachFromParent(XMLNodeData *d);
+} XMLNode;
+
+// This structure is given by the function "enumContents".
+typedef struct XMLNodeContents
+{
+    // This dictates what's the content of the XMLNodeContent
+    enum XMLElementType type;
+    // should be an union to access the appropriate data.
+    // compiler does not allow union of object with constructor... too bad.
+    XMLNode child;
+    XMLAttribute attrib;
+    XMLCSTR text;
+    XMLClear clear;
+
+} XMLNodeContents;
+
+DLLENTRY void free_XMLDLL(void *t); // {free(t);}
+
+// Duplicate (copy in a new allocated buffer) the source string. This is
+// a very handy function when used with all the "XMLNode::*_WOSD" functions.
+// (If (cbData!=0) then cbData is the number of chars to duplicate)
+DLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=0);
+
+// The 3 following functions are processing strings so that all the characters
+// &,",',<,> are replaced by their XML equivalent: &amp;, &quot;, &apos;, &lt;, &gt;.
+// These 3 functions are useful when creating from scratch an XML file using the
+// "printf", "fprintf", "cout",... functions. If you are creating from scratch an
+// XML file using the provided XMLNode class you cannot use these functions (the
+// XMLNode class does the processing job for you during rendering). The second
+// function ("toXMLStringFast") allows you to re-use the same output buffer
+// for all the conversions so that only a few memory allocations are performed.
+// If the output buffer is too small to contain thee resulting string, it will
+// be enlarged.
+DLLENTRY XMLSTR toXMLString(XMLCSTR source);
+DLLENTRY XMLSTR toXMLStringFast(XMLSTR *destBuffer,int *destSz, XMLCSTR source);
+
+// you should not use this one (there is a possibility of "destination-buffer-overflow"):
+DLLENTRY XMLSTR toXMLString(XMLSTR dest,XMLCSTR source);
+
+// Below is a class that allows you to include any binary data (images, sounds,...)
+// into an XML document using "Base64 encoding". This class is completely
+// separated from the rest of the xmlParser library and can be removed without any problem.
+// To include some binary data into an XML file, you must convert the binary data into
+// standard text (using "encode"). To retrieve the original binary data from the
+// b64-encoded text included inside the XML file use "decode". Alternatively, these
+// functions can also be used to "encrypt/decrypt" some critical data contained inside
+// the XML.
+
+class DLLENTRY XMLParserBase64Tool
+{
+public:
+    XMLParserBase64Tool(): buf(NULL),buflen(0){}
+    ~XMLParserBase64Tool();
+
+    void freeBuffer();
+
+    // returns the length of the base64 string that encodes a data buffer of size inBufLen bytes.
+    // If "formatted" parameter is true, some space will be reserved for a carriage-return every 72 chars.
+    static int encodeLength(int inBufLen, char formatted=0);
+
+    // The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
+    // from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
+    // The string will be free'd when the XMLParserBase64Tool object is deleted.
+    // All returned strings are sharing the same memory space.
+    XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0);
+
+    // returns the number of bytes which will be decoded from "inString".
+    static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
+
+    // returns a pointer to a buffer containing the binary data decoded from "inString"
+    // If "inString" is malformed NULL will be returned
+    // The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
+    // All output buffer are sharing the same memory space.
+    unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL);
+
+    // The next function is deprecated.
+    // decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
+    // in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
+    // will be returned; otherwise "TRUE".
+    static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL);
+
+private:
+    void *buf;
+    int buflen;
+    void alloc(int newsize);
+};
+
+#undef  DLLENTRY
+
+#endif
diff --git a/packages/CMakeLists.txt b/packages/CMakeLists.txt
new file mode 100644 (file)
index 0000000..026d707
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+#-----------------------------------------------------------------------------
+SUBDIRS(wx)
+#SUBDIRS(std)
+#-----------------------------------------------------------------------------
diff --git a/packages/wx/CMakeLists.txt b/packages/wx/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cb15efa
--- /dev/null
@@ -0,0 +1,105 @@
+
+#-----------------------------------------------------------------------------
+# THE NAME OF THE BBTK PACKAGE = NAME OF THE CURRENT DIRECTORY
+GET_FILENAME_COMPONENT(BBTK_PACKAGE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+#-----------------------------------------------------------------------------
+# DOES THE USER WANT TO BUILD THE PACKAGE ?
+OPTION(BUILD_BBTK_PACKAGE_${BBTK_PACKAGE_NAME} 
+  "Build the bbtk package ${BBTK_PACKAGE_NAME}" OFF)
+#SWITCH_ON_IF_BUILD_ALL(BUILD_BBTK_PACKAGE_${PACKAGE_NAME})
+#-----------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------
+# IF THE USER HAS CHOSEN TO BUILD THE PACKAGE
+IF(BUILD_BBTK_PACKAGE_${BBTK_PACKAGE_NAME})
+  #---------------------------------------------------------------------------
+
+
+  #===========================================================================
+  # SET(${BBTK_PACKAGE_NAME}_USE_VTK  ON)
+  # SET(${BBTK_PACKAGE_NAME}_USE_ITK  ON)
+  # SET(${BBTK_PACKAGE_NAME}_USE_GDCM ON)
+  # SET(${BBTK_PACKAGE_NAME}_USE_GSMIS ON)
+  SET(${BBTK_PACKAGE_NAME}_USE_WXWIDGETS ON)
+  #===========================================================================
+
+
+
+
+  #===========================================================================
+  # USER SECTION
+  #===========================================================================
+
+  #===========================================================================
+  # PACKAGE AUTHOR
+  # !!! NO COMMA ALLOWED !!!
+  SET(BBTK_PACKAGE_AUTHOR "eduardo.davila/laurent.guigues@creatis.insa-lyon.fr")
+  #===========================================================================
+
+  #===========================================================================
+  # PACKAGE DESCRIPTION
+  SET(BBTK_PACKAGE_DESCRIPTION "Basic graphical interface elements (sliders, buttons ...) based on wxWidgets")
+  #===========================================================================
+
+  #===========================================================================
+  # PACKAGE VERSION NUMBER 
+  SET(BBTK_PACKAGE_MAJOR_VERSION 1)
+  SET(BBTK_PACKAGE_MINOR_VERSION 0)
+  SET(BBTK_PACKAGE_BUILD_VERSION 0)
+  #===========================================================================
+
+
+  #===========================================================================
+  # THE SOURCES OF THE PACKAGE
+  # EITHER UNCOMMENT NEXT LINE TO COMPILE ALL .cxx OF THE DIRECTORY :
+  SET(BBTK_PACKAGE_COMPILE_ALL_CXX ON)
+  # ... OR LIST THE FILES TO COMPILE MANUALLY :
+  #SET(PACKAGE_SOURCES
+    # LIST HERE THE FILES TO COMPILE TO BUILD THE LIB
+    # E.G. TO COMPILE "toto.cxx" ADD "toto" (NO EXTENSION)
+  #    )
+  #===========================================================================
+  
+
+  #===========================================================================
+  INCLUDE_DIRECTORIES(
+    # LIST HERE YOUR INCLUDE DIRECTORIES (EXCEPT BBTK'S)
+    # (Of course, if you build a package outside bbtk, 
+    #  you have to list *all* the include directories -including BBTK's-)    
+    )
+  #===========================================================================
+
+  
+  #===========================================================================
+  SET(BBTK_PACKAGE_LIBS 
+    # LIST HERE THE LIBS TO LINK AGAINST (EXCEPT BBTK)
+    )
+  #===========================================================================
+  
+  #===========================================================================
+  # END OF USER SECTION 
+  # NOTHING INTERESTING FOR YOU BELOW
+  #===========================================================================
+  
+  
+  #---------------------------------------------------------------------------
+  # Include global configuration cmake script
+  INCLUDE(${BBTK_DIR}/BBTKConfigurePackage.cmake)
+  #---------------------------------------------------------------------------
+
+
+  #---------------------------------------------------------------------------
+  # Recurse into subdirs
+  SUBDIRS(src)
+#  SUBDIRS(doc)
+#  SUBDIRS(scripts)
+  #---------------------------------------------------------------------------
+
+  #---------------------------------------------------------------------------
+ENDIF(BUILD_BBTK_PACKAGE_${BBTK_PACKAGE_NAME})
+#-----------------------------------------------------------------------------
+# EOF
+#-----------------------------------------------------------------------------
+
+
diff --git a/packages/wx/bbs/appli/testSlider.bbs b/packages/wx/bbs/appli/testSlider.bbs
new file mode 100644 (file)
index 0000000..96900ea
--- /dev/null
@@ -0,0 +1,6 @@
+description "Simple test of wx::Slider widget"
+author "laurent.guigues@creatis.insa-lyon.fr"
+
+load wx
+new Slider slider
+exec slider
diff --git a/packages/wx/bbs/appli/testSplit.bbs b/packages/wx/bbs/appli/testSplit.bbs
new file mode 100644 (file)
index 0000000..b59e295
--- /dev/null
@@ -0,0 +1,12 @@
+description "Simple test of wx::Split widget"
+author "laurent.guigues@creatis.insa-lyon.fr"
+
+load wx
+new Slider slider1
+new Slider slider2
+new Split main
+
+connect slider1.Widget main.Widget1
+connect slider2.Widget main.Widget2
+
+exec main
diff --git a/packages/wx/src/CMakeLists.txt b/packages/wx/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0230807
--- /dev/null
@@ -0,0 +1,5 @@
+#---------------------------------------------------------------------------
+# Include src configuration cmake script
+INCLUDE(${BBTK_DIR}/BBTKConfigurePackage_src.cmake)
+#---------------------------------------------------------------------------
+
diff --git a/packages/wx/src/bbwxSlider.cxx b/packages/wx/src/bbwxSlider.cxx
new file mode 100644 (file)
index 0000000..557e7b2
--- /dev/null
@@ -0,0 +1,392 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbwxSlider.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ * \file 
+ * \brief Short description in one line
+ *
+ * Long 
+ * description
+ *  
+ */
+
+
+#ifdef _USE_WXWIDGETS_
+
+
+
+#include "bbwxSlider.h"
+#include "bbwxPackage.h"
+
+
+
+
+namespace bbwx
+{
+  
+  //-------------------------------------------------------------------------
+  SliderWidget::SliderWidget(Slider* box, wxWindow *parent,
+                            int orientation,
+                            bool changeresolution,
+                            bool labels,
+                            wxString title,
+                            int vmin,
+                            int vmax,
+                            int value,
+              int reactiveontrack)
+    :  
+    wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL),
+    mBox(box),
+    min(vmin),
+    max(vmax),
+    reactiveOnTrack(reactiveontrack)
+  {
+    wxPanel * panel = this;
+
+    label_min           = NULL;
+    label_max           = NULL;
+    label_vertical      = NULL;
+    mResolutionOfSlider        = NULL;
+    
+    int sizeX,sizeY;
+    long wxlabels=0;
+    long wxorientation=0;
+    if (orientation==0) 
+      {
+       sizeX                   = 2;
+       sizeY                   = 40;
+       wxorientation   = wxSL_HORIZONTAL;
+       if (labels==true)
+         {
+           wxlabels = wxSL_LABELS;
+         }
+      } 
+    else 
+      {
+       sizeX                   = 20;
+       sizeY                   = 2;
+       wxorientation   = wxSL_VERTICAL;
+      }
+    
+    //---------------------------------------------------------------------
+    // 1) Creation of the components of the widget
+    // Any top level sub-widget must have the panel returned by panel
+    // for parent
+    mwxSlider = new wxSlider( panel, 
+                             -1, 0 , 0, 500 , 
+                             wxDefaultPosition, 
+                             wxSize(sizeX,sizeY), 
+                             wxorientation  | wxlabels );
+
+    //    mwxSlider->SetInitialSize(wxSize(sizeX,sizeY));
+
+    // mwxSlider->SetTickFreq(100,0);
+    mwxSlider->SetRange(min,max);
+    mwxSlider->SetValue(value);
+
+    //    RefreshLabels();
+
+    // Connecting events to callbacks
+    Connect( mwxSlider->GetId(), 
+            wxEVT_SCROLL_THUMBRELEASE, 
+
+            (wxObjectEventFunction) 
+            (void (wxPanel::*)(wxScrollEvent&))
+            &SliderWidget::OnSliderRelease ); 
+
+    Connect( mwxSlider->GetId(),  
+            wxEVT_SCROLL_THUMBTRACK, 
+
+            (wxObjectEventFunction) 
+            (void (wxPanel::*)(wxScrollEvent&))
+             &SliderWidget::OnSliderTrack ); 
+    
+
+    // If asked : creation of the other little slider which allows to change 
+    // the resolution of the main slider
+    if (changeresolution==true){
+      // has panel for parent too
+      mResolutionOfSlider = new wxSlider(panel,
+                                        -1,5,1,10,
+                                        wxDefaultPosition,
+                                        wxSize(25,45),
+                                        wxSL_VERTICAL | 
+                                        wxSL_AUTOTICKS |
+                                        wxSL_LEFT  );
+   
+
+      mResolutionOfSlider->SetRange(1,8);
+      mResolutionOfSlider->SetValue(5);
+      // Is wxEVT_COMMAND_SLIDER_UPDATED event 
+      // is connected to the method OnResolutionOfSlider
+      Connect(mResolutionOfSlider->GetId(),
+             wxEVT_COMMAND_SLIDER_UPDATED,
+             (wxObjectEventFunction) 
+             (void (wxPanel::*)(wxScrollEvent&))
+             &SliderWidget::OnResolutionOfSlider ); 
+    }
+    //---------------------------------------------------------------------
+
+    //---------------------------------------------------------------------
+    // 2) Insertion of the components in the window
+    
+    // We use a FlexGridSizer
+    wxFlexGridSizer *sizer;
+
+
+    if (orientation==0) 
+      {
+       // HORIZONTAL
+       if (mResolutionOfSlider!=NULL) 
+         {
+           sizer       = new wxFlexGridSizer(2);
+           if (title!=_T(""))
+             {
+               sizer   -> Add( new wxStaticText(panel,-1, title ) ); 
+               sizer   -> Add( new wxStaticText(panel,-1, _T("") ) ); 
+             }
+         } 
+       else 
+         {
+           sizer       = new wxFlexGridSizer(1);
+           if (title!=_T(""))
+             {
+               sizer   -> Add( new wxStaticText(panel,-1, title ) ); 
+             }
+         }
+       sizer   -> Add( mwxSlider,1,wxGROW ); 
+       sizer   -> AddGrowableCol(0);
+       if (mResolutionOfSlider!=NULL) 
+         {
+           sizer       -> Add( mResolutionOfSlider ); 
+         }
+      } 
+    else 
+      {
+       // VERTICAL 
+       sizer   = new wxFlexGridSizer(1);
+       if (labels==true)  // with lable
+         {
+           label_vertical = new wxStaticText(panel,-1,_T(""));
+           label_min = new wxStaticText(panel,-1,_T(""));
+           label_max = new wxStaticText(panel,-1,_T(""));
+           if (title!=_T(""))
+             {
+               sizer   -> Add( new wxStaticText(panel,-1, title ) );
+               sizer   -> AddGrowableRow(3);
+             } 
+           else 
+             {
+               sizer   -> AddGrowableRow(2);
+             }
+           sizer       -> Add( label_vertical );
+           sizer       -> Add( label_min );
+           sizer       -> Add( mwxSlider,1,wxGROW );
+           sizer       -> Add( label_max );
+           if (mResolutionOfSlider!=NULL) 
+             {
+               sizer   -> Add( mResolutionOfSlider ); 
+             }
+         } 
+       else 
+         {
+           if (title!=_T(""))
+             {
+               sizer   -> Add( new wxStaticText(panel,-1, title ) );
+               sizer   -> AddGrowableRow(1);
+             } 
+           else 
+             {
+               sizer   -> AddGrowableRow(0);
+             }
+           sizer       -> Add( mwxSlider,1,wxGROW );
+           if (mResolutionOfSlider!=NULL) 
+             {
+               sizer   -> Add( mResolutionOfSlider ); 
+             }
+         }
+      }
+    // Initialize the labels 
+    RefreshLabels();  
+    // Insert the sizer in the main panel and refresh the layout
+    panel->SetSizer(sizer);
+    //   panel->SetAutoLayout(true);
+    //    panel->Layout();
+  }
+  //-------------------------------------------------------------------------
+  
+
+  //-------------------------------------------------------------------------
+  SliderWidget::~SliderWidget()
+  {
+  }
+  //-------------------------------------------------------------------------
+
+
+  //-------------------------------------------------------------------------
+  void SliderWidget::OnResolutionOfSlider(wxScrollEvent& event)
+  {
+    int value = mwxSlider->GetValue();
+    int delta = (int) (pow( 4 , mResolutionOfSlider->GetValue() ));
+    int minTmp   = value - delta/2;
+    int maxTmp   = value + delta/2;
+    if (minTmp<min)
+      {
+       minTmp = min;
+       //              maxTmp = delta;
+      }
+    if (maxTmp>max)
+      {
+       maxTmp = max;
+      }
+    mwxSlider->SetRange(minTmp,maxTmp);
+    RefreshLabels();
+  }
+  //-------------------------------------------------------------------------
+
+
+
+  //-------------------------------------------------------------------------
+  void SliderWidget::OnSliderTrack(wxScrollEvent& event)
+  {
+    if(reactiveOnTrack)
+    {
+    // When user releases the slider 
+    // we update the output of the box
+    mBox->bbSetOutputOut( mwxSlider->GetValue() );
+    mBox->bbSetInputIn( mwxSlider->GetValue() );
+    // and signal that the output has changed
+    mBox->bbSignalOutputModification("Out");    
+    }
+    RefreshLabels();  
+  }
+  //-------------------------------------------------------------------------
+
+
+  //-------------------------------------------------------------------------
+  void SliderWidget::OnSliderRelease(wxScrollEvent& event)
+  {
+    // When user releases the slider 
+    // we update the output of the box
+    mBox->bbSetOutputOut( mwxSlider->GetValue() );
+    mBox->bbSetInputIn( mwxSlider->GetValue() );
+    // and signal that the output has changed
+    mBox->bbSignalOutputModification("Out");
+  }
+  //-------------------------------------------------------------------------
+  
+
+  //-------------------------------------------------------------------------
+  void SliderWidget::RefreshLabels()
+  {
+    wxString strValue;
+    if (label_vertical!=NULL)
+      {
+       strValue.Printf( _T("%d"), mwxSlider->GetValue() );
+       label_vertical->SetLabel(strValue);
+      }
+    if (label_min!=NULL)
+      {
+       strValue.Printf( _T("%d"), mwxSlider->GetMin() );
+       label_min->SetLabel(strValue);
+      }
+    if (label_max!=NULL)
+      {
+       strValue.Printf( _T("%d"), mwxSlider->GetMax() );
+       label_max->SetLabel(strValue);
+      }  
+  }
+  //-------------------------------------------------------------------------
+  
+
+  //-------------------------------------------------------------------------
+  void SliderWidget::SetRange(int min, int max)
+  {
+    this->min = min;
+    this->max = max;
+    mwxSlider->SetRange(min,max);
+    RefreshLabels();
+  }
+  //-------------------------------------------------------------------------
+
+
+
+  //--------------------------------------------------------------------------
+  //-------------------------------------------------------------------------
+  // WxBlackBox implementation
+  //--------------------------------------------------------------------------
+  //--------------------------------------------------------------------------
+
+  //--------------------------------------------------------------------------
+  BBTK_USER_BLACK_BOX_IMPLEMENTATION(Slider,bbtk::WxBlackBox);
+  BBTK_ADD_BLACK_BOX_TO_PACKAGE(wx,Slider);
+  //--------------------------------------------------------------------------
+
+  //--------------------------------------------------------------------------
+  void Slider::bbUserConstructor() 
+  { 
+    bbSetInputIn(0);
+    bbSetInputMin(0);
+    bbSetInputMax(500);
+    bbSetOutputOut(0);
+    bbSetInputOrientation(0);
+    bbSetInputChangeResolution(false);
+    bbSetInputLabel(true);
+    bbSetInputReactiveOnTrack(0);    
+  }
+  //--------------------------------------------------------------------------
+
+  //--------------------------------------------------------------------------
+  void Slider::Process() 
+  {
+    int val = bbGetInputIn();
+    bbSetOutputOut( bbGetInputIn() );
+
+    if (bbGetOutputWidget()==0) 
+      {
+       bbSetOutputWidget( new SliderWidget(this, 
+                                           bbGetWxParent(),
+                                           bbGetInputOrientation() , 
+                                           bbGetInputChangeResolution(), 
+                                           bbGetInputLabel(), 
+                                           bbtk::std2wx( bbGetInputTitle() ),
+                                           bbGetInputMin(), 
+                                           bbGetInputMax(),
+                                           val,
+                                           bbGetInputReactiveOnTrack()
+                                           )
+                          );
+      }
+  }
+  //--------------------------------------------------------------------------  
+  /*
+  //--------------------------------------------------------------------------
+  bbtk::WxBlackBoxWidget* Slider::bbUserCreateWidget(wxWindow *parent)
+  {
+   
+
+  }
+  //--------------------------------------------------------------------------
+  */
+
+
+} //namespace bbwx
+
+#endif // _USE_WXWIDGETS_ 
+
+
diff --git a/packages/wx/src/bbwxSlider.h b/packages/wx/src/bbwxSlider.h
new file mode 100644 (file)
index 0000000..a0a090f
--- /dev/null
@@ -0,0 +1,176 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbwxSlider.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*//**
+/**
+ * \file 
+ * \brief Short description in one line
+ * 
+ * Long description which 
+ * can span multiple lines
+*/
+
+/**
+ * \class bbwx::Slider
+ * \brief 
+
+ * \class bbwx::SliderWidget
+ * \brief 
+ */
+
+
+#ifdef _USE_WXWIDGETS_
+
+
+// Prevents multiple inclusions : use symbols of the form
+// __FILENAME_INCLUDED__ 
+// where FILENAME must be replaced by the actual file name
+#ifndef __bbwxSlider_h_INCLUDED__
+#define __bbwxSlider_h_INCLUDED__
+
+// Include wxBlackBox definition
+#include "bbtkWxBlackBox.h"
+
+
+
+// Namespace of the package "wx" is "bbwx" 
+// Namespace associated to packages should be of the form :
+// bbPACKAGENAME
+namespace bbwx
+{
+  
+  
+  
+
+
+
+  //--------------------------------------------------------------------------
+  // Forward declaration of the box
+  class Slider;
+  //--------------------------------------------------------------------------
+
+
+
+  
+  //--------------------------------------------------------------------------
+  // The widget created by the box 
+  // Its name should be : BOXNAMEWidget
+  // It should inherit WxBlackBoxWidget or a descendant such as WxBlackBoxWidgetPanel
+  class SliderWidget : public wxPanel //public bbtk::WxBlackBoxWidgetPanel
+  {
+  public:
+    /// Ctor with the two first params the parent window and the creator box
+    /// which must be passed to the WxBlackBoxWidget constructor.
+    /// The other params initialize the widget 
+    SliderWidget(Slider* box, wxWindow *parent,
+                int orientation,
+                bool changeresolution,
+                bool label, 
+                wxString title,
+                int vmin,
+                int vmax,
+                int value,
+       int track);
+    /// Dtor
+    ~SliderWidget();
+    /// Events callbacks
+    /// Called when the slider is moved
+    void OnSliderTrack(wxScrollEvent& event);
+    /// Called when the slider is released
+    void OnSliderRelease(wxScrollEvent& event);
+    /// Called when the little slider which controls the resolution
+    /// of the main slider is moved (if activated)
+    void OnResolutionOfSlider(wxScrollEvent& event);
+
+    // Accessors
+    int  GetValue() { return mwxSlider->GetValue(); }
+    void SetRange(int min, int max);
+    // Update the texts which display the min/max/current values of the slider
+    void RefreshLabels();
+       
+  private:
+    Slider*    mBox;
+    wxSlider   *mwxSlider;
+    wxSlider   *mResolutionOfSlider;
+    int        min;
+    int        max;
+    int        reactiveOnTrack;
+    wxStaticText       *label_vertical;
+    wxStaticText       *label_min;
+    wxStaticText       *label_max;
+  };
+  //------------------------------------------------------------------------
+  //------------------------------------------------------------------------
+  //------------------------------------------------------------------------
+
+  
+  
+  
+  //------------------------------------------------------------------------
+  // The black box
+  class /*BBTK_EXPORT*/ Slider : public bbtk::WxBlackBox
+  {
+    
+    BBTK_USER_BLACK_BOX_INTERFACE(Slider,bbtk::WxBlackBox);
+    BBTK_DECLARE_INPUT(In,int);
+    BBTK_DECLARE_INPUT(Min,int);
+    BBTK_DECLARE_INPUT(Max,int);
+    BBTK_DECLARE_INPUT(Label,bool);
+    BBTK_DECLARE_INPUT(Title,std::string);
+    BBTK_DECLARE_INPUT(Orientation,int);
+    BBTK_DECLARE_INPUT(ChangeResolution,bool);
+    BBTK_DECLARE_INPUT(ReactiveOnTrack,int);    
+    BBTK_DECLARE_OUTPUT(Out,int);
+    BBTK_PROCESS(Process);
+    void Process();
+
+  protected:
+    virtual void bbUserConstructor();
+    
+    //  private:
+    //  virtual bbtk::WxBlackBoxWidget* bbUserCreateWidget(wxWindow *parent);
+  };
+  //=================================================================
+  //=================================================================
+  // the black box description
+  BBTK_BEGIN_DESCRIBE_BLACK_BOX(Slider,bbtk::WxBlackBox);
+  BBTK_NAME("Slider");
+  BBTK_AUTHOR("eduardo.davila@creatis.insa-lyon.fr");
+  BBTK_DESCRIPTION("Slider widget (wxSlider)");
+  BBTK_INPUT(Slider,In,"Initial position of the slider (default 0)",int);
+  BBTK_INPUT(Slider,Min,"Minimum value of the slider (default 0)",int);
+  BBTK_INPUT(Slider,Max,"Maximum value of the slider (default 500)",int);
+  BBTK_INPUT(Slider,Label,"Show slider labels ? (default FALSE) ",bool);
+  BBTK_INPUT(Slider,Title,"Title shown above the slider (default '') ",
+            std::string);
+  BBTK_INPUT(Slider,Orientation,
+            "Orientation : 0=Horizontal / 1=Vertical (default 0)",int);
+  BBTK_INPUT(Slider,ChangeResolution,
+            "Can the user change the resolution of the slider ? (default FALSE) ",bool);
+  BBTK_INPUT(Slider,ReactiveOnTrack,
+            "Slider sends info when track moves (default 0 = no)",int);  
+  BBTK_OUTPUT(Slider,Out,"Current position of the slider",int);
+  BBTK_END_DESCRIBE_BLACK_BOX(Slider);
+  //=================================================================
+  
+
+
+} //namespace bbwx
+
+#endif  //__bbtkwxSlider_h_INCLUDED__
+
+#endif //_USE_WXWIDGETS_
diff --git a/packages/wx/src/bbwxSplit.cxx b/packages/wx/src/bbwxSplit.cxx
new file mode 100644 (file)
index 0000000..ed66134
--- /dev/null
@@ -0,0 +1,196 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbwxSplit.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+/**
+ *  \file 
+ *  \brief 
+ */
+
+
+#ifdef _USE_WXWIDGETS_
+
+#include "bbwxSplit.h"
+#include "bbwxPackage.h"
+
+//#include "bbtk
+
+namespace bbwx
+{
+  BBTK_ADD_BLACK_BOX_TO_PACKAGE(wx,Split);
+  /*
+  //-------------------------------------------------------------------------
+  SplitWidget::SplitWidget(Split* box,
+                          wxWindow *parent,
+                          int orientation)
+    :
+    WxBlackBoxWidgetPanel(box,parent), 
+    mOrientation(orientation)
+    //( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
+  {
+    wxPanel    *panel                  = this->GetPanel();
+    mwxSplitterWindow          = new wxSplitterWindow(panel,-1,
+                                                      wxDefaultPosition,
+                                                      wxDefaultSize, 
+                                                      wxSP_3D | 
+                                                      wxSP_LIVE_UPDATE );
+    
+    wxBoxSizer *sizer          = new wxBoxSizer(wxVERTICAL);
+    sizer      ->      Add(mwxSplitterWindow, 1, wxGROW, 0);
+#if defined(_WIN32)
+ //mwxSplitterWindow -> SetMinimumPaneSize(25);
+#else
+   mwxSplitterWindow -> SetMinimumPaneSize(25);
+#endif // defined(_WIN32) 
+
+    panel      ->      SetSizer(sizer);
+    panel      ->      SetAutoLayout(true);
+    panel      ->      Layout();
+  }
+  //-------------------------------------------------------------------------
+
+  //-------------------------------------------------------------------------
+  void  SplitWidget::SetChilds(wxWindow* child1,wxWindow* child2,
+                                int prop)
+  {
+    if (mwxSplitterWindow->IsSplit()) return;
+    if (mOrientation==0)
+      {
+       int sz =  (int)(GetParent()->GetSize().GetHeight() * prop * 0.01);
+       mwxSplitterWindow->SplitHorizontally( child1 , child2, sz);
+      } 
+    else 
+      {
+       int sz =  (int)(GetParent()->GetSize().GetWidth() * prop * 0.01);
+       mwxSplitterWindow->SplitVertically( child1 , child2, sz );
+      }
+
+
+  }
+  
+  SplitWidget::~SplitWidget()
+  {
+  }
+  
+
+  //-------------------------------------------------------------------------
+  wxSplitterWindow *SplitWidget::GetWxSplitterWindow()
+  {
+    return mwxSplitterWindow;
+  }
+  
+  */
+  //--------------------------------------------------------------------------
+  //-------------------------------------------------------------------------
+  //--------------------------------------------------------------------------
+  //--------------------------------------------------------------------------
+
+
+  BBTK_USER_BLACK_BOX_IMPLEMENTATION(Split,bbtk::WxBlackBox);
+  
+
+  void Split::bbUserConstructor() 
+  { 
+    bbSetInputOrientation(0);
+    bbSetInputProportion(50);
+  }
+
+  void Split::Process() 
+  { 
+    bbtkDebugMessageInc("Core",9,"Split::Process()"<<std::endl);
+
+    if (bbGetOutputWidget()==0) 
+      {
+       
+       
+       wxSplitterWindow* w = new wxSplitterWindow(bbGetWxParent(),
+                                                  -1,
+                                                  wxDefaultPosition,
+                                                  wxDefaultSize, 
+                                                  //wxSize(400,200),
+                                                  wxSP_3D | 
+                                                  wxSP_LIVE_UPDATE );
+       wxWindow* w1 = bbGetInputWidget1();
+       wxWindow* w2 = bbGetInputWidget2();
+       //w->SetInitialSize(wxSize(100,100));
+       //    int sz =  (int)(GetParent()->GetSize().GetHeight() * prop * 0.01);
+       w1->Reparent(w);
+       w2->Reparent(w);
+       w->SplitHorizontally( w1, w2, 100);
+       //w->SetMinimumPaneSize(100);
+       // w->SetAutoLayout(true);
+       // w->Fit();
+       // w->Layout();
+       
+
+       bbSetOutputWidget( w );
+      }
+  }
+  
+  
+  /**
+   * \brief  Create wxWidget . 
+   *
+   *
+   */ 
+  /*
+  bbtk::WxBlackBoxWidget *Split::bbUserCreateWidget(wxWindow *parent)
+  {
+    //printf("EED Split::CreateWxWindow \n" );
+    bbtkDebugMessageInc("Core",9,"Split::bbUserCreateWidget("<<parent<<")"<<std::endl);
+    
+    SplitWidget *wxwidgetsplit = new SplitWidget(this, parent , 
+                                                bbGetInputOrientation() );
+
+    OutputConnectorMapType::iterator i;
+    for (i=bbGetOutputConnectorMap().begin() ; i!=bbGetOutputConnectorMap().end(); ++i )
+      {
+       if (i->first=="WinChild")
+         {
+           const std::vector<bbtk::Connection*>& C = i->second->GetConnectionVector();
+           std::vector<bbtk::Connection*>::const_iterator j;
+           j = C.begin();
+           if (C.size()==2)
+             {
+               wxPanel *w1 = new wxPanel(wxwidgetsplit->GetWxSplitterWindow() ,-1 );
+               wxPanel *w2 = new wxPanel(wxwidgetsplit->GetWxSplitterWindow() ,-1 );
+               bbtkDebugMessage("Debug",1,"Creating panel for "<<(*j)->GetFullName());
+               bbmOutputWinChild->AddToConnectionToWindowMap(*j,w1);
+               bbtkDebugMessage("Debug",1,"..OK"<<std::endl);
+               j++;
+               bbtkDebugMessage("Debug",1,"Creating panel for "<<(*j)->GetFullName());
+               bbmOutputWinChild->AddToConnectionToWindowMap(*j,w2);
+
+               bbtkDebugMessage("Debug",1,"..OK"<<std::endl);
+               wxwidgetsplit->SetChilds( w1 , w2, bbGetInputProportion() );
+             } // if C
+           break;
+         }// if Child
+      }// if i
+    //
+    
+
+    bbtkDebugDecTab("Core",9);
+
+    return wxwidgetsplit;
+
+      }
+  */
+
+}//namespace bbtk
+
+#endif // _USE_WXWIDGETS_ 
+
diff --git a/packages/wx/src/bbwxSplit.h b/packages/wx/src/bbwxSplit.h
new file mode 100644 (file)
index 0000000..ded5330
--- /dev/null
@@ -0,0 +1,117 @@
+/*=========================================================================
+                                                                                
+  Program:   bbtk
+  Module:    $RCSfile: bbwxSplit.h,v $
+  Language:  C++
+  Date:      $Date: 2008/01/22 15:02:00 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*//**
+ * \brief Short description in one line
+ * 
+ * Long description which 
+ * can span multiple lines
+ */
+/**
+ * \file 
+ * \brief Pattern for the definition of a new type of Node (header)
+ */
+/**
+ * \class bbtk::NodePatern 
+ * \brief Pattern for the definition of a new type of Node 
+ */
+
+
+#ifdef _USE_WXWIDGETS_
+
+
+#ifndef __bbWxSplit_h__
+#define __bbWxSplit_h__
+
+#include "bbtkWxBlackBox.h"
+#include <wx/splitter.h>
+
+
+
+namespace bbwx
+{
+  
+  
+  /*
+  
+  class Split;
+  
+  //--------------------------------------------------------------------------
+  class SplitWidget : public bbtk::WxBlackBoxWidgetPanel 
+  {
+  public:
+    
+    SplitWidget(Split* bbtksplit, wxWindow *parent, int orientation);
+    ~SplitWidget();
+
+    void SetChilds(wxWindow* child1, 
+                  wxWindow* child2,
+                  int proportion);
+
+    wxSplitterWindow *GetWxSplitterWindow();
+    //   void SetProportion(int prop);
+    
+  private:
+    int                        mOrientation;
+    wxSplitterWindow   *mwxSplitterWindow;
+  };
+  
+  //------------------------------------------------------------------------
+  //------------------------------------------------------------------------
+  //------------------------------------------------------------------------
+
+  
+  */
+  
+  
+  class Split : public bbtk::WxBlackBox
+  {
+    
+    BBTK_USER_BLACK_BOX_INTERFACE(Split,bbtk::WxBlackBox);
+    BBTK_DECLARE_INPUT(Widget1,wxWindow*);
+    BBTK_DECLARE_INPUT(Widget2,wxWindow*);
+    BBTK_DECLARE_INPUT(Orientation,int);
+    BBTK_DECLARE_INPUT(Proportion,int);
+    BBTK_PROCESS(Process);
+    // BBTK_CREATE_WIDGET(CreateWidget);
+    
+    void Process();
+    //    void CreateWidget();
+
+  protected:
+    virtual void bbUserConstructor();
+
+  };
+  
+//=================================================================
+// UserBlackBox description
+  BBTK_BEGIN_DESCRIBE_BLACK_BOX(Split,bbtk::WxBlackBox);
+  BBTK_NAME("Split");
+  BBTK_AUTHOR("laurent.guigues@creatis.insa-lyon.fr");
+  BBTK_DESCRIPTION("Widget which splits a window in two fixed size parts (wxSplitterWindow)");
+  BBTK_INPUT(Split,Widget1,"Upper or left widget",wxWindow*);
+  BBTK_INPUT(Split,Widget2,"Lower or right widget",wxWindow*);
+  BBTK_INPUT(Split,Orientation,"Orientation (default 0), 0=Horizontal , 1=Vertical",int);
+   BBTK_INPUT(Split,Proportion,"Proportion (in percent) of the first children in the window",int);
+  BBTK_END_DESCRIBE_BLACK_BOX(Split);
+  //=================================================================
+}
+
+//namespace bbtk
+#endif  //__bbtkWxSplit_h__
+
+#endif //_USE_WXWIDGETS_