/**
 * @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_FUNCTION_H
#define __IWREMOTE_FUNCTION_H

#include <iwear/debugstream.h>
#include <iwremote/statement.h>
#include <string>
#include <iwremote/class.h>
#include <iwremote/type.h>
using std::string;

namespace iwear
{
    namespace net
    {

enum argtype
{
    in_t,
    out_t,
    inout_t,
    plain_t
};

struct FunctionArgument
{
    /**
     * The type of the parameter
     */
PH1  Type* type;

    /**
     * The in/out modifier
     */
PH1  argtype mytype;

    /**
     * The actual name of the parameter
     */
PH1  string id;

PH1  FunctionArgument( Type* type_, argtype mytype_, const string& id_) 
	: type(type_), mytype(mytype_), id(id_) { }

PH2  FunctionArgument( const string& pd, const string& type, const string& id_ );

PH1  string get_crcstring( void );
};


class Function : public ClassItem
{
private:
protected:
public:
    /**
     * In same order as the function parameters
     */
PH1  list<FunctionArgument> arguments;

    /**
     * we only need one ;)
     */
PH1  FunctionArgument return_type;

    bool is_const;

    /**
     * If this is a one-way function we handle it specially when calling
     */
PH1  bool is_oneway;

    /**
     * if its cached we implement a cache and check it frequently 
     */
PH1  bool is_cached;

     /**
      * If this function can be deferred.
      */
PH2  bool is_deferred;
//    uint32_t crcid;
    /**
     * 
     */    
PH1  uint32_t version_id;

    /**
     * if this is a function that implements another interface version, this is
     * the real function on the server host do call
     */
PH1  string versioncall;

    Function( const FunctionArgument& rett, const string& _id, bool con, bool one, bool cac, uint32_t vid, const string& vc = "" ) 
	: ClassItem(_id), return_type(rett), is_const(con), is_oneway(one), is_cached(cac),is_deferred(false), version_id(vid), versioncall(vc) {
	d_dbg << "CREATED FUNCTION OBJECT ID=" <<  _id << " VERSION " << vid << " VERSIONCALL " << vc << std::endl;
	}

    /**
     * return the code to determine the size of outgoing data (this the return
     * type and the amount of out data...
     */
PH1  string get_outsize( void );

    /**
     * this returns the code to determine the amount of data needed to bass to
     * the call (it does not include data that just goes out as this is
     * tempporarily generated locally)
     */
PH1  string get_insize( void );

PH1  void add_argument( const FunctionArgument& fa ) { arguments.push_back(fa); }

    /**
     * Assembles and returns a uinque string that will be used for generating
     * the crcid
     */
PH1  virtual string get_crcstring( void );

    /**
     * generate the crcid number of this function. It will include the
     * arguments, return type and type of the function, and so on
     * @param the class string so same signatures have different crcids
     */
PH1  virtual void generate_crcids(const string&);
    
PH1  virtual classitem_type get_classitem_type( void ) { return function_cit; }
};

}
}

#endif
