//------------------------------------------------------------------------------
// emRecFileModel.h
//
// Copyright (C) 2005-2008,2010,2014 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// 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 version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#ifndef emRecFileModel_h
#define emRecFileModel_h

#ifndef emRec_h
#include <emCore/emRec.h>
#endif

#ifndef emFileModel_h
#include <emCore/emFileModel.h>
#endif


//==============================================================================
//=============================== emRecFileModel ===============================
//==============================================================================

class emRecFileModel : public emFileModel {

public:

	// Base class for an emFileModel where the data is an emRec. This class
	// solves loading and saving of the record, and it provides a signal for
	// getting informed about modifications of the record. In addition, the
	// file state is automatically set to FS_UNSAVED on modifications. A
	// derived class has to specify the record through calling PostConstruct
	// from its constructor. Hint: There is a similar class which is not an
	// emFileModel and which could be used for configuration files:
	// emConfigModel.

	const emSignal & GetChangeSignal() const;
		// Signaled on every modification of the record.

protected:

	emRecFileModel(emContext & context, const emString & name);
		// Do not forget to call PostConstruct from an overloaded
		// constructor.

	void PostConstruct(emRec & rec);
		// Must be called by the constructor of the derived class after
		// the record has been constructed.

	virtual ~emRecFileModel();
		// Destructor.

	emRec & GetRec();
		// Not valid before PostConstruct has been called.

	virtual void ResetData();
	virtual void TryStartLoading() throw(emException);
	virtual bool TryContinueLoading() throw(emException);
	virtual void QuitLoading();
	virtual void TryStartSaving() throw(emException);
	virtual bool TryContinueSaving() throw(emException);
	virtual void QuitSaving();
	virtual emUInt64 CalcMemoryNeed();
	virtual double CalcFileProgress();

private:

	class RecLink : public emRecListener {
	public:
		RecLink(emRecFileModel & model);
	protected:
		virtual void OnRecChanged();
	private:
		emRecFileModel & Model;
	};
	friend class RecLink;

	emSignal ChangeSignal;
	RecLink Link;
	emRecFileReader * Reader;
	emRecFileWriter * Writer;
	int ProtectFileState;
	emUInt64 MemoryNeed;
	int MemoryNeedOutOfDate;
	int ReadStep, ReadStepOfMemCalc;
};

inline const emSignal & emRecFileModel::GetChangeSignal() const
{
	return ChangeSignal;
}

inline emRec & emRecFileModel::GetRec()
{
	return *Link.GetListenedRec();
}


#endif
