#include <xt++/Intrinsic.h>

#include <xt++/Shell.h>
#include <xt++/Xaw/Label.h>
#include <xt++/Xaw/Command.h>
#include <xt++/Xaw/Form.h>
#include <xt++/Xaw/Dialog.h>
#include <xt++/Xaw/Clock.h>

#include <X11/StringDefs.h>
#include <libc.h>
//#include "debug.h"
#include <stream.h>

void Done(Core* , XtPointer , XtPointer);
void EditWidget(Core*, XEvent*, String*, Cardinal*);

void UserDone(Core* , XtPointer , XtPointer);
void QueryUser(Core*, XEvent*, String*, Cardinal*);

class Interactor :public TransientShellWidget {
// private:
 public:
   DialogWidget *dialog;
 public:
   Interactor(Widget parent) :TransientShellWidget("interactor", parent)
     { dialog = new DialogWidget("dialog",this);
       dialog->Manage();
       dialog->AddButton("OK", Done, (XtPointer)this);
//       XtInstallAllAccelerators(this,this);
       this->Realize();
    }
   ~Interactor() { delete dialog; }
};


void Dummy(Core* c, XEvent*, String* args, Cardinal* num)
{
   int d1[100];
   d1[0] = 5;
   cerr << "In Dummy: " << args[0] << "\n";
}

XtActionsRec actions[] =
{ 
   {"QueryUser",  QueryUser },
   {"EditWidget", EditWidget },
   {"Dummy", Dummy}
};


void DoEdit(Core* c, XtPointer d, XtPointer)
{
   Interactor *i = (Interactor*)c;
   char* name = i->dialog->GetValueString();
   Core* w = (Core*)d;
   w->SetValues(XtNlabel,(XtArgVal)name);
   delete i;
}

void EditWidget(Core* c, XEvent*, String*, Cardinal*)
{
   Interactor *i = new Interactor(c);
   i->AddCallback(XtNpopdownCallback,DoEdit,(XtPointer)c);
   Position x_root, y_root;
   c->TranslateCoords(c->Width(),c->Height(),x_root,y_root);
   i->SetValues(XtNx,x_root,XtNy,y_root);
   i->Popup(XtGrabNonexclusive);
}

void UserDone(Core* c, XtPointer, XtPointer)
{
   c->GetAppContext()->ExitLoop();
}

void QueryUser(Core* c, XEvent*, String*, Cardinal*)
{
//   char d1=0;
   Interactor i(c);
//   cerr << "d1= " << (int)d1 << "\n";
   i.AddCallback(XtNpopdownCallback,UserDone,(XtPointer)c);

   Position x_root, y_root;
   c->TranslateCoords(c->Width(),c->Height(),x_root,y_root);
   i.SetValues(XtNx,x_root,XtNy,y_root);
   i.Popup(XtGrabNonexclusive);
   i.GetAppContext()->MainLoop();
   char* name = i.dialog->GetValueString();
   c->SetValues(XtNlabel,(XtArgVal)name);
}


void Done(Core*, XtPointer d, XtPointer)
{
   TransientShellWidget *w = (TransientShellWidget *)d;
//   debugWidget(w);
   w->Popdown();
}

void QuitCB(Core* w , XtPointer, XtPointer)
{
   w->GetAppContext()->ExitLoop();
}

void BeepCB(Core* w , XtPointer d, XtPointer)
{
   TransientShellWidget *ts = (TransientShellWidget *)d;
   Dimension height = w->Height();
   Dimension width  = w->Width();
   Position  x     = w->X();
   Position  y     = w->Y();

   Position x_root, y_root;
   w->TranslateCoords(width/2,height/2,x_root,y_root);
   ts->SetValues(XtNx,x_root,XtNy,y_root);
   ts->Popup(XtGrabNonexclusive);

   cerr << "x= " << x << " y= " << y << "\n ";
   cerr << "width= " << width << " height= " << height << "\n";

   XBell(w->XtDisplay(),50);
}

main(unsigned int argc, char** argv)
{
//   XtToolkitInitialize();

   ApplicationContext appContext;

   appContext.AddActions(actions,XtNumber(actions));

   Display *dpy =  appContext.OpenDisplay(NULL, argv[0], "Eureka",
                        NULL,0,
                        &argc, argv);

//   debugDisplay(dpy);

   ApplicationShellWidget aw( argv[0], "Eureka", dpy);

   FormWidget    form("form", aw);
   form.Manage();

   CommandWidget quit("quit", form);
   quit.AddCallback(XtNcallback, QuitCB, (XtPointer)NULL);
   quit.Manage();

   TransientShellWidget ds("dshell",aw);
   DialogWidget dw("dialog", ds);
   dw.Manage();
   dw.AddButton("OK", Done, (XtPointer)&ds);
   ds.Realize();

   CommandWidget beep("beep", form);
   beep.AddCallback(XtNcallback, BeepCB, (XtPointer)&ds);
   beep.Manage();

   CommandWidget beep2("beep2", form);
   beep2.AddCallback(XtNcallback, BeepCB, (XtPointer)&ds);
   beep2.Manage();

   ClockWidget clock("clock", form);
   clock.Manage();
	
//   StopWatch sw(&form);
//   sw.Manage();

   aw.Realize();

//   debugShell(&aw);

   appContext.MainLoop();

}

								     
