#include "FileManager.h"
#include "Window.h"
bool FileManager::writeTriangle(xmlTextWriterPtr writer, const Triangle &triangle, float height) {
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0)
return false;
//if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0)
// return false;
float y = 0.0f;
if(triangle.getDirection() == Triangle::CW) y = height;
if(!writeVertex(writer, triangle.getVertexA().getX(), y, triangle.getVertexA().getY()))
return false;
//if(!writeTexCoords(writer, triangle.getVertexA().getX(), triangle.getVertexA().getY()))
// return false;
if(!writeVertex(writer, triangle.getVertexB().getX(), y, triangle.getVertexB().getY()))
return false;
//if(!writeTexCoords(writer, triangle.getVertexB().getX(), triangle.getVertexB().getY()))
// return false;
if(!writeVertex(writer, triangle.getVertexC().getX(), y, triangle.getVertexC().getY()))
return false;
//if(!writeTexCoords(writer, triangle.getVertexC().getX(), triangle.getVertexC().getY()))
// return false;
//
if(xmlTextWriterEndElement(writer) < 0)
return false;
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0)
return false;
//if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0)
// return false;
y = height;
if(triangle.getDirection() == Triangle::CW) y = 0.0f;
if(!writeVertex(writer, triangle.getVertexC().getX(), y, triangle.getVertexC().getY()))
return false;
//if(!writeTexCoords(writer, triangle.getVertexC().getX(), triangle.getVertexC().getY()))
// return false;
if(!writeVertex(writer, triangle.getVertexB().getX(), y, triangle.getVertexB().getY()))
return false;
//if(!writeTexCoords(writer, triangle.getVertexB().getX(), triangle.getVertexB().getY()))
// return false;
if(!writeVertex(writer, triangle.getVertexA().getX(), y, triangle.getVertexA().getY()))
return false;
//if(!writeTexCoords(writer, triangle.getVertexA().getX(), triangle.getVertexA().getY()))
// return false;
//
if(xmlTextWriterEndElement(writer) < 0)
return false;
return true;
}
bool FileManager::writeSide(xmlTextWriterPtr writer, const Vertex &v1, const Vertex &v2, float height) {
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0)
return false;
//if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0)
// return false;
if(!writeVertex(writer, v1.getX(), 0, v1.getY()))
return false;
if(!writeTexCoords(writer, v1.getX(), v1.getY()))
return false;
if(!writeVertex(writer, v2.getX(), 0, v2.getY()))
return false;
if(!writeTexCoords(writer, v2.getX(), v2.getY()))
return false;
if(!writeVertex(writer, v2.getX(), height, v2.getY()))
return false;
if(!writeTexCoords(writer, v2.getX(), v2.getY()))
return false;
//
if(xmlTextWriterEndElement(writer) < 0)
return false;
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0)
return false;
//if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0)
// return false;
if(!writeVertex(writer, v2.getX(), height, v2.getY()))
return false;
if(!writeTexCoords(writer, v2.getX(), v2.getY()))
return false;
if(!writeVertex(writer, v1.getX(), height, v1.getY()))
return false;
if(!writeTexCoords(writer, v1.getX(), v1.getY()))
return false;
if(!writeVertex(writer, v1.getX(), 0, v1.getY()))
return false;
if(!writeTexCoords(writer, v1.getX(), v1.getY()))
return false;
//
if(xmlTextWriterEndElement(writer) < 0)
return false;
return true;
}
bool FileManager::writeVertex(xmlTextWriterPtr writer, float x, float y, float z) {
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"vertex") < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"x", "%f", x) < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"y", "%f", y) < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"z", "%f", z) < 0)
return false;
//
if(xmlTextWriterEndElement(writer) < 0)
return false;
return true;
}
bool FileManager::writeTexCoords(xmlTextWriterPtr writer, float s, float t) {
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"texcoords") < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"s", "%f", s) < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"t", "%f", t) < 0)
return false;
//
if(xmlTextWriterEndElement(writer) < 0)
return false;
return true;
}
bool FileManager::writeStart(xmlTextWriterPtr writer, const Vertex3d &start) {
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"start") < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"x", "%f", start.getX()) < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"y", "%f", start.getY()) < 0)
return false;
if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"z", "%f", start.getZ()) < 0)
return false;
//
if(xmlTextWriterEndElement(writer) < 0)
return false;
return true;
}
FileManager::FileManager(Window *window) {
this->window = window;
filename = NULL;
dirty = false;
}
FileManager::~FileManager() {
if(filename)
g_free(filename);
}
bool FileManager::save(GtkWindow *parent) {
if(filename == NULL)
return saveAs(parent);
return write();
}
bool FileManager::saveAs(GtkWindow *parent) {
GtkWidget *dialog = gtk_file_chooser_dialog_new(NULL, parent, GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
if(filename)
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
else
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "level.lvl");
if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
gtk_widget_destroy(dialog);
return false;
}
if(filename)
g_free(filename);
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
gtk_widget_destroy(dialog);
if(!filename)
return false;
return write();
}
bool FileManager::write() {
xmlTextWriterPtr writer;
writer = xmlNewTextWriterFilename(filename, 9);
if(!writer)
return false;
if(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterStartDTD(writer, (xmlChar*)"level", (xmlChar*)"-//libzoom//DTD level 0.1//EN", (xmlChar*)"level.dtd") < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterSetIndent(writer, 1) < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterSetIndentString(writer, (xmlChar*)" ") < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterEndDTD(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"level") < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"info") < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterWriteElement(writer, (xmlChar*)"name", (xmlChar*)"Level") < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterWriteElement(writer, (xmlChar*)"desc", (xmlChar*)"Description") < 0) {
xmlFreeTextWriter(writer);
return false;
}
for(Level::iterator object = window->getLevel().begin(); ; object++) {
if(object == window->getLevel().end()) {
xmlFreeTextWriter(writer);
return false;
}
if(!(*object)->isOfType("PlayerStart"))
continue;
if(!writeStart(writer, *(PlayerStart*)&**object)) {
xmlFreeTextWriter(writer);
return false;
}
break;
}
//
if(xmlTextWriterEndElement(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"rooms") < 0) {
xmlFreeTextWriter(writer);
return false;
}
for(Level::iterator object = window->getLevel().begin(); object != window->getLevel().end(); object++) {
if(!(*object)->isOfType("Room"))
continue;
Room *room = (Room*)&**object;
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"room") < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"id", (xmlChar*)room->getName().c_str()) < 0) {
xmlFreeTextWriter(writer);
return false;
}
std::vector triangles;
room->triangulate(triangles);
for(std::vector::iterator triangle = triangles.begin(); triangle != triangles.end(); triangle++) {
if(!writeTriangle(writer, *triangle, room->getHeight())) {
xmlFreeTextWriter(writer);
return false;
}
}
std::vector vertices = *room;
if(room->getDirection() == Triangle::CCW) {
vertices = std::vector(vertices.rbegin(), vertices.rend());
}
for(std::vector::iterator v1 = vertices.begin(); v1 != vertices.end(); v1++) {
std::vector::iterator v2 = v1+1;
if(v2 == vertices.end()) v2 = vertices.begin();
if(!writeSide(writer, *v1, *v2, room->getHeight())) {
xmlFreeTextWriter(writer);
return false;
}
}
//
if(xmlTextWriterEndElement(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
}
//
if(xmlTextWriterEndElement(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"gates") < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterEndElement(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterStartElement(writer, (xmlChar*)"textures") < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterEndElement(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
//
if(xmlTextWriterEndElement(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
if(xmlTextWriterEndDocument(writer) < 0) {
xmlFreeTextWriter(writer);
return false;
}
xmlFreeTextWriter(writer);
return true;
}