//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / OVOPS++
//
//File: protocol.h
//
//Version: $Revision: 1.33 $
//
//State: $State: Exp $
//
//Date: $Date: 1999/03/09 10:14:52 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
// 
//Authors:
//      Pasi Nummisalo
//      Timo Pärnänen
//      Juhana Räsänen
//
//Description:
//      A Protocol Conduit implements a communication protocol which can
//      be described by a finite state machine. The protocol remembers
//      the current state of the communication.
//
//Copyright:     
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//      
//Licence:
//     
//
//History:
//
//
 
#ifndef __PF_PROTOCOL_H__
#define __PF_PROTOCOL_H__

#include <typeinfo>
#include <string>
#include <list>
#include "types.h"
#include "transp.h"
#include "state.h"
#include "conduit.h"
#include "sf/task.h"
#include "timers.h"

class pfProtocol : public pfState, public sfTask, public pfTimers
{
    public:
        static pfConduit createProtocol(void);
        pfProtocol(const pfProtocol &other_);
        virtual ~pfProtocol(void);
        
        virtual pfId getId(void) const;
        virtual pfKey getKey(void) const;
        
        void changeState(pfState *state_);
        pfState *getState(void) const;

        virtual void accept(pfTransporter *transporter_)
            throw(pfNullPointerException);

        virtual void connectToA(pfConduit &conduit_);
        virtual void connectToB(pfConduit &conduit_);
        virtual void disconnect(void);

        // Methods used for trace
        virtual void setTraceOn(void);

        virtual void toA(pfMessenger *messenger_);
        virtual void toB(pfMessenger *messenger_);
        virtual void toA(pfTransporter *transporter_);
        virtual void toB(pfTransporter *transporter_); 

    protected:
        pfProtocol(void);
        friend class pfConduit;
        virtual pfProtocol *cloneImplementation(void) const;
        virtual void setId(pfId id_);
        virtual void setKey(pfKey key_);
        virtual void acceptSynchronous(pfTransporter *transporter_);
        virtual void acceptAsynchronous(pfTransporter *transporter_);

        virtual void runCallback(void);
        virtual void error(pfUlong cause_);

        void incRefCount(void);
        void decRefCount(void);
        virtual int noReference(void) const;

        pfConduit _sideA;
        pfConduit _sideB;
        pfKey _key;
        bool _traceOn;
        
    private:
	pfProtocol &operator=(const pfProtocol &other_);
        pfId _id;
        long _refCount;
        pfState *_state;

        typedef list<pfTransporter *> transporterList;
        typedef transporterList::iterator transporterListIterator;
        transporterList _messageQueue;
};

#endif // __PF_PROTOCOL_H__

