#include "ImgFactory.h"
#include <vector>
#pragma warning(disable:4996)

static std::vector<std::wstring> GetArrBySpliteString(std::wstring SourceStr, std::wstring FirstFlag, std::wstring FinalFlag)
{
	int ROffset = 0;
	std::vector<std::wstring>SpliteResult;
	while (SourceStr.find(FirstFlag, ROffset) >= 0 && SourceStr.find(FirstFlag, ROffset) <= wcslen(SourceStr.c_str()))
	{
		int findex = SourceStr.find(FirstFlag, ROffset);
		int sindex = SourceStr.find(FinalFlag, findex + wcslen(FirstFlag.c_str()));
		if (SourceStr.find(FinalFlag, findex + wcslen(FirstFlag.c_str())) >= 0 && SourceStr.find(FinalFlag, findex + wcslen(FirstFlag.c_str())) <= wcslen(SourceStr.c_str()))
		{
			SpliteResult.push_back(SourceStr.substr(findex + wcslen(FirstFlag.c_str()), sindex - findex - wcslen(FirstFlag.c_str())));
		}
		ROffset = sindex;
	}
	return SpliteResult;
}

CImgLoader::CImgLoader()
{

}

CImgLoader::~CImgLoader()
{

}

const wchar_t* CImgLoader::GetImgType()
{
	return NULL;
}

void CImgLoader::Print()
{
	printf("未实现图片解码器\n");
}

Gdiplus::Image* CImgLoader::LoadImage(wchar_t * szImgPath)
{
	return NULL;
}

CImgSaver::CImgSaver()
{

}

CImgSaver::~CImgSaver()
{

}

const wchar_t* CImgSaver::GetImgType()
{
	return NULL;
}

void CImgSaver::Print()
{
	printf("未实现图片编码器\n");
}

bool CImgSaver::SaveImage(wchar_t * szImgPath, Gdiplus::Image* pImg, wchar_t* szImgType)
{
	return NULL;
}

void CImageFactory::RegisterLoader(IForwarder<CImgLoader>* pObj, wchar_t* szImgType)
{
	if (!pObj) return;
	const wchar_t *szType = szImgType? szImgType : pObj->InvokeClass()->GetImgType();
	if (szType)
	{
		std::wstring str = std::wstring(L"|") + szType + std::wstring(L"|");
		std::vector<std::wstring> vcType = GetArrBySpliteString(str, L"|", L"|");
		for (std::vector<std::wstring>::iterator it = vcType.begin(); it != vcType.end(); it++)
			m_loaderFactory.RegisterFactory(it->c_str(), pObj->Clone());
	}
	delete pObj;
	pObj = NULL;
}

void CImageFactory::RegisterSaver(IForwarder<CImgSaver>* pObj, wchar_t* szImgType)
{
	if (!pObj) return;
	const wchar_t *szType = szImgType? szImgType : pObj->InvokeClass()->GetImgType();
	if (szType)
	{
		std::wstring str = std::wstring(L"|") + szType + std::wstring(L"|");
		std::vector<std::wstring> vcType = GetArrBySpliteString(str, L"|", L"|");
		for (std::vector<std::wstring>::iterator it = vcType.begin(); it != vcType.end(); it++)
			m_saverFactory.RegisterFactory(it->c_str(), pObj->Clone());
	}
	delete pObj;
	pObj = NULL;
}

Gdiplus::Image* CImageFactory::InvokeLoader(wchar_t * szImgPath)
{
	if (!szImgPath) return false;
	wchar_t szImgExt[10] = {0};
	_wsplitpath(szImgPath, NULL, NULL, NULL, szImgExt);
	CImgLoader* pLoader = m_loaderFactory.InvokeClass(&szImgExt[1]);
	if (pLoader)
		return pLoader->LoadImage(szImgPath);
	else {
		std::wstring szImgList;
		GetImgListForLoader(szImgList);
        wprintf(L"暂不支持%s图片格式，现已支持的格式有：%s\n", &szImgExt[1], szImgList.c_str());
	}
	return NULL;
}

bool CImageFactory::InvokeSaver(wchar_t * szImgPath, Gdiplus::Image* pImg, wchar_t* szImgType)
{
	if (!pImg || !szImgPath) return false;
	wchar_t szImgExt[10] = {0};
	_wsplitpath(szImgPath, NULL, NULL, NULL, szImgExt);
	CImgSaver* pLoader = m_saverFactory.InvokeClass(szImgType? szImgType : &szImgExt[1]);
	if (pLoader)
		return pLoader->SaveImage(szImgPath, pImg, szImgType);
	else {
		std::wstring szImgList;
		GetImgListForSaver(szImgList);
		wprintf(L"暂不支持%s图片格式，现已支持的格式有：%s\n", &szImgExt[1], szImgList.c_str());
	}
	return false;
}

#ifndef IMPLEMENT_GET_IMGLIST
#define IMPLEMENT_GET_IMGLIST(szList, objFactory)					  \
	std::list<std::wstring> imgTypes = objFactory.GetKeys();	      \
	std::list<std::wstring>::iterator it = imgTypes.begin();		  \
	for (; it != imgTypes.end(); it++)								  \
	{																  \
		szList += it != imgTypes.begin() ? L"|" : L"";			      \
		szList += *it;											      \
	}																  \

#endif

void CImageFactory::GetImgListForLoader(std::wstring &szImgList)
{
	IMPLEMENT_GET_IMGLIST(szImgList, m_loaderFactory)
}

void CImageFactory::GetImgListForSaver(std::wstring &szImgList)
{
	IMPLEMENT_GET_IMGLIST(szImgList, m_saverFactory)
}
