// -*- C++ -*-
/* This file is part of
* ======================================================
* 
*           LyX, the High Level Word Processor 	 
*	    Copyright (C) 1995 Matthias Ettrich
*
*           This file is Copyleft (C) 1996
*           Lars Gullik Bjønnes
*
*======================================================*/

#ifndef _BUFFER_H_
#define _BUFFER_H_


#include "xdefinitions.h"
#include "lyx_cb.h"
#include "lyxtext.h"
#include "lyxscreen.h"
#include "lyxparameters.h"
#include "lyxrc.h"
#include "inset.h"

class Buffer {
	friend class BufferList;
        void init()
        {
             parameters.Copy(lyxrc.parameters);
        }
	bool lyx_clean;  // is save needed
	bool bak_clean;  // is auto save needed
	bool dvi_clean;  // do we need to run LaTeX
public:
	LyXTextParameters parameters;
	LyXText *text;
	LyXScreen *screen;
	UpdatableInset* the_locking_inset;
	char* filename;
	char* tmppath; //where the temporaries go if we want them
	char* buffername;
	char* filepath;
	char save;         // what is this used for?
	bool read_only;     // buffer is r/o 
	bool allowAccents; // do we allow accents on all chars in this buffer
	const char*GetLanguage() {
		return (const char*)parameters.language;
	}
	bool isLyxClean() { return lyx_clean; }
	bool isDviClean() { return dvi_clean; }
	bool isBakClean() { return bak_clean; }
	void markDviClean() { dvi_clean = true; }
	void markBakClean() { bak_clean = true; }
	void markDviDirty() { dvi_clean = false; }
	void markDirty() {
		lyx_clean = false;
		dvi_clean = false;
		bak_clean = false;
	}
	Buffer() {
		filename = NULL;
		buffername = NULL;
		tmppath = NULL;
		filepath = NULL;
		text = NULL;
		screen = NULL;
		the_locking_inset = NULL;
		lyx_clean = false;
		bak_clean = false;
		dvi_clean = false;
		allowAccents = false;
		read_only = false;
		parameters.paragraph = NULL;
	        inset_slept = false;
		// parameters.Copy(lyxrc.parameters);
	}
	~Buffer(){
		// here the buffer should take care that it is
		// saved properly, before it goes into the void.
		delete text;
		delete screen;
		delete filename;
		delete tmppath;
	}
 protected:
        inline void InsetUnlock(void);
        inline void InsetSleep(void);
        inline void InsetWakeup(void);
        bool inset_slept;   
        int  slx, sly;
};

extern void Update(signed char);
extern void BeforeChange();

class BufferList {
private:
        //const int NUMBER_OF_BUFFERS = 50; //Sun's CC does not like that
        enum{ NUMBER_OF_BUFFERS = 50 };
        Buffer *buffer[NUMBER_OF_BUFFERS];
        int current_buffer;
        int old_current_buffer;
public:
 	BufferList();
	~BufferList();
	bool isEmpty();
        Buffer* current();
	void write(Buffer *);
	void QwriteAll();
	void closeAll();
	void resize();
	void readFile(const char*, bool);
	void newFile(const char*, const char*);
	void makePup(int);
	void switchBuffer(int);
	void updateInset(Inset*, bool = true);
	int unlockInset(UpdatableInset*);
	void emergencyWriteAll();
	void close(); // closes current buffer
	void prev();
	bool exists(const char *); // returns true if the buffer exists already
        
        // Open and lock an updatable inset
        void open_new_inset(UpdatableInset* new_inset)
        {
	   BeforeChange();
	   current()->text->FinishUndo();
	   current()->text->InsertInset(new_inset);
	   current()->text->CursorLeft();
	   Update(1);
	   new_inset->Edit(0,0);
	}

};


extern BufferList bufferlist;

inline  
void Buffer::InsetSleep(void)
{
    if (the_locking_inset && !inset_slept) {
	the_locking_inset->GetCursorPos(slx, sly);
        the_locking_inset->InsetUnlock();
	inset_slept = true;
    }
}

inline  
void Buffer::InsetWakeup(void)
{
    if (the_locking_inset && inset_slept) {
	the_locking_inset->Edit(slx, sly);
	inset_slept = false;
    }	
}

inline
void Buffer::InsetUnlock()
{
    if (the_locking_inset) {
        if (!inset_slept) the_locking_inset->InsetUnlock();
	the_locking_inset = NULL;
	text->FinishUndo();
    	inset_slept = false;
    }
}

#endif
