/*     Bed a menu-driven multi dataformat binary editor for Linux            */
/*     Copyright (C) 1998 Jaap Korthals Altes <jkaltes@hetnet.nl>       */
/*                                                                           */
/*     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, write to the Free Software           */
/*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             */
/* Fri Dec  8 22:14:27 2000                                                  */
#ifndef SCREENPART_H
#define SCREENPART_H
const int maxlabel=80;
class Editor;
class Filter;
#define General ScreenPart

extern const char screenpartname[];
class Parent {
	 char *name;			
	class Parent *parent;
	public:
	Parent(char *nam,class Parent *par) {
		name=nam;
		parent=par;
		};
	char *getname(void) {return name;}
	int isparent(const char *nam);	
	};	
//char child::thename[]=childname;
#define parentdef(par,child,childname)  class Parent child::desc=Parent(childname,&par::desc);
#define thename desc.getname()
#define parentd(par,child) parentdef(par,child,#child)
#define declareparent \
	public:\
	static class Parent desc; \
	virtual class Parent *getdesc(void) { return &desc;};

//	static  char thename[]; 
#define  has_super(inst,Type) (inst&&inst->isparent(Type::desc.getname()))
#define asciichild(x) has_super(x,Ascii)
#define instance(inst,Type) (inst->getname()==Type::desc.getname())
class ScreenPart {
	declareparent
	public:
	Editor *editor;
	ScreenPart *contain;
	int left,top,spaceafter,maxres,apart,bytes,half,oldhalf;
	DataType type;
//	const char *name;
	char label[maxlabel];
	char *userlabel;
	int begin(void) {return half=0;};
	int end(void) {
		oldhalf=half;
		return  (half=(maxres-1));
		};
	const char *getname(void) {return getdesc()->getname();}
   	int isparent(const char *nam) {return getdesc()->isparent(nam);}

	inline int x(int pos) { return (((pos%nrx())/bytes)*(maxres+apart));}; /*** position to x **/
	inline int y(int pos) { return (pos/nrx());};		/*** position to y **/
	inline void postoxy(int pos,int &x1,int &y1) { /*** convert position on screen to x and y **/
			y1=y(pos);
			x1=x(pos);
			};
	int &nrx(void); /*max number of elements in x direction**/
	int &nry(void); /*max number of elements in y direction**/
	inline int oldpos(void); /*Previous position on screen of cursor **/
	inline void placepart(int l, int t) { left=l;top=t;}; /** sets left and top position of screenpart **/
	int movepos(int pos); /* Move to put pos */
	inline int cols(void) {return nrx();};
	inline int rows(void) {return nry();};
	int partwidth(void);
	void troggleselect(int pos); /*switch between selected and not selected */
	virtual int chbytes(int bytes) {return -1;}
	virtual short chbase(short base) {return -1;}
	int ScreenPart::datbytes(int byt=-1) ;
	virtual int userconfig(int kind);
	ScreenPart(ScreenPart &part);
	ScreenPart( Editor *ed,int max,int b,int len=4,int x1=0, int y1=0, int a=1);
	virtual ~ScreenPart();
	virtual ScreenPart *newone(void) =0;
	void chput(unsigned char ch) {};
	int nocursor(void); /* removes cursor of current position */
	void cursorpos(int pos);
	void leave(void) {oldhalf=half;half=maxres;};
	int newchar(int key);

	int addchar(int key) ;


#define fromascii(to,from, len)  bin2search((from),(char *)(to),len)

	 int filterformat2bin(char *from, unsigned char *to, int len) ;
 int filformat2bin(char *from, unsigned char *to, int &len) ;
	 int bin2f(unsigned char *bin, char *formal, int len) ;
	virtual inline int isel(int key)=0; 
	int select(void); 
	 int backchar(void) ;
	 int nextchar(void) ;
	int rewritepart(int size) ;
	int putline(int y) ;
	void unittoscreen(int pos) ;
	void printchar(int pos) ;
	inline int oppos(int pos) ;
	int oppos(int pos,int size) ;
	virtual int addkey(unsigned char *bin,int binlen, int key, int pos ) ;
/*formal=in dstatype bin: binary. len: gives back lenght of formal used 
 returns number of bytes used
*/
inline	virtual int form2bin(char *formal, unsigned char *bin, int &len){
		len=format2bin(formal, bin,  len); 
		return datbytes();
		}
inline	virtual int format2bin(char *formal, unsigned char *bin, int len){
		formal2bin(formal, bin,  len); 
		return len;
		}
//convert dataspecific string (formal) to binary array (bin). len is length of formal
	virtual int formal2bin(char *formal, unsigned char *bin, int len) {
		return 0;
		}

/*convert binary array (bin) to dataspecific string (formal). len is length
of bin*/
	virtual int bin2formal(unsigned char *bin, char *formal, int len) =0;

virtual int ScreenPart::search2bin(char *formal, unsigned char *bin, int len)  ;
virtual int ScreenPart::bin2search(unsigned char *bin,  char *formal, int len)  ;
	virtual void poschanged(int pos) {};
	public:
	Filter **filters;
	int firstfilter,lastfilter,maxfilter;
	public:
	int fromfilefilters(char *input,int &len,char *output) ;
	int tofilefilters(char *input,int &len,char *output) ;
virtual	int addfilter(Filter *fil) ;
virtual int ScreenPart::setfilter(Filter *fil) ;
	int getbytes(void);
int ScreenPart::filebytes(int b) ;
int ScreenPart::screenbytes(int b) ;
int ScreenPart::addreverse(int  len, int un);
int ScreenPart::screenupdatefilters(int byt) ;
int ScreenPart::addskip(int  take, int skip,int byt) ;
	virtual void mklabel(void);
	ScreenPart *getsubpart(int &forstart,int &binstart,int pos);
	virtual ScreenPart *ScreenPart::getchild(int &forstart,int &binstart,int pos);
	int ScreenPart::rmlastfilt(char *name=NULL);
	int ScreenPart::rmlastfilter(void);
	char *ScreenPart::lastfiltername(void);
	Filter *ScreenPart::getlastfilter(void) ;
	int ScreenPart::equal(ScreenPart *part) ;
	int ScreenPart::reverse(void) ;
	int ScreenPart::allocfilters(int nr) ;
	int ScreenPart::copyfiltersbefore(ScreenPart *part) ;
	int ScreenPart::copyfiltersafter(ScreenPart *part) ;
	int	ScreenPart::mkfilterstr(char *str,int max) ;
	int ScreenPart::filtersstring(char *buf) ;
	virtual int calcsizes(void) ;
	virtual char *getconvstr(void);
	virtual int setconvstr(char *str);
ScreenPart *ScreenPart::getchild(void) ;
ScreenPart *ScreenPart::getparent(ScreenPart *start=NULL) ;
ScreenPart *ScreenPart::getsubpart(void) ;
virtual int ScreenPart::byteoff2screen(int pos) {
		return -1;
		}
virtual int ScreenPart::screen2byteoff(int pos) {
		return -1;
		}
int ScreenPart::byte2screen(int pos) ;
int ScreenPart::screen2byte(int pos) ;
int ScreenPart::fromfilefilterspos(int pos) ;
int ScreenPart::tofilefilterspos(int pos) ;
ScreenPart *ScreenPart::getsuperpart(void) ;
int ScreenPart::getbase(void);
char *ScreenPart::takeuserlabel(void);
	};

	
/*	ScreenPart( Editor *ed,int max,int b,int len=4,int x1=0, int y1=0, int a=1)
ed: 
max: each elements screenbreath
b: Signifier
len: number of bytes
x1, y1: transform every position of screenpart. This is never used so, untested
a: number of spaces between each element
*/
#include "typelist.h"
#endif
