//===========================================================================//
// File:	channel.hpp                                                         //
// Project: MUNGA           Brick: Watcher											  //
// Contents: 						  															  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  -----------------------------------------------------------//
// 2/23/97  JMA  Initial coding.															  //
//---------------------------------------------------------------------------//
// Copyright (C) 1997, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

#include "Adept.hpp"
#include "Component.hpp"

namespace Adept {

	class Channel__FactoryRequestParameters:
		public Component__FactoryRequestParameters
	{
	public:
		Component::CommandEncoder
			m_commandEncoder;
	};

	//##########################################################################
	//############################  Channel  #################################
	//##########################################################################

	//##########################################################################
	// The following classes must always be typedef'd or overriden by an
	// inheritor
	//

	typedef Component__ClassData			Channel__ClassData;
	typedef Component__Message				Channel__Message;
	class Channel__FactoryRequestParameters;

	//---------------------  End of inheritance stuff -------------------------

	class Channel:
		public Component
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		typedef Component BaseClass;

	public:
		typedef Channel__ClassData		ClassData;
		typedef Channel__Message			Message;
		typedef Channel__FactoryRequestParameters
			FactoryRequestParameters;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor/Destructor
	//
	public:
		Channel() : 
			Component(Channel::DefaultData),
			dependantComponents(NULL)
			{}

		~Channel();

	protected:
		Channel(
			ClassData *class_data,
			Stuff::MemoryStream *stream,
			ComponentWeb *owning_web
		);

		void
			ReadOutputsFromStream(
				Stuff::MemoryStream *stream,
				ComponentWeb *owning_web
			);

		void
			SkipStreamData(Stuff::MemoryStream *stream);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Virtual data
	//
	public:
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Data flow
	//
	public:
		void
			NotifyDependantsOfChange();
		int
			GetCommand()
				{Check_Object(this); return channelCommand;}
		void
			AddDependant(Component *component)
				{
					Check_Object(this); Check_Object(component);
					dependantComponents.Add(component);
				}
		void
			SetCommand(int channel_command)
				{Check_Object(this); channelCommand = channel_command;}

	protected:
		Stuff::ChainOf<Component*>
			dependantComponents;
		int
			channelCommand;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Tool Support
	//
	public:
		static ClassData*
			CreateFactoryRequest(FactoryRequestParameters *parameters);

		static bool
			ReadOutputsFromPage(FactoryRequestParameters *parameters);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test support
	//
	public:
		void
      	TestInstance();
	};

	//##########################################################################
	//############################  ChannelOf  #################################
	//##########################################################################

	template <class T> class ChannelOf:
		public Channel
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		typedef Channel BaseClass;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor/Destructor
	//
	public:
		~ChannelOf();

	protected:
		ChannelOf(
			ClassData *class_data,
			Stuff::MemoryStream *stream,
			ComponentWeb *owning_web
		);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Virtual data
	//
	public:
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Data flow
	//
	public:
		virtual const T&
			ReadChannel();

	protected:
		T
			channelOutput;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test Support
	//
	public:
		void
			TestInstance();
	};

	//
	// Class Data Support
	//
	template <class T> ChannelOf<T>::ClassData*
		ChannelOf<T>::DefaultData = NULL;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	template <class T> void
		ChannelOf<T>::TerminateClass()
	{
		Unregister_Object(DefaultData);
		delete DefaultData;
		DefaultData = NULL;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	template <class T> ChannelOf<T>::~ChannelOf()
	{
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	template <class T> const T&
		ChannelOf<T>::ReadChannel()
	{
		Check_Object(this);
		return channelOutput;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//
	template <class T> void
		ChannelOf<T>::TestInstance()
	{
		Verify(IsDerivedFrom(DefaultData));
	}

}

