#include <common/opndlgex.hpp>
#include <common/notify.hpp>
#include <common/array.hpp>

CustomOpenDialog::CustomOpenDialog(void)
{
  mInitHandler.setCallback(this,&CustomOpenDialog::initHandler);
	mCommandHandler.setCallback(this,&CustomOpenDialog::commandHandler);
	mNotifyHandler.setCallback(this,&CustomOpenDialog::notifyHandler);
	insertHandler(VectorHandler::InitDialogHandler,&mInitHandler);
	insertHandler(VectorHandler::CommandHandler,&mCommandHandler);
	insertHandler(VectorHandler::NotifyHandler,&mNotifyHandler);
}

CustomOpenDialog::CustomOpenDialog(const CustomOpenDialog &someCustomOpenDialog)
{ // private implementation
  *this=someCustomOpenDialog;
}

CustomOpenDialog::~CustomOpenDialog()
{
	removeHandler(VectorHandler::InitDialogHandler,&mInitHandler);
	removeHandler(VectorHandler::CommandHandler,&mCommandHandler);
	removeHandler(VectorHandler::NotifyHandler,&mNotifyHandler);
}

CustomOpenDialog &CustomOpenDialog::operator=(const CustomOpenDialog &someCustomOpenDialog)
{ // private implementation
  return *this;
}

const String &CustomOpenDialog::openFileName(void)
{
  return mOpenFileNameString;
}

void CustomOpenDialog::setFilterPattern(const String &strFilterPattern)
{
  mFilterPatternString=strFilterPattern;
}

void CustomOpenDialog::setTitle(const String &strTitle)
{
  mTitleString=strTitle;
}

void CustomOpenDialog::setFileTitle(const String &strFileTitle)
{
  mFileTitleString=strFileTitle;
}

BOOL CustomOpenDialog::perform(GUIWindow &parentWindow,const String &strTemplateName)
{
  String filterString;

  if(strTemplateName.isNull())return FALSE;
  if(mFilterPatternString.isNull()||mTitleString.isNull())return FALSE;
	filterString=mFilterPatternString.betweenString('.',0);
	mOpenDialog.instance(parentWindow.processInstance());
	mOpenDialog.templateName(strTemplateName);
	mOpenDialog.filter(filterString);
	mOpenDialog.filterPattern(mFilterPatternString);
	if(mFileTitleString.isNull())mOpenDialog.fileName(mFilterPatternString);
	else mOpenDialog.fileName(mFileTitleString);
	mOpenDialog.title(mTitleString);
	mOpenDialog.fileTitle(mTitleString);
	mOpenDialog.creationFlags(OpenDialog::Flags(OpenDialog::EXPLORER|OpenDialog::PATHMUSTEXIST|OpenDialog::ENABLEHOOK|OpenDialog::ENABLETEMPLATE));
	mOpenDialog.hookProc((LPOFNHOOKPROC)&DWindow::OFHookProc);
	mOpenDialog.customData((DWORD)(GUIWindow*)(DWindow*)this);
	mOpenDialog.owner(parentWindow);
	if(!mOpenDialog.getOpenFileName())return FALSE;
	mOpenFileNameString=mOpenDialog.fileName();
  return TRUE;
}

CallbackData::ReturnType CustomOpenDialog::commandHandler(CallbackData &someCallbackData)
{
  return handleCommand(someCallbackData);
}

CallbackData::ReturnType CustomOpenDialog::initHandler(CallbackData &someCallbackData)
{
  return handleInit(someCallbackData);
}

CallbackData::ReturnType CustomOpenDialog::notifyHandler(CallbackData &someCallbackData)
{
  NotifyMessageHeader notifyMessageHeader;
  OFNOTIFY *pOFNOTIFY=(OFNOTIFY*)someCallbackData.lParam();
	if(!pOFNOTIFY)return FALSE;
	notifyMessageHeader=pOFNOTIFY->hdr;
	switch(notifyMessageHeader.code())
	{
	  case CDN_FILEOK :
		  if(handleFileOk(notifyMessageHeader)){::SetWindowLong(*this,DWL_MSGRESULT,TRUE);return TRUE;}
			return FALSE;
	  case CDN_FOLDERCHANGE :
		  return handleFolderChange(notifyMessageHeader);
		case CDN_HELP :
		  return handleHelp(notifyMessageHeader);
		case CDN_INITDONE :
		  return handleInitDone(notifyMessageHeader);
		case CDN_SELCHANGE :
		  return handleSelChange(notifyMessageHeader);
		case CDN_SHAREVIOLATION :
		  return handleShareViolation(notifyMessageHeader);
		case CDN_TYPECHANGE :
		  return handleTypeChange(notifyMessageHeader);
	}
	return FALSE;
}

BOOL CustomOpenDialog::getFilePath(String &strFilePath)const
{
  String svFilePath;

	if(!isValid())return FALSE;
  if(0>GUIWindow::sendMessage(parent(),CDM_GETFILEPATH,String::MaxString,(LPARAM)(LPSTR)svFilePath))return FALSE;
	strFilePath=svFilePath;
	return TRUE;
}

BOOL CustomOpenDialog::setDefaultExtension(const String &strDefExt)const
{
  if(!isValid()||strDefExt.isNull())return FALSE;
  GUIWindow::sendMessage(parent(),CDM_SETDEFEXT,0,(LPARAM)(LPSTR)(String&)strDefExt);
	return TRUE;
}

BOOL CustomOpenDialog::getFolderIDList(Array<BYTE> &arrayList)const
{
  DWORD requiredBytes;

  if(!isValid())return FALSE;
  requiredBytes=GUIWindow::sendMessage(parent(),CDM_GETFOLDERIDLIST,0,0L);
	arrayList.size(requiredBytes);
	return arrayList.size()==GUIWindow::sendMessage(parent(),CDM_GETFOLDERIDLIST,requiredBytes,(LPARAM)(LPSTR)&arrayList[0]);
}

BOOL CustomOpenDialog::getFolderPath(String &strFolderPath)const
{
  String svFolderPath;

	if(!isValid())return FALSE;
  if(0>GUIWindow::sendMessage(parent(),CDM_GETFOLDERPATH,String::MaxString,(LPARAM)(LPSTR)svFolderPath))return FALSE;
	strFolderPath=svFolderPath;
	return TRUE;
}

BOOL CustomOpenDialog::getSpec(String &strFileSpec)const
{
  String svFileSpec;

  if(!isValid())return FALSE;
  if(0>GUIWindow::sendMessage(parent(),CDM_GETSPEC,String::MaxString,(LPARAM)(LPSTR)svFileSpec))return FALSE;
	strFileSpec=svFileSpec;
	return TRUE;
}

BOOL CustomOpenDialog::hideControl(UINT controlID)const
{
  if(!isValid())return FALSE;
  GUIWindow::sendMessage(parent(),CDM_HIDECONTROL,(WPARAM)controlID,0L);
	return TRUE;
}

BOOL CustomOpenDialog::setControlText(UINT controlID,const String &strControlText)const
{
  if(!isValid()||strControlText.isNull())return FALSE;
  GUIWindow::sendMessage(parent(),CDM_SETCONTROLTEXT,(WPARAM)controlID,(LPARAM)(LPSTR)(String&)strControlText);
	return TRUE;
}

// **** virtuals

BOOL CustomOpenDialog::handleFileOk(const NotifyMessageHeader &/*notifyMessageHeader*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleFolderChange(const NotifyMessageHeader &/*notifyMessageHeader*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleHelp(const NotifyMessageHeader &/*notifyMessageHeader*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleInitDone(const NotifyMessageHeader &/*notifyMesageHeader*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleSelChange(const NotifyMessageHeader &/*notifyMessageHeader*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleShareViolation(const NotifyMessageHeader &/*notifyMessageHeader*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleTypeChange(const NotifyMessageHeader &/*notifyMessageHeader*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleCommand(CallbackData &/*someCallbackData*/)
{
  return FALSE;
}

BOOL CustomOpenDialog::handleInit(CallbackData &/*someCallbackData*/)
{
  return TRUE;
}
