#ifndef __IMGFACTORY_H
#define __IMGFACTORY_H

#include "CAutoRegisterFactory.h"
#include <gdiplus.h>

class CImgLoader {
public:
	CImgLoader();
	virtual ~CImgLoader();
	virtual const wchar_t* GetImgType();
	virtual void Print();
	virtual Gdiplus::Image* LoadImage(wchar_t * szImgPath);
};

class CImgSaver {
public:
	CImgSaver();
	virtual ~CImgSaver();
	virtual const wchar_t* GetImgType();
	virtual void Print();
	virtual bool SaveImage(wchar_t * szImgPath, Gdiplus::Image* pImg, wchar_t* szImgType = NULL);
};

template<typename TSub, typename TBase>
class TplClassTemplate :public IForwarder<TBase>
{
private:
	TSub m_Obj;

public:
	virtual ~TplClassTemplate() {}

public:
	virtual TBase* CloneClass() { return new TSub; }
	virtual TBase* InvokeClass() { return &m_Obj; }

	IForwarder<TBase>* Clone() {
		return new TplClassTemplate;
	}
};

#ifndef TPL_IMG_ACTION
#define TPL_IMG_ACTION(prefix, object)                  \
template<typename TBase>                                \
class TplClassOf##prefix                                \
{                                                       \
public:                                                 \
	TplClassOf##prefix() :m_pTemp(NULL)                 \
	{                                                   \
		m_pTemp = new TplClassTemplate<TBase, object>;  \
	}                                                   \
                                                        \
	operator IForwarder<object>*()                      \
	{                                                   \
		return m_pTemp;                                 \
	}                                                   \
private:                                                \
	IForwarder<object> *m_pTemp;                        \
};
#endif

TPL_IMG_ACTION(Loader, CImgLoader)
TPL_IMG_ACTION(Saver, CImgSaver)

class CImageFactory{
public:
	CImageFactory();
	void RegisterLoader(IForwarder<CImgLoader>* pObj, wchar_t* szImgType = NULL);
	void RegisterSaver(IForwarder<CImgSaver>* pObj, wchar_t* szImgType = NULL);
	Gdiplus::Image* InvokeLoader(wchar_t * szImgPath);
	bool InvokeSaver(wchar_t * szImgPath, Gdiplus::Image* pImg, wchar_t* szImgType = NULL);
	void GetImgListForLoader(std::wstring &szImgList);
	void GetImgListForSaver(std::wstring &szImgList);

private:
	CSingleRegisteredFactory<std::wstring, CImgLoader> m_loaderFactory;
	CSingleRegisteredFactory<std::wstring, CImgSaver> m_saverFactory;
};

#endif