/* TUI display source/assembly window.

   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
   Inc.

   Contributed by Hewlett-Packard Company.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
   "defs.h" should be included first.  Unfortunatly some systems
   (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
   and they clash with "bfd.h"'s definiton of true/false.  The correct
   fix is to remove true/false from "bfd.h", however, until that
   happens, hack around it by including "config.h" and <curses.h>
   first.  */

#include "config.h"
#ifdef HAVE_NCURSES_H       
#include <ncurses.h>
#else
#ifdef HAVE_CURSES_H
#include <curses.h>
#endif
#endif

#include "defs.h"
#include <ctype.h>
#include "symtab.h"
#include "frame.h"
#include "breakpoint.h"
#include "value.h"
#include "source.h"

#include "tui.h"
#include "tuiData.h"
#include "tuiStack.h"
#include "tuiWin.h"
#include "tuiGeneralWin.h"
#include "tuiSourceWin.h"
#include "tuiSource.h"
#include "tuiDisassem.h"


/* Function to display the "main" routine.  */
void
tui_display_main (void)
{
  if ((sourceWindows ())->count > 0)
    {
      CORE_ADDR addr;

      addr = tuiGetBeginAsmAddress ();
      if (addr != (CORE_ADDR) 0)
	{
	  struct symtab_and_line sal;

	  tuiUpdateSourceWindowsWithAddr (addr);
	  sal = find_pc_line (addr, 0);
          if (sal.symtab)
             tuiUpdateLocatorFilename (sal.symtab->filename);
          else
             tuiUpdateLocatorFilename ("??");
	}
    }
}



/*
   ** tuiUpdateSourceWindow().
   **    Function to display source in the source window.  This function
   **    initializes the horizontal scroll to 0.
 */
void
tuiUpdateSourceWindow (TuiWinInfoPtr winInfo, struct symtab *s,
                       TuiLineOrAddress lineOrAddr, int noerror)
{
  winInfo->detail.sourceInfo.horizontalOffset = 0;
  tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror);

  return;
}				/* tuiUpdateSourceWindow */


/*
   ** tuiUpdateSourceWindowAsIs().
   **        Function to display source in the source/asm window.  This
   **        function shows the source as specified by the horizontal offset.
 */
void
tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo, struct symtab *s,
                           TuiLineOrAddress lineOrAddr, int noerror)
{
  TuiStatus ret;

  if (winInfo->generic.type == SRC_WIN)
    ret = tuiSetSourceContent (s, lineOrAddr.lineNo, noerror);
  else
    ret = tuiSetDisassemContent (lineOrAddr.addr);

  if (ret == TUI_FAILURE)
    {
      tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
      tuiClearExecInfoContent (winInfo);
    }
  else
    {
      tui_update_breakpoint_info (winInfo, 0);
      tuiShowSourceContent (winInfo);
      tuiUpdateExecInfo (winInfo);
      if (winInfo->generic.type == SRC_WIN)
	{
	  struct symtab_and_line sal;
	  
	  sal.line = lineOrAddr.lineNo +
	    (winInfo->generic.contentSize - 2);
	  sal.symtab = s;
	  set_current_source_symtab_and_line (&sal);
	  /*
	     ** If the focus was in the asm win, put it in the src
	     ** win if we don't have a split layout
	   */
	  if (tuiWinWithFocus () == disassemWin &&
	      currentLayout () != SRC_DISASSEM_COMMAND)
	    tuiSetWinFocusTo (srcWin);
	}
    }


  return;
}				/* tuiUpdateSourceWindowAsIs */


/*
   ** tuiUpdateSourceWindowsWithAddr().
   **        Function to ensure that the source and/or disassemly windows
   **        reflect the input address.
 */
void
tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr)
{
  if (addr != 0)
    {
      struct symtab_and_line sal;
      TuiLineOrAddress l;
      
      switch (currentLayout ())
	{
	case DISASSEM_COMMAND:
	case DISASSEM_DATA_COMMAND:
	  tuiShowDisassem (addr);
	  break;
	case SRC_DISASSEM_COMMAND:
	  tuiShowDisassemAndUpdateSource (addr);
	  break;
	default:
	  sal = find_pc_line (addr, 0);
	  l.lineNo = sal.line;
	  tuiShowSource (sal.symtab, l, FALSE);
	  break;
	}
    }
  else
    {
      int i;

      for (i = 0; i < (sourceWindows ())->count; i++)
	{
	  TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];

	  tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
	  tuiClearExecInfoContent (winInfo);
	}
    }

  return;
}				/* tuiUpdateSourceWindowsWithAddr */

/*
   ** tuiUpdateSourceWindowsWithLine().
   **        Function to ensure that the source and/or disassemly windows
   **        reflect the input address.
 */
void
tuiUpdateSourceWindowsWithLine (struct symtab *s, int line)
{
  CORE_ADDR pc;
  TuiLineOrAddress l;
  
  switch (currentLayout ())
    {
    case DISASSEM_COMMAND:
    case DISASSEM_DATA_COMMAND:
      find_line_pc (s, line, &pc);
      tuiUpdateSourceWindowsWithAddr (pc);
      break;
    default:
      l.lineNo = line;
      tuiShowSource (s, l, FALSE);
      if (currentLayout () == SRC_DISASSEM_COMMAND)
	{
	  find_line_pc (s, line, &pc);
	  tuiShowDisassem (pc);
	}
      break;
    }

  return;
}				/* tuiUpdateSourceWindowsWithLine */

/*
   ** tuiClearSourceContent().
 */
void
tuiClearSourceContent (TuiWinInfoPtr winInfo, int displayPrompt)
{
  if (m_winPtrNotNull (winInfo))
    {
      register int i;

      winInfo->generic.contentInUse = FALSE;
      tuiEraseSourceContent (winInfo, displayPrompt);
      for (i = 0; i < winInfo->generic.contentSize; i++)
	{
	  TuiWinElementPtr element =
	  (TuiWinElementPtr) winInfo->generic.content[i];
	  element->whichElement.source.hasBreak = FALSE;
	  element->whichElement.source.isExecPoint = FALSE;
	}
    }

  return;
}				/* tuiClearSourceContent */


/*
   ** tuiEraseSourceContent().
 */
void
tuiEraseSourceContent (TuiWinInfoPtr winInfo, int displayPrompt)
{
  int xPos;
  int halfWidth = (winInfo->generic.width - 2) / 2;

  if (winInfo->generic.handle != (WINDOW *) NULL)
    {
      werase (winInfo->generic.handle);
      checkAndDisplayHighlightIfNeeded (winInfo);
      if (displayPrompt == EMPTY_SOURCE_PROMPT)
	{
	  char *noSrcStr;

	  if (winInfo->generic.type == SRC_WIN)
	    noSrcStr = NO_SRC_STRING;
	  else
	    noSrcStr = NO_DISASSEM_STRING;
	  if (strlen (noSrcStr) >= halfWidth)
	    xPos = 1;
	  else
	    xPos = halfWidth - strlen (noSrcStr);
	  mvwaddstr (winInfo->generic.handle,
		     (winInfo->generic.height / 2),
		     xPos,
		     noSrcStr);

	  /* elz: added this function call to set the real contents of
	     the window to what is on the  screen, so that later calls
	     to refresh, do display
	     the correct stuff, and not the old image */

	  tuiSetSourceContentNil (winInfo, noSrcStr);
	}
      tuiRefreshWin (&winInfo->generic);
    }
  return;
}				/* tuiEraseSourceContent */


/* Redraw the complete line of a source or disassembly window.  */
static void
tui_show_source_line (TuiWinInfoPtr winInfo, int lineno)
{
  TuiWinElementPtr line;
  int x, y;

  line = (TuiWinElementPtr) winInfo->generic.content[lineno - 1];
  if (line->whichElement.source.isExecPoint)
    wattron (winInfo->generic.handle, A_STANDOUT);

  mvwaddstr (winInfo->generic.handle, lineno, 1,
             line->whichElement.source.line);
  if (line->whichElement.source.isExecPoint)
    wattroff (winInfo->generic.handle, A_STANDOUT);

  /* Clear to end of line but stop before the border.  */
  getyx (winInfo->generic.handle, y, x);
  while (x + 1 < winInfo->generic.width)
    {
      waddch (winInfo->generic.handle, ' ');
      getyx (winInfo->generic.handle, y, x);
    }
}

/*
   ** tuiShowSourceContent().
 */
void
tuiShowSourceContent (TuiWinInfoPtr winInfo)
{
  if (winInfo->generic.contentSize > 0)
    {
      int lineno;

      for (lineno = 1; lineno <= winInfo->generic.contentSize; lineno++)
        tui_show_source_line (winInfo, lineno);
    }
  else
    tuiEraseSourceContent (winInfo, TRUE);

  checkAndDisplayHighlightIfNeeded (winInfo);
  tuiRefreshWin (&winInfo->generic);
  winInfo->generic.contentInUse = TRUE;
}


/*
   ** tuiHorizontalSourceScroll().
   **      Scroll the source forward or backward horizontally
 */
void
tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo,
                           TuiScrollDirection direction,
                           int numToScroll)
{
  if (winInfo->generic.content != (OpaquePtr) NULL)
    {
      int offset;
      struct symtab *s;
      struct symtab_and_line cursal = get_current_source_symtab_and_line ();

      if (cursal.symtab == (struct symtab *) NULL)
	s = find_pc_symtab (deprecated_selected_frame->pc);
      else
	s = cursal.symtab;

      if (direction == LEFT_SCROLL)
	offset = winInfo->detail.sourceInfo.horizontalOffset + numToScroll;
      else
	{
	  if ((offset =
	     winInfo->detail.sourceInfo.horizontalOffset - numToScroll) < 0)
	    offset = 0;
	}
      winInfo->detail.sourceInfo.horizontalOffset = offset;
      tuiUpdateSourceWindowAsIs (
				  winInfo,
				  s,
				  ((TuiWinElementPtr)
				   winInfo->generic.content[0])->whichElement.source.lineOrAddr,
				  FALSE);
    }

  return;
}				/* tuiHorizontalSourceScroll */


/* Set or clear the hasBreak flag in the line whose line is lineNo.  */
void
tuiSetIsExecPointAt (TuiLineOrAddress l, TuiWinInfoPtr winInfo)
{
  int changed = 0;
  int i;
  TuiWinContent content = (TuiWinContent) winInfo->generic.content;

  i = 0;
  while (i < winInfo->generic.contentSize)
    {
      int newState;

      if (content[i]->whichElement.source.lineOrAddr.addr == l.addr)
        newState = TRUE;
      else
	newState = FALSE;
      if (newState != content[i]->whichElement.source.isExecPoint)
        {
          changed++;
          content[i]->whichElement.source.isExecPoint = newState;
          tui_show_source_line (winInfo, i + 1);
        }
      i++;
    }
  if (changed)
    tuiRefreshWin (&winInfo->generic);
}

/* Update the execution windows to show the active breakpoints.
   This is called whenever a breakpoint is inserted, removed or
   has its state changed.  */
void
tui_update_all_breakpoint_info ()
{
  TuiList* list = sourceWindows ();
  int i;

  for (i = 0; i < list->count; i++)
    {
      TuiWinInfoPtr win = (TuiWinInfoPtr) list->list[i];

      if (tui_update_breakpoint_info (win, FALSE))
        {
          tuiUpdateExecInfo (win);
        }
    }
}


/* Scan the source window and the breakpoints to update the
   hasBreak information for each line.
   Returns 1 if something changed and the execution window
   must be refreshed.  */
int
tui_update_breakpoint_info (TuiWinInfoPtr win, int current_only)
{
  int i;
  int need_refresh = 0;
  TuiSourceInfoPtr src = &win->detail.sourceInfo;

  for (i = 0; i < win->generic.contentSize; i++)
    {
      struct breakpoint *bp;
      extern struct breakpoint *breakpoint_chain;
      int mode;
      TuiSourceElement* line;

      line = &((TuiWinElementPtr) win->generic.content[i])->whichElement.source;
      if (current_only && !line->isExecPoint)
         continue;

      /* Scan each breakpoint to see if the current line has something to
         do with it.  Identify enable/disabled breakpoints as well as
         those that we already hit.  */
      mode = 0;
      for (bp = breakpoint_chain;
           bp != (struct breakpoint *) NULL;
           bp = bp->next)
        {
          if ((win == srcWin
               && bp->source_file
               && (strcmp (src->filename, bp->source_file) == 0)
               && bp->line_number == line->lineOrAddr.lineNo)
              || (win == disassemWin
                  && bp->address == line->lineOrAddr.addr))
            {
              if (bp->enable_state == bp_disabled)
                mode |= TUI_BP_DISABLED;
              else
                mode |= TUI_BP_ENABLED;
              if (bp->hit_count)
                mode |= TUI_BP_HIT;
              if (bp->cond)
                mode |= TUI_BP_CONDITIONAL;
              if (bp->type == bp_hardware_breakpoint)
                mode |= TUI_BP_HARDWARE;
            }
        }
      if (line->hasBreak != mode)
        {
          line->hasBreak = mode;
          need_refresh = 1;
        }
    }
  return need_refresh;
}


/*
   ** tuiSetExecInfoContent().
   **      Function to initialize the content of the execution info window,
   **      based upon the input window which is either the source or
   **      disassembly window.
 */
TuiStatus
tuiSetExecInfoContent (TuiWinInfoPtr winInfo)
{
  TuiStatus ret = TUI_SUCCESS;

  if (winInfo->detail.sourceInfo.executionInfo != (TuiGenWinInfoPtr) NULL)
    {
      TuiGenWinInfoPtr execInfoPtr = winInfo->detail.sourceInfo.executionInfo;

      if (execInfoPtr->content == (OpaquePtr) NULL)
	execInfoPtr->content =
	  (OpaquePtr) allocContent (winInfo->generic.height,
				    execInfoPtr->type);
      if (execInfoPtr->content != (OpaquePtr) NULL)
	{
	  int i;

          tui_update_breakpoint_info (winInfo, 1);
	  for (i = 0; i < winInfo->generic.contentSize; i++)
	    {
	      TuiWinElementPtr element;
	      TuiWinElementPtr srcElement;
              int mode;

	      element = (TuiWinElementPtr) execInfoPtr->content[i];
	      srcElement = (TuiWinElementPtr) winInfo->generic.content[i];

              memset(element->whichElement.simpleString, ' ',
                     sizeof(element->whichElement.simpleString));
              element->whichElement.simpleString[TUI_EXECINFO_SIZE - 1] = 0;

	      /* Now update the exec info content based upon the state
                 of each line as indicated by the source content.  */
              mode = srcElement->whichElement.source.hasBreak;
              if (mode & TUI_BP_HIT)
                element->whichElement.simpleString[TUI_BP_HIT_POS] =
                  (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
              else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
                element->whichElement.simpleString[TUI_BP_HIT_POS] =
                  (mode & TUI_BP_HARDWARE) ? 'h' : 'b';

              if (mode & TUI_BP_ENABLED)
                element->whichElement.simpleString[TUI_BP_BREAK_POS] = '+';
              else if (mode & TUI_BP_DISABLED)
                element->whichElement.simpleString[TUI_BP_BREAK_POS] = '-';

              if (srcElement->whichElement.source.isExecPoint)
                element->whichElement.simpleString[TUI_EXEC_POS] = '>';
	    }
	  execInfoPtr->contentSize = winInfo->generic.contentSize;
	}
      else
	ret = TUI_FAILURE;
    }

  return ret;
}


/*
   ** tuiShowExecInfoContent().
 */
void
tuiShowExecInfoContent (TuiWinInfoPtr winInfo)
{
  TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;
  int curLine;

  werase (execInfo->handle);
  tuiRefreshWin (execInfo);
  for (curLine = 1; (curLine <= execInfo->contentSize); curLine++)
    mvwaddstr (execInfo->handle,
	       curLine,
	       0,
	       ((TuiWinElementPtr)
		execInfo->content[curLine - 1])->whichElement.simpleString);
  tuiRefreshWin (execInfo);
  execInfo->contentInUse = TRUE;

  return;
}				/* tuiShowExecInfoContent */


/*
   ** tuiEraseExecInfoContent().
 */
void
tuiEraseExecInfoContent (TuiWinInfoPtr winInfo)
{
  TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;

  werase (execInfo->handle);
  tuiRefreshWin (execInfo);

  return;
}				/* tuiEraseExecInfoContent */

/*
   ** tuiClearExecInfoContent().
 */
void
tuiClearExecInfoContent (TuiWinInfoPtr winInfo)
{
  winInfo->detail.sourceInfo.executionInfo->contentInUse = FALSE;
  tuiEraseExecInfoContent (winInfo);

  return;
}				/* tuiClearExecInfoContent */

/*
   ** tuiUpdateExecInfo().
   **        Function to update the execution info window
 */
void
tuiUpdateExecInfo (TuiWinInfoPtr winInfo)
{
  tuiSetExecInfoContent (winInfo);
  tuiShowExecInfoContent (winInfo);
}				/* tuiUpdateExecInfo */

TuiStatus
tuiAllocSourceBuffer (TuiWinInfoPtr winInfo)
{
  register char *srcLineBuf;
  register int i, lineWidth, maxLines;
  TuiStatus ret = TUI_FAILURE;

  maxLines = winInfo->generic.height;	/* less the highlight box */
  lineWidth = winInfo->generic.width - 1;
  /*
     ** Allocate the buffer for the source lines.  Do this only once since they
     ** will be re-used for all source displays.  The only other time this will
     ** be done is when a window's size changes.
   */
  if (winInfo->generic.content == (OpaquePtr) NULL)
    {
      srcLineBuf = (char *) xmalloc ((maxLines * lineWidth) * sizeof (char));
      if (srcLineBuf == (char *) NULL)
	fputs_unfiltered (
	   "Unable to Allocate Memory for Source or Disassembly Display.\n",
			   gdb_stderr);
      else
	{
	  /* allocate the content list */
	  if ((winInfo->generic.content =
	  (OpaquePtr) allocContent (maxLines, SRC_WIN)) == (OpaquePtr) NULL)
	    {
	      tuiFree (srcLineBuf);
	      srcLineBuf = (char *) NULL;
	      fputs_unfiltered (
				 "Unable to Allocate Memory for Source or Disassembly Display.\n",
				 gdb_stderr);
	    }
	}
      for (i = 0; i < maxLines; i++)
	((TuiWinElementPtr)
	 winInfo->generic.content[i])->whichElement.source.line =
	  srcLineBuf + (lineWidth * i);
      ret = TUI_SUCCESS;
    }
  else
    ret = TUI_SUCCESS;

  return ret;
}				/* tuiAllocSourceBuffer */


/*
   ** tuiLineIsDisplayed().
   **      Answer whether the a particular line number or address is displayed
   **      in the current source window.
 */
int
tuiLineIsDisplayed (int line, TuiWinInfoPtr winInfo,
                    int checkThreshold)
{
  int isDisplayed = FALSE;
  int i, threshold;

  if (checkThreshold)
    threshold = SCROLL_THRESHOLD;
  else
    threshold = 0;
  i = 0;
  while (i < winInfo->generic.contentSize - threshold && !isDisplayed)
    {
      isDisplayed = (((TuiWinElementPtr)
		      winInfo->generic.content[i])->whichElement.source.lineOrAddr.lineNo
		     == (int) line);
      i++;
    }

  return isDisplayed;
}				/* tuiLineIsDisplayed */


/*
   ** tuiLineIsDisplayed().
   **      Answer whether the a particular line number or address is displayed
   **      in the current source window.
 */
int
tuiAddrIsDisplayed (CORE_ADDR addr, TuiWinInfoPtr winInfo,
		    int checkThreshold)
{
  int isDisplayed = FALSE;
  int i, threshold;

  if (checkThreshold)
    threshold = SCROLL_THRESHOLD;
  else
    threshold = 0;
  i = 0;
  while (i < winInfo->generic.contentSize - threshold && !isDisplayed)
    {
      isDisplayed = (((TuiWinElementPtr)
		      winInfo->generic.content[i])->whichElement.source.lineOrAddr.addr
		     == addr);
      i++;
    }

  return isDisplayed;
}


/*****************************************
** STATIC LOCAL FUNCTIONS               **
******************************************/
