/*
 * Copyright 2009  Gregory Haynes <greg@greghaynes.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.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#ifndef QINFINITY_ABSTRACT_TEXT_BUFFER_H
#define QINFINITY_ABSTRACT_TEXT_BUFFER_H

#include "textbuffer.h"

class QString;

namespace QInfinity
{

class TextChunk;

/**
 * @brief Base class for implementing a text buffer.
 *
 * The AbstractTextBuffer is used to implement a custom
 * TextBuffer.  Most projects using the InfText or similar
 * plugin will find this of use.  You can cause your
 * custom implementation to be used by creating a subclass
 * of NotePlugin which creates the proper subclass.
 *
 * Currently, the AbstractTextBuffer provides the same
 * functionality as a DefaultTextBuffer only with calls to
 * the wrapping virtual functions appended for insert and
 * erase text.  In the future this will likely be changed.
 */
class AbstractTextBuffer
	: public TextBuffer
{
	public:
		/**
		 * @brief Used by wrapped GObject
		 */
		static void bufferIfaceInit( gpointer g_iface,
			gpointer iface_data );
		/**
		 * @brief Used by wrapped GObject
		 */
		static void textBufferIfaceInit( gpointer g_iface,
			gpointer iface_data );

		/**
		 * @brief Create a text buffer base class.
		 */
		AbstractTextBuffer( const QString &encoding,
			QObject *parent = 0 );

		virtual ~AbstractTextBuffer();

		InfTextChunk *chunk();

	protected:
		/**
		 * @brief Called to insert text into buffer.
		 *
		 * Your implementation must account for all of
		 * the text provided by this method, and only
		 * for that text.  Not doing so can lead to
		 * inconsistancies among users.
		 */
		virtual void onInsertText( unsigned int offset,
			const TextChunk &chunk,
			User *user ) = 0;

		/**
		 * @brief Called to erase text from buffer.
		 */
		virtual void onEraseText( unsigned int offset,
			unsigned int length,
			User *user ) = 0;

	private:
		static void insert_text_cb( InfTextBuffer *buffer,
			unsigned int offset,
			InfTextChunk *chunk,
			InfUser *user );
		static void erase_text_cb( InfTextBuffer *buffer,
			unsigned int offset,
			unsigned int length,
			InfUser *user );

};

}

G_BEGIN_DECLS

#define QINF_TEXT_TYPE_ABSTRACT_BUFFER                 (qinf_text_abstract_buffer_get_type())
#define QINF_TEXT_ABSTRACT_BUFFER(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), QINF_TEXT_TYPE_ABSTRACT_BUFFER, QInfTextAbstractBuffer))
#define QINF_TEXT_ABSTRACT_BUFFER_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST((klass), QINF_TEXT_TYPE_ABSTRACT_BUFFER, QInfTextAbstractBufferClass))
#define QINF_TEXT_IS_ABSTRACT_BUFFER(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), QINF_TEXT_TYPE_ABSTRACT_BUFFER))
#define QINF_TEXT_IS_ABSTRACT_BUFFER_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE((klass), QINF_TEXT_TYPE_ABSTRACT_BUFFER))
#define QINF_TEXT_ABSTRACT_BUFFER_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS((obj), QINF_TEXT_TYPE_ABSTRACT_BUFFER, QInfTextAbstractBufferClass))

typedef struct _QInfTextAbstractBufferClass QInfTextAbstractBufferClass;
typedef struct _QInfTextAbstractBuffer QInfTextAbstractBuffer;

struct _QInfTextAbstractBufferClass
{
	GObjectClass parent_class;
};

struct _QInfTextAbstractBuffer
{
	GObject parent;
};

GType
qinf_text_abstract_buffer_get_type(void) G_GNUC_CONST;

QInfTextAbstractBuffer*
qinf_text_abstract_buffer_new(const gchar* encoding);

G_END_DECLS

#endif
