/*
 *                         OpenSplice DDS
 *
 *   This software and documentation are Copyright 2006 to TO_YEAR PrismTech
 *   Limited, its affiliated companies and licensors. All rights reserved.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 */
#ifndef _XBE_SOURCE_HH
#define _XBE_SOURCE_HH

#include "cppgen_iostream.h"
#include "cppgen_fstream.h"
#include "be_extern.h"
#include "xbe_globals.h"

class be_Source
{
public:

   be_Source ();
   virtual ~be_Source ();

   pbbool Open (const DDS_StdString & mainFilename);
   void Close ();

   inline const DDS_StdString & Basename () const
   {
      return m_basename;
   }

   inline ostream& Stream ()
   {
      return os;
   }

   inline const DDS_StdString & Filename () const
   {
      return m_filename;
   }

   inline const DDS_StdString & CreationTime () const
   {
      return creationTime;
   }

   inline const DDS_StdString & Margin () const
   {
      return margin;
   }

   inline void Indent ()
   {
      margin += "   ";
   }

   void Outdent ();
   void SetAccess (const DDS_StdString & access);

   virtual pbbool IsNotOkay ()
   {
      return (os ? FALSE : TRUE);
   }

   static const DDS_StdString PublicAccess;
   static const DDS_StdString ProtectedAccess;
   static const DDS_StdString PrivateAccess;
   static String_map idlIncludes;
   static String_map otherIncludes;

protected:

   DDS_StdString m_basename;
   DDS_StdString m_filename;
   DDS_StdString creationTime;
   DDS_StdString margin;
   ofstream os;
   pbbool closed;

private:

   friend void BE_produce ();
   static void Initialize ();
};

class be_ClientHeader : public be_Source
{
public:

   be_ClientHeader ();
   virtual ~be_ClientHeader ();

   pbbool Open(const DDS_StdString & mainFilename);

private:

   void GenerateSecondaryIncludes (ostream&);

   DDS_StdString ndefname;
};

class be_ClientImplementation : public be_Source
{
public:

   be_ClientImplementation ();
   virtual ~be_ClientImplementation ();

   pbbool Open (const DDS_StdString & mainFilename);
};

#if defined(DDS_TIE_HEADER)

class be_ServerTieHeader : public be_Source
{
public:

   DDS_StdString ndefname;
   DDS_StdString filename;

   be_ServerTieHeader ();
   virtual ~be_ServerTieHeader ();

   pbbool Open(const DDS_StdString & mainFilename);
};

#endif

class be_ServerHeader : public be_Source
{
public:

   DDS_StdString ndefname;

#if defined(DDS_TIE_HEADER)
   be_ServerTieHeader tieHeader;
#endif

   be_ServerHeader ();
   virtual ~be_ServerHeader ();

   pbbool Open (const DDS_StdString & mainFilename);
};

class be_ServerImplementation : public be_Source
{
public:

   be_ServerImplementation ();
   virtual ~be_ServerImplementation ();

   pbbool Open (const DDS_StdString & mainFilename);
};

class be_root;

class be_Noop
{
public:

   be_Noop (int) {};
};

class be_Tab
{

private:

#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x500))

//   friend class ostream;
#endif

   be_Source & source;

public:

   be_Tab(const be_Source& _source_)
         :
         source(*(be_Source*)&_source_)
   {}

   inline const DDS_StdString&
   Margin() const
   {
      return source.Margin();
   }

   be_Noop indent()
   {
      source.Indent();
      return 0;
   }

   be_Noop outdent()
   {
      source.Outdent();
      return 0;
   }
};


inline ostream&
operator<<(ostream& os, const be_Tab& tab)
{
   os << tab.Margin();
   return os;
}

inline ostream&
operator<<(ostream& os, const be_Noop&)
{
   return os;
}

#endif
