//-------------------------------------------------------------------------
//
// File:		ImportableI.h
// Desc:		Importable interface.
// Author:		memon <memon@inside.org>
//
//-------------------------------------------------------------------------
//	Copyright (c) 2000-2002 Moppi Productions. All Rights Reserved.
//  This file is part of Moppi Demopaja SDK. For conditions of 
//  distribution and use, see the accompanying license.txt file.
//  http://moppi.inside.org/demopaja/
//-------------------------------------------------------------------------

#ifndef __DEMOPAJA_IMPORTABLEI_H__
#define __DEMOPAJA_IMPORTABLEI_H__

// Forward declaration
namespace Import {
	class ImportableI;
};

#include "PajaTypes.h"
#include "DataBlockI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "ClassIdC.h"
#include "ImportInterfaceC.h"
#include "FileHandleC.h"
#include "TimeContextC.h"
#include "DeviceContextC.h"



namespace PluginClass {
	//! The importable super class ID.
	/*! Every importer should return SUPERCLASS_IMPORT as super class if it only
		implements the ImportableI interface. */
	const PluginClass::SuperClassIdC		SUPERCLASS_IMPORT = PluginClass::SuperClassIdC( 0x2000000 );
};

namespace Import {

	//! Importable file interface.
	/*!	Importable files are key elements in the Demopaja system. Importers
		imports and holds the external data in the system, and effects are used to display
		it. This allows data sharing between the effects.
		All the importers are derived from this base class.

		The copy() method is used to copy the file properties while the file is reloaded.
	*/
	class ImportableI : public Edit::EditableI
	{
	public:
		//! Returns the name of the file this importable refers to.
		virtual const char*					get_filename() = 0;
		//! Loads the file specified in by the argument.
		/*! When a file is reloaded, a new instance of a importable is created,
			the copy() method is called first to enable copy settings from old file,
			and finally load_file() is called.

			If the copy() method is implemented so that it also duplicates the data, load_file()
			should check and delete all existing data if needed.

			Not used for procedural importables. See: \see create_file().

			Default implementation returns false.
		*/
		virtual bool						load_file( const char* szName, ImportInterfaceC* pInterface );

		//! Creates the file.
		/*!	This method is similar as the load_file() but is used for procedural importables.

			Default implementation returns false.
		*/
		virtual bool						create_file( ImportInterfaceC* pInterface );

		//! Prompts the properties dialog.
		/*!	\return \b True if the changes should be committed, or \b false if the action should be cancelled.
			The default implementation returns \b true.
			See also: \see has_properties().
		*/
		virtual bool						prompt_properties( PajaSystem::DeviceContextC* pContext, 
																PajaSystem::TimeContextC* pTimeContext,
																ImportInterfaceC* pInterface );

		//! Returns \b true if the importable has editable properties.
		/*!	The default implementation returns \b false.
			See also: \see prompt_properties().
		*/
		virtual bool						has_properties();

		//! Initialize importable.
		/*! \param ui32Reason The reason this method was called.
		
			If ui32Reason is \b INIT_INITIAL_UPDATE, the importable has been
			just instantiated (created) and all available data is
			passed to the importable. This happens either if the importable
			has just been created by the user or the importable is just
			loaded.

			If ui32Reason is \b INIT_DEVICE_CHANGED, the settings for a device
			has been changed. importable should check that all the devices it uses
			and release all resources bind to them and later restore the resources
			when INIT_DEVICE_VALIDATE command is send. If a device is removed or
			replaced with another (in case of graphics device), the device which present
			is present when INIT_DEVICE_CHANGED is called may not be anymore present
			when INIT_DEVICE_VALIDATE is called later.

			If ui32Reason is \b INIT_DEVICE_INVALIDATE, most a device has gone into a state
			where some device resources needs to released so that the device can be reset.
			Such case can be for example when graphics device changes resolution.

			If ui32Reason is \b INIT_DEVICE_VALIDATE, initialize() is called either after
			INIT_DEVICE_INVALIDATE or INIT_DEVICE_CHANGED. In both cases the importable should
			try to restore and recreate the resources it uses from devices.
		*/
		virtual void						initialize( PajaTypes::uint32 ui32Reason, 
														PajaSystem::DeviceContextC* pContext, 
														PajaSystem::TimeContextC* pTimeContext ) = 0;

		//! This method is called when a referenced file is changed.
		/* \param pHandle pointer to the handle of the file which has changed.
			When a file is changed in any way each file in file list which has the changed
			file as a reference is updated using this method.

			The default implmentation does nothing.
		*/
		virtual void						update_notify( FileHandleC* pHandle,
															PajaSystem::DeviceContextC* pContext, 
															PajaSystem::TimeContextC* pTimeContext,
															ImportInterfaceC* pInterface );

		//! Returns the number of referenced files.
		/*!	If the importable has references to other files (such as textures
			in 3D meshes) this method returns number of file references.

			File loading is implemented in the ImportInterfaceC which is passed to the
			load_file() method.

			The default implementation returns zero.
		*/
		virtual PajaTypes::uint32			get_reference_file_count();

		//! Returns file reference at speficied index.
		/*!	The default implementation returns zero. */
		virtual FileHandleC*				get_reference_file( PajaTypes::uint32 ui32Index );

		//! Returns super class ID of the importer.
		virtual PluginClass::SuperClassIdC	get_super_class_id() = 0;
		//! Returns unique class ID of the importer.
		virtual PluginClass::ClassIdC		get_class_id() = 0;
		//! Returns importer's class name as NULL terminated string.
		virtual const char*					get_class_name() = 0;

		//! Return short info about the file.
		/*! The information can be for example width and height and bit depth, etc.
			This information is displayed in the File Inspector window.
		*/
		virtual const char*					get_info() = 0;

		//! Evaluate the state of the importable at specified time.
		/*!	Before using any importable the importable should be evalutated to a certain time.
			
			\code
			void
			TestEffectC::eval_state( PajaTypes::int32 i32Time, DeviceContextC* pContext, TimeContextC* pTimeContext )
			{
				...
				ImportableImageI*	pImp = 0;
				FileHandleC*		pHandle = 0;
				int32				i32FileTime = 0;
				// Get the file handle and evaluation time from the file parameter.
				pParamFile->get_file( i32Time, pHandle, i32FileTime );
				if( pHandle ) {
					pImp = (ImportableImageI*)pHandle->get_importable();
				if( pImp ) {
					pImp->eval_state( i32FileTime, pContext, pTimeContext );
					// Now the importable is valid and ready to use
					...
				}
				...
			}

			\end code
		*/
		virtual void						eval_state( PajaTypes::int32 i32Time, PajaSystem::DeviceContextC* pContext, PajaSystem::TimeContextC* pTimeContext ) = 0;

		//! Returns duration of the file in given time context.
		/*! If the duration cannot be determined (for example the data is a still image)
			negative value should be returned.

			Example:
			\code
			int32
			MASImportC::get_duration( TimeContextC* pTimeContext )
			{
				int32	i32Length = m_i32LastFrame - m_i32FirstFrame;
				// Convert the FPS timecode to Demopaja timecode.
				return pTimeContext->convert_fps_to_time( i32Length, m_i32FPS );
			}
			\endcode
		*/
		virtual PajaTypes::int32			get_duration( PajaSystem::TimeContextC* pTimeContext ) = 0;

		//! Returns start label (a numerical value).
		/*! The value does not have to be related to the returned duration.
			The start label is shown in the duration bar in the timegraph.
			The Demopaja system will find nice values for the labels between the
			start and end label returned from the importable.

			Example:
			\code
			float32
			MASImportC::get_start_label( TimeContextC* pTimeContext )
			{
				return m_i32FirstFrame;
			}
			\endcode
		*/
		virtual PajaTypes::float32			get_start_label( PajaSystem::TimeContextC* pTimeContext ) = 0;
		
		//! Returns end label (a numerical value).
		/*! The value does not have to be related to the returned duration.
			The start label is shown in the duration bar in the timegraph.
			The Demopaja system will find nice values for the labels between the
			start and end label returned from the importable.

			Example:
			\code
			float32
			MASImportC::get_end_label( TimeContextC* pTimeContext )
			{
				return m_i32LastFrame;
			}
			\endcode
		*/
		virtual PajaTypes::float32			get_end_label( PajaSystem::TimeContextC* pTimeContext ) = 0;

		//! Returns the default effect class ID this importable creates if dropped to a File List (or to the Layout View).
		virtual PluginClass::ClassIdC		get_default_effect() = 0;

		//! Test if the given importable is same as this.
		/*!	This method is used to check if two files are same, while merging
			two lists of files. The defauls implementation checks if the
			file name (get_filename()) and the class ID (get_class_id())
			of both importables are same. If they are the method returns true.
		*/
		virtual bool						equals( ImportableI* pImp );

	protected:
		//! Default constructor.
		ImportableI();
		//! Constructor with reference to the original.
		ImportableI( Edit::EditableI* pOriginal );
		//! Default destructor.
		virtual ~ImportableI();

	};

};

#endif