// -*- C++ -*-

/* 
 * GChemPaint library
 * operation.h 
 *
 * Copyright (C) 2002-2005 Jean Bréfort <jean.brefort@normalesup.org>
 *
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include "gchempaint-config.h"
#include "operation.h"
#include "document.h"
#include <cstring>

xmlDocPtr pXmlDoc = xmlNewDoc((const xmlChar*)"1.0");//Needed to create xmlNodes

gcpOperation::gcpOperation(gcpDocument* pDoc, unsigned long ID):
	m_pDoc (pDoc),
	m_ID (ID)
{
}

gcpOperation::~gcpOperation()
{
	if (m_Nodes) delete[] m_Nodes;
}

void gcpOperation::Undo(){}
void gcpOperation::Redo(){}

void gcpOperation::Add(unsigned type)
{
	m_pDoc->LoadObjects(m_Nodes[type]);
}

void gcpOperation::Delete (unsigned type)
{
	xmlNodePtr node = m_Nodes[type]->children;
	char* Id;
	while (node)
	{
		Id = (strcmp ((const char*) node->name, "object"))?
			 (char*) xmlGetProp (node, (xmlChar*) "id"):
			 (char*) xmlGetProp (node->children, (xmlChar*) "id");
		m_pDoc->Remove (Id);
		xmlFree (Id);
		node = node->next;
	}
}

void gcpOperation::AddObject(Object* pObject, unsigned type)
{
	xmlNodePtr node = pObject->Save(pXmlDoc);
	if (node) xmlAddChild(m_Nodes[type], node);
}

void gcpOperation::AddNode(xmlNodePtr node, unsigned type)
{
	if (node) xmlAddChild(m_Nodes[type], node);
}

gcpAddOperation::gcpAddOperation(gcpDocument* pDoc, unsigned long ID): gcpOperation(pDoc, ID)
{
	m_Nodes = new xmlNodePtr[1];
	*m_Nodes = xmlNewDocNode(pXmlDoc, NULL, (const xmlChar*)"add", NULL);
}

gcpAddOperation::~gcpAddOperation()
{
	if (*m_Nodes) xmlFreeNode(*m_Nodes);
}

void gcpAddOperation::Undo()
{
	Delete();
}

void gcpAddOperation::Redo()
{
	Add();
}

gcpDeleteOperation::gcpDeleteOperation(gcpDocument* pDoc, unsigned long ID): gcpOperation(pDoc, ID)
{
	m_Nodes = new xmlNodePtr[1];
	*m_Nodes = xmlNewDocNode(pXmlDoc, NULL, (const xmlChar*)"delete", NULL);
}

gcpDeleteOperation::~gcpDeleteOperation()
{
	if (*m_Nodes) xmlFreeNode(*m_Nodes);
}

void gcpDeleteOperation::Undo()
{
	Add();
}

void gcpDeleteOperation::Redo()
{
	Delete();
}

gcpModifyOperation::gcpModifyOperation(gcpDocument* pDoc, unsigned long ID): gcpOperation(pDoc, ID)
{
	m_Nodes = new xmlNodePtr[2];
	m_Nodes[0] = xmlNewDocNode(pXmlDoc, NULL, (const xmlChar*)"before", NULL);
	m_Nodes[1] = xmlNewDocNode(pXmlDoc, NULL, (const xmlChar*)"after", NULL);
}

gcpModifyOperation::~gcpModifyOperation()
{
	if (!m_Nodes) return;
	if (m_Nodes[0]) xmlFreeNode(m_Nodes[0]);
	if (m_Nodes[1]) xmlFreeNode(m_Nodes[1]);
}

void gcpModifyOperation::Undo()
{
	Delete(1);
	Add(0);
}

void gcpModifyOperation::Redo()
{
	Delete(0);
	Add(1);
}


syntax highlighted by Code2HTML, v. 0.9.1