/*******************************************************************************
 * filemessagehandler.cpp
 *
 * ---------------------------------------------------------------------------
 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
 *
 * POV-Ray is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * POV-Ray is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * ---------------------------------------------------------------------------
 * POV-Ray is based on the popular DKB raytracer version 2.12.
 * DKBTrace was originally written by David K. Buck.
 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
 * ---------------------------------------------------------------------------
 * $File: //depot/public/povray/3.x/source/frontend/filemessagehandler.cpp $
 * $Revision: #1 $
 * $Change: 6069 $
 * $DateTime: 2013/11/06 11:59:40 $
 * $Author: chrisc $
 *******************************************************************************/

// configbase.h must always be the first POV file included within base *.cpp files
#include "base/configbase.h"
#include "base/types.h"
#include "base/path.h"

#include "frontend/configfrontend.h"
#include "frontend/renderfrontend.h"
#include "frontend/filemessagehandler.h"

// this must be the last file included
#include "base/povdebug.h"

namespace pov_frontend
{

FileMessageHandler::FileMessageHandler()
{
}

FileMessageHandler::~FileMessageHandler()
{
}

void FileMessageHandler::HandleMessage(const SceneData& sd, POVMSType ident, POVMS_Object& msg, POVMS_Object& result)
{
	switch(ident)
	{
		case kPOVMsgIdent_FindFile:
			(void)FindFile(sd.searchpaths, msg, result);
			break;
		case kPOVMsgIdent_ReadFile:
			if(ReadFile(sd.searchpaths, msg, result) == true)
				sd.readfiles.push_back(result);
			break;
		case kPOVMsgIdent_CreatedFile:
			CreatedFile(msg);
			sd.createdfiles.push_back(msg);
			break;
	}
}

bool FileMessageHandler::FindFile(const list<Path>& lps, POVMS_Object& msg, POVMS_Object& result)
{
	POVMS_List files;
	Path path;

	msg.Get(kPOVAttrib_ReadFile, files);

	for(int i = 1; i <= files.GetListSize(); i++)
	{
		POVMS_Attribute attr;

		files.GetNth(i, attr);

		path = FindFilePath(lps, Path(attr.GetUCS2String()));

		if(path.Empty() == false)
			break;
	}

	result.SetUCS2String(kPOVAttrib_ReadFile, path().c_str());

	return (path.Empty() == false);
}

bool FileMessageHandler::ReadFile(const list<Path>& lps, POVMS_Object& msg, POVMS_Object& result)
{
	Path path(FindFilePath(lps, Path(msg.GetUCS2String(kPOVAttrib_ReadFile))));

	if(path.Empty() == false)
		result.SetUCS2String(kPOVAttrib_LocalFile, path().c_str());

	return (path.Empty() == false);
}

void FileMessageHandler::CreatedFile(POVMS_Object&)
{
}

Path FileMessageHandler::FindFilePath(const list<Path>& lps, const Path& f)
{
	// check the current working dir (or full path if supplied) first
	// note that if the file doesn't have a path and it is found in the
	// CWD, the CWD is not returned as part of the path.
	if(CheckIfFileExists(f) == true)
		return f;

	// if the path is absolute there's no point in checking the include paths;
	// given it wasn't found above we can just return an empty path
	if(f.HasVolume() == true)
		return Path();

	Path path(f);

	for(list<Path>::const_iterator i(lps.begin()); i != lps.end(); i++)
	{
		Path path (*i, f);

		if(CheckIfFileExists(path) == true)
			return path;
	}

	// not found so return empty path
	return Path();
}

}
