// This may look like C code, but it is really -*- C++ -*-

//<copyright>
// 
// Copyright (c) 1994
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
// 
//</copyright>

//<file>
//
// Name:        priority.h
//
// Purpose:     interface to priority chooser
//
// Created:      8 Feb 94   Michael Pichler
//
// Changed:     13 Jun 94   Michael Pichler
//
//
//</file>


#ifndef harmony_widgets_priority_h
#define harmony_widgets_priority_h


#include <hyperg/hyperg/language.h>

#include <InterViews/enter-scope.h>
class Action;
class BoxGlyph;
class ManagedWindow;
class Patch;
class PolyGlyph;


// clearPolyGlyph moved to glyphutil



//<class>
//
// Name: PriorityChooser
//
// Purpose: dialog (modal) for ordering items; there is a list of "selected"
//          items and one of "unselected" items; the items of both lists can be
//          rearranged and exchanged by a kind of drag-and-drop
//
// Style name: PriorityChooser
//
// attributes: foreground, background, font (InterViews)
//
//
//</class>



class PriorityChooser
{
  public:
    enum { Ok = 1, Cancel = 2 };        // return value of dialog

    static int run (                    // run the dialog (modal)
      PolyGlyph* sel,                   //   initially selected glyphs
      PolyGlyph* unsel,                 //   initially unselected glyphs
      HgLanguage::Language language,    //   language for standard buttons
      int mustselectone,                //   must select at least one item
      const char* wintitle,             //   window title
      const char* headline,             //   dialog title line
      const char* selboxtitle = 0,      //   heading of selected items
      const char* unselboxtitle = 0,    //   heading of unselected items
      const char* buttonall = 0,        //   label of button "select all"
      const char* buttonnone = 0        //   label of button "deselect all"
    );
};




//<class>
//
// Name: PrChooser<class Item>
//
// Purpose: interface to PriorityChooser dialog on item level
//          pseudo-template using preprocessor macros
//          the two lists or "selected" and "unselected"
//          items are managed by this class.
//          class Item is the type of items
//          (has to be derived from Glyph)
//
//
// Public Interface:
//
// declarePrChooser(Item)
//   generate declaration of priority chooser for item class Item
//
// implementPrChooser(Item)
//   generate implementation of priority chooser for Item class
//
// PrChooser(Item)
//   class name
//
//
// Member functions:
//
// void appendSelected (Item*);
// void appendUnselected (Item*);
//   append an item to the list of selected/unselected glyphs
//
// int run (...);
//   run the dialog (modal);
//   return value: PriorityChooser::Ok or PriorityChooser::Cancel
//   same arguments as PriorityChooser::run, only the two lists
//   of selected/unselected items are not given
//
// GlyphIndex countSelcected ();
// GlyphIndex countUnselected ();
//   return the number of items in the selected/unselected list
//   (GlyphIndex is long)
//
// Item* componentSelected (GlyphIndex i);
// Item* componentUnselected (GlyphIndex i);
//   return the i-th component of the selected/unselected list;
//   i has to be in range 0 to countSelected/Unselected - 1
//
//
// Style: see class PriorityChooser
//
//
//</class>


#if defined(__STDC__) || defined(__ANSI_CPP__)
#define __PrChooser(T) T##_PrChooser
#define PrChooser(T) __PrChooser(T)
#else
#define __PrChooser(T) T/**/_PrChooser
#define PrChooser(T) __PrChooser(T)
#endif


#define declarePrChooser(Item) \
class PrChooser(Item) \
{ \
  public: \
    PrChooser(Item) (); \
    ~PrChooser(Item) (); \
 \
    /* add data to the lists */ \
    void appendSelected (Item*); \
    void appendUnselected (Item*); \
 \
    /* run the dialog */ \
    int run ( \
      HgLanguage::Language language, \
      int mustselectone, \
      const char* wintitle, \
      const char* headline, \
      const char* selboxtitle = 0, \
      const char* unselboxtitle = 0, \
      const char* buttonall = 0, \
      const char* buttonnone = 0 \
    ); \
 \
    /* get back data from lists */ \
    GlyphIndex countSelected (); \
    GlyphIndex countUnselected (); \
    Item* componentSelected (GlyphIndex); \
    Item* componentUnselected (GlyphIndex); \
 \
  private: \
    PolyGlyph* sel_; \
    PolyGlyph* unsel_; \
};


#define implementPrChooser(Item) \
PrChooser(Item)::PrChooser(Item) () \
{ \
  sel_ = new PolyGlyph (); \
  unsel_ = new PolyGlyph (); \
} \
 \
PrChooser(Item)::~PrChooser(Item) () \
{ \
  delete sel_; \
  delete unsel_; \
} \
 \
void PrChooser(Item)::appendSelected (Item* item) \
{ \
  sel_->append (item); \
} \
 \
void PrChooser(Item)::appendUnselected (Item* item) \
{ \
  unsel_->append (item); \
} \
 \
int PrChooser(Item)::run ( \
  HgLanguage::Language language, \
  int mustselectone, \
  const char* wintitle, \
  const char* headline, \
  const char* selboxtitle, \
  const char* unselboxtitle, \
  const char* buttonall, \
  const char* buttonnone \
) \
{ \
  return PriorityChooser::run (sel_, unsel_, language, mustselectone, wintitle, headline, \
    selboxtitle, unselboxtitle, buttonall, buttonnone); \
} \
 \
GlyphIndex PrChooser(Item)::countSelected () \
{ \
  return sel_->count (); \
} \
 \
GlyphIndex PrChooser(Item)::countUnselected () \
{ \
  return unsel_->count (); \
} \
 \
Item* PrChooser(Item)::componentSelected (GlyphIndex i) \
{ \
  return (Item*) sel_->component (i); \
} \
 \
Item* PrChooser(Item)::componentUnselected (GlyphIndex i) \
{ \
  return (Item*) unsel_->component (i); \
}



#endif
