/*
 *    Rosegarden MIDI Sequencer
 *
 *    File:           MidiSetupDlgs.c
 *
 *    Description:    Code to display and run dialogues from the MIDI menu on
 *                    the sequencer main window.
 *
 *    Author:         AJG
 *
 * History:
 * 
 * Update       Date            Programmer      Comments
 * ======       ====            ==========      ========
 * 001          28/04/94        AJG             File Created.
 *
 */

#undef POSIX_PLEASE
#undef _POSIX_SOURCE

#include <sys/types.h>
#include <dmedia/midi.h>

#include <MidiXInclude.h>
#include <MidiFile.h>
#include <MidiErrorHandler.h>

#include "Globals.h"
#include "EventDlgs.h"
#include "Sequence.h"
#include "Main.h"

#include <ctype.h>
#include <Debug.h>

void Midi_InitialPatchesDlg(void) { }

extern char *MidiPortName;
extern int MidiEventBufferSize;
extern Boolean MidiPortSync;
extern Boolean MidiMaintainTempo;
extern int MidiEventBufferTimer;

Boolean SetupSync;
Boolean MaintainTempo;

Widget SetupDlg;
Widget SetupEventBufSizeField;
Widget SetupTrackingButton;
Widget SetupBufferTimeField;
Widget SetupPortNameField;

void Midi_SetupDlg(void);

int midiPortCount;
static String *midiPortNameList;

void Midi_GetMidiPorts()
{
  int i;
  
  if (midiPortCount <= 0) midiPortNameList = 0;
  else {

    midiPortNameList = (String *)XtMalloc(midiPortCount * sizeof(String));

    for (i = 0; i < midiPortCount; ++i) {
      String name = mdGetName(i);
      if (!name) break;
      midiPortNameList[i] = XtNewString(name);
    }

    midiPortCount = i;
  }
}

void Midi_FreeMidiPorts()
{
  int i;
  if (!midiPortNameList) return;
  for (i = 0; i < midiPortCount; ++i) XtFree(midiPortNameList[i]);
  XtFree(midiPortNameList);
}


void Midi_SetupCB(Widget w, XtPointer a, XtPointer b)
{
BEGIN("Midi_SetupCB");

	Midi_SetupDlg();

END;
}


void Midi_SetupCancelCB(Widget w, XtPointer a, XtPointer b)
{
BEGIN("Midi_SetupCancelCB");

        YDestroyOptionMenu(SetupTrackingButton);
	XtDestroyWidget(SetupDlg);

END;
}


void Midi_SetupSyncCB(Widget w, XtPointer a, XtPointer b)
{
BEGIN("Midi_SetupSyncCB");

	SetupSync = !SetupSync;

END;
}


void Midi_SetupMaintainTempoCB(Widget w, XtPointer a, XtPointer b)
{
BEGIN("Midi_SetupMaintainTempoCB");

	MaintainTempo = !MaintainTempo;

END;
}


/*
 * Function:     Midi_SetupOKCB
 *
 * Description:  For Linux this will ignore the checking for the
 *               data returned by SetupPortNameField . . for the
 *               moment at least.  
 *
 */
void Midi_SetupOKCB(Widget w, XtPointer a, XtPointer b)
{
char *EventBufStr;
int   EventBufSize;

char *PortNameStr;

BEGIN("Midi_SetupOKCB");

    XtFree(MidiPortName);
    if (midiPortCount <= 0) MidiPortName = XtNewString("(no device)");
    else {
      int port = YGetCurrentOption(SetupPortNameField);
      MidiPortName = XtNewString(midiPortNameList[port]);
      YDestroyOptionMenu(SetupPortNameField);
      Midi_FreeMidiPorts();
    }

    YGetValue(SetupEventBufSizeField, XtNstring, &EventBufStr);

    EventBufSize = atoi(EventBufStr);

    if (EventBufSize < 1) 
    {
        YQuery(SetupDlg, "Invalid Event Buffer Size", 1, 0, 0, "Continue",
                                                                       NULL);
        END;
    }

    MidiEventBufferSize = EventBufSize;

    YDestroyOptionMenu(SetupTrackingButton);
    XtDestroyWidget(SetupDlg);

END;
}

	
void Midi_SetupDlg(void)
{
Widget SetupPane;
Widget SetupTopBox;
Widget SetupLabel;

Widget SetupForm;
Widget SetupPortNameLabel;
Widget SetupEventBufSizeLabel;
Widget SetupBottomBox;
Widget SetupOK;
Widget SetupCancel;
Widget SetupHelp = 0;

Widget SetupBufferTimeLabel;
Widget SetupMaintainTempoButton;
Widget SetupPortSyncButton;

XPoint op;
char   TextBuffer[32];

BEGIN("Midi_SetupDlg");

    SetupDlg = XtCreatePopupShell("Midi Setup", transientShellWidgetClass, 
                                     topLevel, NULL, 0);

    SetupPane = YCreateWidget("Midi Setup Pane", panedWidgetClass, SetupDlg);

    SetupTopBox = YCreateShadedWidget("Midi Setup Title Box", boxWidgetClass,
                                              SetupPane, MediumShade);

    SetupLabel = YCreateLabel("Configure MIDI Setup", SetupTopBox);

	
    SetupForm = YCreateShadedWidget("Midi Setup Form", formWidgetClass,
                                              SetupPane, LightShade);

    SetupPortNameLabel = YCreateLabel("Midi Port:", SetupForm);

    Midi_GetMidiPorts();

    if (midiPortCount > 0) {

      int i;
      for (i = 0; i < midiPortCount; ++i) {
	if (!strcmp(midiPortNameList[i], MidiPortName)) break;
      }

      SetupPortNameField = YCreateOptionMenu
	(SetupForm, midiPortNameList, midiPortCount,
	 i < midiPortCount ? i : 0, NULL, NULL);

    } else {
      SetupPortNameField = YCreateLabel("No devices", SetupForm);
    }

    SetupPortSyncButton = YCreateToggle("Synchronous Mode", SetupForm,
					Midi_SetupSyncCB);

    SetupEventBufSizeLabel = YCreateLabel("Event Buffer Size:", SetupForm);

    SetupEventBufSizeField = YCreateSurroundedWidget("Event Buffer Size",
                           asciiTextWidgetClass, SetupForm, NoShade, NoShade);

    SetupBufferTimeLabel = YCreateLabel("Input Buffer Timer:", SetupForm);

    SetupBufferTimeField = YCreateSurroundedWidget("Input Buffer Time",
                           asciiTextWidgetClass, SetupForm, NoShade, NoShade);

    SetupTrackingButton = Midi_PlayTrackingMenuButton(SetupForm);

    SetupBottomBox = YCreateShadedWidget("Midi Setup Button Box",
                           boxWidgetClass, SetupPane, MediumShade);

    SetupOK     = YCreateCommand("OK", SetupBottomBox);
    SetupCancel = YCreateCommand("Cancel", SetupBottomBox);

    if (appData.interlockWindow)
    {
        SetupHelp   = YCreateCommand("Help", SetupBottomBox);
        XtAddCallback(SetupHelp,   XtNcallback, Midi_HelpCallback,
                                               "Midi - MIDI Setup");
    }

    XtAddCallback(SetupOK, XtNcallback, Midi_SetupOKCB, NULL);
    XtAddCallback(SetupCancel, XtNcallback, Midi_SetupCancelCB, NULL);


/************************************/
/* Format the form widget contents. */
/************************************/

    YSetValue(XtParent(SetupEventBufSizeLabel), XtNfromVert,
                                         XtParent(SetupPortNameLabel));
    YSetValue(XtParent(SetupEventBufSizeField), XtNfromHoriz,
                                         XtParent(SetupEventBufSizeLabel));
    YSetValue(XtParent(SetupEventBufSizeField), XtNfromVert,
                                         XtParent(SetupPortNameLabel));

    YSetValue(XtParent(SetupPortNameField), XtNfromHoriz,
                                         XtParent(SetupEventBufSizeLabel));
    YSetValue(XtParent(SetupBufferTimeLabel), XtNfromVert,
                                         XtParent(SetupEventBufSizeField));
    YSetValue(XtParent(SetupBufferTimeField), XtNfromHoriz,
                                         XtParent(SetupBufferTimeLabel));
    YSetValue(XtParent(SetupBufferTimeField), XtNfromVert,
                                         XtParent(SetupEventBufSizeField));

    YSetValue(XtParent(SetupTrackingButton), XtNfromVert,
                                         XtParent(SetupBufferTimeLabel));

    YSetValue(XtParent(SetupPortNameField), XtNfromVert,
                                         XtParent(SetupPortSyncButton));
    YSetValue(XtParent(SetupPortNameLabel), XtNfromVert,
                                         XtParent(SetupPortSyncButton));

    YSetValue(SetupBufferTimeField, XtNeditType, XawtextEdit);

    YSetValue(SetupEventBufSizeField, XtNeditType, XawtextEdit);

    sprintf(TextBuffer, "%d", MidiEventBufferSize);
    YSetValue(SetupEventBufSizeField, XtNstring, TextBuffer);
    
    YSetValue(SetupPortNameField, XtNeditType, XawtextEdit);
    YSetValue(SetupPortNameField, XtNstring, MidiPortName);

    sprintf(TextBuffer, "%d", MidiEventBufferTimer);
    YSetValue(SetupBufferTimeField, XtNstring, TextBuffer);
    SetupSync = MidiPortSync;
    MaintainTempo = MidiMaintainTempo;

    YSetToggleValue(SetupPortSyncButton, SetupSync);

    op = YPlacePopupAndWarp
      (SetupDlg, XtGrabNonexclusive, SetupOK, SetupCancel);

    if (midiPortCount > 0) {
      YFixOptionMenuLabel(SetupPortNameField);
    }

    YFixOptionMenuLabel(SetupTrackingButton);

    YAssertDialogueActions(SetupDlg, SetupOK, SetupCancel, SetupHelp);
END;
}

