//*************************************************************************//
// Filename:    WindowList.c
// Autor:       Christian Taulien of Strange Intelligence
// Purpose:     WindowList-Function for Felix.api
// Creation:    24. März 1998
//*************************************************************************//
#include "WindowList.h"
#include "processcomm.h"
#include "freshlocale.h"

#include <string.h>

#include <exec/exec.h>
#include <utility/utility.h>
#include <diskfont/diskfont.h>
#include <graphics/gfx.h>
#include <dos/dos.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/utility_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/graphics_protos.h>
#include <clib/gadtools_protos.h>

#define SIFC_MAX(a,b) ((a)>(b) ? (a) : (b))
#define SIFC_MIN(a,b) ((a)<(b) ? (a) : (b))

extern "C" void NewList(struct List *list);
extern FLXWatchListC *glob_poWatches;

char *createNameFromInstance(struct APIInstance *arg_poAPIInstance)
/*S*/
{
  TRACE("Entry");

  char *name = NULL;
  char *sDocName = ((struct EditConfig *) arg_poAPIInstance->api_Environment)->Name;
  ULONG sDocNameLen = strlen(sDocName);

  if (strlen(sDocName)>0)
  {
    name = new char [sDocNameLen+2];

    // if the speicher could be reserviert
    if (name)
    {
      strcpy(name, sDocName);
    } // if
  } // if
return name;
}
/*E*/

//******************************************************************//
//******************************************************************//
//
//  WNameNodeC
//
//******************************************************************//
//******************************************************************//
WNameNodeC::WNameNodeC(struct APIInstance *arg_poInstance, WNameListC *arg_poNameList)
/*S*/
{
  TRACE("Konstruktor");
  // init the baseclassmembers
  ln_Succ       = NULL;
  ln_Pred       = NULL;
  ln_Type       = NT_USER;
  ln_Pri        = 0;

  // now our members
  m_poAPIInstance = arg_poInstance;
  ln_Name         = createNameFromInstance(arg_poInstance);

} // WNameNodeC::WNameNodeC()
/*E*/
WNameNodeC::~WNameNodeC()
/*S*/
{
  TRACE("Destruktor");

  if (ln_Name)
  {
    delete ln_Name;
  } // if

  // if the node is in a list
  if (ln_Pred && ln_Succ)
  {
    Remove(this);
  } // if
}
/*E*/
WNameNodeC *WNameNodeC::getNext(void)
/*S*/
{
  TRACE("getNext()");
  if (ln_Succ && ln_Succ->ln_Succ)
  {
    return (WNameNodeC *) ln_Succ;
  } // if

return NULL;
}
/*E*/
WNameNodeC *WNameNodeC::getPrev(void)
/*S*/
{
  TRACE("getPrev()");
  if (ln_Pred && ln_Pred->ln_Pred)
  {
    return (WNameNodeC *) ln_Pred;
  } // if

return NULL;
}
/*E*/

//******************************************************************//
//******************************************************************//
//
//  WNameListC
//
//******************************************************************//
//******************************************************************//
WNameListC::WNameListC()
/*S*/
{
  TRACE("Konstruktor");
  NewList(this);
} // WNameListC::WNameListC()
/*E*/
WNameListC::~WNameListC()
/*S*/
{
  TRACE("Destruktor");
  removeAll();

} // WNameListC::~FLXWacthListC()
/*E*/
void WNameListC::removeAll()
/*S*/
{
  TRACE("Entry");
  // wenn die Liste nicht leer ist
  if (!IsListEmpty(this))
  {
    WNameNodeC *pNode;
    while (pNode = (WNameNodeC *) RemHead(this))
    {
      pNode->ln_Succ = NULL;
      pNode->ln_Pred = NULL;
      delete pNode;
    } // while
  } // if
  NewList(this);
}
/*E*/
BOOL WNameListC::addWName(struct APIInstance *arg_poInstance)
/*S*/
{
  TRACE("addWName()");
  TRACE(arg_poInstance->api_Name);
  // neuen Watch erzeugen
  WNameNodeC *poNode = new WNameNodeC(arg_poInstance, this);
  if (poNode)
  {
    // hänge diesen in die Liste ein
    AddTail(this, poNode);
  }
  else
  {
    TRACE("Kein Speicher");
    return FALSE;
  } // if
return TRUE;
}
/*E*/
int WNameListC::sortIn(struct APIInstance *arg_poInstance)
/*S*/
{
  TRACE("sortIn()");
  int iIndex = -1;

  // neue Node erzeugen
  WNameNodeC *poNode = new WNameNodeC(arg_poInstance, this);
  if (poNode)
  {
    iIndex = 0;
    // wenn die Watchliste nicht leer ist
    if (!IsListEmpty(this))
    {
      // hole letzen eintrag
      WNameNodeC *pCurNode = (WNameNodeC *) lh_TailPred;
      do
      {
        // wenn der neue eintrag kleiner ist, als der aktuelle
        if (Stricmp(pCurNode->ln_Name, poNode->ln_Name)<=0)
        {
          Insert(this, poNode, pCurNode);
          return iIndex;
        } // if

        iIndex++;
      } while (pCurNode = pCurNode->getPrev());
    } // if

    // hänge diesen vor die Liste.
    AddHead(this, poNode);
  }
  else
  {
    TRACE("Kein Speicher");
    return FALSE;
  } // if
return iIndex;
}
/*E*/
WNameNodeC *WNameListC::findWName(struct APIInstance *arg_poInstance)
/*S*/
{
  TRACE("Entry");
  WNameNodeC *pNode = NULL;

  // wenn die Watchliste nicht leer ist
  if (!IsListEmpty(this))
  {
    pNode = (WNameNodeC *) lh_Head;
    do
    {
      if (pNode->m_poAPIInstance == arg_poInstance)
      {
        return pNode;
      } // if
    } while (pNode = pNode->getNext());
  } // if

return pNode;
}
/*E*/
int WNameListC::indexOf(WNameNodeC *arg_pNode)
/*S*/
{
  TRACE("Entry");

  // wenn die Watchliste nicht leer ist
  if (arg_pNode && !IsListEmpty(this))
  {
    int iIndex = 0;

    // hole 1. eintrag
    WNameNodeC *pNode = (WNameNodeC *) lh_Head;
    do
    {
      // wenn gefunden
      if (pNode==arg_pNode)
      {
        return iIndex;
      } // if

      iIndex++;
    } while (pNode = pNode->getNext());
  } // if

return -1;
}
/*E*/
WNameNodeC *WNameListC::operator[](int arg_iIndex)
/*S*/
{ 
  TRACE("ENTRY");

  WNameNodeC *pNode = NULL;

  // wenn die Watchliste nicht leer ist
  if (!IsListEmpty(this))
  {
    int index = 0;

    // hole 1. eintrag
    pNode = (WNameNodeC *) lh_Head;
    do
    {
      // wenn i.ten eintrag erreicht
      if (index == arg_iIndex)
      {
        return pNode;
      } // if

      index++;
    } while (pNode = pNode->getNext());
  } // if

return pNode;
}
/*E*/
int WNameListC::getSize(void)
/*S*/
{
  TRACE("ENTRY");
  int iSize = 0;

  // wenn die Liste nicht leer ist
  if (!IsListEmpty(this))
  {
    // hole 1. Eintrag
    WNameNodeC *pNode = (WNameNodeC *) lh_Head;
    for (iSize=1; pNode = pNode->getNext(); iSize++);
  } // if

return iSize;
}
/*E*/

//******************************************************************//
//******************************************************************//
//
//  VisualInfoC
//
//******************************************************************//
//******************************************************************//
VisualInfoC::~VisualInfoC()
/*S*/
{
  // wenn der VisualInfo-Member gültig ist.
  if (m_iVisualInfo)
  {
    FreeVisualInfo(m_iVisualInfo);
  } // if
}
/*E*/
void VisualInfoC::initVisualInfo(struct Screen *arg_poScreen)
/*S*/
{ 
  TRACE("Entry")
  m_iVisualInfo = NULL;
  // wenn screen-parameter gültig
  if (arg_poScreen)
  {
    // hole visual info
    m_iVisualInfo = GetVisualInfo(arg_poScreen, TAG_DONE);
  } // if
}
/*E*/


//******************************************************************//
//******************************************************************//
//
//  WindowListC
//
//******************************************************************//
//******************************************************************//
int WindowListC::m_iLeft = -1;
int WindowListC::m_iTop = -1;

WindowListC::WindowListC(FLXWatchListC *arg_poWatches)
  : m_poWatches(arg_poWatches)
/*S*/
{
  TRACE("Entry");
  m_iWinHeight            = 30;
  m_iWinWidth             = 30;
  m_iMaxVisibleEntries    = 15;
  m_poFirstGadget         = NULL;
  m_apoGadgets[IDC_LISTE] = NULL;
  m_apoGadgets[IDC_OKAY]  = NULL;
  m_apoGadgets[IDC_CLOSE] = NULL;
  m_apoGadgets[IDC_CANCEL]= NULL;
  m_poWindow              = NULL;
};
/*E*/
WindowListC::~WindowListC()
/*S*/
{
  TRACE("Entry");
  // Das Fenster schließen, wenn nötig
  closeWindowList();
}
/*E*/

BOOL WindowListC::openWindowList(struct APIMessage *arg_poIMsg)
/*S*/
{
  TRACE("Entry");

BOOL erfolg = FALSE;
  // wenn das Fenster schon offen ist
  if (isOpen())
  {
    TRACE("schon offen");
    // dann nur aktivieren und zurückkehren
    ActivateWindow(m_poWindow);
    WindowToFront(m_poWindow);
    return TRUE;
  } // if

  // Wenn wir eine Watch-Liste haben.
  if (m_poWatches)
  {
    TRACE("m_poWatches ok");
    struct Screen *pScreen = arg_poIMsg->api_Instance->api_Screen;
    if (createGadgets(pScreen))
    {
      TRACE("Gadgets ok");
      validateWindowPosition(pScreen);
      if (m_poWindow = OpenWindowTags(NULL,
            WA_Width, m_iWinWidth,
            WA_Height, m_iWinHeight,
            WA_AutoAdjust, TRUE,
            WA_Top, m_iTop,
            WA_Left, m_iLeft,
            WA_PubScreen, pScreen,
            WA_Activate, TRUE,
            WA_DragBar, TRUE,
            WA_DepthGadget, TRUE,
            WA_CloseGadget, TRUE,
            WA_SizeGadget, FALSE,
            WA_SmartRefresh, TRUE,
            WA_RMBTrap, TRUE,
            WA_IDCMP, CLOSEWINDOW
                    | REFRESHWINDOW
                    | BUTTONIDCMP
                    | LISTVIEWIDCMP
                    | IDCMP_VANILLAKEY
                    | IDCMP_RAWKEY,
            WA_Title, glob_poCatalog->getString(T_WINDOWLISTTITLE),
            TAG_DONE))
      {
        showGadgets();
        erfolg = TRUE;
      } // if
    } // if
  } // if
return erfolg;
}
/*E*/
void WindowListC::closeWindowList()
/*S*/
{
  TRACE("Entry");
  // wenn wir ein Fenster offen haben
  if (m_poWindow)
  {
    // schließen
    struct Message *poMsg;
    while (poMsg = GetMsg(m_poWindow->UserPort))
    {
      ReplyMsg(poMsg);
    } // while
    m_iLeft = m_poWindow->LeftEdge;
    m_iTop = m_poWindow->TopEdge;

    CloseWindow(m_poWindow);
    m_poWindow = NULL;
  } // if

  freeGadgets();

}
/*E*/
void WindowListC::updateWindowList(struct APIInstance *arg_poInstance)
/*S*/
{
  TRACE("Entry");
  // wenn die interne Liste gültig ist
  // wenn wir ein Listen-Gadget haben
  if (m_apoGadgets[IDC_LISTE])
  {
    // Lösche die Liste im Gadget
    GT_SetGadgetAttrs(m_apoGadgets[IDC_LISTE], NULL, NULL,
      GTLV_Labels, ~0,
      TAG_DONE);
  } // if

  // erstmal alle Einträge entfernen
  m_oWindowNameList.removeAll();

  // Fülle die Liste mit allen aktuellen Einträgen
  FLXNodeC *pFLXNode = m_poWatches->getFirst();
  while (pFLXNode)
  {
    m_oWindowNameList.sortIn(pFLXNode->m_poAPIInstance);
    pFLXNode = pFLXNode->getNext();
  } // if

  // Ermittle die Nummer des Eintrages, der für die arg_poInstance steht
  WNameNodeC *pNameNode = m_oWindowNameList.findWName(arg_poInstance);
  ULONG ulCurrWinEntry  = m_oWindowNameList.indexOf(pNameNode);
  if (ulCurrWinEntry == -1)
  {
    ulCurrWinEntry = 0;
  } // if

  // wenn wir ein Listen-Gadget haben
  if (m_apoGadgets[IDC_LISTE])
  {
    // aktualisiere die Liste des List-Gadgets
    GT_SetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
      GTLV_Selected, ulCurrWinEntry,
      GTLV_MakeVisible, ulCurrWinEntry,
      GTLV_Labels, &m_oWindowNameList,
      TAG_DONE);
  } // if
}
/*E*/
char *WindowListC::getSelectedName()
/*S*/
{
  TRACE("Entry");
  // hole aktuelle position
  ULONG ulCurSel = 0;
  GT_GetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                    GTLV_Selected, &ulCurSel,
                    TAG_DONE);

  // hole den so-und-so-vielten eintrag
  WNameNodeC *pNameNode = m_oWindowNameList[ulCurSel];
  if (pNameNode)
  {
    return pNameNode->m_poAPIInstance->api_Name;
  } // if
return NULL;;
}
/*E*/
struct Gadget *WindowListC::createGadgets(struct Screen *arg_pScreen)
/*S*/
{
  TRACE("Entry");
  // Rückgabe
  struct Gadget *pGad = NULL;

  // parameter-check
  if (!arg_pScreen)
  {
    TRACE("Wrong createGadgets()-Parameter!");
    return pGad;
  } // if

  struct TextAttr *pTAttr = arg_pScreen->Font;
  VisualInfoC oVI(arg_pScreen);
  if (!oVI)
  {
    TRACE("VisualInfo failed");
    return pGad;
  } // if

  // initialisiere Rastport
  struct RastPort TextRP;
  InitRastPort(&TextRP);

  // Öffne font
  struct TextFont *font = OpenFont(pTAttr);
  if (font)
  {
    TRACE("Font ok");
    // Font im RastPort setzen
    SetFont(&TextRP, font);

    int wTextBreiteMax = TextLength(&TextRP, glob_poCatalog->getString(T_WEITER),strlen(glob_poCatalog->getString(T_WEITER)));
    wTextBreiteMax = SIFC_MAX(wTextBreiteMax, TextLength(&TextRP, glob_poCatalog->getString(T_SCHLIESSEN),strlen(glob_poCatalog->getString(T_SCHLIESSEN))));
    wTextBreiteMax = SIFC_MAX(wTextBreiteMax, TextLength(&TextRP, glob_poCatalog->getString(T_ABBRECHEN),strlen(glob_poCatalog->getString(T_ABBRECHEN))));

    // Ermittle den breitesten Buttontext
    int  wXOffSet     = 10;   // Mindestabstand zw. den Buttons
    int  wInnerOffset = 5*2;  // Rand links und rechts vom Buttontext
    int  iYOffset     = 6;    // höhe der Gadgets
    WORD wButtonGesamtBreite;
    WORD wListViewBreite;

    m_iWinHeight = 30;
    m_iWinWidth = 30;

    int iNumberOfEntries = (arg_pScreen->Height-40-arg_pScreen->WBorTop-font->tf_YSize*2)/font->tf_YSize;
    if (iNumberOfEntries > m_iMaxVisibleEntries)
    {
      iNumberOfEntries = m_iMaxVisibleEntries;
    } // if

    // Berechne die Breite der Button-Gadgets...
    do
    {
      wButtonGesamtBreite = (wTextBreiteMax+wInnerOffset)*3+wXOffSet*2;

      wListViewBreite = SIFC_MAX(wButtonGesamtBreite, 300); // Mindestbreite
      wListViewBreite = SIFC_MIN(wListViewBreite, arg_pScreen->Width-30); // Maximalbreite

      // wenn die buttons noch breiter sind, als die liste
      if (wButtonGesamtBreite > wListViewBreite)
      {
        // solange vom x-offset noch was weg genommen werden kann, sonst innersoffset decrementieren
        wXOffSet>2 ? wXOffSet-- : wInnerOffset--;
      }
      // oder wenn wButtonGesamtBreite zu klein
      else if (wButtonGesamtBreite < wListViewBreite)
      {
        // wenn die buttons noch größer gemacht werden können, sonst die Abständer vergrößern
        wInnerOffset < 20 ? wInnerOffset++ : wXOffSet++;
      } // if

    // solange ungleich und innersoffset noch nicht zu klein
    } while ((wButtonGesamtBreite != wListViewBreite) && (wInnerOffset>2));


    // für Gadtools erforderlich
    pGad = CreateContext(&m_poFirstGadget);
    if (pGad)
    {
      TRACE("CreateContext ok");
    } // if

    // Das ListView-Gadget
    struct NewGadget ng;
    ng.ng_LeftEdge   = arg_pScreen->WBorLeft + 4;
    ng.ng_TopEdge    = arg_pScreen->WBorTop + arg_pScreen->BarHeight + font->tf_YSize + 5;
    ng.ng_Width      = wButtonGesamtBreite;
    ng.ng_Height     = font->tf_YSize*iNumberOfEntries+4; // platz für x einträge
    ng.ng_GadgetText = glob_poCatalog->getString(T_LISTE);
    ng.ng_TextAttr   = pTAttr;
    ng.ng_Flags      = NG_HIGHLABEL;
    ng.ng_GadgetID   = IDC_LISTE;
    ng.ng_UserData   = NULL;
    ng.ng_VisualInfo = oVI;
    m_apoGadgets[IDC_LISTE] = pGad = CreateGadget(LISTVIEW_KIND, pGad, &ng,
        GTLV_MakeVisible, 0,
        GTLV_Selected, 0,
        GTLV_ShowSelected, 0,
        TAG_DONE);

    // Das Weiter-Gadget
    if (pGad)
    {
      TRACE("List-Gadget ok");
      ng.ng_TopEdge += pGad->Height   + 16;
      ng.ng_Width    = wTextBreiteMax + wInnerOffset;
      ng.ng_Height   = font->tf_YSize + iYOffset;
      m_iWinHeight   = ng.ng_TopEdge  + pGad->Height + 4;
    } // if
    ng.ng_GadgetText = glob_poCatalog->getString(T_WEITER);
    ng.ng_GadgetID   = IDC_OKAY;
    ng.ng_Flags      = 0;
    m_apoGadgets[IDC_OKAY] = pGad = CreateGadget(BUTTON_KIND, pGad, &ng,
        GT_Underscore, '_',
        TAG_DONE);

    // Das Schließen-Gadget
    if (pGad)
    {
      TRACE("Weiter-Gadget ok");
      ng.ng_LeftEdge += pGad->Width + wXOffSet;
      m_iWinHeight = ng.ng_TopEdge + pGad->Height + iYOffset;
    } // if
    ng.ng_GadgetText  = glob_poCatalog->getString(T_SCHLIESSEN);
    ng.ng_GadgetID    = IDC_CLOSE;
    m_apoGadgets[IDC_CLOSE] = pGad = CreateGadget(BUTTON_KIND, pGad, &ng,
        GT_Underscore, '_',
        TAG_DONE);

    // Das Abbrechen-Gadget
    if (pGad)
    {
      TRACE("Schließen-Gadget ok");
      ng.ng_LeftEdge += pGad->Width + wXOffSet;
      m_iWinHeight = ng.ng_TopEdge + pGad->Height + iYOffset;
    } // if
    ng.ng_GadgetText  = glob_poCatalog->getString(T_ABBRECHEN);
    ng.ng_GadgetID    = IDC_CANCEL;
    m_apoGadgets[IDC_CANCEL] = pGad = CreateGadget(BUTTON_KIND, pGad, &ng,
        GT_Underscore, '_',
        TAG_DONE);

    if (pGad)
    {
      TRACE("Abbrechen-Gadget ok");
      m_iWinHeight = ng.ng_TopEdge + pGad->Height + iYOffset;
    } // if
    m_iWinWidth = wButtonGesamtBreite+9+arg_pScreen->WBorRight+arg_pScreen->WBorLeft;

    // Font wieder schließen
    CloseFont(font);
  } // if

return pGad;
}
/*E*/
void WindowListC::freeGadgets()
/*S*/
{
  // wenn das Fenster noch offen ist
  if (m_poWindow)
  {
    // die gadget vorher removen
    hideGadgets();
  } // if

  // wenn die gadget "befreit" werden müssen
  if (m_poFirstGadget)
  {
    FreeGadgets(m_poFirstGadget);
    m_poFirstGadget = NULL;
  } // if
}
/*E*/
BOOL SAVEDS WindowListC::handleWindowList()
/*S*/
{
  TRACE("Entry");
  BOOL result = FALSE;

  if (!m_poWindow)
  {
    TRACE("falsche params");
    return result;
  } // if

  struct IntuiMessage *poIMsg;
  while (poIMsg = GT_GetIMsg(m_poWindow->UserPort))
  {
    TRACE("GT-IMessage geholt");
    ULONG ulIMsgClass = poIMsg->Class;
    APTR  pIAddress   = poIMsg->IAddress;
    ULONG ulQualifier = poIMsg->Qualifier;
    WORD  wICode      = poIMsg->Code;

    GT_ReplyIMsg(poIMsg);
    switch (ulIMsgClass)
    {
      case IDCMP_RAWKEY:
/*S*/ // IDCMP_RAWKEY
          TRACE("Taste (IDCMP_RAWKEY)");
          switch (wICode)
          {
            ULONG ulPos;
            // Wenn Taste Cursor Up oder Left...
            case 0x4c:
            case 0x4f:
              // wenn shift
              if (ulQualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
              {
                ulPos=NULL;
                GT_SetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                    GTLV_Selected, ulPos,
                    GTLV_MakeVisible, ulPos,
                    TAG_DONE);
              }
              else
              {
                GT_GetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                    GTLV_Selected, &ulPos,
                    TAG_DONE);
                // wenn man noch nach oben kann
                if (ulPos > 0)
                {
                  ulPos--;
                  GT_SetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                      GTLV_Selected, ulPos,
                      GTLV_MakeVisible, ulPos,
                      TAG_DONE);
                } // if
              } // if
              break;
            // wenn Taste Cursor Down or Right
            case 0x4e:
            case 0x4d:
              // wenn mit shift
              if (ulQualifier&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
              {
                // maximal-position ermitteln
                ulPos = m_oWindowNameList.getSize()-1;

                GT_SetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                    GTLV_Selected, ulPos,
                    GTLV_MakeVisible, ulPos,
                    TAG_DONE);
              }
              else
              {
                GT_GetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                    GTLV_Selected, &ulPos,
                    TAG_DONE);
                // wenn man noch nach unten kann
                if (ulPos < m_oWindowNameList.getSize())
                {
                  ulPos++;
                  GT_SetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                      GTLV_Selected, ulPos,
                      GTLV_MakeVisible, ulPos,
                      TAG_DONE);
                } // if
              } // if
              break;
          } // switch
        break;
/*E*/
      case IDCMP_VANILLAKEY:
/*S*/ // VANILLAKEY
          TRACE("Taste (vanilla)");
          switch (wICode)
          {
            // wenn abbrechen
            case 27:
              TRACE("Abbruch");
              result = TRUE;
              break;
            case 32:
              TRACE("Fenster Aktivieren");
              sendMsgToGoldED("WINDOW USE=\"%s\"", getSelectedName(), FALSE);
              result = FALSE;
              break;
            case 10:
            case 13:
              TRACE("Fenster Aktivieren");
              sendMsgToGoldED("WINDOW USE=\"%s\"", getSelectedName(), FALSE);
              result = TRUE;
              break;
            default:
              // in kleinbuchstaben wandeln
              wICode = ToLower(wICode);

              if (wICode == glob_poCatalog->getShortCutLowerCase(T_ABBRECHEN), FALSE)
              {
                TRACE("Abbruch");
                return TRUE;
              } //

              if (wICode == glob_poCatalog->getShortCutLowerCase(T_WEITER), FALSE)
              {
                TRACE("Fenster Aktivieren");
                sendMsgToGoldED("WINDOW USE=\"%s\"", getSelectedName(), FALSE);
                result = TRUE;
                break;
              } // if

              if (wICode == glob_poCatalog->getShortCutLowerCase(T_SCHLIESSEN))
              {
                TRACE("Fenster schließen");
                sendMsgToGoldED("WINDOW QUIET USE=\"%s\"", getSelectedName(), FALSE);
                sendMsgToGoldED("QUIT", NULL, TRUE);
                result = FALSE;
              } // if
            break;
          } // switch
          break;
/*E*/
      case IDCMP_GADGETUP:
/*S*/ // IDCMP_GADGETUP
            TRACE("GADGETUP-Msg");

            { // dummy scope
              struct Gadget *poGad = (struct Gadget *) pIAddress;
              if (poGad)
              {
                switch (poGad->GadgetID)
                {
                  case IDC_LISTE:
                    TRACE("Auf die liste geklickt");
                    { // dummy scope
                      static ULONG ulOldSeconds   = NULL;
                      static ULONG ulOldMicros    = NULL;
                      static ULONG ulOldSelection = NULL;

                      // hole aktuelle selection
                      ULONG ulNewSelection = NULL;
                      GT_GetGadgetAttrs(m_apoGadgets[IDC_LISTE], m_poWindow, NULL,
                                        GTLV_Selected, &ulNewSelection,
                                        TAG_DONE);

                      // hole aktuelle Zeit der Message
                      ULONG ulNewSeconds = poIMsg->Seconds;
                      ULONG ulNewMicros  = poIMsg->Micros;

                      // wenn doppelgeklickt und der selbe eintrag angewählt
                      if ((ulOldSelection == ulNewSelection) &&
                          DoubleClick(ulOldSeconds, ulOldMicros,
                                      ulNewSeconds, ulNewMicros))
                      {
                        sendMsgToGoldED("WINDOW USE=\"%s\"", getSelectedName(), FALSE);
                        result = FALSE;
                      } // if

                      // merke die zeit als die jetzt alte
                      ulOldSelection = ulNewSelection;
                      ulOldSeconds   = ulNewSeconds;
                      ulOldMicros    = ulNewMicros;
                    } // dummy scope
                    break;
                  case IDC_OKAY:
                    TRACE("Weiter");
                    sendMsgToGoldED("WINDOW USE=\"%s\"", getSelectedName(), FALSE);
                    result = TRUE;
                    break;
                  case IDC_CLOSE:
                    TRACE("Schließen");
                    sendMsgToGoldED("WINDOW QUIET USE=\"%s\"", getSelectedName(), FALSE);
                    sendMsgToGoldED("QUIT", NULL, TRUE);
                    result = FALSE;
                    break;
                  case IDC_CANCEL:
                    TRACE("Abbruch");
                    result = TRUE;
                    break;
                } // switch
              } // if
            } // dummy scope
          break;
/*E*/
      case IDCMP_CLOSEWINDOW:
/*S*/ // IDCMP_CLOSEWINDOW
          TRACE("CloseGad");
          result = TRUE;
          break;
/*E*/
      case IDCMP_REFRESHWINDOW:
/*S*/ // IDCMP_REFRESHWINDOW
          GT_BeginRefresh(m_poWindow);
          GT_EndRefresh(m_poWindow, TRUE);
          break;
/*E*/
      default:
        TRACE("unwichtige imsgclass");
        break;
    } // if
  } // while
  TRACE("exit");
return result;
}
/*E*/
void WindowListC::validateWindowPosition(struct Screen *arg_poScreen)
/*S*/
{ 
  TRACE("Entry");
  // wenn der Screen ok ist
  if (arg_poScreen)
  {
    // wenn horizontal zentrieren
    if (m_iLeft == -1)
    {
      m_iLeft = (arg_poScreen->Width-m_iWinWidth)/2;
    } // if

    // wenn vertikal zentrieren
    if (m_iTop == -1)
    {
      m_iTop = (arg_poScreen->Height-m_iWinHeight)/2;
    } // if
  } // if
}
/*E*/
void WindowListC::setWindowPosition(int arg_iX /*= -1*/, int arg_iY /*= -1*/, BOOL arg_bNow /*= TRUE*/)
/*S*/
{                                   
  m_iLeft = arg_iX;
  m_iTop = arg_iY;

  // wenn das Fenster offen ist
  if (isOpen())
  {
    validateWindowPosition(m_poWindow->WScreen);

    // und umstellen sofort gewünscht
    if (arg_bNow)
    {
      MoveWindow(m_poWindow, m_iLeft-m_poWindow->LeftEdge, m_iTop-m_poWindow->TopEdge);
    } // if
  } // if
}
/*E*/
void WindowListC::clearWindow()
/*S*/
{
  // wenn Fenster offen
  if (isOpen())
  {
    EraseRect(m_poWindow->RPort,
              m_poWindow->BorderLeft,
              m_poWindow->BorderTop,
              m_poWindow->Width-m_poWindow->BorderRight-1,
              m_poWindow->Height-m_poWindow->BorderBottom-1);

  } // if
}
/*E*/
void WindowListC::hideGadgets()
/*S*/
{        
  TRACE("Entry");
  // validation check
  if (!m_poWindow || !m_poFirstGadget)
  {
    TRACE("Falsche Parameter");
    return;
  } // if

  if (!m_bGadgetsAttached)
  {
    TRACE("Gadgets garnicht attached");
    return;
  } // if
  RemoveGList(m_poWindow, m_poFirstGadget, ~0);

  m_bGadgetsAttached = FALSE;
}
/*E*/
void WindowListC::showGadgets()
/*S*/
{
  TRACE("Entry");
  // validation check
  if (!m_poWindow || !m_poFirstGadget)
  {
    TRACE("Falsche Parameter");
    return;
  } // if

  // wenn das Fenster bereits Gadgets hat
  if (m_bGadgetsAttached)
  {
    TRACE("Gadgets bereits vorhanden");
    return;
  }

  clearWindow();
  AddGList(m_poWindow, m_poFirstGadget, -1, -1, NULL);
  RefreshGList(m_poFirstGadget, m_poWindow, NULL, -1);
  GT_RefreshWindow(m_poWindow, NULL);

  VisualInfoC oVI(m_poWindow);
  if (oVI.isOk())
  {
    TRACE("Visualinfo ok");
    DrawBevelBox( m_poWindow->RPort,
                  m_poWindow->WScreen->WBorLeft + 4,
                  m_apoGadgets[IDC_OKAY]->TopEdge - 8,
                  m_apoGadgets[IDC_LISTE]->Width,
                  2,
                  GT_VisualInfo, (APTR) oVI,
                  GTBB_Recessed, TRUE,
                  TAG_DONE );
  } // if

  m_bGadgetsAttached = TRUE;
}
/*E*/
void WindowListC::resizeWindow(int arg_iEntries /*= 0*/, int arg_iX /*= -1*/, int arg_iY /*= -1*/)
/*S*/
{
  // wenn das Fenster nicht offen ist
  if (!isOpen())
  {
    return;
  } // if

  // gadgets entfernen
  freeGadgets();

  // wenn die Anzahl der Einträge gesetzt werden soll.
  if (arg_iEntries > 1)
  {      
    setMaxVisibleEntries(arg_iEntries);
  } // if

  // gadgets erstellen
  createGadgets(m_poWindow->WScreen);

  // Fensterposition berechnen
  setWindowPosition(arg_iX, arg_iY, FALSE);

  // Fenstergröße anpassen
  ChangeWindowBox(m_poWindow, m_iLeft, m_iTop, m_iWinWidth, m_iWinHeight);

  // gadgets anzeigen
  showGadgets();
}
/*E*/

