// This file is part of the Coral project.
// Please read the copyright notice in the LICENSE file.

#include "xmi_writer_common.h"

#include <sstream>
#include <fstream>
#include <coral/core/Project.h>

namespace coral { namespace io {

	NAMESPACE_BEGIN();
	const char* escape_table[] = {
		"&", "&amp;",
		"<", "&lt;",
		">", "&gt;",
		"\"","&quot;",
		"\011", "&#9;",
		"\012", "&#10;",
		"\015", "&#13;",
	};
	NAMESPACE_END();

	std::string escape(const std::string& to_escape) {
		std::string result(to_escape);

		for (const char** search_for = &escape_table[0];
		     search_for < &escape_table[ARRAY_SIZE(escape_table)];
		     search_for += 2) {
			std::string::size_type pos = 0;
			for (;;) {
				std::string::size_type match;
				match = result.find_first_of(*search_for, pos);
				if (match == std::string::npos) break;
				result.replace(match, 1, *(search_for+1) );
				pos = match + std::strlen(*(search_for+1)) - 1;
			}
		}

		return result;
	}

	std::string qescape(const std::string& to_escape) {
		std::string result("\"");
		result += escape(to_escape);
		result += "\"";
		return result;
	}

	void writeField(std::ostream& out,
			const ElementPrimitive* e,
			int margin) {
		std::string spaces(margin, ' '); // could be faster...
		out << spaces
		    << "<XMI.field>" << escape(e->__str__().toUTF8()) << "</XMI.field>\n";
	}



	XMIStreamerCommon::XMIStreamerCommon() {
		id_ctr = 0;
	}

	XMIStreamerCommon::~XMIStreamerCommon() throw () {
		;
	}

static const std::string eclipse_ns =
  "http://www.eclipse.org/emf/2002/Ecore";
		
	std::string XMIStreamerCommon::getID(const Element* e) {
		e2id_type::const_iterator i = e2id.find(e);
		int id = -1;
		if (i == e2id.end()) {
			/*
			 * Stupid stupid stupid. See note in
			 * xmi_writer_2.
			 */
			/*
			 * Eclipse compat
			 */
			bool iseclipse =
				(e->__type__()->__package__()->getXMLNS() == eclipse_ns);

			if (iseclipse) {
				return e->__XMIid__();
			}
			id = ++id_ctr;
			e2id[e] = id;
		} else {
			id = (*i).second;
		}
		std::ostringstream ret;
		ret << "e" << id;
		return ret.str();
	}

} }
