/* Copyright (C) 1996,1997 Robert H”hne, see COPYING.RH for details */
/* This file is part of RHIDE. */
#define Uses_TEvent
#define Uses_TEditWindow
#define Uses_TFileEditor
#define Uses_TKeys
#define Uses_TProgram
#define Uses_TDeskTop

#define Uses_TMsgListBox
#define Uses_TMsgCollection
#define Uses_ideCommands
#define Uses_ideFunctions
#include <libide.h>

#define Uses_TEnterListBox
#define Uses_tvutilCommands
#include <libtvuti.h>

#include <stdio.h>
#include <string.h>

TMsgListBox::TMsgListBox(const TRect& bounds, ushort aNumCols, 
                         TScrollBar *aScrollBar)
    : TEnterListBox(bounds,aNumCols,aScrollBar)
{
  helpCtx = hcMsgListBox;
}

void TMsgListBox::handleEvent(TEvent &event)
{
  msg_rec *rec;
  ccIndex index;
  TEnterListBox::handleEvent(event);
  if (!list()) return;
  switch (event.what)
  {
    case evCommand:
      switch (event.message.command)
      {
        case cmNextMsg:
          for (index=focused+1;index<range;index++)
          {
            rec = (msg_rec *)list()->at(index);
            if (rec->filename && rec->lineno > 0)
            {
              selectItem(index);
              clearEvent(event);
              break;
            }
          }
          break;
        case cmPrevMsg:
          for (index=focused-1;index>=0;index--)
          {
            rec = (msg_rec *)list()->at(index);
            if (rec->filename && rec->lineno > 0)
            {
              selectItem(index);
              clearEvent(event);
              break;
            }
          }
          break;
        default:
          break;
      }
    default:
      break;
  }
}

static int in_focus = 0;
static int in_select = 0;

void TMsgListBox::focusItem(ccIndex item)
{
  in_focus++;
  msg_rec *rec = (msg_rec *)list()->at(item);
  TEnterListBox::focusItem(item);
  in_focus--;
  if (in_focus || in_select) return;
  if (!rec->filename || rec->lineno == 0) return;
  if (message(TProgram::application,evBroadcast,cmFocusWindow,rec->filename))
  {
    message(TProgram::application,evBroadcast,cmGotoWindowLine,
              (void *)rec->lineno);
  }
}

void TMsgListBox::selectItem(ccIndex item)
{
  in_select++;
  msg_rec *rec = (msg_rec *)list()->at(item);
  TEnterListBox::focusItem(item);
  TEnterListBox::selectItem(item);
  in_select--;
  if (in_select) return;
  if (!rec->filename || rec->lineno == 0) return;
  if (message(TProgram::application,evBroadcast,cmOpenWindow,rec->filename))
  {
    message(TProgram::application,evBroadcast,cmShowWindowMsg,
              (void *)rec->msg);
    message(TProgram::application,evBroadcast,cmGotoWindowLine,
              (void *)rec->lineno);
  }
}

void TMsgListBox::getText(char *dest, ccIndex item, short maxLen)
{
  char temp[10];
  static char tmp[1000];
  strcpy(tmp," ");
  if (!list()) return;
  msg_rec *rec = (msg_rec *)list()->at(item);
  if (!rec->filename)
  {
    switch (rec->type)
    {
      case msgError:
        strcpy(tmp,_("Error: "));
        break;
      case msgWarning:
        strcpy(tmp,_("Warning: "));
        break;
      default:
        tmp[0] = 0;
        break;
    }
    if (rec->msg)
      strcat(tmp,rec->msg);
  }
  else
  {
    if (rec->lineno > 0)
    {
      strcpy(tmp,rec->filename);
      strcat(tmp,"(");
      sprintf(temp,"%d",rec->lineno);
      strcat(tmp,temp);
      strcat(tmp,") ");
      switch (rec->type)
      {
        case msgError:
          strcat(tmp,_("Error: "));
          break;
        case msgWarning:
          strcat(tmp,_("Warning: "));
          break;
        default:
          break;
      }
    }
    else
    {
      *tmp = 0;
    }
    if (rec->msg)
      strcat(tmp,rec->msg);
  }
  strncpy(dest,tmp,maxLen);
  dest[maxLen] = 0;
}

void TMsgListBox::shutDown()
{
  destroy( list() );
  TEnterListBox::shutDown();
}

void TMsgListBox::setState(ushort aState, Boolean enable)
{
  TEnterListBox::setState(aState,enable);
#if 0
  static int focus_called = 0;
  if (aState & (sfSelected | sfActive) && enable == True && range > 0)
  {
    if (!focus_called && getState(sfActive))
    {
      focus_called++; // this is needed, because focusItem calls select()
      focusItem(focused);
      focus_called--;
    }
  }
#endif
}
