/*------------------------------------------------------------------------*
  Filename....: star_init.c


		 COPYRIGHT (C) 2001.  All Rights Reserved.
		 auto*des*sys, Inc., Columbus, Ohio, USA.
 *------------------------------------------------------------------------*/

#include "star.h"

#include "fz_plugin_glue_api.h"
#include "fz_tool_api.h"

star_plugin_stuff		plugin_stuff;

/************************************************************************
	acquires all application provided service function sets.
*************************************************************************/
static fzrt_error_td star_acquire_fsets ( void )
{
	fzrt_error_td err = FZRT_NOERR;

	
	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_MATH_FSET_TYPE, FZ_MATH_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_math_fset), sizeof(plugin_stuff.math_funcs),
									 (fzpl_fset_td *)&plugin_stuff.math_funcs );
	}
	
	if(err == FZRT_NOERR)
	{
		err =(*plugin_stuff.fsf->fzpl_fset_acquire)(FZ_MODEL_FSET_TYPE, FZ_MODEL_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_model_fset), sizeof(plugin_stuff.model_funcs),
									(fzpl_fset_td *)&plugin_stuff.model_funcs);
	}

	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_TYPE_FSET_TYPE, FZ_TYPE_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_type_fset), sizeof(plugin_stuff.type_funcs),
									 (fzpl_fset_td *)&plugin_stuff.type_funcs );
	}

	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_FUIM_FSET_TYPE, FZ_FUIM_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_fuim_fset), sizeof(plugin_stuff.fuim_funcs),
									 (fzpl_fset_td *)&plugin_stuff.fuim_funcs );
	}
	
	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_FZRT_BASE_FSET_TYPE, FZ_FZRT_BASE_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_fzrt_base_fset), sizeof(plugin_stuff.fzrt_base_funcs),
									 (fzpl_fset_td *)&plugin_stuff.fzrt_base_funcs );
	}

	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_FZRT_MEM_FSET_TYPE, FZ_FZRT_MEM_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_fzrt_mem_fset), sizeof(plugin_stuff.fzrt_mem_funcs),
									 (fzpl_fset_td *)&plugin_stuff.fzrt_mem_funcs );
	}

	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_FZRT_FILE_FSET_TYPE, FZ_FZRT_FILE_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_fzrt_file_fset), sizeof(plugin_stuff.fzrt_file_funcs),
									 (fzpl_fset_td *)&plugin_stuff.fzrt_file_funcs );
	}

	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_FZRT_GRAF_FSET_TYPE, FZ_FZRT_GRAF_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_fzrt_graf_fset), sizeof(plugin_stuff.fzrt_graf_funcs),
									 (fzpl_fset_td *)&plugin_stuff.fzrt_graf_funcs );
	}
	
	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_FZRT_UI_FSET_TYPE, FZ_FZRT_UI_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_fzrt_ui_fset), sizeof(plugin_stuff.fzrt_ui_funcs),
									 (fzpl_fset_td *)&plugin_stuff.fzrt_ui_funcs );
	}

	if(err == FZRT_NOERR)
	{
		err = (*plugin_stuff.fsf->fzpl_fset_acquire) ( FZ_IOST_FSET_TYPE, FZ_IOST_FSET_VERSION, FZRT_UUID_NULL,
									 FZPL_TYPE_STRING(fz_iost_fset), sizeof(fz_iost_fset),
									 (fzpl_fset_td *)&plugin_stuff.iost_funcs );
	}
	
	return err;
}

/************************************************************************
	releases all application provided service function sets.
*************************************************************************/
static void star_release_fsets ( void )
{
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.math_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.model_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.type_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.fuim_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.iost_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.fzrt_base_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.fzrt_mem_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.fzrt_file_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.fzrt_graf_funcs );
	(*plugin_stuff.fsf->fzpl_fset_release) ( (fzpl_fset_td *)&plugin_stuff.fzrt_ui_funcs );
}




/************************************************************************
	A first pass check to see if the plugin can be loaded.
	Checks licensing.
	Checks that application defined function sets which are
		needed by the plugins are available.
	Verifies that plugin and application are compatible.
	Verifies that plugin type is expected by application.
	Informs the application if this plugin is dependent on
		function sets from other plugins.
*************************************************************************/
static fzrt_error_td star_check_config ( const fzpl_fset_glue_fset * const fsf, const fzpl_host_config_td * const hostConfig )
{
	fzrt_error_td					err = FZRT_NOERR;

	plugin_stuff.fsf = fsf;
	plugin_stuff.fz_rsrc_ref_func = -1;
	plugin_stuff.floc = NULL;

	/*  Make sure required application defined function sets are available */
	/*  Release the function sets at unload. */
	err = star_acquire_fsets();

	/* Make sure the plugin's resource file is available and load it */
	if ( err == FZRT_NOERR )
	{
		plugin_stuff.fzrt_file_funcs.fzrt_file_floc_init(&plugin_stuff.floc);
		err = (*fsf->fzpl_plugin_file_get_floc)(plugin_stuff.floc);
		if(err == FZRT_NOERR)
		{
			err = plugin_stuff.fzrt_base_funcs.fzrt_fzr_open(plugin_stuff.floc, "star", &plugin_stuff.fz_rsrc_ref_func);
		}
	}	

	if ( err != FZRT_NOERR )
	{
		star_release_fsets();
	}

	return err;
}


/************************************************************************
	Generates error strings for any errors created by the plugin
*************************************************************************/
static fzrt_boolean star_error_str_func(fzrt_int err, char *str, short str_len)
{
	/* ADD ERROR STRINGS, IF ANY */
	
	return(FALSE);
}


/************************************************************************
	Registers plugins and their assocoated function sets.
*************************************************************************/
static fzrt_error_td star_register_plugins ( const fzpl_fset_glue_fset * const fsf, const fzpl_host_config_td * const hostConfig )
{
	fzrt_error_td				err = FZRT_NOERR;
	fzrt_boolean				otype_failed = FALSE;
	char						pname[FZPL_NAME_SIZE];

	/* Register the object type plugin */
	plugin_stuff.fzrt_base_funcs.fzrt_fzr_get_string(plugin_stuff.fz_rsrc_ref_func, STAR_STRINGS, STAR_OTYP_PLUGIN_NAME_STR, pname);
	err = (*fsf->fzpl_plugin_register)( STAR_OTYP_PLUGIN_ID, pname, STAR_OTYP_PLUGIN_VERSION,
						STAR_OTYP_PLUGIN_VENDOR,
						STAR_OTYP_PLUGIN_URL,
						FZ_OTYP_EXTS_TYPE, FZ_OTYP_EXTS_VERSION,
						star_error_str_func, 0, NULL,
						&plugin_stuff.star_otyp_plugin_runtime_id);
	
	if ( err != FZRT_NOERR )
	{
		otype_failed = TRUE;
	}
	else
	{
		/* Add the function sets implemented by the object type plugin */
		err = (*fsf->fzpl_plugin_add_fset)( plugin_stuff.star_otyp_plugin_runtime_id, FZ_OTYP_CBAK_FSET_TYPE,
				  FZ_OTYP_CBAK_FSET_VERSION, FZ_OTYP_CBAK_FSET_NAME,
				  FZPL_TYPE_STRING(fz_otyp_cbak_fset), sizeof ( fz_otyp_cbak_fset ),
				  star_otyp_get_callback_fset, FALSE);
	}
			
	/* REGISTER STAR TOOL */
	if(err == FZRT_NOERR)
	{				
		/* Register the tool plugin */
		plugin_stuff.fzrt_base_funcs.fzrt_fzr_get_string(plugin_stuff.fz_rsrc_ref_func, STAR_STRINGS, STAR_TOOL_PLUGIN_NAME_STR, pname);
		err = (*fsf->fzpl_plugin_register)( STAR_TOOL_PLUGIN_ID, pname, STAR_TOOL_PLUGIN_VERSION,
							STAR_TOOL_PLUGIN_VENDOR,
							STAR_TOOL_PLUGIN_URL,
							FZ_TOOL_EXTS_TYPE, FZ_TOOL_EXTS_VERSION,
							star_error_str_func, 0, NULL,
							&plugin_stuff.star_tool_plugin_runtime_id);
		
		if ( err != FZRT_NOERR )
		{
			err = FZRT_NOERR;
		}
		else
		{
			
			/* Add the function sets implemented by the tool plugin */
			err = (*fsf->fzpl_plugin_add_fset)( plugin_stuff.star_tool_plugin_runtime_id, FZ_TOOL_CBAK_FSET_TYPE,
					  FZ_TOOL_CBAK_FSET_VERSION, FZ_TOOL_CBAK_FSET_NAME,
					  FZPL_TYPE_STRING(fz_tool_cbak_fset), sizeof ( fz_tool_cbak_fset ),
					  star_tool_get_callback_fset, FALSE);
			
			err |= (*fsf->fzpl_plugin_add_fset)( plugin_stuff.star_tool_plugin_runtime_id, FZ_NOTF_CBAK_FSET_TYPE,
					  FZ_NOTF_CBAK_FSET_VERSION, FZ_NOTF_CBAK_FSET_NAME,
					  FZPL_TYPE_STRING(fz_notf_cbak_fset), sizeof ( fz_notf_cbak_fset ),
					  star_notf_get_callback_fset, FALSE);
		}
	}

	if ( otype_failed )
	{
		star_release_fsets();
		err =  plugin_stuff.fzrt_base_funcs.fzrt_error_set ( FZRT_UNKNOWN_ERROR, FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_FZRT, 0 );
	}
	else
	{	err = FZRT_NOERR;
	}

	return err;
}

/************************************************************************
	Unregisters plugins.
*************************************************************************/
static fzrt_error_td star_unregister_plugins ( const fzpl_fset_glue_fset * const fsf )
{
	fzrt_error_td					err = FZRT_NOERR;

	if(plugin_stuff.fz_rsrc_ref_func !=-1)
	{	plugin_stuff.fzrt_base_funcs.fzrt_fzr_close(plugin_stuff.fz_rsrc_ref_func);
	}

	/* Unregister the plugins */
	err  = (*fsf->fzpl_plugin_unregister)( plugin_stuff.star_otyp_plugin_runtime_id );
	err = (*fsf->fzpl_plugin_unregister)( plugin_stuff.star_tool_plugin_runtime_id );

	if (plugin_stuff.floc) plugin_stuff.fzrt_file_funcs.fzrt_file_floc_finit(&plugin_stuff.floc);

	/* Release application implemented function sets */
	star_release_fsets();

	return err;
}

/************************************************************************
	The main plugin file entry point.  Plugin initialization
	happens via this function.
*************************************************************************/
FZPL_PLUGIN_FUNC(fzrt_error_td) fz_plugin_entry( const fzpl_fset_glue_fset * const fsf, fzpl_command_td cmd, const fzpl_host_config_td * const hostConfig )
{
	fzrt_error_td err = FZRT_NOERR;

	switch ( cmd )
	{
		case FZPL_PLUGIN_CHECK:
			err = star_check_config ( fsf, hostConfig );
		break;
		
		case FZPL_PLUGIN_INITIALIZE:
			err = star_register_plugins ( fsf, hostConfig );
		break;
		
		case FZPL_PLUGIN_EXIT:
			err = star_unregister_plugins ( fsf );
		break;
	}

	return ( err );
}

