
/* Menu.c */

/*
   Musical Notation Editor for X, Chris Cannam 1994

   Menu handling
*/


#include "General.h"
#include "IO.h"
#include "Widgets.h"
#include "Visuals.h"
#include "Menu.h"

#include "text_above.xbm"
#include "text_above_large.xbm"
#include "text_below.xbm"
#include "text_below_italic.xbm"

#include <Yawn.h>
#include <YSmeBSB.h>
#include <ILClient.h>

#define EditMenuUndo Unimplemented
#define StaveMenuConnectAbove Unimplemented
#define StaveMenuConnectBelow Unimplemented
#define StaveMenuDisconnect Unimplemented
#define GroupMenuGrace Unimplemented
#define ToolsMenuPreferences Unimplemented
#define TextMenuDynamic Unimplemented

/*#include "toolbar/undo.xbm"*/
#include "toolbar/ninja_cross.xbm"
#include "toolbar/cut.xbm"
#include "toolbar/copy.xbm"
#include "toolbar/paste.xbm"
#include "toolbar/edit.xbm"
#include "toolbar/chord.xbm"
#include "toolbar/slur.xbm"
#include "toolbar/tie.xbm"
#include "toolbar/beam.xbm"
#include "toolbar/tuplet.xbm"
#include "toolbar/break.xbm"
#include "toolbar/text1.xbm"
#include "toolbar/text2.xbm"
#include "toolbar/text3.xbm"
#include "toolbar/text4.xbm"
#include "toolbar/sequence.xbm"
#include "toolbar/crescendo.xbm"
#include "toolbar/decrescendo.xbm"


static YMenuElement editMenu[] = {
  /*  { "Undo",           FileLoadedMode | SlaveToSequencerMode | FileNotLoadedMode,
                                               EditMenuUndo,          undo_bits, NULL, },
  YMenuDivider,
*/
  { "Delete",         NoAreaSweptMode | SlaveToSequencerMode,         EditMenuDelete,        ninja_cross_bits, NULL, },
  YMenuDivider,
  { "Cut",            NoAreaSweptMode | SlaveToSequencerMode,         EditMenuCut,           cut_bits, NULL, },
  { "Copy",           NoAreaSweptMode | SlaveToSequencerMode,         EditMenuCopy,          copy_bits, NULL, },
  { "Paste",          CursorNotPlacedMode | SlaveToSequencerMode,     EditMenuPaste,         paste_bits, NULL, },
  { "Show Clipboard", NullMode | SlaveToSequencerMode,                EditMenuShowClipboard, NULL, NULL, },
  YMenuDivider,
  { "Chord",          NoAreaSweptMode | SlaveToSequencerMode,         EditMenuChord,        chord_bits, NULL, },
  { "Unchord",        NoAreaSweptMode | SlaveToSequencerMode,         EditMenuUnchord,      NULL, NULL, },
  { "Create Chord . . .", CursorNotPlacedMode | SlaveToSequencerMode, EditMenuCreateChord,  NULL, NULL },
  { "Edit Chord . . .",   NoAreaSweptMode | SlaveToSequencerMode | MultipleItemsSweptMode,
                                               EditMenuChangeChord,   edit_bits, NULL },
  YMenuDivider,
  { "Select this Bar",     CursorNotPlacedMode | SlaveToSequencerMode,     EditMenuSelectBar,    NULL, NULL, },
  { "Select this Staff",   CursorNotPlacedMode | SlaveToSequencerMode,     EditMenuSelectStaff,  NULL, NULL, },
};

static YMenuId editMenuId = NULL;


static YMenuElement staveMenu[] = {
  { "Add Staff . . .",   FileNotLoadedMode | SlaveToSequencerMode,       StaveMenuNewStave,     NULL, NULL, },
  { "Delete Staff",   CursorNotPlacedMode | SlaveToSequencerMode,     StaveMenuDeleteStave,  NULL, NULL, },
  { "Empty Staff",    CursorNotPlacedMode | SlaveToSequencerMode,     StaveMenuEmptyStave,   NULL, NULL, },
  { "Rename Staff . . .", CursorNotPlacedMode | SlaveToSequencerMode,    StaveMenuRenameStave,  NULL, NULL, },
  YMenuDivider,
  /*  { "Bracket with Next",  CursorNotPlacedMode | SlaveToSequencerMode,     StaveMenuConnectBelow, NULL, NULL, },
  { "Unbracket",     CursorNotPlacedMode | SlaveToSequencerMode,     StaveMenuDisconnect,   NULL, NULL, },
  YMenuDivider,*/
  { "Fill to End",     CursorNotPlacedMode | SlaveToSequencerMode,     StaveMenuFillToEnd,   NULL, NULL, },
};

static YMenuId staveMenuId = NULL;


static YMenuElement markMenu[] = {
  { "Accent",         NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  { "Staccato",       NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  { "Legato",         NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  { "Sforzando",      NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  { "Rinforzando",    NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  { "Trill",          NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  { "Turn",           NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  { "Pause",          NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuMark,          NULL, NULL, },
  YMenuDivider,
  { "Unmark",         NoAreaSweptMode | SlaveToSequencerMode,         MarkMenuUnmark,        NULL, NULL, },
};

static YMenuId markMenuId = NULL;


static YMenuElement groupMenu[] = {
  { "Beam",           NoAreaSweptMode | SlaveToSequencerMode,         GroupMenuBeam,         beam_bits, NULL, },
  /*  { "Grace",          NoAreaSweptMode | SlaveToSequencerMode,         GroupMenuGrace,        NULL, NULL, },*/
  { "Tuplet . . .",   NoAreaSweptMode | SlaveToSequencerMode,         GroupMenuTuplet,       NULL, NULL, },
  { "Simple Tuplet",  NoAreaSweptMode | SlaveToSequencerMode,         GroupMenuSimpleTuplet, tuplet_bits, NULL, },
  { "Break Group",    NoAreaSweptMode | SlaveToSequencerMode,         GroupMenuBreakGroup,   break_bits, NULL, },
  YMenuDivider,
  { "Tie",            NoAreaSweptMode | SlaveToSequencerMode | SingleItemSweptMode,         GroupMenuTie,         tie_bits, NULL, },
  { "Slur",           NoAreaSweptMode | SlaveToSequencerMode | SingleItemSweptMode,         GroupMenuSlur,         slur_bits, NULL, },
  { "Crescendo",      NoAreaSweptMode | SlaveToSequencerMode,         GroupMenuCrescendo,    crescendo_bits, NULL, },
  { "Decrescendo",    NoAreaSweptMode | SlaveToSequencerMode,         GroupMenuDecrescendo,  decrescendo_bits, NULL, }, 
  { "Remove Indications", NoAreaSweptMode | SlaveToSequencerMode,      GroupMenuRemove,       NULL, NULL, },
  YMenuDivider,
  { "Auto-Beam",      FileNotLoadedMode | SlaveToSequencerMode,       GroupMenuAutoBeam,     NULL, NULL, },
  { "Transpose . . .",   FileNotLoadedMode | SlaveToSequencerMode,       GroupMenuTranspose,    NULL, NULL, },
  /* JPff insertion */
  { "Invert . . .",      FileNotLoadedMode | SlaveToSequencerMode,       GroupMenuInvert,       NULL, NULL, },
  { "Retrograde",  FileNotLoadedMode | SlaveToSequencerMode,       GroupMenuRetrograde,   NULL, NULL, },
};

static YMenuId groupMenuId = NULL;


static YMenuElement textMenu[] = {
  /* resource file adds the dots to the first four entries */
  { "Text Above",       CursorNotPlacedMode | SlaveToSequencerMode,     TextMenuTextAbove,     text1_bits, NULL, },
  { "Text Above, Large",       CursorNotPlacedMode | SlaveToSequencerMode,     TextMenuTextAboveBig,  text2_bits, NULL, },
  { "Text Below",       CursorNotPlacedMode | SlaveToSequencerMode,     TextMenuTextBelow,     text3_bits, NULL, },
  { "Text Below, Italic",       CursorNotPlacedMode | SlaveToSequencerMode,     TextMenuTextBelowI,    text4_bits, NULL, },
  /*  YMenuDivider,
  { "Dynamic . . .",    CursorNotPlacedMode | SlaveToSequencerMode,     TextMenuDynamic,  NULL, NULL, },*/
  YMenuDivider,
  { "Clear Group",    NoAreaSweptMode | SlaveToSequencerMode,         TextMenuUnlabelGroup,  NULL, NULL, },
  { "Clear Bar",      CursorNotPlacedMode | SlaveToSequencerMode,     TextMenuUnlabelBar,    NULL, NULL, },
  { "Clear Staff",    CursorNotPlacedMode | SlaveToSequencerMode,     TextMenuUnlabelStaff,  NULL, NULL, },
};

static YMenuId textMenuId = NULL;

static YMenuElement toolsMenu[] = {
  { "Sequence!",       FileNotLoadedMode | SlaveToSequencerMode | SequencerRunningMode,
                                               ToolsMenuSequence,     sequence_bits, NULL, },
  /*  { "Play MIDI",      FileNotLoadedMode | SlaveToSequencerMode | SequencerRunningMode,
                                               ToolsMenuPlayMidi,     NULL, NULL, },*/
  { "Import MIDI . . .", NullMode | SlaveToSequencerMode,                ToolsMenuImportMidi,   NULL, NULL, },
  { "Export MIDI . . .", FileNotLoadedMode | SlaveToSequencerMode,       ToolsMenuWriteMidi,    NULL, NULL, },
  YMenuDivider,
  { "Import old Rosegarden file . . .", NullMode | SlaveToSequencerMode, LoadOld, NULL, NULL, },
  YMenuDivider,
  { "Export MusicTeX . . .",FileNotLoadedMode | SlaveToSequencerMode,       ToolsMenuExportTeX,    NULL, NULL, },
    /*  YMenuDivider,
  { "Preferences . . .", NullMode | SlaveToSequencerMode,                ToolsMenuPreferences,  NULL, NULL, },*/
};

static YMenuId toolsMenuId = NULL;

static YMenuElement barMenu[] = {
  { "Plain",          CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuPlain,          NULL, NULL, },
  { "Double Bar",     CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuDoubleBar,      NULL, NULL, },
  { "Repeat at Start", CursorNotPlacedMode | SlaveToSequencerMode,    BarMenuRepeatAtStart,  NULL, NULL, },
  { "Repeat at End",  CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuRepeatAtEnd,    NULL, NULL, },
  YMenuDivider,
  { "Label . . .",       CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuLabel,          NULL, NULL, },
  { "Remove Label",   CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuUnlabel,        NULL, NULL, },
  YMenuDivider,
  { "Metronome . . .",   CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuMetronome,      NULL, NULL, },
  { "Remove Metronome", CursorNotPlacedMode | SlaveToSequencerMode,   BarMenuRemoveMet,      NULL, NULL, },
  YMenuDivider,
  /*  { "Remove Time Signature", CursorNotPlacedMode | SlaveToSequencerMode, BarMenuRemoveTime,  NULL, NULL, },
  YMenuDivider,*/
  { "Key Signature . . .",   CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuKeySignature,      NULL, NULL, },
  { "Time Signature . . .", CursorNotPlacedMode | SlaveToSequencerMode,     BarMenuTimeSignature,  NULL, NULL, },
};

static YMenuId barMenuId = NULL;



void IssueMenuComplaint(String s)
{
  Begin("IssueMenuComplaint");

  XBell(display, 70);
  (void)YQuery(topLevel, s, 1, 0, 0, "Okay", NULL);

  End;
}


void Unimplemented(Widget w, XtPointer a, XtPointer b)
{
  Begin("Unimplemented");
  (void)YQuery(topLevel, "Sorry, that function is not yet implemented.",
		1, 0, 0, "Continue", NULL);
  End;
}


void InstallEditMenu(Widget edit)
{
  Begin("InstallEditMenu");

  editMenuId = YCreateMenu(edit, "Edit Menu", XtNumber(editMenu), editMenu);

  End;
}


void InstallStaveMenu(Widget stavew)
{
  Begin("InstallStaveMenu");

  staveMenuId =
    YCreateMenu(stavew, "Stave Menu", XtNumber(staveMenu), staveMenu);

  End;
}


void InstallGroupMenu(Widget group)
{
  Begin("InstallGroupMenu");

  groupMenuId =
    YCreateMenu(group, "Group Menu", XtNumber(groupMenu), groupMenu);

  End;
}


void InstallMarkMenu(Widget mark)
{
  int    i, j;
  Pixmap map;

  Begin("InstallMarkMenu");

  markMenuId =
    YCreateMenu(mark, "Mark Menu", XtNumber(markMenu), markMenu);

  for (i = 0; i < XtNumber(markMenu) - 2; ++i) {

    YSetValue(markMenu[i].widget, XtNleftMargin, NoteWidth + 12);

    for (j = 0; j < chordModVisualCount; ++j)
      if (!strncasecmp(chordModVisuals[j].name, markMenu[i].label,
		       strlen(markMenu[i].label))) break;

    if (j < chordModVisualCount) {

      map = XCreateBitmapFromData
	(display, RootWindowOfScreen(XtScreen(topLevel)),
	 chordModVisuals[j].bitmap, NoteWidth, ChordModHeight);

      YSetValue(markMenu[i].widget, XtNleftBitmap, map);
    }
  }

  End;
}
  


void InstallTextMenu(Widget text)
{
  int    i;
  Pixmap map;

  Begin("InstallTextMenu");

  textMenuId =
    YCreateMenu(text, "Text Menu", XtNumber(textMenu), textMenu);

  for (i = 0;
       i < XtNumber(textMenu) &&
       (textMenu[i].label ? strncmp(textMenu[i].label,"Text",4) : True); ++i);

  if (i < XtNumber(textMenu)) {

    map = XCreateBitmapFromData
      (display, RootWindowOfScreen(XtScreen(text)), text_above_bits,
       text_above_width, text_above_height);
    YSetValue(textMenu[i].widget, XtNleftMargin, text_above_width + 9);
    YSetValue(textMenu[i].widget, XtNleftBitmap, map); i++;

    map = XCreateBitmapFromData
      (display, RootWindowOfScreen(XtScreen(text)), text_above_large_bits,
       text_above_large_width, text_above_large_height);
    YSetValue(textMenu[i].widget, XtNleftMargin, text_above_large_width + 9);
    YSetValue(textMenu[i].widget, XtNleftBitmap, map); i++;

    map = XCreateBitmapFromData
      (display, RootWindowOfScreen(XtScreen(text)), text_below_bits,
       text_below_width, text_below_height);
    YSetValue(textMenu[i].widget, XtNleftMargin, text_below_width + 9);
    YSetValue(textMenu[i].widget, XtNleftBitmap, map); i++;

    map = XCreateBitmapFromData
      (display, RootWindowOfScreen(XtScreen(text)), text_below_italic_bits,
       text_below_italic_width, text_below_italic_height);
    YSetValue(textMenu[i].widget, XtNleftMargin, text_below_italic_width + 9);
    YSetValue(textMenu[i].widget, XtNleftBitmap, map);
  }

  End;
}


void InstallBarMenu(Widget bar)
{
  Begin("InstallBarMenu");

  barMenuId =
    YCreateMenu(bar, "Bar Menu", XtNumber(barMenu), barMenu);

  End;
}


void InstallToolsMenu(Widget tools)
{
  Begin("InstallToolsMenu");

  toolsMenuId =
    YCreateMenu(tools, "Tools Menu", XtNumber(toolsMenu), toolsMenu);

  End;
}


void EnterMenuMode(MenuMode mode)
{
  Begin("EnterMenuMode");
  
  YEnterMenuMode(    fileMenuId, mode );
  YEnterMenuMode(    editMenuId, mode );
  YEnterMenuMode(   groupMenuId, mode );
  YEnterMenuMode(   staveMenuId, mode );
  YEnterMenuMode(     barMenuId, mode );
  YEnterMenuMode(    markMenuId, mode );
  YEnterMenuMode(    textMenuId, mode );
  YEnterMenuMode(   toolsMenuId, mode );

  End;
}


void LeaveMenuMode(MenuMode mode)
{
  Begin("LeaveMenuMode");
  
  YLeaveMenuMode(    fileMenuId, mode );
  YLeaveMenuMode(    editMenuId, mode );
  YLeaveMenuMode(   groupMenuId, mode );
  YLeaveMenuMode(   staveMenuId, mode );
  YLeaveMenuMode(     barMenuId, mode );
  YLeaveMenuMode(    markMenuId, mode );
  YLeaveMenuMode(    textMenuId, mode );
  YLeaveMenuMode(   toolsMenuId, mode );

  End;
}


Boolean QueryMenuMode(MenuMode mode)
{
  Begin("QueryMenuMode");
  Return(YQueryMenuMode(fileMenuId, mode));
}


void MenuCleanUp(void)
{
  Begin("MenuCleanUp");

  FileMenuCleanUp();

  if (    editMenuId) YDestroyMenu(    editMenuId);
  if (   groupMenuId) YDestroyMenu(   groupMenuId);
  if (     barMenuId) YDestroyMenu(     barMenuId);
  if (   staveMenuId) YDestroyMenu(   staveMenuId);
  if (    textMenuId) YDestroyMenu(    textMenuId);
  if (    markMenuId) YDestroyMenu(    markMenuId);
  if (   toolsMenuId) YDestroyMenu(   toolsMenuId);

  End;
}

