/***************************************************************************
                          commands_insert  -  description
                             -------------------
    begin                : Wed Nov 26 2003
    copyright            : (C) 2003 by The KXMLEditor Team
    email                : lvanek@user.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
#include "commands_insert.h"

#include <tqstring.h>

#include <kdebug.h>

//////////////////////////////////////////////////////////////////////////////////////////
///////////		Inserting new XML element			//////////
//////////////////////////////////////////////////////////////////////////////////////////

KXEElementCommand::KXEElementCommand(
  KXEDocument *pDocument,
  TQDomDocument * pDomDoc,
  TQString strNsURI,
  TQString strPrefix,
  TQString strName
  )
 : KXECommand(pDocument)
{
  if ( pDomDoc == 0 )
    kdError() << "KXEElementCommand::KXEElementCommand the given XML document object is empty." << endl;
 
  m_pDomDoc = pDomDoc;
  
  if ( strNsURI.isEmpty() )
    m_domElement = m_pDomDoc->createElement( strName );
  else
    m_domElement = m_pDomDoc->createElementNS( strNsURI, strPrefix + ":" + strName );
}

KXEElementCommand::KXEElementCommand(
  KXEDocument *pDocument,
  TQDomElement & domParentElement,
  TQString strNsURI,
  TQString strPrefix,
  TQString strName,
  bool bAtTop
  )
 : KXECommand(pDocument)
{
  if ( domParentElement.isNull() )
    kdError() << "KXEElementCommand::KXEElementCommand the given XML element object is empty." << endl;

  m_domParentElement = domParentElement;
  m_pDomDoc = 0;
  m_bAtTop = bAtTop;

  if ( strNsURI.isEmpty() )
    m_domElement = m_domParentElement.ownerDocument().createElement( strName );
  else
    m_domElement = m_domParentElement.ownerDocument().createElementNS( strNsURI, strPrefix + ":" + strName );
}

KXEElementCommand::~KXEElementCommand()
{
}

void KXEElementCommand::execute()
{
  if ( m_pDomDoc )
  {
    // Insert root element
    m_pDomDoc->appendChild( m_domElement );
  }
  else
  {
    if( !m_domParentElement.isNull() )
    {
      // Insert child element
      if ( m_bAtTop )
      {                                         // insert as first child
        TQDomNode domFirstChildNode = m_domParentElement.firstChild();
        if ( domFirstChildNode.isNull() )
          m_domParentElement.appendChild( m_domElement ); // no childs yet -> simply append
        else
          m_domParentElement.insertBefore( m_domElement, domFirstChildNode );
      }
      else                                      // insert as last child
        m_domParentElement.appendChild( m_domElement );
    }
    else
    {
      kdError() << "KXEElementCommand::execute document and element object is empty." << endl;
    }
  }
  m_pDocument->updateNodeCreated(m_domElement);
}

void KXEElementCommand::unexecute()
{
  if ( m_domElement.parentNode().removeChild( m_domElement ).isNull() )
		kdError() << "KXEElementCommand::unexecute error removing the selected node." << endl;
	else
	{
		m_pDocument->updateNodeDeleted(m_domElement);
  }
}

//////////////////////////////////////////////////////////////////////////////////////////
///////////		inserting new attribute				//////////
//////////////////////////////////////////////////////////////////////////////////////////

KXEAttributeCommand::KXEAttributeCommand(
  KXEDocument *pDocument,
  TQDomElement &domOwnerElement,
  TQString strNamespace,
  TQString strQName,
  TQString strValue
  )
 : KXECommand(pDocument)
{
  if ( domOwnerElement.isNull() )
	{
		kdError() << k_funcinfo << "KXEAttributeCommand::KXEAttributeCommand - The given owner element is empty." << endl;
		return;
	}

  m_domOwnerElement = domOwnerElement;
  m_strNamespace = strNamespace;
  m_strQName = strQName;
  m_strValue = strValue;
}

KXEAttributeCommand::~KXEAttributeCommand()
{
}

void KXEAttributeCommand::execute()
{
  if ( m_strNamespace.isEmpty() )
		m_domOwnerElement.setAttribute( m_strQName, m_strValue );
	else
		m_domOwnerElement.setAttributeNS( m_strNamespace, m_strQName, m_strValue );

  m_pDocument->updateNodeChanged( m_domOwnerElement ) ;
}

void KXEAttributeCommand::unexecute()
{
  if ( m_strNamespace.isEmpty() )
    m_domOwnerElement.removeAttribute(m_strQName);
  else
    m_domOwnerElement.removeAttributeNS(m_strNamespace, m_strQName);

  m_pDocument->updateNodeChanged( m_domOwnerElement ) ;
}

//////////////////////////////////////////////////////////////////////////////////////////
///////////		Inserting new character data			//////////
//////////////////////////////////////////////////////////////////////////////////////////

KXECharDataCommand::KXECharDataCommand(
  KXEDocument *pDocument,
  TQDomElement & domParentElement,
  bool bAtTop,
  CharDataKind eCharDataKind,
  TQString strContents
  )
 : KXECommand(pDocument)
{
  if ( domParentElement.isNull() )
	{
		kdError() << k_funcinfo << "KXECharDataCommand::KXECharDataCommand - The given parent object is empty." << endl;
		return;
	}
  
  m_domParentElement = domParentElement;
  m_bAtTop = bAtTop;

  switch ( eCharDataKind )
  {
    case CharDataTextNode:
          m_domCharData = domParentElement.ownerDocument().createTextNode( strContents );
          break;

    case CharDataCDATASection:
          m_domCharData = domParentElement.ownerDocument().createCDATASection( strContents );
          break;

    case CharDataComment:
          m_domCharData = domParentElement.ownerDocument().createComment( strContents );
          break;

    default:
          kdError() << "KXECharDataCommand::KXECharDataCommand unrecognized char. data type." << endl;
          break;    
   }         
}

KXECharDataCommand::~KXECharDataCommand()
{
}

void KXECharDataCommand::execute()
{
  if ( m_bAtTop )
		{                                         // insert as first child
			TQDomNode domFirstChildNode = m_domParentElement.firstChild();
			if ( domFirstChildNode.isNull() )
				m_domParentElement.appendChild( m_domCharData ); // no childs yet -> simply append
			else
				m_domParentElement.insertBefore( m_domCharData, domFirstChildNode );
		}
		else                                      // insert as last child
			m_domParentElement.appendChild( m_domCharData );

   m_pDocument->updateNodeCreated(m_domCharData);
}

void KXECharDataCommand::unexecute()
{
  if ( m_domCharData.parentNode().removeChild( m_domCharData ).isNull() )
		kdError() << "KXECharDataCommand::unexecute error removing the selected node." << endl;
	else
	{
		m_pDocument->updateNodeDeleted(m_domCharData);
  }
}

//////////////////////////////////////////////////////////////////////////////////////////
///////////		Inserting new proc instr.			//////////
//////////////////////////////////////////////////////////////////////////////////////////

KXEProcInstrCommand::KXEProcInstrCommand(
  KXEDocument *pDocument,
  TQDomDocument * pDomDoc,
  bool bAtTop,
  TQString strTarget,
  TQString strData
  )
 : KXECommand(pDocument)
{
  if ( pDomDoc == 0 )
	{
		kdError() << k_funcinfo << "KXEProcInstrCommand::KXEProcInstrCommand - The given parent object is empty." << endl;
		return;
	}
	
  m_pDomDoc = pDomDoc;
  m_bAtTop = bAtTop;
  
  m_domProcInstr = pDomDoc->createProcessingInstruction( strTarget, strData );
}

KXEProcInstrCommand::KXEProcInstrCommand(
  KXEDocument *pDocument,
  TQDomElement & domParentElement,
  bool bAtTop,
  TQString strTarget,
  TQString strData
  )
 : KXECommand(pDocument)
{
  if ( domParentElement.isNull() )
	{
		kdError() << k_funcinfo << "KXEProcInstrCommand::KXEProcInstrCommand - The given parent object is empty." << endl;
		return;
	}
	
  m_domParentElement = domParentElement;
  m_pDomDoc = 0;
  m_bAtTop = bAtTop;

  m_domProcInstr = domParentElement.ownerDocument().createProcessingInstruction( strTarget, strData );
}


KXEProcInstrCommand::~KXEProcInstrCommand()
{
}

void KXEProcInstrCommand::execute()
{
  if ( m_pDomDoc )
  {
    // Insert root proc. instr
    m_pDomDoc->appendChild( m_domProcInstr );
  }
  else
  {
    if( !m_domParentElement.isNull() )
    {
      // Insert child proc. instr
      if ( m_bAtTop )
    		{                                         // insert as first child
			TQDomNode domFirstChildNode = m_domParentElement.firstChild();
    			if ( domFirstChildNode.isNull() )
    				m_domParentElement.appendChild( m_domProcInstr ); // no childs yet -> simply append
    			else
    				m_domParentElement.insertBefore( m_domProcInstr, domFirstChildNode );
    		}
    		else                                      // insert as last child
    			m_domParentElement.appendChild( m_domProcInstr );
     }
     else
     {
       kdError() << "KXEElementCommand::execute document and element object is empty." << endl;
     }
   }
   m_pDocument->updateNodeCreated(m_domProcInstr);
}

void KXEProcInstrCommand::unexecute()
{
  if ( m_domProcInstr.parentNode().removeChild( m_domProcInstr ).isNull() )
		kdError() << "KXEProcInstrCommand::unexecute error removing the selected node." << endl;
	else
	{
		m_pDocument->updateNodeDeleted(m_domProcInstr);
  }
}