//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / OVOPS++
//
//File: mux.h
//
//Version: $Revision: 1.41 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/11/05 08:20:03 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
// 
//Authors:
//      Pasi Nummisalo
//      Timo Pärnänen
//      Juhana Räsänen
//
//Description:
//      A Mux is a conduit that connects one SideA conduit to any
//      number of sideB conduits. A Mux multiplexes information 
//      chunks arriving on sideB to the single neighbor conduit connected
//      on sideB.
//
//Copyright:    
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//      
//Licence:
//     
//
//History:
//
//
 
#ifndef __PF_MUX_H__
#define __PF_MUX_H__

#include "pf/protocol.h"
#include <map>
#include "pf/exception.h"

class pfMux : public pfProtocol
{
    public:
        static pfConduit createMux(pfKey maxKeyValue_, const string &keyName_);
        pfMux(const pfMux &other_);
        virtual ~pfMux(void);
        void accept(pfTransporter *transporter_);
        
        void tryToGotoB(pfTransporter *transporter_)
            throw(pfOutOfRangeException);

        virtual pfKey installOnSideB(pfConduit &conduit_);        
        virtual void connectToB(pfConduit &conduit_, pfKey key_)
            throw(pfOutOfRangeException);
        virtual void removeFromSideB(pfKey key_);

        virtual bool isKeyInstalled(pfKey key_) const;

        virtual void toB(pfTransporter *transporter_);
        
        virtual void toAllB(pfTransporter *transporter_);
        virtual void toFactory(pfTransporter *transporter_);
        
        virtual void deleteTransporter(pfTransporter *transporter_);

    protected:
        pfMux(pfKey maxKeyValue_, const string &keyName_);
        virtual pfProtocol* cloneImplementation(void) const;
        virtual void acceptSynchronous(pfTransporter *transporter_);  
        
    private:
	pfMux &operator=(const pfMux &other_);
        typedef map<pfKey, pfConduit, less<pfKey> > mapType;
        typedef mapType::iterator mapIterType;
        typedef mapType::const_iterator mapConstIterType;
        mapType _map;

        pfKey _cursor;
        pfKey _maxKeyValue;
        string _keyName;
        pfTransporter *_transporter;
};

#endif // __PF_MUX_H__

