/*
 *  Copyright (c) 2008 Cyrille Berger <cberger@cberger.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version of the License.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "Statement.h"

// Cauchy
#include <Cauchy/Debug.h>
#include <Cauchy/Macros_p.h>
#include <Cauchy/Utils_p.h>
#include <Cauchy/Variable.h>

// AST
#include "Expression.h"
#include "GenerationVisitor.h"

using namespace Cauchy::AST;

void Statement::setComment(const Cauchy::String& str)
{
  m_comment = str;
}

Cauchy::String Statement::comment() const
{
  return m_comment;
}

CommentStatement::CommentStatement(const Cauchy::String& str) : m_string(str)
{
}

CommentStatement::~CommentStatement()
{
}

void CommentStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->generateComment(m_string, annotation());
}

StatementsList::~StatementsList()
{
  deleteAll( m_list );
}

void StatementsList::appendStatement( Statement* _statement )
{
  m_list.push_back( _statement );
}

void StatementsList::generateStatement( GenerationVisitor* _generationVisitor) const
{
  foreach(Statement* statement, m_list)
  {
    statement->generateStatement(_generationVisitor);
  }
}

//---------------------------------------------------//
//------------------- IfStatement -------------------//
//---------------------------------------------------//
IfStatement::~IfStatement()
{
  delete m_expression;
  delete m_ifStatement;
}

void IfStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->generateIfElseStatement(m_expression->generateValue(_generationVisitor), m_ifStatement, std::vector< std::pair<Expression*, Statement*> >(), 0, comment(), annotation());
}

IfElseStatement::~IfElseStatement()
{
  delete m_expression;
  delete m_ifStatement;
  delete m_elseStatement;
}

void IfElseStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->generateIfElseStatement(m_expression->generateValue(_generationVisitor), m_ifStatement, m_elseIfStatements, m_elseStatement, comment(), annotation());
}

ForStatement::~ForStatement()
{
  delete m_expression;
  delete m_forStatement;
}

WhileStatement::~WhileStatement()
{
  delete m_expression;
  delete m_whileStatement;
}

void WhileStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->startWhileStatement(m_expression->generateValue(_generationVisitor), comment(), annotation());
  m_whileStatement->generateStatement(_generationVisitor);
  _generationVisitor->endWhileStatement(annotation());
}

void ForStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->generateForStatement(m_variable, m_expression->generateValue(_generationVisitor), m_forStatement, comment(), annotation());
}

//------------------------- BreakStatment -------------------------//

BreakStatement::BreakStatement()
{
}

BreakStatement::~BreakStatement()
{
}

void BreakStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->generateBreak(annotation());
}

//------------------------- ReturnStatement -------------------------//

ReturnStatement::ReturnStatement(FunctionDefinition* _functionDeclaration) : m_functionDeclaration( _functionDeclaration)
{
}

ReturnStatement::~ReturnStatement()
{
}

void ReturnStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->generateReturnStatement(m_functionDeclaration, comment(), annotation());
}

//------------------------- PrintStatement -------------------------//

PrintStatement::PrintStatement(Cauchy::AST::Expression* _expr ) : m_expr(_expr)
{
}

PrintStatement::~PrintStatement()
{
  delete m_expr;
}

void PrintStatement::generateStatement( GenerationVisitor* _generationVisitor) const
{
  _generationVisitor->generatePrintStatement(m_expr->generateValue(_generationVisitor), comment(), annotation());
}
