/* appl.cc */

// #include <typeinfo>
// #include <iostream>

#include "plugin-conf.h" // symbol DYNAMIC_PLUGINS, symbols <...>_PLUGIN
#include "view-conf.h" // recompile when view library is changed

// #include "sim.h"

#ifndef DYNAMIC_PLUGINS
   #ifdef GTK_APPL
      #include "gtk-preview.hpp" // function gtk_preview_init
   #endif

   #ifdef QT_APPL
      #include "qt-preview.hpp" // function qt_preview_init
   #endif

   #ifdef MOTIF_APPL
      #include "motif-preview.hpp" // function motif_preview_init
   #endif

   #ifdef ROOT_PLUGIN
      #include "root-preview.hpp" // function root_preview_init
   #endif

   #ifdef INVENTOR_PLUGIN
      #include "inventor.h" // function inventor_init
   #endif
#endif

// #include "inf.h"
// #include "prgio.h" // function LoadProject
#include "load.h" // function load_and_run
#include "ioexception.h" // class IOException
#include "dirs.h"// const SrcDir
#include "compile3.h" // function compile3_init

#include "toolbox.hpp" // class TToolboxItem
#include "palette.hpp" // class TPalette
#include "win.hpp" // var MainForm
#include "ext.hpp" // function load_components

OPEN_NAMESPACE

/******************************** PLUG-INS ********************************/

#ifdef DYNAMIC_PLUGINS
   #define LOAD_PLUGIN(dir_name, lib_name, func_name) \
      load_plugin (plugin_file_name (dir_name, lib_name), #func_name);
#else
   #define LOAD_PLUGIN(dir_name, lib_name, func_name) func_name ();
#endif

void plugin_err (string file_name, string msg)
{
   // error ("plugin " + filename + " : " + msg);
   warning ("Error loading plugin " + file_name + " (" + msg + ")");
}

string plugin_file_name (string dir_name, string lib_name)
{
   string result = "";
   result = PlatformRealDir (lib_folder, "src/" + dir_name) + '/'+ lib_name + ".so";  // !? path
   return result;
}

#ifdef DYNAMIC_PLUGINS

void load_plugin (string file_name, string func_name)
{
   string result = load_and_run (file_name, func_name);
   if (result != "")
      plugin_err (file_name, result);
}

#endif

/* ---------------------------------------------------------------------- */

void LoadIcons (string file_name)
{
   try
   {
      // !? @@ LoadPictures (file_name);
   }
   catch (IOException e)
   {
      warning ("Error reading icons from " + file_name + " (" + e.what () + ")");
   }
}

void LoadComponents (string file_name)
{
    try
    {
       load_components (file_name);
    }
    catch (IOException e)
    {
       warning ("Error loading components " + file_name + " (" + e.what () + ")");
    }
}

/********************************** MAIN **********************************/

CLOSE_NAMESPACE

USE_NAMESPACE

extern "C" int main (int argc, char * argv [])
{  
   set_prog_name ("appl");

   SimAppl::init (& argc, & argv);
   #ifdef GTK_APPL
      gtk_rc_parse ("appl.rc"); // !?
   #endif

   bool start = true;
   bool ok = false;

   while (! ok)
      try
      {
         if (start)
         {
            start = false;

            MainForm = new TMainForm ();
            // MainForm->Window->show ();

            // !? LoadIcons (SimpleIconsDir + "icons.xpm");

            /* tree of components */
            toolbox = new TToolboxItem ();
            toolbox->setTitle ("toolbox");

            /* palette */
            palette = new TPalette ();
            MainForm->PaletteView->Connect (palette);

            /* register factories */
            compile3_init ();

            // add all registered factories into one toolbox branch
            add_list_into_toolbox ("internal factories", & factories);

            // add factories from one module into toolbox
            add_list_into_toolbox ("dataprog factories", dataprog_factories ());
            // add_components_into_toolbox ("dataprog factories", dataprog_factories ());

            // load component definitions from .t file
            // LoadComponents (SrcDir + "data/simple.t"); // !? path

            #ifdef GTK_APPL
               LOAD_PLUGIN ("gtk/preview", "libgtk-preview", gtk_preview_init);
            #endif

            #ifdef QT_APPL
               LOAD_PLUGIN ("qt/preview", "libqt-preview", qt_preview_init);
            #endif

            #ifdef MOTIF_APPL
               LOAD_PLUGIN ("motif/preview", "libmotif-preview", motif_preview_init);
            #endif

            #ifdef ROOT_PLUGIN
               // LOAD_PLUGIN ("root", "libroot-preview", root_preview_init);
            #endif

            #ifdef INVENTOR_PLUGIN
               LOAD_PLUGIN ("inventor", "libinv", inventor_init);
            #endif

            // fill palette with factories, which PageName != ""
            initialize_palette ();

            // !? preview factories are not registered
            initialize_palette_with_samples ();

            /* tree */

            // !? MainForm->Window->show ();

            /*
            TProject * p = new TProject;
            p->setTitle ("Top");
            p->Name = "Top";
            MainForm->LoadTree (p); // initialize tree, !? delete
            */
            // MainForm->LoadTree (new TProject); // initialize tree, !? delete
            MainForm->LoadFile (PlatformRealDir (data_folder, "examples/mini.t")); // !? path

            // both => !? !! error

            MainForm->Window->show ();
         }

         SimAppl::main ();
         ok = true;
      }
      /*
      catch (antlr::RecognitionException & e)
      {
         show_error (e.getMessage (), e.getFilename (), e.getLine (), e.getColumn ());
      }
      */
      catch (IOException & e)
      {
         show_error (e.getMessage (), e.getFilename (), e.getLine (), e.getColumn ());
      }
      catch (std::exception & e)
      {
         show_error (e.what ());
      }
      catch (...)
      {
         show_error ("unknown exception");
      }

    return 0; // !?
}