//-----------------------------------------------------------------------------
// File: CSourceWriter.cpp
//-----------------------------------------------------------------------------
// Project: Kactus 2
// Author: Joni-Matti Maatta
// Date: 6.12.2011
//
// Description:
// Text writer for writing C source files.
//-----------------------------------------------------------------------------

#include "CSourceWriter.h"

#include <QFileInfo>
#include <QDateTime>

//-----------------------------------------------------------------------------
// Function: CSourceWriter::CSourceWriter()
//-----------------------------------------------------------------------------
CSourceWriter::CSourceWriter(QString const& filename, QString const& indentString)
    : indentString_(indentString), indentLevel_(0), file_(filename), stream_()
{
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::~CSourceWriter()
//-----------------------------------------------------------------------------
CSourceWriter::~CSourceWriter()
{
    file_.close();
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::open()
//-----------------------------------------------------------------------------
bool CSourceWriter::open()
{
    // Open the file for writing.
    if (!file_.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        return false;
    }

    stream_.setDevice(&file_);

    return true;
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::increaseIndentLevel()
//-----------------------------------------------------------------------------
void CSourceWriter::increaseIndentLevel()
{
    ++indentLevel_;
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::decreaseIndentLevel()
//-----------------------------------------------------------------------------
void CSourceWriter::decreaseIndentLevel()
{
    if (indentLevel_ > 0)
    {
        --indentLevel_;
    }
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::writeFileHeader()
//-----------------------------------------------------------------------------
void CSourceWriter::writeFileHeader()
{
	QDateTime now = QDateTime::currentDateTime();

	// Write the file header comment.
	writeLine("/*");
	writeLine(" * File: " + QFileInfo(file_.fileName()).fileName());
	writeLine(" *");
	writeLine(" *  Generated by Kactus2 on " + now.date().toString("yyyy-MM-dd") + ".");
	writeLine(" */");
	writeEmptyLine();
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::writeLine()
//-----------------------------------------------------------------------------
void CSourceWriter::writeLine(QString const& line)
{
    // Write indentation.
    for (unsigned int i = 0; i < indentLevel_; ++i)
    {
        stream_ << indentString_;
    }

    stream_ << line << Qt::endl;
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::writeEmptyLine()
//-----------------------------------------------------------------------------
void CSourceWriter::writeEmptyLine()
{
    stream_ << Qt::endl;
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::writeInclude()
//-----------------------------------------------------------------------------
void CSourceWriter::writeInclude(QString const& headerName, bool local)
{
    if (local)
    {
        writeLine("#include \"" + headerName + "\"");
    }
    else
    {
        writeLine("#include <" + headerName + ">");
    }
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::beginBlock()
//-----------------------------------------------------------------------------
void CSourceWriter::beginBlock()
{
    writeLine("{");
    increaseIndentLevel();
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::endBlock()
//-----------------------------------------------------------------------------
void CSourceWriter::endBlock()
{
    decreaseIndentLevel();
    writeLine("}");
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::writeHeaderComment()
//-----------------------------------------------------------------------------
void CSourceWriter::writeHeaderComment(QString const& desc)
{
    writeLine("//-----------------------------------------------------------------------------");
    writeLine("// " + desc);
    writeLine("//-----------------------------------------------------------------------------");
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::beginStruct()
//-----------------------------------------------------------------------------
void CSourceWriter::beginStruct()
{
    writeLine("typedef struct");
    beginBlock();
}

//-----------------------------------------------------------------------------
// Function: CSourceWriter::endStruct()
//-----------------------------------------------------------------------------
void CSourceWriter::endStruct(QString const& name)
{
    decreaseIndentLevel();
    writeLine("} " + name + ";");
}
