#ifndef CODE_SETUPDIALOG_CXX
#define CODE_SETUPDIALOG_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: setup_dialog.cxx,v 1.10 1999/01/24 23:43:02 schmitzj Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include "types.h"
#include <Xclasses/tools.h>
#include <Xclasses/Xwindows.h>
#include <Xclasses/appwindow.h>
#include <Xclasses/Xcolors.h>
#include <Xclasses/config.h>
#include <Xclasses/file_dialog.h>
#include <Xclasses/easy_dialog.h>

#include <Xclasses/text.h>
#include <Xclasses/mxknob.h>
#include <Xclasses/group.h>
#include <Xclasses/bordergroup.h>
#include <Xclasses/input.h>
#include <Xclasses/checkbox.h>
#include <Xclasses/fontgroup.h>
#include <Xclasses/choice.h>
#include <Xclasses/ruler.h>
#include <Xclasses/fbutton.h>
#include <Xclasses/button.h>
#include <Xclasses/slider.h>
#include <Xclasses/card.h>
#include <Xclasses/rubbergroup.h>
#include <Xclasses/dirview.h>
#include <Xclasses/dlist.h>
#include <Xclasses/popup.h>
#include <Xclasses/menu.h>
#include <Xclasses/appwindow.h>
#include <Xclasses/popbutton.h>
#include <Xclasses/colornamegroup.h>

#include "../include/setup_dialog.h"
#include "include/setup_dialog_p.h"
#include "../include/defaults.h"
#include "../include/menu.h"
#include "../include/XCprogram_p.h"

#define ST_POPUP

static struct defaultstruct setup_defaults,bak_defaults;
extern configopts def_o[];

static void zfunc1(int v,char *buf,int s)
{
	if (v==0)
		sprintf(buf,"off");
	else
		sprintf(buf,"%d.%01ds",v/10,v-((v/10)*10));
}
static void zfunc2(int v,char *buf,int s)
{
	if (v==0)
		sprintf(buf,"never");
	else
		sprintf(buf,"%d.%01ds",v/10,v-((v/10)*10));
}

static void clfunc(int v,char *buf,int s)
{
	sprintf(buf,"%d.%03ds",v/1000,v-((v/1000)*1000));
}

setup_dialog::setup_dialog(void) : Xcolors()
{
	p=NULL;
	if (FindObject(".setup_dialog"))
	{
		Name("setup_dialog_dummy");
		return;
	}
	while (!(p=new psetup_dialog))
	{
		outOfMemory("setup_dialog");
	}
	p->o=this;
	setup_defaults=defaults;
	Name("setup_dialog");
}
psetup_dialog::psetup_dialog() : callable()
{
}
psetup_dialog::~psetup_dialog()
{
}
setup_dialog::~setup_dialog()
{
	DeleteObjectTree(FullName(),DOT_NOTBASE);
	if (p) delete p;
}

int setup_dialog::Start(Xwindows *w)
{
	if (!p) return 0;

	static char *f_name[8]={NULL,"Gadget","Group","Fixed",
					        "Small","Big","Menu","Help bubble"};
	static char pn1[60],pn2[60],pn3[60],pn4[60],buf[50];
	static char *md[]={pn1,pn2,pn3,pn4,NULL};
	int i;

	p->aw=new appwindow;
	p->aw->Name("settings_dialog_window");
	p->aw->ParentClass(this);

	sprintf(pn1,"%s on display %s",thisProgram->name->Name(),DisplayName());
	sprintf(pn2,"%s global",thisProgram->name->Name());
	sprintf(pn3,"Xclasses global on display %s",DisplayName());
	sprintf(pn4,"Xclasses global");

	group *maingp=new group;
	
	maingp->Name("maingroup");
	maingp->Vert();
	maingp->YDistance(5);
	choice *mode=new choice;
	maingp->Add(mode);
	 mode->Name("savemode");
	 mode->Items(md);
	 mode->Selected(1);
	 mode->Callback(p,(CALLBACK)&psetup_dialog::readconfhook);
	card *optscard=new card;
	maingp->Add(optscard);
	 optscard->Name("optscard");
	group *savegroup=new group;
	maingp->Add(savegroup);
	 savegroup->Name("savegroup");
	 savegroup->Horiz();
//	 savegroup->DialogMode();
	 fbutton *but_save=new fbutton,*but_close=new fbutton;
	 text *but_status=new text;
	 savegroup->Add(but_save);
	  but_save->Name("but_save");
	  but_save->Text(" _Save ");
	  but_save->Callback(p,(CALLBACK)&psetup_dialog::writeconfhook);
	 savegroup->Add(but_status);
	  but_status->Name("but_status");
	  but_status->NoUnderline();
	  but_status->Text("              ");
	  but_status->Font(FONT_SMALL);
	  but_status->Center();
	 savegroup->Add(but_close);
	  but_close->Name("but_close");
	  but_close->Text(" _Close ");
	  but_close->ApplyXKey(XK_Escape);
	  but_close->Callback(p,(CALLBACK)&psetup_dialog::gghandler);

// --------------------------------------------------------------
// card 1 - Fonts
// --------------------------------------------------------------

	bordergroup *fontsgroup=new bordergroup,*allfonts_box=new bordergroup;
	rubbergroup *allfonts=new rubbergroup;
	optscard->Add("Fonts",allfonts_box);
	 allfonts_box->Title("Object fonts");
	 allfonts_box->Name(NULL);
	 allfonts_box->Add(allfonts);
	 allfonts->Name("allfonts");
	 allfonts->Horiz();
	 allfonts->Add(fontsgroup);
	  fontsgroup->Vert();
	  fontsgroup->Name("fontsgroup");
	  fontsgroup->Weight(150);
	  input *f_font;
#ifndef ST_POPUP
	  button *f_get;
	  button *f_old;
#else
	  button *f_old;
	  popbutton *f_pb;
#endif
	  group *f_gp;
	  for(i=1;i<FONTS;i++)
	  {
	    f_font=new input;
#ifndef ST_POPUP
	    f_get=new button;
	    f_old=new button;
#else
	    f_old=new button;
#endif
	    f_gp=new group;
#ifdef ST_POPUP
	    f_pb=new popbutton;
#endif
	  	fontsgroup->Add(f_gp,f_name[i]);
	   	 f_gp->Horiz();
	   	 f_gp->UseSmallest();
	   	 f_gp->Name(NULL);
	   	 f_gp->Center();
	   	 f_gp->Add(f_font);
	   	  f_font->Font(FONT_FIXED);
	   	  f_font->MaxChars(sizeof(setup_defaults.font[i]));
	   	  f_font->AlwaysMode();
	   	  sprintf(buf,"font_%d",i);
	   	  f_font->Name(buf);
#ifndef ST_POPUP
	   	 f_gp->Add(f_get);
	   	  f_get->Callback(p,(CALLBACK)&psetup_dialog::font_get);
	   	  f_get->Text("get");
	   	  f_get->Font(FONT_SMALL);
	   	  f_get->Weight(10);
	   	  sprintf(buf,"get_%d",i);
	   	  f_get->Name(buf);
#else
		 group *fontsel=new group;
		 fontsel->Vert();
		 fontsel->Name(NULL);
		 fontgroup *fgp=new fontgroup;
		 fgp->Name("fontsel");
		 if (i==3) fgp->Spacing_Fixed();
		 fontsel->Add(fgp);
		 fbutton *b=new fbutton;
		 b->Text("Set font");
		 b->Name("get_button");
		 fontsel->Add(b);
 	   	 f_gp->Add(f_pb);
	   	  sprintf(buf,"get_%d",i);
	   	  f_pb->Name(buf);
 	   	  f_pb->Text("Font...");
 	   	  f_pb->Weight(10);
 	   	  f_pb->Font(FONT_SMALL);
 	   	  f_pb->Apply(fontsel,"choose font");
 	   	  f_pb->CloseGadget(b);
	   	  f_pb->Callback(p,(CALLBACK)&psetup_dialog::font_get);
#endif
	   	 f_gp->Add(f_old);
	   	  f_old->Callback(p,(CALLBACK)&psetup_dialog::font_undo);
	   	  f_old->Text("undo");
	   	  f_old->Font(FONT_SMALL);
	   	  f_old->Weight(10);
	   	  sprintf(buf,"old_%d",i);
	   	  f_old->Name(buf);
	 }
#ifndef ST_POPUP
	 fontgroup *fontsel=new fontgroup;
	 allfonts->Add(fontsel);
	  fontsel->Name("fontsel");
	  fontsel->Weight(30);
#endif


// --------------------------------------------------------------
// card 2 - General
// --------------------------------------------------------------

	bordergroup *gengroup1=new bordergroup;
	group *gengroup2=new group;
	optscard->Add("General",gengroup1);
	 gengroup1->Title("General settings");
	 gengroup1->Name("gengroup");
	 gengroup1->Horiz();
	 gengroup1->XDistance(5);
	 gengroup1->Add(gengroup2);
	  gengroup2->Name(NULL);
	  gengroup2->Vert();
	  gengroup2->YDistance(3);

	  bordergroup *helpgroup=new bordergroup;
	  gengroup2->Add(helpgroup);
	   helpgroup->Name("helpgroup");
	   helpgroup->Title("Help bubble");
	   helpgroup->Vert();
	   helpgroup->YDistance(2);
	   
	   slider *opendelay=new slider,*closedelay=new slider;
	   choice *bubblemode=new choice;
	   static char *bubblemodetxt[]={"Bubbles","Boxes",NULL};
	   helpgroup->Add(opendelay,"o_pen delay");
		opendelay->Horiz();
		opendelay->MinValue(0);
		opendelay->MaxValue(100);
		opendelay->TextCallback(zfunc1);
		opendelay->Callback(p,(CALLBACK)&psetup_dialog::gghandler);
		opendelay->Name("opendelay");
	   helpgroup->Add(closedelay,"c_lose delay");
		closedelay->Horiz();
		closedelay->MinValue(0);
		closedelay->MaxValue(200);
		closedelay->TextCallback(zfunc2);
		closedelay->Name("closedelay");
	   helpgroup->Add(bubblemode,"Helpbox apperance");
	    bubblemode->Name("bubblemode");
		bubblemode->Items(bubblemodetxt);

	  bordergroup *mixgroup=new bordergroup;
	  gengroup2->Add(mixgroup);
	   mixgroup->Vert();
	   mixgroup->Name("mixgroup");
	    group *basecolorgroup=new group;
	   mixgroup->Add(basecolorgroup);
	    basecolorgroup->Horiz();
		basecolorgroup->UseSmallest();
	    basecolorgroup->Name("basecolorgroup");
	     input *basecolor=new input;
	    basecolorgroup->Add(basecolor);
	     basecolor->Name("basecolor");
         basecolor->Text("_Base color");
	     basecolor->MaxChars(sizeof(setup_defaults.basecolor)-1);
	     basecolor->AlwaysMode();
		 popbutton *basecolorpopupb=new popbutton;
		basecolorgroup->Add(basecolorpopupb);
		  group *colpopgp=new group;
		  colpopgp->Name("colorpopupgroup");
		  colpopgp->Vert();
		   colornamegroup *colpopg=new colornamegroup;
		   colpopg->Name("color");
		  colpopgp->Add(colpopg);
		   fbutton *colpopb=new fbutton;
		   colpopb->Text("Use");
		  colpopgp->Add(colpopb);
		 basecolorpopupb->Name("basecolorpopupbutton");
		 basecolorpopupb->Text("...");
		 basecolorpopupb->Weight(5);
		 basecolorpopupb->Apply(colpopgp,"choose color",160);
		 basecolorpopupb->CloseGadget(colpopb);
		 basecolorpopupb->Callback(p,(CALLBACK)&psetup_dialog::colorhandler);

	group *gengroup3=new group;
	 gengroup1->Add(gengroup3);
	  gengroup3->Name(NULL);

	  bordergroup *clickgroup=new bordergroup;
	  gengroup3->Add(clickgroup);
	   clickgroup->Name("clickgroup");
	   clickgroup->Title("Double click delay");
	   clickgroup->Vert();
	   clickgroup->YDistance(5);
	   
	   slider *clickdelay=new slider;
	   clickgroup->Add(clickdelay);
		clickdelay->Horiz();
		clickdelay->MinValue(10);
		clickdelay->MaxValue(1000);
		clickdelay->TextCallback(clfunc);
		clickdelay->Name("clickdelay");
		clickdelay->Callback(p,(CALLBACK)&psetup_dialog::gghandler);
	   fbutton *clicktest=new fbutton;
	   clickgroup->Add(clicktest);
	    clicktest->Name("clicktest");
	    clicktest->Text("click to test");
		clicktest->Callback(p,(CALLBACK)&psetup_dialog::gghandler);
	   text *clickreport=new text;
	   clickgroup->Add(clickreport);
	    clickreport->Name("clickreport");
	    clickreport->Text(" ");
	    clickreport->Center();
	    clickreport->Font(FONT_FIXED);

	  bordergroup *inputmodegroup=new bordergroup;
	  gengroup3->Add(inputmodegroup);
	   inputmodegroup->Name("inputmodegroup");
	   inputmodegroup->Title("Line input focus");
	   inputmodegroup->Vert();
	   inputmodegroup->YDistance(5);
	   
	   choice *inputmode=new choice;
	   static char *inputmodetxt[]={"program settings","click only","pointer position",NULL};
	   inputmodegroup->Add(inputmode,"activate by");
	    inputmode->Name("inputmode");
		inputmode->Items(inputmodetxt);

// --------------------------------------------------------------
// card 3 - Popup/Menu
// --------------------------------------------------------------

	bordergroup *popupgroup=new bordergroup;
	optscard->Add("Pull Down/Popup",popupgroup);
	 popupgroup->Title("Pull Down menu and popup");
	 popupgroup->Name("popupgroup");
	 popupgroup->Vert();
	 popupgroup->YDistance(8);
	 checkbox *popupmove=new checkbox;
	 popupgroup->Add(popupmove);
	  popupmove->Name("popupmove");
	  popupmove->Text("don't _highlight menu item\nduring mouse move");
	 checkbox *popupline=new checkbox;
	 popupgroup->Add(popupline);
	  popupline->Name("popupline");
	  popupline->Text("place all items in a line");
	 checkbox *newmenustyle=new checkbox;
	 popupgroup->Add(newmenustyle);
	  newmenustyle->Name("newmenustyle");
	  newmenustyle->Text("alternate menu style");


// --------------------------------------------------------------
// card 4 - Scroller/Slider/Listview
// --------------------------------------------------------------

	bordergroup *card4group=new bordergroup;
	card4group->Name(NULL);
	optscard->Add("Scroller/Slider/Lists",card4group);
	 card4group->Title("Scroller, Slider & Lists settings");
	 card4group->Horiz();
	 card4group->XDistance(5);
	 bordergroup *scrollergroup=new bordergroup;
	 card4group->Add(scrollergroup);
	  scrollergroup->Title("Scroller and Slider settings");
	  scrollergroup->Name("scrollergroup");
	  scrollergroup->Vert();
	  scrollergroup->YDistance(5);
	  bordergroup *scgp=new bordergroup;
	  scrollergroup->Add(scgp);
	   scgp->Name(NULL);
	   scgp->Title("Sc_roller");
	   scgp->UseSmallest();
	   scgp->Vert();
	   mxknob *scrollermode=new mxknob;
	   static char *scmd[]={"Xclasses default","up (like IRIX)","with border (like pOS)",NULL};
	   scgp->Add(scrollermode);
	    scrollermode->Name("scrollermode");
	    scrollermode->Items(scmd);
	    scrollermode->ApplyKey('r');

	   ruler *scrl=new ruler;
	   scgp->Add(scrl);
	    scrl->Horiz();
	   mxknob *scrollerbuttons=new mxknob;
	   static char *scbt[]={"_arrow at edges","_both arrows right/bottom",NULL};
	   scgp->Add(scrollerbuttons);
	    scrollerbuttons->Name("scrollerbuttons");
	    scrollerbuttons->Items(scbt);

	  bordergroup *slgp=new bordergroup;
	  scrollergroup->Add(slgp);
	   slgp->Name(NULL);
	   slgp->Title("S_lider");
	   mxknob *slidermode=new mxknob;
	   slgp->Add(slidermode);
	    slidermode->Name("slidermode");
	    slidermode->Items(scmd);
	    slidermode->ApplyKey('l');

	 bordergroup *listsgroup=new bordergroup;
	 card4group->Add(listsgroup);
	  listsgroup->Title("lists & listview settings");
	  listsgroup->Name("listsgroup");
	  listsgroup->Vert();
	  listsgroup->YDistance(5);

	  choice *multichoice1=new choice,*multichoice2=new choice,*multichoice3=new choice;
	  static char *multitxt1[]={"Shift","Control","Alt",NULL};
	  static char *multitxt2[]={"Button 2 (middle)","Button 3 (right)","Off",NULL};
	  listsgroup->Add(multichoice1,"_Multiselection with button 1 and");
	   multichoice1->Name("multichoice1");
	   multichoice1->Items(multitxt1);
	  listsgroup->Add(multichoice2,"_Block multiselection with button 1 and");
	   multichoice2->Name("multichoice2");
	   multichoice2->Items(multitxt1);
	  listsgroup->Add(multichoice3,"With m_ouse");
	   multichoice3->Name("multichoice3");
	   multichoice3->Items(multitxt2);



// --------------------------------------------------------------
// card n - Config-Manager
// --------------------------------------------------------------

#define CFGMGRCARD	4
	bordergroup *managergroup=new bordergroup;
	optscard->Add("Settings manager",managergroup);
	 managergroup->Title("Program settings manager");
	 managergroup->Name("managergroup");
	 managergroup->Horiz();
	 managergroup->XDistance(5);

	 dirview *fileslist=new dirview;
	 managergroup->Add(fileslist);
	  fileslist->Name("fileslist");
	  fileslist->FilesOnly();
	  fileslist->MultiSelect();
	  {
	  	char *h=getenv("HOME");
	    if (h) fileslist->SetDir(h);
	  }
	  fileslist->SetPattern(".Xclasses*");
	  fileslist->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
	 bordergroup *mcontrolgroup=new bordergroup;
	 managergroup->Add(mcontrolgroup);
	  mcontrolgroup->Name("mcontrolgroup");
	  mcontrolgroup->Weight(60);
	  mcontrolgroup->Vert();
	  fbutton *ctlremove=new fbutton;
	  mcontrolgroup->Add(ctlremove);
	   ctlremove->Text("remo_ve");
	   ctlremove->Name("remove");
	   ctlremove->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
	  fbutton *ctlread=new fbutton;
	  mcontrolgroup->Add(ctlread);
	   ctlread->Text("_read");
	   ctlread->Name("read");
	   ctlread->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
	  ruler *ruler1=new ruler;
	  mcontrolgroup->Add(ruler1);
	   ruler1->Horiz();
	   ruler1->Space(4);
	    popup *pop=new popup;
	    pop->Name("dspname_popup");
	    pop->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
	    pop->AddHeadline("set display");
	    pop->Add(DisplayName(),NULL,1);
	  input *ctldspname=new input;
	  mcontrolgroup->Add(ctldspname);
	   ctldspname->Text("_Display");
	   ctldspname->Name("dspname");
	   ctldspname->ContextPopup(pop);
	   ctldspname->MaxChars(50);
	   ctldspname->AlwaysMode();
	   ctldspname->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
		pop=new popup;
	    pop->Name("prgname_popup");
	    pop->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
	    pop->AddHeadline("set program");
	    pop->Add(thisProgram->name->Name(),NULL,1);
	  input *ctlprgname=new input;
	  mcontrolgroup->Add(ctlprgname);
	   ctlprgname->Text("_Program");
	   ctlprgname->Name("prgname");
	   ctlprgname->ContextPopup(pop);
	   ctlprgname->MaxChars(50);
	   ctlprgname->AlwaysMode();
	   ctlprgname->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
	  fbutton *ctlrename=new fbutton;
	  mcontrolgroup->Add(ctlrename,NULL);
	   ctlrename->Text("re_name");
	   ctlrename->Name("rename");
	   ctlrename->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
	  fbutton *ctllink=new fbutton;
	  mcontrolgroup->Add(ctllink,NULL);
	   ctllink->Text("_link to selected");
	   ctllink->Name("symlink");
	   ctllink->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);
//	  ctllink=new fbutton;
//	  mcontrolgroup->Add(ctllink,NULL);
//	   ctllink->Text("hard link to selected");
//	   ctllink->Name("link");
//	   ctllink->Callback(p,(CALLBACK)&psetup_dialog::filelisthook);


	  mcontrolgroup->Lock();

	p->hmenu=new menu;
	p->hmenu->NoHelpMenu(REASON_HELPWINDOW,(void*)this);
	p->hmenu->AddMenu("Setup");
	p->hmenu->Callback(p,(CALLBACK)&psetup_dialog::menuhandler);
	p->hmenu->AddSub("Load config");
	p->hmenu->AddHeadline("load config");
	p->hmenu->Add(pn1,"a1",1);
	p->hmenu->Add(pn2,"a2",2);
	p->hmenu->Add(pn3,"a3",3);
	p->hmenu->Add(pn4,"a4",4);
	p->hmenu->AddRuler();
	p->hmenu->Add("from file...","l",5);
	p->hmenu->AddRuler();
	p->hmenu->Add("Settings manager","m",6);
	p->hmenu->EndSub();
	p->hmenu->Add("Close",7);
	p->hmenu->Add("Close & use in new windows","w",8);

	p->hmenu->AddMenu("Extra");
	p->hmenu->Add("Save class view","Ctrl+Alt+Shift+Enter",1);

#ifdef ROOTID
	if (getuid()==ROOTID)
#else
	if (getuid()==0)
#endif
	{
		static char *mxp1[]={"private config files","global config files",NULL};
		static char *mxc1[]={"f5","f6",NULL};
		p->hmenu->AddMenu("Root");
		p->hmenu->Add("Save for program systemwide...",1);
		p->hmenu->Add("Save Xclasses systemwide...",2);
		p->hmenu->AddRuler();
		p->hmenu->AddHeadline("Settings manager");
		p->hmenu->AddMX(mxp1,mxc1,3);
	}

	{
		int x,y;
		GetPositionOnRoot(display(),w->window(),x,y);
		p->aw->InitSize(x,y,10);
	}
	p->aw->Init();
	p->aw->Callback(p,(CLOSECALLBACK)&psetup_dialog::close);
	p->aw->PlaceUnderPointer();
	p->aw->SetGroup(maingp);
	p->aw->SetMenu(p->hmenu);
	p->aw->Create();

	p->readconf();
	return 1;
}

void psetup_dialog::GUI2config(struct defaultstruct &defaults)
{
	char nme[100];
	for(int i=1;i<FONTS;i++)
	{
		sprintf(nme,".maingroup.optscard.allfonts.fontsgroup.font_%d",i);
		input *fnt=(input*)FindObject(o->FullName(),nme);
		fnt->Input(defaults.font[i]);
	}

	defaults.help_wait=((slider*)FindObject(o->FullName(),".helpgroup.opendelay"))->Value();
	defaults.help_shown=((slider*)FindObject(o->FullName(),".helpgroup.closedelay"))->Value();
	defaults.help_bubblemode=((choice*)FindObject(o->FullName(),".helpgroup.bubblemode"))->Selected()==0?1:0;

	((input*)FindObject(o->FullName(),".mixgroup.basecolorgroup.basecolor"))->Input(defaults.basecolor);
	defaults.dclickdelay=((slider*)FindObject(o->FullName(),".clickgroup.clickdelay"))->Value();

	defaults.inputmode=((choice*)FindObject(o->FullName(),".inputmodegroup.inputmode"))->Selected();

	defaults.nopopupmove=((checkbox*)FindObject(o->FullName(),".popupgroup.popupmove"))->State()==PRESSED;
	defaults.popupline=((checkbox*)FindObject(o->FullName(),".popupgroup.popupline"))->State()==PRESSED;
	defaults.menunewstyle=((checkbox*)FindObject(o->FullName(),".popupgroup.newmenustyle"))->State()==PRESSED;

	defaults.scroller_emboss=(embosstype)((mxknob*)FindObject(o->FullName(),".scrollergroup.scrollermode"))->Selected();
	defaults.slider_emboss=(embosstype)((mxknob*)FindObject(o->FullName(),".scrollergroup.slidermode"))->Selected();
	defaults.scroller_buttonstogether=(int)((mxknob*)FindObject(o->FullName(),".scrollergroup.scrollerbuttons"))->Selected();
	defaults.listview_multikey=(listmultikey)((choice*)FindObject(o->FullName(),".listsgroup.multichoice1"))->Selected();
	defaults.listview_multiblockkey=(listmultikey)((choice*)FindObject(o->FullName(),".listsgroup.multichoice2"))->Selected();
	defaults.listview_multibutton=(listmultibutton)((choice*)FindObject(o->FullName(),".listsgroup.multichoice3"))->Selected();
}
void psetup_dialog::config2GUI(struct defaultstruct &defaults)
{
	char nme[100];
	for(int i=1;i<FONTS;i++)
	{
		sprintf(nme,".maingroup.optscard.allfonts.fontsgroup.font_%d",i);
		input *fnt=(input*)FindObject(o->FullName(),nme);
		fnt->Default(defaults.font[i]);

#ifdef ST_POPUP
		sprintf(nme,".maingroup.optscard.allfonts.fontsgroup.get_%d",i);
		Xclasses *obj=(Xclasses*)FindObject(o->FullName(),nme);
		fontgroup *ftg=(fontgroup*)FindObject(obj->FullName(),".fontsel");
		
		ftg->SetFont(defaults.font[i]);
#endif
	}

	((slider*)FindObject(o->FullName(),".helpgroup.opendelay"))->Value(defaults.help_wait);
	((slider*)FindObject(o->FullName(),".helpgroup.closedelay"))->Value(defaults.help_shown);	
	((choice*)FindObject(o->FullName(),".helpgroup.bubblemode"))->Selected(defaults.help_bubblemode?0:1);

	((input*)FindObject(o->FullName(),".mixgroup.basecolorgroup.basecolor"))->Default(defaults.basecolor);
	((colornamegroup*)FindObject(o->FullName(),".colorpopupgroup.color"))->SetColor(defaults.basecolor);

	((slider*)FindObject(o->FullName(),".clickgroup.clickdelay"))->Value(defaults.dclickdelay);
	((choice*)FindObject(o->FullName(),".inputmodegroup.inputmode"))->Selected(defaults.inputmode);

	((checkbox*)FindObject(o->FullName(),".popupgroup.popupmove"))->State(defaults.nopopupmove?PRESSED:RELEASED);
	((checkbox*)FindObject(o->FullName(),".popupgroup.popupline"))->State(defaults.popupline?PRESSED:RELEASED);
	((checkbox*)FindObject(o->FullName(),".popupgroup.newmenustyle"))->State(defaults.menunewstyle?PRESSED:RELEASED);

	((mxknob*)FindObject(o->FullName(),".scrollergroup.scrollermode"))->Selected(defaults.scroller_emboss);
	((mxknob*)FindObject(o->FullName(),".scrollergroup.slidermode"))->Selected(defaults.slider_emboss);
	((mxknob*)FindObject(o->FullName(),".scrollergroup.scrollerbuttons"))->Selected(defaults.scroller_buttonstogether);

	((choice*)FindObject(o->FullName(),".listsgroup.multichoice1"))->Selected(defaults.listview_multikey);
	((choice*)FindObject(o->FullName(),".listsgroup.multichoice2"))->Selected(defaults.listview_multiblockkey);
	((choice*)FindObject(o->FullName(),".listsgroup.multichoice3"))->Selected(defaults.listview_multibutton);
}

void psetup_dialog::close(void)
{
	int x,y,w,h;
	char buf[200];
	aw->WMPosition(x,y);
	aw->Size(w,h);
	sprintf(buf,"%dx%d%+d%+d",w,h,x,y);
	aw->SetResource("*settings_dialog_window.geometry",buf);
	aw->Close();
	delete o;
}
void psetup_dialog::menuhandler(gadget *g,int i)
{
	switch (((menu*)g)->Selection())
	{
		case 0x01000001:
		case 0x01000002:
		case 0x01000003:
		case 0x01000004: // load 1-4
			{
				choice *mode=(choice*)FindObject(o->FullName(),".maingroup.savemode");
				int m=mode->Selected();
				mode->Selected(((menu*)g)->MID()-1);
				readconf();
				mode->Selected(m);
			}
			break;
		case 0x01000005: // load... (?)
			readconf(1);
			break;
		case 0x01000006: // settings manager card
			((card*)FindObject(o->FullName(),".maingroup.optscard"))->Selected(CFGMGRCARD);
			break;
		case 0x01000008: // quit & use
			GUI2config(defaults);
		case 0x01000007: // quit
			close();
			break;
		case 0x02000001: // Save class view
			writeObjectTree();
			break;
		case 0x03000001: // root, prg global
			writeconf(1);
			break;
		case 0x03000002: // root, Xclasses global
			writeconf(2);
			break;
		case 0x03000003: // settings manager MX
			{
				dirview *fileslist=((dirview*)FindObject(o->FullName(),".managergroup.fileslist"));
				if (((menu*)g)->Selected(2,3)==0)
				{
					char *h=getenv("HOME");
					if (h) fileslist->SetDir(h);
					fileslist->SetPattern(".Xclasses*");
				}
				else
				{
					fileslist->SetDir(GLOBAL_CONFIGS);
					fileslist->SetPattern("*");
				}
				((group*)FindObject(o->FullName(),".managergroup.mcontrolgroup"))->Lock();
				((card*)FindObject(o->FullName(),".maingroup.optscard"))->Selected(CFGMGRCARD);
			}
			break;
	}
}
void psetup_dialog::gghandler(gadget *g,int i)
{
	if (!strcmp("but_close",g->Name()))
	{
		close();
	}
	else if (!strcmp("opendelay",g->Name()))
	{ // help wait
		if (((slider*)FindObject(o->FullName(),".helpgroup.opendelay"))->Value())
		{
			((slider*)FindObject(o->FullName(),".helpgroup.closedelay"))->Unlock();
			((choice*)FindObject(o->FullName(),".helpgroup.bubblemode"))->Unlock();
		}
		else
		{
			((slider*)FindObject(o->FullName(),".helpgroup.closedelay"))->Lock();
			((choice*)FindObject(o->FullName(),".helpgroup.bubblemode"))->Lock();
		}
	}
	else if (!strcmp("clickdelay",g->Name()))
	{
		defaults.dclickdelay=((slider*)FindObject(o->FullName(),".clickgroup.clickdelay"))->Value();
	}
	else if (!strcmp("clicktest",g->Name()))
	{
		if (aw->DoubleClick())
			((text*)FindObject(o->FullName(),".clickgroup.clickreport"))->Text("yes");
		else
			((text*)FindObject(o->FullName(),".clickgroup.clickreport"))->Text("no");
	}
}
void psetup_dialog::colorhandler(gadget *g,int i)
{
	((input*)FindObject(o->FullName(),".mixgroup.basecolorgroup.basecolor"))->Default(
		((colornamegroup*)FindObject(o->FullName(),".colorpopupgroup.color"))->GetColor()
	);
}

void psetup_dialog::font_undo(gadget *g,int i)
{
	int n=atoi(g->Name()+4);
	char buf[100];
	sprintf(buf,".fontsgroup.font_%d",n);
	((input*)FindObject(o->FullName(),buf))->Default(setup_defaults.font[n]);

#ifdef ST_POPUP
	char nme[100];
	sprintf(nme,".maingroup.optscard.allfonts.fontsgroup.get_%d",n);
	Xclasses *obj=(Xclasses*)FindObject(o->FullName(),nme);
	fontgroup *ftg=(fontgroup*)FindObject(obj->FullName(),".fontsel");
		
	ftg->SetFont(setup_defaults.font[n]);
#endif
}
void psetup_dialog::font_get(gadget *g,int i)
{
	int n=atoi(g->Name()+4);
	char buf[100];
	sprintf(buf,".fontsgroup.font_%d",n);
#ifdef ST_POPUP
	((input*)FindObject(o->FullName(),buf))->Default(((fontgroup*)FindObject(g->FullName(),".fontsel"))->GetFont());
#else
	((input*)FindObject(o->FullName(),buf))->Default(((fontgroup*)FindObject(o->FullName(),".allfonts.fontsel"))->GetFont());
#endif
}
void psetup_dialog::filelisthook(gadget *gg,int id)
{
	int refresh=0;
	dirview *flst=((dirview*)FindObject(o->FullName(),".managergroup.fileslist"));
	if (!strcmp(gg->Name(),"fileslist"))
	{
    	input *inp;
		group *mcgp=((group*)FindObject(o->FullName(),".managergroup.mcontrolgroup"));
		char buf[200],*c1,*c2;
		int mark=0;
    	mcgp->Unlock();

		inp=((input*)FindObject(o->FullName(),".prgname"));
		inp->Default("");
		inp=((input*)FindObject(o->FullName(),".dspname"));
		inp->Default("");

		flst->GetFile(buf,sizeof(buf));
		if (hmenu->Selected(2,3)==0)
		{
			strcpy(buf,&buf[10]);
		}
		else
		{
			strcpy(buf,&buf[9]);
			inp=((input*)FindObject(o->FullName(),".dspname"));
			inp->Lock();
		}
		c1=buf; c2=buf;
		while (*c2)
		{
			if (*c2=='_')
			{
				mark|=1;
				*c2=0;
				if (mark & 2)
					inp=((input*)FindObject(o->FullName(),".dspname"));
				else
					inp=((input*)FindObject(o->FullName(),".prgname"));
				inp->Default(c1);
				c1=c2+1;
				mark&=~2;
			}
			if (*c2==':')
			{
				mark|=2;
			}
			c2++;
		}
		*c2=0;
		if (mark & 2)
			inp=((input*)FindObject(o->FullName(),".dspname"));
		else
			inp=((input*)FindObject(o->FullName(),".prgname"));
		inp->Default(c1);
	}
	else if (!strcmp(gg->Name(),"remove"))
	{
		refresh=1;
		char path[500],fle[200];
		int f=0,md=0;
		easy_dialog sure;
		char txt[600];

		if (!flst->IsSelectedMarked())
		{
			flst->GetDir(path,sizeof(path));
			flst->GetFile(fle,sizeof(fle));
			strncat(path,fle,sizeof(path));

			sprintf(txt,"Really delete file\n\n'%s' ?",path);
			sure.Text(txt);
			sure.Options("Yes|all|abort|No");
			if (md==2 || (md=sure.Start(aw))<3)
			{
				remove(path);
//				printf("del %s\n",path);
			}
		}
		while (md<3 && (f=flst->FindNextMarked(f,fle,sizeof(fle))))
		{
			flst->GetDir(path,sizeof(path));
			strncat(path,fle,sizeof(path));

			sprintf(txt,"Really delete file\n\n'%s' ?",path);
			sure.Text(txt);
			sure.Options("Yes|all|abort|No");
			if (md==2 || (md=sure.Start(aw))<3)
			{
				remove(path);
//				printf("del %s\n",path);
			}
		}
	}
	else if (!strcmp(gg->Name(),"rename"))
	{
		refresh=1;
		char path[500],fle[200];
		char npath[500],buf[55];
		flst->GetDir(path,sizeof(path));
		flst->GetFile(fle,sizeof(fle));
		strncat(path,fle,sizeof(path));

		flst->GetDir(npath,sizeof(npath));
		if (hmenu->Selected(2,3)==0)
			strncat(npath,".Xclasses",sizeof(npath));
		else
			strncat(npath,"Xclasses",sizeof(npath));

    	input *inp;
		inp=((input*)FindObject(o->FullName(),".prgname"));
		inp->Input(buf);
		if (strlen(buf))
		{
			strncat(npath,"_",sizeof(npath));
			strncat(npath,buf,sizeof(npath));
		}
		inp=((input*)FindObject(o->FullName(),".dspname"));
		inp->Input(buf);
		if (strlen(buf))
		{
			strncat(npath,"_",sizeof(npath));
			strncat(npath,buf,sizeof(npath));
		}

		if (rename(path,npath))
		{
			easy_dialog errord;
			errord.Text("Can't rename file!");
			errord.Options("Ok");
			errord.Start(aw);
		}
//		printf("ren %s -> %s\n",path,npath);
	}
	else if (!strcmp(gg->Name(),"link") || !strcmp(gg->Name(),"symlink"))
	{
		refresh=1;
		char path[500],fle[200];
		char npath[500],buf[55];
		flst->GetDir(path,sizeof(path));
		flst->GetFile(fle,sizeof(fle));
		strncat(path,fle,sizeof(path));

		flst->GetDir(npath,sizeof(npath));
		if (hmenu->Selected(2,3)==0)
			strncat(npath,".Xclasses",sizeof(npath));
		else
			strncat(npath,"Xclasses",sizeof(npath));

    	input *inp;
		inp=((input*)FindObject(o->FullName(),".prgname"));
		inp->Input(buf);
		if (strlen(buf))
		{
			strncat(npath,"_",sizeof(npath));
			strncat(npath,buf,sizeof(npath));
		}
		inp=((input*)FindObject(o->FullName(),".dspname"));
		inp->Input(buf);
		if (strlen(buf))
		{
			strncat(npath,"_",sizeof(npath));
			strncat(npath,buf,sizeof(npath));
		}
		if (!strcmp(gg->Name(),"symlink"))
		{
			if (symlink(path,npath))
			{
				easy_dialog errord;
				errord.Text("Can't create link!");
				errord.Options("Ok");
				errord.Start(aw);
			}
		}
		else
		{
			if (link(path,npath))
			{
				easy_dialog errord;
				errord.Text("Can't create link!");
				errord.Options("Ok");
				errord.Start(aw);
			}
		}
//		printf("link %s -> %s\n",path,npath);
	}
	else if (!strcmp(gg->Name(),"read"))
	{
		char path[500],fle[200];
		flst->GetDir(path,sizeof(path));
		flst->GetFile(fle,sizeof(fle));
		strncat(path,fle,sizeof(path));
		readconf(2,path);
	}
	else if (!strcmp(gg->Name(),"dspname_popup"))
	{
		input *inp=((input*)FindObject(o->FullName(),".dspname"));
		switch (((popup*)gg)->PID())
		{
			case 1:
				inp->Default(o->DisplayName());
				break;
		}
	}
	else if (!strcmp(gg->Name(),"prgname_popup"))
	{
		input *inp=((input*)FindObject(o->FullName(),".prgname"));
		switch (((popup*)gg)->PID())
		{
			case 1:
				inp->Default(thisProgram->name->Name());
				break;
		}
	}

/*	char path[400],fle[200];
	int f=0;

	if (!flst->IsSelectedMarked())
	{
		flst->GetDir(path,sizeof(path));
		flst->GetFile(fle,sizeof(fle));
	}

	while (f=flst->FindNextMarked(f,fle,sizeof(fle)))
	{
		flst->GetDir(path,sizeof(path));
	} */

	if (refresh)
	{
		group *mcgp=((group*)FindObject(o->FullName(),".managergroup.mcontrolgroup"));
    	mcgp->Lock();
		flst->RereadDir();
	}
}
void psetup_dialog::readconfhook(void)
{
	readconf();
}
void psetup_dialog::writeconfhook(void)
{
	writeconf();
}
void psetup_dialog::readconf(int m,char *cnme)
{
	char cname[400];

	if (m==1)
	{
		static file_dialog flg;
		flg.SetPattern(".Xclasses*");
		{
	  		char *h=getenv("HOME");
			if (h) flg.SetDir(h);
		}
		if (!flg.Start(aw))
		{
			return;
		}
		char buf[200];
		flg.GetDir(cname,sizeof(cname));
		flg.GetFile(buf,sizeof(buf));
		strncat(cname,buf,sizeof(cname));
	}
	else if (m==2)
	{
		strcpy(cname,cnme);
	}
	else
	{
		choice *mode=(choice*)FindObject(o->FullName(),".maingroup.savemode");
		switch (mode->Selected())
		{
			case 0: // prg, display
				sprintf(cname,"Xclasses_%s_%s",prgname,o->DisplayName());
				break;
			case 1: // prg
				sprintf(cname,"Xclasses_%s",prgname);
				break;
			case 2: // global, display
				sprintf(cname,"Xclasses_%s",o->DisplayName());
				break;
			case 3: // global, display
				sprintf(cname,"Xclasses");
				break;
		}
	}
	bak_defaults=defaults;
	config readcfg(cname);
	readcfg.SetItems(def_o);
	readcfg.Read();
	setup_defaults=defaults;
	defaults=bak_defaults;

	config2GUI(setup_defaults);

	text *txt=((text*)FindObject(o->FullName(),".savegroup.but_status"));
	char buf[20+strlen(cname)];
	buf[0]=0;
	sprintf(buf,"Loaded %s",cname);
	txt->Text(buf);
}
void psetup_dialog::writeconf(int r)
{
	char cname[70];

	if (r)
	{
		easy_dialog yesno;
		char buf[100];
		if (r==1)
		{
			sprintf(buf,"Write Xclasses system config\nfor %s?",prgname);
			sprintf(cname,"Xclasses_%s",prgname);
		}
		else
		{
			sprintf(buf,"Write Xclasses system config file?");
			sprintf(cname,"Xclasses");
		}
		yesno.Text(buf);
		yesno.Options("Yes|No");
		if (yesno.Start(aw)==2) return;
	}
	else
	{	
		choice *mode=(choice*)FindObject(o->FullName(),".maingroup.savemode");
		switch (mode->Selected())
		{
			case 0: // prg, display
				sprintf(cname,"Xclasses_%s_%s",prgname,o->DisplayName());
				break;
			case 1: // prg
				sprintf(cname,"Xclasses_%s",prgname);
				break;
			case 2: // global, display
				sprintf(cname,"Xclasses_%s",o->DisplayName());
				break;
			case 3: // global, display
				sprintf(cname,"Xclasses");
				break;
		}
	}

	bak_defaults=defaults;
	config readcfg(cname);
	readcfg.SetItems(def_o);

	GUI2config(setup_defaults);
	defaults=setup_defaults;

	if (r)
	{
		readcfg.RootWrite();
	}
	else
	{
		readcfg.Write();
	}
	defaults=bak_defaults;	

	dirview *flst=((dirview*)FindObject(o->FullName(),".managergroup.fileslist"));
	flst->RereadDir();
	group *mcgp=((group*)FindObject(o->FullName(),".managergroup.mcontrolgroup"));
   	mcgp->Lock();

	text *txt=((text*)FindObject(o->FullName(),".savegroup.but_status"));
	char buf[20+strlen(cname)];
	buf[0]=0;
	sprintf(buf,"Saved %s",cname);
	txt->Text(buf);
}

#endif
