text: /* -*- Mode: C; tab-width: 4 -*-
   *
   * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *     http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef	__EXPLORER_BAR_WINDOW__
  #define	__EXPLORER_BAR_WINDOW__
  
  #pragma once
  
  #include	"afxtempl.h"
  
  #include	"dns_sd.h"
  #include	<list>
  
  //===========================================================================================================================
  //	Structures
  //===========================================================================================================================
  
  // Forward Declarations
  
  struct	ServiceHandlerEntry;
  class	ExplorerBarWindow;
  
  // ServiceInfo
  
  struct	ServiceInfo
  {
  	CString						displayName;
  	char *						name;
  	char *						type;
  	char *						domain;
  	uint32_t					ifi;
  	HTREEITEM					item;
  	ServiceHandlerEntry *		handler;
  	DWORD						refs;
  	
  	ServiceInfo( void )
  	{
  		item	= NULL;
  		type 	= NULL;
  		domain	= NULL;
  		handler	= NULL;
  	}
  	
  	~ServiceInfo( void )
  	{
  		if( name )
  		{
  			free( name );
  		}
  		if( type )
  		{
  			free( type );
  		}
  		if( domain )
  		{
  			free( domain );
  		}
  	}
  };
  
  typedef CArray < ServiceInfo *, ServiceInfo * >		ServiceInfoArray;
  
  // TextRecord
  
  struct	TextRecord
  {
  	uint8_t *		mData;
  	uint16_t		mSize;
  	
  	TextRecord( void )
  	{
  		mData = NULL;
  		mSize = 0;
  	}
  	
  	~TextRecord( void )
  	{
  		if( mData )
  		{
  			free( mData );
  		}
  	}
  	
  	void	GetData( void *outData, uint16_t *outSize )
  	{
  		if( outData )
  		{
  			*( (void **) outData ) = mData;
  		}
  		if( outSize )
  		{
  			*outSize = mSize;
  		}
  	}
  	
  	OSStatus	SetData( const void *inData, uint16_t inSize )
  	{
  		OSStatus		err;
  		uint8_t *		newData;
  		
  		newData = (uint8_t *) malloc( inSize );
  		require_action( newData, exit, err = kNoMemoryErr );
  		memcpy( newData, inData, inSize );
  		
  		if( mData )
  		{
  			free( mData );
  		}
  		mData = newData;
  		mSize = inSize;
  		err  = kNoErr;
  		
  	exit:
  		return( err );
  	}
  };
  
  // ResolveInfo
  
  struct	ResolveInfo
  {
  	CString						host;
  	uint16_t					port;
  	uint32_t					ifi;
  	TextRecord					txt;
  	ServiceHandlerEntry *		handler;
  };
  
  // ServiceHandlerEntry
  
  struct	ServiceHandlerEntry
  {
  	const char *			type;
  	const char *			urlScheme;
  	DNSServiceRef			ref;
  	ServiceInfoArray		array;
  	ExplorerBarWindow *		obj;
  	bool					needsLogin;
  	
  	ServiceHandlerEntry( void )
  	{
  		type		= NULL;
  		urlScheme	= NULL;
  		ref 		= NULL;
  		obj			= NULL;
  		needsLogin	= false;
  	}
  	
  	~ServiceHandlerEntry( void )
  	{
  		int		i;
  		int		n;
  		
  		n = (int) array.GetSize();
  		for( i = 0; i < n; ++i )
  		{
  			delete array[ i ];
  		}
  	}
  };
  
  typedef CArray < ServiceHandlerEntry *, ServiceHandlerEntry * >		ServiceHandlerArray;
  
  //===========================================================================================================================
  //	ExplorerBarWindow
  //===========================================================================================================================
  
  class	ExplorerBar;	// Forward Declaration
  
  class	ExplorerBarWindow : public CWnd
  {
  	protected:
  
  		ExplorerBar *			mOwner;
  		CTreeCtrl				mTree;
  		
  		ServiceHandlerArray		mServiceHandlers;
  		DNSServiceRef			mResolveServiceRef;
  		
  	public:
  		
  		ExplorerBarWindow( void );
  		virtual	~ExplorerBarWindow( void );
  
  	protected:
  		
  		// General
  		
  		afx_msg int		OnCreate( LPCREATESTRUCT inCreateStruct );
  		afx_msg void	OnDestroy( void );
  		afx_msg void	OnSize( UINT inType, int inX, int inY );
  		afx_msg void	OnDoubleClick( NMHDR *inNMHDR, LRESULT *outResult );
  		afx_msg LRESULT	OnServiceEvent( WPARAM inWParam, LPARAM inLParam );
  		
  		// Browsing
  		
  		static void DNSSD_API
  			BrowseCallBack(
  				DNSServiceRef 			inRef,
  				DNSServiceFlags 		inFlags,
  				uint32_t 				inInterfaceIndex,
  				DNSServiceErrorType 	inErrorCode,
  				const char *			inName,	
  				const char *			inType,	
  				const char *			inDomain,	
  				void *					inContext );
  		LONG OnServiceAdd( ServiceInfo * service );
  		LONG OnServiceRemove( ServiceInfo * service );
  		
  		// Resolving
  		
  		OSStatus	StartResolve( ServiceInfo *inService );
  		void		StopResolve( void );
  
  
  		void		Stop( DNSServiceRef ref );
  
  
  		static void DNSSD_API
  			ResolveCallBack(
  				DNSServiceRef			inRef,
  				DNSServiceFlags			inFlags,
  				uint32_t				inInterfaceIndex,
  				DNSServiceErrorType		inErrorCode,
  				const char *			inFullName,	
  				const char *			inHostName, 
  				uint16_t 				inPort,
  				uint16_t 				inTXTSize,
  				const char *			inTXT,
  				void *					inContext );
  		LONG OnResolve( ResolveInfo * resolve );		
  				
  		// Accessors
  	
  	public:
  	
  		ExplorerBar *	GetOwner( void ) const				{ return( mOwner ); }
  		void			SetOwner( ExplorerBar *inOwner )	{ mOwner = inOwner; }
  		
  		DECLARE_MESSAGE_MAP()
  	private:
  
  		typedef std::list< DNSServiceRef >  ServiceRefList;
  		
  		HTREEITEM		m_about;
  		ServiceRefList	m_serviceRefs;
  		CImageList		m_imageList;
  };
  
  #endif	// __EXPLORER_BAR_WINDOW__
  