//-----------------------------------------------------------
// Copyright Christian Arnault LAL-Orsay CNRS
// arnault@lal.in2p3.fr
// See the complete license in cmt_license.txt "http://www.cecill.info". 
//-----------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "cmt_include.h"
#include "cmt_use.h"

/*----------------------------------------------------------*/
/*                                                          */
/*  Operations on Include                                   */
/*                                                          */
/*----------------------------------------------------------*/

/*----------------------------------------------------------*/
void Include::action (const CmtSystem::cmt_string_vector& words, Use* use)
{
  cmt_string name;

  if (use == 0) use = &(Use::current());

  for (int i = 1; i < words.size (); i++)
    {
      name = words[i];
      if (name == "") return;
      add (name, use);
    }
}

/*----------------------------------------------------------*/
Include* Include::find (const cmt_string& name, Use* use)
{
  int include_index;

  if (use == 0) use = &(Use::current());

  if (use->includes.size () == 0) return (0);

  for (include_index = 0;
       include_index < use->includes.size ();
       include_index++)
    {
      Include& incl = use->includes[include_index];

      if (incl.use != use) continue;

      if (incl.name == name)
        {
          return (&incl);
        }
    }

  return (0);
}

/*----------------------------------------------------------*/
Include* Include::add (const cmt_string& name, Use* use)
{
  if (name == "") return (0);

  if (use == 0) use = &(Use::current());

  {
    Include* incl;

    incl = find (name, use);
    if (incl != 0) return (incl);
  }

  Include& incl = use->includes.add ();

  incl.name = name;
  incl.use = use;

  return (&incl);
}

/*----------------------------------------------------------*/
void Include::print_all (PrintMode mode)
{
  int number;
  int include_number;
  Use::UsePtrVector& uses = Use::get_ordered_uses ();

  if (uses.size () > 0)
    {
      for (number = 0; number < uses.size (); number++)
        {
          const Use* use = uses[number];

	  Package* p = use->get_package ();
          if (p->is_cmt ()) continue;

          cout << "-I${" << use->prefix << "ROOT}/src ";

          for (include_number = 0;
               include_number < use->includes.size ();
               include_number++)
            {
              const Include& incl = use->includes[include_number];

              cout << "-I" << incl.name << " ";
            }
        }
    }

  for (include_number = 0;
       include_number < (Use::current()).includes.size ();
       include_number++)
    {
      const Include& incl = (Use::current()).includes[include_number];

      cout << "-I" << incl.name << " ";
    }
}

/*----------------------------------------------------------*/
void Include::print_filters (PrintMode mode)
{
  int number;
  int include_number;
  Use::UsePtrVector& uses = Use::get_ordered_uses ();

  if (uses.size () > 0)
    {
      for (number = 0; number < uses.size (); number++)
        {
          Use* use = uses[number];

          cout << "s#" <<
              ".*" << SLASH <<
              use->get_package_name () << SLASH <<
              use->version << SLASH <<
              "#$(" << use->prefix << "ROOT)" << SLASH <<
              "#g" << endl;

          for (include_number = 0;
               include_number < use->includes.size ();
               include_number++)
            {
              Include& incl = use->includes[include_number];

              const cmt_string& d = Cmt::filter_dir (incl.name);

              if (d.size () > 0)
                {
                  cout << "s#" << d << "#" <<
                      incl.name << "#g" << endl;
                }
            }
        }
    }

  {
    const Use* use = &(Use::current());

    cout << "s#" << ".*" << SLASH <<
        use->get_package_name () << SLASH <<
        use->version << SLASH <<
        "#$(" << use->prefix << "ROOT)" << SLASH <<
        "#g" << endl;

    for (include_number = 0;
         include_number < use->includes.size ();
         include_number++)
      {
        const Include& incl = use->includes[include_number];

        const cmt_string& d = Cmt::filter_dir (incl.name);

        if (d.size () > 0)
          {
            cout << "s#" << d << "#" <<
                incl.name << "#g" << endl;
          }
      }
  }
}

/*----------------------------------------------------------*/
void Include::clear_all ()
{
}

/*----------------------------------------------------------*/
Include::Include ()
{
  use = 0;
}

/*----------------------------------------------------------*/
Include::~Include ()
{
  use = 0;
}

