///////////////////////////////////////////////////////////////////////////////
/// @file Assembler.cpp
///
/// @brief Destiny3D Shader Assembler
///
/// @author JesusFreak
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date May 2002
/// @author JesusFreak
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

// Include needed headers
#include "deString.hpp"
#include "deFileSystem.hpp"
#include "deDriver.hpp"
#include "iostream.h"

// The name of the inputfile
deString InputFile;

void ErrorCallback(int Line,char * Error)
{
	cout << InputFile << "(" << Line << ") : " << Error << "\n";
}

/////////////////////////////////////////////////////////////////////////////////////////////
// deBoolean Assemble(int ArgCount,char * Arguments[]) - The main program for the assembler
/////////////////////////////////////////////////////////////////////////////////////////////
deBoolean Assemble(int ArgCount,char * Arguments[])
{
	// Get the names of the input and output files.
	InputFile = Arguments[2];
	deString OutputFile = Arguments[3];

	// Open the shader file
	deFSReal ShaderFile;
	if(!ShaderFile.Open(InputFile,deFS_Open_Existing | deFS_Open_Read))
	{
		cout << "Error opening shader file.\n";
		return deFALSE;
	}

	// Get the size of the file
	long FileSize = ShaderFile.GetSize();
	if(FileSize <= 0)
	{
		ShaderFile.Close();
		cout << "Error reading file. The input file may not be valid shader file.\n";
		return deFALSE;
	}

	// Create a buffer to hold the file
	char * Buffer = new char[FileSize];

	// Read the file into the buffer
	if(ShaderFile.Read(Buffer,FileSize) != FileSize)
	{
		ShaderFile.Close();
		cout << "Error reading file.\n";
		return deFALSE;
	}

	// Close the shader file
	ShaderFile.Close();

	// Create a new shader object
	IdeShader * Shader = IdeShader_Create();

	deBoolean Ret = Shader->Assemble(Buffer,ErrorCallback);

	// Free the buffer
	delete[] Buffer;
	Buffer = NULL;

	if(Ret)
	{
		// Open the output file
		deFSReal AssembledFile;
		if(!AssembledFile.Open(OutputFile,deFS_Open_CreateAlways | deFS_Open_Write))
		{
			cout << "Error creating output file.\n";
			Shader->Release();
			return deFALSE;
		}

		// Write the shader to the output file
		Ret = Shader->Write(&AssembledFile);

		// Close the assembled file
		AssembledFile.Close();

		cout << "Shader assembled successfully\n";
	}
	else
	{
		cout << "Error Assembling shader\n";
	}

	// Release our shader object
	Shader->Release();

	return Ret;
}