/* TUI display source/assembly window.

   Copyright 1998, 1999, 2000, 2001, 2002, 2003 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.  */

#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"

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

/* 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 (get_frame_pc (deprecated_selected_frame));
      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               **
******************************************/
