// This module implements the TQextScintillaDocument class.
//
// Copyright (c) 2006
// 	Riverbank Computing Limited <info@riverbankcomputing.co.uk>
// 
// This file is part of TQScintilla.
// 
// This copy of TQScintilla 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, or (at your option) any
// later version.
// 
// TQScintilla is supplied 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
// TQScintilla; see the file LICENSE.  If not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "tqextscintilladocument.h"
#include "tqextscintillabase.h"


// This internal class encapsulates the underlying document and is shared by
// TQextScintillaDocument instances.
class TQextScintillaDocumentP
{
public:
	TQextScintillaDocumentP() : doc(0), nr_displays(0), nr_attaches(1) {}

	long doc;			// The Scintilla document.
	int nr_displays;		// The number of displays.
	int nr_attaches;		// The number of attaches.
};


// The ctor.
TQextScintillaDocument::TQextScintillaDocument()
{
	pdoc = new TQextScintillaDocumentP();
}


// The dtor.
TQextScintillaDocument::~TQextScintillaDocument()
{
	detach();
}


// The copy ctor.
TQextScintillaDocument::TQextScintillaDocument(const TQextScintillaDocument &that)
{
	attach(that);
}


// The assignment operator.
TQextScintillaDocument &TQextScintillaDocument::operator=(const TQextScintillaDocument &that)
{
	if (pdoc != that.pdoc)
	{
		detach();
		attach(that);
	}

	return *this;
}


// Attach an existing document to this one.
void TQextScintillaDocument::attach(const TQextScintillaDocument &that)
{
	++that.pdoc -> nr_attaches;
	pdoc = that.pdoc;
}


// Detach the underlying document.
void TQextScintillaDocument::detach()
{
	if (!pdoc)
		return;

	if (--pdoc -> nr_attaches == 0)
	{
		if (pdoc -> doc && pdoc -> nr_displays == 0)
		{
			TQextScintillaBase *tqsb = TQextScintillaBase::pool();

			// Release the explicit reference to the document.  If
			// the pool is empty then we just accept the memory
			// leak.
			if (tqsb)
				tqsb -> SendScintilla(TQextScintillaBase::SCI_RELEASEDOCUMENT,0,pdoc -> doc);
		}

		delete pdoc;
	}

	pdoc = 0;
}


// Undisplay and detach the underlying document.
void TQextScintillaDocument::undisplay(TQextScintillaBase *tqsb)
{
	if (--pdoc -> nr_attaches == 0)
		delete pdoc;
	else if (--pdoc -> nr_displays == 0)
	{
		// Create an explicit reference to the document to keep it
		// alive.
		tqsb -> SendScintilla(TQextScintillaBase::SCI_ADDREFDOCUMENT,0,pdoc -> doc);
	}

	pdoc = 0;
}


// Display the underlying document.
void TQextScintillaDocument::display(TQextScintillaBase *tqsb,const TQextScintillaDocument *from)
{
	long ndoc;

	if (from)
	{
		ndoc = from -> pdoc -> doc;
		tqsb -> SendScintilla(TQextScintillaBase::SCI_SETDOCPOINTER,0,ndoc);
	}
	else
		ndoc = tqsb -> SendScintilla(TQextScintillaBase::SCI_GETDOCPOINTER);

	pdoc -> doc = ndoc;
	++pdoc -> nr_displays;
}