/*     Bed a Binary EDitor for Linux and for Rxvt running under Linux.       */
/*     Copyright (C) 1998  Jaap Korthals Altes <jkaltes@hetnet.nl>      */
/*                                                                           */
/*     Bed 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.                                   */
/*                                                                           */
/*     Bed 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 bed; if not, write to the Free Software                    */
/*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             */
/*                                                                           */
/* Sun Dec  6 18:34:27 1998                                                  */
#ifndef GETFILE_H
#define GETFILE_H
#include <features.h>
#include <string.h>
#include "views.h"
#ifdef  __cplusplus
#include "config.h"
#include CURSES_HEADER 
extern WINDOW *takescr;
class winsel {
	public:
	char al[80];
	int in;
	char **strings;
	int tot,beg,h,l,x,y,sel,icase;
	winsel(char **str,int nr,int xpos,int ypos,int begin=0,int hight=10,int len=20) {
		strings=str;
		tot=nr;
		h=hight;
		beg=begin-h/2;if(beg<0) beg=0;
		sel=begin-beg;
		l=len;
		x=xpos;
		in=0;
		y=ypos;
		icase=1;
		};
	~winsel() {}
	char *current(void) {
		if(!tot)
			return NULL;
		return strings[beg+sel];
		};
	void leave(void) ;
	void show(void) ;
//	char *select(void) ;
	char *select(int key) ;
	int selectindex(int key) ;
	void showsel(int) ;
	};


class line {
	public:
	char *buf;
	int end,&endptr;
	int size,pos,bij;
	int bufgegsize;
	int x,y;
	int start;
	line(char *name,int xpos,int ypos,int s=38,int maxgegs=80) ;
	line(char *name,int &p,int xpos,int ypos,int s=38,int maxgegs=80) ;
	~line(); 
	void show(void) ;
	void add(int key) ;
	void take(void) ;
inline	void cursor(void) {
		wmove(takescr,y,x+pos+1-bij);
		}
	char *change(int key) ;
	char *line::setvalue(char *name,int len) ;
	};

class item {
	public:
	char text[80],*after;
	int ch;
	char lowch;
	int x,y;
	public:

	item::item(void) {;};
	item::item(const char *txt1,int ya,int xb) ;
	char thekey(void) {return lowch;};
	virtual ~item() {};
	virtual void show(void) =0;
	virtual void select(void)=0; 
	virtual int switchvar(void) =0;
	virtual int save(void) {return 0;} ;
	virtual int saveall(void) {return 0;} ;
	virtual int change(int key) {if(key==' '||key=='x'||key=='*') return switchvar(); return 0;};

	};


class lineitem:public item {
	line l;
	char *var;
	public:
	lineitem(const char *txt,char *name,int ypos,int xpos,int s=35,int maxgeg=80): item(txt,ypos,xpos),l(name,xpos+strlen(txt),ypos,s,maxgeg) {
		var=name;
		}
	lineitem(const char *txt,int &len,char *name,int ypos,int xpos,int s=35,int maxgeg=80): item(txt,ypos,xpos),l(name,len,xpos+strlen(txt),ypos,s,maxgeg) {
		var=name;
		}
	~lineitem() {};
	void show(void) ;
	void select(void);

	int switchvar(void) {l.change(' ');return 0;};
	int save(void) {memmove(var,l.buf,l.end);var[l.end]='\0';l.endptr=l.end;return 0;};
	int change(int key) { return (int)l.change(key);};
	int saveall(void);
	};

class check: public item {
	public:
	int var;
	int &old;
	check(void): old(var) {; };
	check(char *txt,int y1,int x1,int &var1): item(txt,y1,x1), old(var1) {
		var=var1;
		};
	void show(void) ;
	void select(void) ;
	 int switchvar(void) ;
	 int save(void) {
		old=var;
		return 0;
		};
	int saveall(void) {
		save();
		return 2; 
		};

	};
class orcheck;
class Common {
	public:
	int nr;
	int &old;
	orcheck *last;
	Common(int &v,int n=1000):old(v) {
		nr=n;
		};
	orcheck *setlast(orcheck *l) {
		last=l;
		return l;
		}
	int save(void);
	};
class orcheck: public item {
	public:
	int val;
	Common *com;
	orcheck(char *txt,int y1,int x1,int v,Common *c): item(txt,y1,x1), val(v),com(c) {
	c->nr++;
		};
	~orcheck() {
		if(com->nr==1)
			delete com;
		else
			com->nr--;
		}
	void show(void) ;
	void select(void) ;
	 int switchvar(void) ;
	 int save(void) {
	 	return com->save();
		};
	void orcheck::showvar(void);
	void orcheck::selectvar(void) ;
	 void orcheck::sel(void) ;
	int saveall(void) {
			return 2; 
			};
	};
class action: public item {
	protected:
	int &var;
	public:
//	action(void) {;};
	action(char *txt,int y1,int x1,int &v): item(txt, y1, x1),var(v) {;};
	void show(void) ;
	void select(void) ;
	 virtual int switchvar(void) {
		return 0;
		};
	virtual int saveall(void) {
		var=1;
		return 1;
		};
	};

class saveaction: public action {
	public:
	saveaction(char *txt,int y,int x,int &var): action(txt,y,x,var) {
		}
	int saveall(void) {
		action::saveall();
		return 2;
		}
	};
class ok: public action {
	item **alles;
	int nr;
	public:
	ok(item **al,int len,int y,int x,int &var): action("  ~Ok  ",y,x,var) {
		alles=al;
		nr=len;
		}
	int saveall(void) ;
	};
class itemlist:public item {
	int &ant;
	winsel wins;
	public:
	itemlist(const char *txt,char **str,int nr,int ypos,int xpos,int &a,int begin=0,int hight=10,int len=20);
	~itemlist() ;
	void show(void) ;
	void select(void) ;
	int switchvar(void) ;
	int save(void) ;
	int saveall(void) ;
	int change(int key) ;
	};

void label(int y,int x,const char *str) ;

int show(item **al,int showformsmaxar,int sel) ;
extern int zomaareenvar;
#define listall(txt,y,x,str,nr,var,beg,hi,len) (showformsarray[showformsiter++]= new itemlist(txt,str,nr,y,x,var,beg,hi,len))
#define list(txt,y,x,str,nr,var) listall(txt,y,x,str,nr,var,0,10,20)
#define el(check,str,y,x,var) (showformsarray[showformsiter++]= new check(str,y,x,var))
#define checker(str,y,x,var) (showformsarray[showformsiter++]= new check(str,y,x,var))
#define saveact(str,y,x) (showformsarray[showformsiter++]= new saveaction(str,y,x,zomaareenvar))
#define saveacti(str,y,x,var) (showformsarray[showformsiter++]= new saveaction(str,y,x,var))
#define act(str,y,x) (showformsarray[showformsiter++]= new action(str,y,x,zomaareenvar))
#define acti(str,y,x,var) (showformsarray[showformsiter++]= new action(str,y,x,var))
#define oker(showformsarray,showformsmaxar,y,x) (showformsarray[showformsiter++]= new ok(showformsarray,showformsmaxar,y,x))
#define oke(y,x) (showformsarray[showformsiter++]= new ok(showformsarray,showformsmaxar,y,x,zomaareenvar))
#define okvar(y,x,var) (showformsarray[showformsiter++]= new ok(showformsarray,showformsmaxar,y,x,var))
#define liner(txt,name,x,y) (showformsarray[showformsiter++]= new lineitem(txt,name,x,y))
#define linerlen(txt,len,name,x,y) (showformsarray[showformsiter++]= new lineitem(txt,len,name,x,y))
#define linernr(txt,name,x,y,nr) (showformsarray[showformsiter++]= new lineitem(txt,name,x,y,nr))
#define linernrmax(txt,name,x,y,nr,max) (showformsarray[showformsiter++]= new lineitem(txt,name,x,y,nr,max))
#define linerlennr(txt,len,name,x,y,nr) (showformsarray[showformsiter++]= new lineitem(txt,len,name,x,y,nr))
#define linerlennrmax(txt,len,name,x,y,nr,max) (showformsarray[showformsiter++]= new lineitem(txt,len,name,x,y,nr,max))
#define orel(txt,y,x,val)  (showformsarray[showformsiter++]=new orcheck(txt,y,x,val,com))
#define oreen(txt,y,x,val)  (showformsarray[showformsiter++]=new orcheck(txt,y,x,val,com=new Common(var)))

#define ore(txt,y,x,val,com)  (showformsarray[showformsiter++]=new orcheck(txt,y,x,val,com))
#define orsel(txt,y,x,val,com)  (showformsarray[showformsiter++]=com->setlast(new orcheck(txt,y,x,val,com)))
/*
#define ors(var,items...,item) {Common *com=new Common(var);int was=showformsiter;0,  ##items,com->last=showformsarray[was+val]}
#define ors(var,items...) {Common *com=new Common(var);int was=showformsiter;  ##items,com->last=showformsarray[was+val]}
*/


extern WINDOW *getshowwin(int l,int c,int by,int bx) ;

#define initdialog(nr) {item **showformsarray;int showformsiter=0,showformsmaxar=(nr);  showformsarray=new (item *)[showformsmaxar];
#define dodialog(ant,l,c,sel) if((takescr=getshowwin((l),(c),(thelines-(l))/2,(thecols-(c))/2))){ (ant)=show(showformsarray,showformsiter,(sel));};for(int dodialogiter=0;dodialogiter<showformsiter;dodialogiter++) delete showformsarray[dodialogiter];delete[] showformsarray;};
#define dodialogpost(ant,l,c,sel,post) if((takescr=getshowwin((l),(c),(thelines-(l))/2,(thecols-(c))/2))){(post);(ant)=show(showformsarray,showformsiter,(sel));};for(int dodialogiter=0;dodialogiter<showformsiter;dodialogiter++) delete showformsarray[dodialogiter];delete[] showformsarray;};
#define showdialog(ant,l,c,sel) if((takescr=getshowwin((l),c,(thelines-(l))/2,(thecols-c)/2))){ant=show(showformsarray,showformsiter,sel);};
#define deldialog for(int dodialogiter=0;dodialogiter<showformsiter;dodialogiter++) delete showformsarray[dodialogiter];delete[] showformsarray;};

#define opt(name,y,x,val) ore(name,y,x,val,comptr) 

#endif


#define begindialog(l,c,nr) if((takescr=getshowwin((l),(c),(thelines-(l))/2,(thecols-(c))/2))){item **showformsarray;int showformsiter=0,showformsmaxar=nr;  showformsarray=new (item *)[showformsmaxar]; 

#define enddialog(ant,sel) ant=show(showformsarray,showformsiter,(sel));for(int dodialogiter=0;dodialogiter<showformsiter;dodialogiter++) delete showformsarray[dodialogiter];delete[] showformsarray;};

#define beginoptions(name)  {int startformsiter=showformsiter; Common *comptr=new Common((name),0);
#define endoptions(sel)	;comptr->last=(orcheck*)showformsarray[startformsiter+(sel)];}; 
#include "varmacro.h"


#ifdef OLDGCCVARMACRO
#define lcconfig(l,c,items...) lcsconfig(l,c,1,items) VARMACRO
#define lcsconfig(l,c,sel,items...) plcsconfig(l,c,sel,0,items) VARMACRO
#define plcsconfig(l,c,sel,post,items...) {int throwawayant;palcsconfig(throwawayant,l,c,sel,post,items) } VARMACRO
#define alcsconfig(ant,l,c,sel,items...) palcsconfig(ant,l,c,sel,0,items)  VARMACRO
#define palcsconfig(ant,l,c,sel,post,items...) {item **showformsarray;int showformsiter=0; int showformsmaxar=sizeof((item* []){items})/sizeof(item *); if((takescr=getshowwin(l,c,(thelines-l)/2,(thecols-c)/2))) { showformsarray=new (item *)[showformsmaxar],items;post;ant=show(showformsarray,showformsmaxar,sel);for(showformsiter=0;showformsiter<showformsmaxar;showformsiter++) delete showformsarray[showformsiter];delete[] showformsarray;};} VARMACRO
#define options(name,sel,items...)  {int startformsiter=showformsiter; Common *comptr=new Common(name,0);items,comptr->last=(orcheck*)showformsarray[startformsiter+sel];}; VARMACRO
#else
#define lcconfig(l,c,...) lcsconfig(l,c,1,__VA_ARGS__) 
#define lcsconfig(l,c,sel,...) plcsconfig(l,c,sel,0,__VA_ARGS__) 
#define plcsconfig(l,c,sel,post,...) {int throwawayant;palcsconfig(throwawayant,l,c,sel,post,__VA_ARGS__) } 
#define alcsconfig(ant,l,c,sel,...) palcsconfig(ant,l,c,sel,0,__VA_ARGS__)  
#define palcsconfig(ant,l,c,sel,post,...) {item **showformsarray;int showformsiter=0; int showformsmaxar=sizeof((item* []){__VA_ARGS__})/sizeof(item *); if((takescr=getshowwin(l,c,(thelines-l)/2,(thecols-c)/2))) { showformsarray=new (item *)[showformsmaxar],__VA_ARGS__;post;ant=show(showformsarray,showformsmaxar,sel);for(showformsiter=0;showformsiter<showformsmaxar;showformsiter++) delete showformsarray[showformsiter];delete[] showformsarray;};} 
#define options(name,sel,...)  {int startformsiter=showformsiter; Common *comptr=new Common(name,0);__VA_ARGS__,comptr->last=(orcheck*)showformsarray[startformsiter+sel];}; 

#endif
#endif

