//
// C++ Interface: kxedocument
//
// Description:
//
//
// Author: Adam Charytoniuk <achary@poczta.onet.pl>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef KXEDOCUMENT_H
#define KXEDOCUMENT_H

#include <kurl.h>

#include <tqobject.h>
#include <tqdom.h>
#include <tdeparts/part.h>
#include <kxmlguiclient.h>

#define SCHEMA_NAMESPACE 		"http://www.w3.org/2001/XMLSchema-instance"
#define SCHEMA_ATTRIBUTE		"schemaLocation"
#define SCHEMA_ATTRIBUTE_XSI	"xsi:schemaLocation"

class TQString;
class KCommand;


/**
@file
*/

/**
@short Base class for documents in KXMLEditor.

Stores XML document data which can be manipulated by KXMLEditor application.


@author Adam Charytoniuk
*/
class KXEDocument : public TQObject, public TQDomDocument, public KXMLGUIClient
{
        TQ_OBJECT
public:
	/** @short Constructor */
	KXEDocument(TQObject *parent=0, const char *name=0);

	/** @short Destructor */
	~KXEDocument();

	/** @short Saves document into given file */
	bool save(const TQString &);

	/** @short Loads document from given file */
	bool open(const TQString &);

	/** @short Sets modification flag.

	Should be called after every operation done on the document content  */
	void setModified(bool value=true);

	/** @short Returns true if this document was modified and not saved yet */
	bool isModified() {return m_bIsModified;}

        /** @short Changes document url */
	void setURL(KURL url);

	/** @short Executes given command and adds it into internal document command history list

		@param pCmd pointer to KXECommand object which encapsulates required operations
					on a document content
	 */
	
	/** @short Notifies views about creating new element

		@param node newly created node
	*/
	void updateNodeCreated(const TQDomNode & node);

	/** @short Notifies views about deleting node

	This should be called before given node from the document will be deleted.
	This will give a chanse to the views to remove that node visualization.
		@param node that is going to be deleted
	*/
	void updateNodeDeleted(const TQDomNode & node);

	/** @short Notifies views about element properties changes

	Should be called after element name or element attributes are changed.
		@param domElement element that has changed
	*/
	void updateNodeChanged( const TQDomElement & domElement );

	/** @short Notifies views after change char. data properties

	Should be called after any kind of character data is changed
	(including texts, comments, .CDATA sections).
		@param node character data node that has changed
	*/
	void updateNodeChanged( const TQDomCharacterData & node ) ;

	/** @short Notifies views after change proc. instr. properties

	Should be called after any processing intruction is changed.
		@param domProcInstr processing instruction that has changed
	*/
	void updateNodeChanged( const TQDomProcessingInstruction &domProcInstr );

	/** @short Notifies views after moving node

	Should be called if any node in the document was moved.
		@param node XML node that has been moved
	*/
	void updateNodeMoved( const TQDomNode & node );

	/** @short Removes spec. processing instruction from XML file.

		@param target name of the proc. instruction target
		@warning Removes processing instruction from DomDocument children node list only (no subnodes are modiified).
		@sa setSpecProcInstr()
	*/
	void removeSpecProcInstr(const TQString &target);

	/** @short Adds or changes (if already exists) processing instruction.

	Processing instruction will be added as a child in TQDomDocument object.
		@param target processing intruction target
		@param data processing intruction data
		@sa removeSpecProcInstr()
	*/
	virtual void setSpecProcInstr(const TQString& target, const TQString& data);

	/** @short  Returns processing instruction located in TQDomDocument.

	If given processing intruction is not found, null node is returned.
		@param target name of the processing instruction target.
		@sa setSpecProcInstr()
	*/
	TQDomNode getSpecProcInstr(const TQString& target);

	/** @short  Attaches stylesheet to current XML file.

	If file is already attached to stylesheet, this attachment will be overriten.
		@param stylesheet url to stylesheet location
		@sa detachStylesheet()
	*/
	virtual void attachStylesheet(const KURL& stylesheet);

	/** @short  Detaches stylesheet from current XML file.

		@sa attachStylesheet()*/
	virtual void detachStylesheet();

	/** Attaches schema to current XML file. If file is already attached to schema,
	this attachment will be overriten.
		@param schema url to schema location
		@sa detachSchema()*/
	virtual void attachSchema(const KURL& schema);

	/** @short Detaches schema from current XML file.

		@sa attachSchema()*/
	virtual void detachSchema();

	/** @short prepares content of newly created document.

	The preparation will be done accordingly to settings.
	In addition, signal sigOpened() is emited to notify all views
	about the change.*/
	virtual void newFile();


	/** @short Inserts special proc.instruction into document. */
	KCommand * actVersionEncoding();

	/** @short Called on user's action response.

	Creates <?xml-stylesheet ...?> processing instruction
	with reference to specified stylesheet URI.
	*/
  KCommand * actAttachStylesheet();

	/** @short Called on user's action response. */
	KCommand * actDetachStylesheet();

	/** @short Called on user's action response */
	KCommand * actDetachSchema();

	/** @short Called on user's action response */
	KCommand * actAttachSchema();

private:
	TQString m_strCompressedTarEntryName;
	/** Equals true if document was opened from compressed file */
	bool m_bDocIsCompressed;
	/** @short Stores modification flag */
	bool m_bIsModified;
	KURL m_url;

signals:
	/** @short Emmited when document has a new content.

	This may happen in the following scenarios:
	- document was opened from the fille or URL,
	- document has modified big part of the content
	- document initialized it's content after creations

		@sa newFile()
	*/
	void sigOpened();

	/** @short Emitted when document content have been changed.

	This allows to notify all attached views about that event.*/
	void sigModified(bool value);

	void sigURLChanged(KURL url);
	/** @short Emitted when new node was added to document.*/
	void sigNodeCreated(const TQDomNode & node);
	/** @short Emitted everytime node was deleted from document.*/
	void sigNodeDeleted(const TQDomNode & node);
	/** @short Emitted everytime document element was changed .*/
	void sigNodeChanged( const TQDomElement & domElement );
	/** @short Emitted everytime character data node was changed.

	This is the case for nodes like:
	- text,
	- comments,
	- CDATA sections,
	*/
	void sigNodeChanged( const TQDomCharacterData & node ) ;
	/** @short Emitted everytime processing instruction in document was changed .*/
	void sigNodeChanged( const TQDomProcessingInstruction &domProcInstr );
	/** @short Emitted everytime document node was moved was changed .*/
	void sigNodeMoved( const TQDomNode & node );
};

#endif