#include <string.h>
#include <stream.h>
#include <fstream.h>
#include <strstream.h>

extern "C" { void exit(int); }

#define GPR_DEFAULT_FILL GPR_SOLID

#include <xmCi2.h>

#define XmSnone 0

extern char* ctrlClassNames[];
extern int ctrlDefSizes[][2];
extern xmStyle ctrlAllStyles[];
extern xmStyle ctrlDefStyles[];
extern char* ctrlDefText[];
extern char* ctrlTextPref[];
extern char* ctrlTextPostf[];

extern char* alignStyleNames[];
extern xmStyle alignStyleValues[3];

#define RE_DIALOG_STYLE_COUNT 12

extern char* dlgStyleConstants[RE_DIALOG_STYLE_COUNT];
extern xmStyle dlgStyleValues[RE_DIALOG_STYLE_COUNT];

#define RE_CONTROL_STYLE_COUNT 27

extern char* ctrlStyleConstants[RE_CONTROL_STYLE_COUNT];

#define MAX_RE_CONTROLS 10

class HexDumper;

class ReDialog : public CiObject
{
	bool valid;
	char name[100];
	char text[100];
	xmStyle style;

	char* className()			{ return("ReDialogClass"); }

	void setAsCurrent(void*);
	void editConfig(void*);
public:
	ReDialog(HexDumper&);
	ReDialog(int, int);
	~ReDialog();

	bool isValid()				{ return(valid); }
	xmStyle getStyle()			{ return(style); }
	char* getDescr()			{ return(name); }
	char* getContents()			{ return(text); }

	void setStyle(xmStyle s)	{ style = s; }
	void setDescr(char* txt)	{ strncpy(name, txt, 100); }
	void setContents(char* txt)	{ setText(strncpy(text, txt, 100)); update(); }

	char* dumpOn(HexDumper&);
	char* dumpOn(ostream&);
}; 

class ReControl : public CiObject
{
friend class ReControlTemplate;
friend ReDialog::ReDialog(HexDumper&);
friend class ReWindow;
	bool valid;
	ctrlType ctrlClass;
	xmStyle style;
	char name[100];
	char text[100];

	char* className()			{ return("ReControlClass"); }
	virtual bool isTemplate()	{ return(FALSE); }

	void setAsCurrent(void*);

	ReControl(HexDumper&, CiObject*);
	ReControl(ReControlTemplate*);
	ReControl(ctrlType, int, int);
	~ReControl();
public:
	bool isValid()				{ return(valid); }
	ctrlType getClass()			{ return(ctrlClass); }
	bool isCtrl(ctrlType t)		{ return(ctrlClass == t ? TRUE : FALSE); }
	xmStyle getStyle()			{ return(style); }
	char* getDescr()			{ return(name); }
	char* getContents()			{ return(text); }
	char* getGrpEdDescr();

	void setStyle(xmStyle s)	{ style = s; }
	void setDescr(char* txt)	{ strncpy(name, txt, 100); }
	void setContents(char* txt)	{ ostrstream strm; strm << ctrlTextPref[ctrlClass] << strncpy(text, txt, 100) << ctrlTextPostf[ctrlClass]; strm.put('\0'); setText(strm.str()); update(); }

	ReControl* deepCopy();

	char* dumpOn(HexDumper&);
	char* dumpOn(ostream&);
};

class ReControlTemplate : public ReControl
{
friend class ReWindow;
	gprPoint fixedLoc;

	char* className()			{ return("ReControlTemplateClass"); }
	bool isTemplate()			{ return(TRUE); }

	void makeInstance(void*);

	ReControlTemplate(ctrlType, int, int);
	~ReControlTemplate();
};

class ReWorld : public XmCiWorld
{
public:
	ReWorld(char* n) : XmCiWorld(n, 10, 10, 1200, 1000)		{}

	bool userSelect(DrawPrim*, int, int);
};

class ReTestDlg;
class ReGroupConfig;

class ReWindow : public XmWindow
{
	XmCiWorld* world;
	ReDialog* curEdited;
	ReControl* curSelected;
	ReTestDlg* curTested;
	ReGroupConfig* curGroupEditor;
	bool pendingChanges;
	char* currFileName;
	ReControl** clipboard;

//	bool initWindowSize(int&, int&, int& nw, int& nh) { nw = 800; nh = 600; return(TRUE); }

	void createCiWorld();

	void createNamesBar();
	void createStylesBar();

	void changeName(XmEdit*);
	void changeText(XmEdit*);
	void changeAlignment(XmComboBox*);
	void changeStyle(XmCheckBox*);
	void changeComboStyle(XmRadioButton*);
public:
	ReWindow();

	void initialize();

	void gnuInit()	{ setInitWindowSize(300, 300, 800, 600); ReWindow::initialize(); }

	void fcmdNew(void*);
	void fcmdOpen(void*);
	void fcmdSave(char*);
	void ecmd(char*);
	void mcmd(char*);
	void openTest(void*);
	void editGroups(void*);
	void editDlgSettings(void*);
	void about(void*);

	void quit(void*);

	void setCurrent(ReControl*);
	ReDialog* currentDialog()		{ return(curEdited); }
};

class ReDialogConfig : public XmUserDialog
{
	ReDialog* theDlg;

//	bool initWindowSize(int&, int&, int&, int&);

	void createContents();
	void initContents();
public:
	ReDialogConfig(ReDialog* dlg, XmObject* parent = NULL) : XmUserDialog("Dialog Parameters", parent, (xmStyle )0x0L)
	{ theDlg = dlg; }

	void gnuOpen()	{ setInitWindowSize(400, 400, 454, 368); ReDialogConfig::createContents(); ReDialogConfig::initContents(); realize(); }

	void cmd(char*);
};

class ReGroupItem : public CiObject
{
friend class ReGroupConfig;
friend class ReGroupWorld;
	ReControl* theControl;
	int tmpIndex;

	ReGroupItem(ReControl*, int, int, int);

	void moved(void*);
};

class ReGroupConfig;

class ReGroupWorld : public XmCiWorld
{
	ReGroupConfig* master;
public:
	ReGroupWorld(ReGroupConfig* cfg) : XmCiWorld("Group Edit")		{ master = cfg; }

	bool userMove(DrawPrim*, int, int, int, int);
};

class ReGroupConfig : public XmWindow
{
	XmCiWorld* world;
	ReDialog* theDlg;

//	bool initWindowSize(int&, int&, int& nw, int& nh)	{ nw = 350; nh = 400; return(TRUE); }

	void addGroup(ReControl*, int&);
	void getGroup(ReControl*);
public:
	ReGroupConfig(ReDialog*);

	void initialize();

	void gnuOpen()	{ setInitWindowSize(400, 400, 350, 400); ReGroupConfig::initialize(); realize(); }

	void reArrange(bool);
	void cmd(char*);
};

extern ReWindow* Editor;

extern char* tbName[];
extern char* tbText[];
extern char* tbNameAndText[];
extern char* tbAlignment[];
extern char* tbScroll[];
extern char* tbCombo[];
extern char* tbAllStyles[];

class ReTestDlg : public XmUserDialog
{
	ReDialog* templ;

//	bool initWindowSize(int&, int&, int&, int&);

	void createContents();
	void createSubtree(CiObject*, XmDialogPane*);
public:
	ReTestDlg(ReDialog* dlg) : XmUserDialog(dlg->getDescr(), Editor)	{ templ = dlg; }

	void gnuOpen()	{ setInitWindowSize(350, 350, templ->extent().x, templ->extent().y); ReTestDlg::createContents(); realize(); }
};

