// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#include <OB/CORBA.h>
#include <OB/Util.h>

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/MainW.h>
#include <Xm/RowColumn.h>
#include <Xm/Frame.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/PushB.h>
#include <Xm/CascadeB.h>
#include <Xm/Protocols.h>

#if XlibSpecificationRelease >= 5
#    include <Xm/AtomMgr.h>
#endif

#include <Receiver_impl.h>

// ----------------------------------------------------------------------
// Callback helper functions
// ----------------------------------------------------------------------

static void
Quit(Widget, XtPointer clientData, XtPointer)
{
    Receiver_impl* client = (Receiver_impl*)clientData;
    client -> quit();
}

static void
About(Widget, XtPointer clientData, XtPointer)
{
    Receiver_impl* client = (Receiver_impl*)clientData;
    client -> about();
}

static void
Help(Widget, XtPointer clientData, XtPointer)
{
    Receiver_impl* client = (Receiver_impl*)clientData;
    client -> help();
}

static void
TextInput(Widget w, XtPointer clientData, XtPointer)
{
    Receiver_impl* client = (Receiver_impl*)clientData;
    client -> textInput(w);
}

// ----------------------------------------------------------------------
// Set window title
// ----------------------------------------------------------------------

void
Receiver_impl::setTitle()
{
    CORBA_String_var message =
	CORBA_string_alloc(2 + strlen(nick_) + 1 + strlen(id_) + 1 +
			   strlen(host_));

    strcpy(message.inout(), nick_);
    strcat(message.inout(), " (");
    strcat(message.inout(), id_);
    strcat(message.inout(), "@");
    strcat(message.inout(), host_);
    strcat(message.inout(), ")");

    XtVaSetValues(parent_, XmNtitle, message.inout(), 0);
}

// ----------------------------------------------------------------------
// Register with the server
// ----------------------------------------------------------------------
 
void
Receiver_impl::_register()
{
    ReceiverBase_impl::_register();
    setTitle();
}

// ----------------------------------------------------------------------
// Receiver constructor and desctructor
// ----------------------------------------------------------------------

Receiver_impl::Receiver_impl(Widget parent, Broadcaster_ptr server)
    : ReceiverBase_impl(server), parent_(parent)
{
    Atom atom = XmInternAtom(XtDisplay(parent_), "WM_DELETE_WINDOW", false);
    XmAddWMProtocolCallback(parent_, atom,
                            (XtCallbackProc)Quit, this);

    //
    // Create widgets
    //
    Widget mainWindow =
	XtVaCreateWidget("mainWindow",
			 xmMainWindowWidgetClass, parent_,
			 XmNcommandWindowLocation, XmCOMMAND_BELOW_WORKSPACE,
			 0);

    Widget menuBar =
	XmCreateMenuBar(mainWindow,
			"menuBar",
			0,
			0);

    XtManageChild(menuBar);

    Widget textOutputFrame =
	XtVaCreateManagedWidget("textOutputFrame",
				xmFrameWidgetClass, mainWindow,
				0);
    
    textOutput_ =
	XmCreateScrolledText(textOutputFrame,
			     "textOutput",
			     0,
			     0);
    
    XtVaSetValues(textOutput_,
		  XmNeditMode, XmMULTI_LINE_EDIT,
 		  XmNeditable, False,
		  XmNcursorPositionVisible, False,
 		  0);
    
    XtManageChild(textOutput_);

    Widget textInputFrame =
	XtVaCreateManagedWidget("textInputFrame",
				xmFrameWidgetClass, mainWindow,
				0);
    
    Widget textInput =
	XtVaCreateManagedWidget("textInput",
				xmTextFieldWidgetClass, textInputFrame,
				0);

    XtAddCallback(textInput, XmNactivateCallback, TextInput, (XtPointer)this);

    XmMainWindowSetAreas(mainWindow,
                         menuBar,
                         textInputFrame,
                         0,
                         0,
                         textOutputFrame);

    //
    // Create file menu
    //
    Widget fileMenuButton =
	XtVaCreateManagedWidget("fileMenuButton",
				xmCascadeButtonWidgetClass, menuBar,
				0);

    Widget fileMenu = XmCreatePulldownMenu(menuBar, "fileMenu", 0, 0);

    Widget quitButton =
	XtVaCreateManagedWidget("quitButton",
				xmPushButtonWidgetClass, fileMenu,
				0);

    XtVaSetValues(fileMenuButton, XmNsubMenuId, fileMenu, 0);

    XtAddCallback(quitButton, XmNactivateCallback, Quit, (XtPointer)this);

    //
    // Create help menu
    //
    Widget helpMenuButton =
	XtVaCreateManagedWidget("helpMenuButton",
				xmCascadeButtonWidgetClass, menuBar,
				0);

    Widget helpMenu = XmCreatePulldownMenu(menuBar, "helpMenu", 0, 0);

    Widget aboutButton =
	XtVaCreateManagedWidget("aboutButton",
				xmPushButtonWidgetClass, helpMenu,
				0);

    Widget commandButton =
	XtVaCreateManagedWidget("commandButton",
				xmPushButtonWidgetClass, helpMenu,
				0);

    XtVaSetValues(helpMenuButton, XmNsubMenuId, helpMenu, 0);

    XtAddCallback(aboutButton, XmNactivateCallback, About, (XtPointer)this);
    XtAddCallback(commandButton, XmNactivateCallback, Help, (XtPointer)this);

    XtVaSetValues(menuBar,
		  XmNmenuHelpWidget, helpMenuButton,
		  0);

    XtManageChild(mainWindow);

    //
    // Realize parent, which is the top-level widget
    //
    XtRealizeWidget(parent_);

    //
    // Register with the server
    //
    _register();
}

// ----------------------------------------------------------------------
// Print message
// ----------------------------------------------------------------------

void
Receiver_impl::print(const char* text)
{
    XmTextPosition position = XmTextGetLastPosition(textOutput_);

    CORBA_String_var s = CORBA_string_alloc(1 + strlen(text));
    s[0] = '\n';
    strcpy(&s[1], text);

    XmTextInsert(textOutput_, position, s.inout());
}

// ----------------------------------------------------------------------
// Receiver callbacks
// ----------------------------------------------------------------------

void
Receiver_impl::textInput(Widget w)
{
    char* s = XmTextFieldGetString(w);

    if(s)
    {
	parse(s);

	XtFree(s);
    }

    XmTextFieldSetString(w, "");
}


