#include <list>

#include "SynTree/Statement.h"
#include "ChooseMutator.h"

namespace ControlStruct {
    Statement *ChooseMutator::mutate( ChooseStmt *chooseStmt) {
	bool enclosingChoose = insideChoose;
	insideChoose = true;
	mutateAll( chooseStmt->get_branches(), *this );
	insideChoose = enclosingChoose;
	return new SwitchStmt( chooseStmt->get_labels(),  chooseStmt->get_condition(), chooseStmt->get_branches() );
    }

    Statement *ChooseMutator::mutate( SwitchStmt *switchStmt ) {
	bool enclosingChoose = insideChoose;
	insideChoose = false;
	mutateAll( switchStmt->get_branches(), *this );
	insideChoose = enclosingChoose;
	return switchStmt;
    }

    Statement *ChooseMutator::mutate( FallthruStmt *fallthruStmt ) {
	delete fallthruStmt;
	return new NullStmt();
    }

    Statement* ChooseMutator::mutate(CaseStmt *caseStmt) {
	std::list< Statement * > &stmts = caseStmt->get_statements();

	if ( insideChoose ) {
	    BranchStmt *posBrk;
	    if ( (( posBrk = dynamic_cast< BranchStmt * > ( stmts.back() ) ) && 
		  ( posBrk->get_type() == BranchStmt::Break ))  // last statement in the list is a (superfluous) 'break' 
		 || dynamic_cast< FallthruStmt * > ( stmts.back() ) )
		; 
	    else {
		stmts.push_back( new BranchStmt( std::list< Label >(), "", BranchStmt::Break ) );
	    } // if
	} // if

	mutateAll ( stmts, *this );
	return caseStmt;
    }
} // namespace ControlStruct
