/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 * 
 * The iWear Framework is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWREMOTE_CPPOUTPUT_H
#define __IWREMOTE_CPPOUTPUT_H

#include <iwremote/srcoutput.h>
#include <iwremote/function.h>
#include <iwremote/enum.h>

#include <iostream>
#include <vector>

using std::ostream;
using std::ofstream;
using std::vector;

namespace iwear
{
    namespace net
    {
class Namespace;	
class Class;
class Declaration;
class Type;
class CppOutput : public SrcOutput
{
private:
protected:
    ostream& ccout;
    ostream& chout;
    ostream& scout;
    ostream& shout;
    
    ostream& cmhout;
    ofstream* cmhout_p;

    ostream& cmcout;
    ofstream* cmcout_p;

    ofstream* ccout_p;
    ofstream* chout_p;
    ofstream* scout_p;
    ofstream* shout_p;

    string filebase;
    string fileprefix;

    protection last_prot;

    void output_client( TranslationUnit& );
    void output_server( TranslationUnit& );
    void output_common( TranslationUnit& );
    
    void output_server_namespace( Namespace& ns, uint32_t indlev );
    void output_server_class( Class& c, uint32_t indlev );
    void output_server_classcommon( Class& c, uint32_t indlev );
    void output_server_function( Class& c, Function& f, uint32_t indlev );
    void output_server_subclassinitializer(iwear::net::Class&);

    void output_client_namespace( Namespace& ns, uint32_t indlev );
    void output_client_function( Class& c, Function& f, uint32_t indlev );
    void output_client_class( Class& c, uint32_t indlev );
    void output_client_subclassinitializer( Class& c );

    void output_common_namespace( Namespace& ns, uint32_t indlev );
    void output_common_function( Class& c, Function& f, uint32_t indlev );
    void output_common_class( Class& c, uint32_t indlev );
    void output_common_classcommon( Class& c, uint32_t indlev );
    void output_common_enum( Enum& c, uint32_t indlev );
    void output_common_declaration( Declaration& d, uint32_t indlev );
    void output_common_subclassinitializer( Class& c );

    void output_falist( ostream& out, list<FunctionArgument>& fal, argtype filter = inout_t );
    void output_protection( ostream& out, protection prot, uint32_t indlev);
    void output_derivation( ostream& o, derivation d );
    void output_function( ostream& out, Function& f, const string& prfx, argtype filter = inout_t ); 
    void output_client_function_start( Class& c, Function& f, const string&, uint32_t indlev );
    void output_client_function_finish( Function& f, const string& rets );



    void fill_type( const string&, const string&, Type* t, ostream& o, const string&, 
	    const string& = "=", const string& = "" );
    void fill_from_type( const string&, const string&, Type* t, ostream& o, const string&, 
	    uint32_t lvl );

    void output_common_adapter( Class& c );

    void output_type( ostream&, Type* );

    /**
     * Get the necessary indentation string for the specified level
     */
    string ind( int indlev );

    vector<string> indvec;

    uint32_t indlev;

    void open_files( void );
public:
    virtual void output_tu( TranslationUnit& tu );
    virtual void output_tu( TranslationUnit& tu, const string&  );

    CppOutput( const string& filebase );
    virtual ~CppOutput( );
};

}
}
#endif
