/* -*- mode: c++; c-basic-offset: 4; -*-
 *
 * MICO --- a CORBA implementation
 * Copyright (C) 1997-98 Kay Roemer & Arno Puder
 * 
 * Operation provider basic decl.
 * Copyright (C) 1999 Andreas Schultz                                 
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Send comments and/or bug reports to:
 *                mico@informatik.uni-frankfurt.de
 * 
 */


#ifndef __mico_operation_h__
#define __mico_operation_h__

class WorkerThread;
class ThreadPool;

class OperationInfoNode : public CORBA::ServerlessObject {
protected:
    MsgChannel *nextOP;
    ThreadPool *tp;
    OP_id_type OP_id;
public:
    OperationInfoNode();
    virtual ~OperationInfoNode();

    ThreadPool& getThreadPool() const;

    void setThreadPool(ThreadPool* _tp);

    OP_id_type get_OP_id() const;
    void set_OP_id( const OP_id_type _id );

    MsgChannel & get_nextOP() const;
    void set_nextOP( MsgChannel & _nextOP);
};

class Operation: public MsgChannel
#ifdef DEBUG_NAMES
          , public _namedObject
#endif // DEBUG_NAMES
{
protected:
    OperationInfoNode    *info;
    WorkerThread         *thr;
public:
    
    enum OP_id_type_decl { Accept, Reader, Writer, DeCode, ORB }; 
    Operation();
    Operation( const Operation &op );
    Operation( ThreadPool& _tp );
    virtual ~Operation();
    void start();
	 
    void Info( OperationInfoNode &_info );
    OperationInfoNode& Info() const;
    void Thread( WorkerThread *_thr );
    WorkerThread* Thread() const;

    virtual void initShutdown();
    virtual void finalizeShutdown();

    //    virtual msg_type * get_msg( OP_id_type nextOP_id);
    void put_msg( OP_id_type nextOP_id, msg_type *msg);
    void send_msg( OP_id_type nextOP_id, msg_type * msg);

    virtual void process( msg_type *msg );
    virtual void _run() = 0;

    virtual Operation *copy() const = 0;
};

class activeOperation: public Operation {
protected:
    passiveMsgQueue *input_mc;
public:
    activeOperation();
    activeOperation( const activeOperation &op );
    activeOperation( ThreadPool& _tp );
    
    void registerInputMC( passiveMsgQueue *mc ) {
	input_mc = mc;
    };
    passiveMsgQueue *getInputMC() const {
	return input_mc;
    };
    
    void initShutdown();
    
    void _run();
};

class passiveOperation: public Operation {
protected:
    msg_type *_msg; 
public:
    passiveOperation(): Operation() {};
    passiveOperation( ThreadPool& _tp ): Operation( _tp ) {};

    void put_msg( OP_id_type nextOP_id, msg_type *msg);
    void _run();
};

#endif // __mico_operation_h__
