#include <coral/core/Element.h>
#include <coral/coral.h>
#include <coral/core/garbage_collector.h>
#include <coral/core/util/TransactionManager.h>

#include <iostream>


#include <unistd.h>

int main() {
	coral::init_coral_framework();
	coral::autounref<coral::Language> uml14
		= coral::Language::__getLanguage__("UML", 1, 4);

	int i = coral::all_modelelements_size();

	coral::Atom* _c = uml14->getElement("Class")->newAtom();
	coral::Atom* _m = uml14->getElement("Model")->newAtom();
	coral::Element* c = static_cast<coral::Element*>(_c);
	coral::Element* m = static_cast<coral::Element*>(_m);

	m->__getSlotByName__("ownedElement").insert(c);

	coral::Transaction::Manager* manager = coral::Transaction::getTransactionManager();
	coral_assert(manager);

	coral_assert(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() == coral::unicodestring("", true));

	manager->beginModifyCmd();

	dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__setString__(coral::unicodestring("newclassname", true));

	manager->endModifyCmd();

	coral_assert(manager->canUndo());
	coral_assert(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() == coral::unicodestring("newclassname", true));
	manager->undo();
	coral_assert(!manager->canUndo());
	std::cout << "Class name " << dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() << std::endl;
	coral_assert(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() == coral::unicodestring("", true));
	coral_assert(manager->canRedo());
	manager->redo();
	coral_assert(!manager->canRedo());
	std::cout << "Class name " << dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() << std::endl;
	coral_assert(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() == coral::unicodestring("newclassname", true));

	manager->beginModifyCmd();
	dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__setString__(coral::unicodestring("newclassname2", true));
	dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__setString__(coral::unicodestring("newclassname3", true));
	manager->endModifyCmd();

	coral_assert(manager->canUndo());
	std::cout << "Class name " << dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() << std::endl;
	coral_assert(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() == coral::unicodestring("newclassname3", true));
	manager->undo();
	std::cout << "Class name " << dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() << std::endl;
	coral_assert(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() == coral::unicodestring("newclassname", true));

	coral_assert(manager->canRedo());
	manager->redo();
	coral_assert(manager->canUndo());
	std::cout << "Class name " << dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() << std::endl;
	coral_assert(dynamic_cast<coral::ElementString*>(c->__getSlotByName__("name")[0])->__getString__() == coral::unicodestring("newclassname3", true));

	return 0;
}
